33 #include <condition_variable>
36 #include <arpa/inet.h>
47 #define DEFAULT_ALLOW_OPTIMISTIC_SEND true
49 #define DEFAULT_ALLOW_OPTIMISTIC_SEND false
50 #define USE_WAKEUP_PIPE
60 static const int PING_INTERVAL = 2 * 60;
62 static const int TIMEOUT_INTERVAL = 20 * 60;
64 static const int FEELER_INTERVAL = 120;
66 static const unsigned int MAX_INV_SZ = 50000;
68 static const unsigned int MAX_LOCATOR_SZ = 101;
70 static constexpr
size_t MAX_ADDR_TO_SEND = 1000;
72 static constexpr
double MAX_ADDR_RATE_PER_SECOND{0.1};
76 static constexpr
size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET{MAX_ADDR_TO_SEND};
78 static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
80 static const unsigned int MAX_SUBVERSION_LENGTH = 256;
82 static const int MAX_OUTBOUND_CONNECTIONS = 16;
84 static const int MAX_ADDNODE_CONNECTIONS = 16;
86 static const int INBOUND_EVICTION_PROTECTION_TIME = 1;
88 static const bool DEFAULT_LISTEN =
true;
90 static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
92 static const size_t SETASKFOR_MAX_SZ = 2 * MAX_INV_SZ;
94 static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS = 125;
96 #define ENOUGH_CONNECTIONS 2
98 #define MAX_TIMEOFFSET_DISCONNECTIONS 16
102 static const bool DEFAULT_FORCEDNSSEED =
false;
103 static const size_t DEFAULT_MAXRECEIVEBUFFER = 5 * 1000;
104 static const size_t DEFAULT_MAXSENDBUFFER = 1 * 1000;
107 static const unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24;
118 AddedNodeInfo(
const std::string& _strAddedNode,
const CService& _resolvedAddress,
bool _fConnected,
bool _fInbound):
139 std::vector<unsigned char>
data;
195 CConnman(uint64_t seed0, uint64_t seed1);
205 const char* strDest =
nullptr,
206 bool fOneShot =
false,
207 bool fFeeler =
false,
208 bool fAddnode =
false,
209 bool masternode_connection =
false,
210 bool masternode_probe_connection =
false);
225 bool ForNode(
const CService& addr,
const std::function<
bool(
const CNode* pnode)>& cond,
const std::function<
bool(
CNode* pnode)>& func);
229 template<
typename Callable>
233 for (
auto&& node :
vNodes)
241 template<
typename Callable>
246 std::vector<CNode*> nodesCopy =
vNodes;
247 std::shuffle(nodesCopy.begin(), nodesCopy.end(), ctx);
248 for (
auto&& node : nodesCopy)
256 template<
typename Callable>
260 for (
auto&& node :
vNodes) {
266 template<
typename Callable>
270 for (
auto&& node :
vNodes) {
276 template<
typename Callable,
typename CallableAfter>
280 for (
auto&& node :
vNodes) {
287 template<
typename Callable,
typename CallableAfter>
291 for (
auto&& node :
vNodes) {
338 void Ban(
const CNetAddr& netAddr,
const BanReason& reason, int64_t bantimeoffset = 0,
bool sinceUnixEpoch =
false);
339 void Ban(
const CSubNet& subNet,
const BanReason& reason, int64_t bantimeoffset = 0,
bool sinceUnixEpoch =
false);
348 bool AddNode(
const std::string& node);
391 bool InitBinds(
const std::vector<CService>& binds,
const std::vector<CService>& whiteBinds);
401 bool GenerateSelectSet(std::set<SOCKET>& recv_set, std::set<SOCKET>& send_set, std::set<SOCKET>& error_set);
402 void SocketEvents(std::set<SOCKET>& recv_set, std::set<SOCKET>& send_set, std::set<SOCKET>& error_set);
500 #ifdef USE_WAKEUP_PIPE
514 extern std::unique_ptr<CConnman>
g_connman;
523 template <
typename I>
526 while (first != last) {
527 if (!(*first))
return false;
582 extern std::map<CNetAddr, LocalServiceInfo>
mapLocalHost;
662 int readHeader(
const char* pch,
unsigned int nBytes);
663 int readData(
const char* pch,
unsigned int nBytes);
805 CNode(
NodeId id,
ServiceFlags nLocalServicesIn,
int nMyStartingHeightIn,
SOCKET hSocketIn,
const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
const std::string& addrNameIn =
"",
bool fInboundIn =
false);
846 unsigned int total = 0;
848 total += msg.vRecv.size() + 24;
852 bool ReceiveMsgBytes(
const char* pch,
unsigned int nBytes,
bool& complete);
928 void AskFor(
const CInv& inv, int64_t doubleRequestDelay = 2 * 60 * 1000000);
971 inline std::chrono::microseconds
PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
973 return std::chrono::microseconds{
PoissonNextSend(now.count(), average_interval.count())};
std::map< CSubNet, CBanEntry > banmap_t
Stochastical (IP) address manager.
std::vector< bool > m_asmap
A CService with information about it as peer.
void resize(size_type n, value_type c=0)
The block chain is a tree shaped structure starting with the genesis block at the root,...
Signals for UI communication.
std::condition_variable condMsgProc
void SweepBanned()
clean unused entries (if bantime has expired)
std::thread threadMessageHandler
void ThreadOpenAddedConnections()
int GetBestHeight() const
void ReleaseNodeVector(const std::vector< CNode * > &vecNodes)
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
void DeleteNode(CNode *pnode)
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
std::unique_ptr< TierTwoConnMan > m_tiertwo_conn_man
bool GetNetworkActive() const
void ForEachNodeThen(Callable &&pre, CallableAfter &&post) const
ServiceFlags nLocalServices
Services this instance offers.
size_t GetNodeCount(NumConnections num)
std::atomic< bool > flagInterruptMsgProc
unsigned int GetReceiveFloodSize() const
std::list< CNode * > vNodesDisconnected
uint64_t GetTotalBytesRecv()
void SetBestHeight(int height)
bool ForEachNodeInRandomOrderContinueIf(Callable &&func)
void ForEachNodeThen(Callable &&pre, CallableAfter &&post)
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
void AddNewAddress(const CAddress &addr, const CAddress &addrFrom, int64_t nTimePenalty=0)
std::vector< std::string > vAddedNodes GUARDED_BY(cs_vAddedNodes)
CThreadInterrupt interruptNet
std::unique_ptr< CSemaphore > semAddnode
std::atomic< NodeId > nLastNodeId
void SetServices(const CService &addr, ServiceFlags nServices)
void RecordBytesSent(uint64_t bytes)
std::thread threadDNSAddressSeed
bool Unban(const CNetAddr &ip)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, Optional< Network > network)
Return all or many randomly selected addresses, optionally by network.
std::deque< std::string > vOneShots
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound=nullptr, const char *strDest=nullptr, bool fOneShot=false, bool fFeeler=false, bool fAddnode=false, bool masternode_connection=false, bool masternode_probe_connection=false)
unsigned int nPrevNodeCount
void NotifyNumConnectionsChanged()
void SetBannedSetDirty(bool dirty=true)
set the "dirty" flag for the banlist
ServiceFlags GetLocalServices() const
bool DisconnectNode(const std::string &node)
size_t SocketSendData(CNode *pnode)
ServiceFlags nRelevantServices
Services this instance cares about.
std::vector< CNode * > CopyNodeVector()
std::vector< ListenSocket > vhListenSocket
void ThreadOpenConnections(const std::vector< std::string > connect)
size_t GetMaxOutboundNodeCount()
CClientUIInterface * clientInterface
void GetBanned(banmap_t &banmap)
std::unique_ptr< CSemaphore > semOutbound
void ThreadSocketHandler()
RecursiveMutex cs_totalBytesSent
std::thread threadOpenConnections
void ForEachNode(Callable &&func) const
RecursiveMutex cs_vOneShots
bool fMsgProcWake
flag for waking the message processor.
CNode * FindNode(const CNetAddr &ip)
void Init(const Options &connOptions)
constexpr static const CAllNodes AllNodes
unsigned int GetSendBufferSize() const
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg, bool allowOptimisticSend=DEFAULT_ALLOW_OPTIMISTIC_SEND)
void MarkAddressGood(const CAddress &addr)
void RelayInv(CInv &inv, int minProtoVersion=ActiveProtocol())
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
unsigned int nReceiveFloodSize
std::atomic< bool > wakeupSelectNeeded
RecursiveMutex cs_totalBytesRecv
static bool NodeFullyConnected(const CNode *pnode)
void WakeMessageHandler()
void SetNetworkActive(bool active)
void SetAsmap(std::vector< bool > asmap)
bool IsBanned(CNetAddr ip)
bool AttemptToEvictConnection(bool fPreferNewConnection)
Try to find a connection to evict when the node is full.
bool Start(CScheduler &scheduler, const Options &options)
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
bool Bind(const CService &addr, unsigned int flags)
bool IsNodeConnected(const CAddress &addr)
void ThreadDNSAddressSeed()
int wakeupPipe[2]
a pipe which is added to select() calls to wakeup before the timeout
std::vector< CSubNet > vWhitelistedRange
void ThreadMessageHandler()
bool fAddressesInitialized
uint64_t GetTotalBytesSent()
void WakeSelect()
Interrupt the select/poll system call.
RecursiveMutex cs_vAddedNodes
std::thread threadOpenAddedConnections
CSipHasher GetDeterministicRandomizer(uint64_t id)
Get a unique deterministic randomizer.
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
bool BannedSetIsDirty()
check is the banlist has unwritten changes
void InactivityCheck(CNode *pnode)
std::atomic< int > nBestHeight
bool CheckIncomingNonce(uint64_t nonce)
uint64_t nTotalBytesRecv GUARDED_BY(cs_totalBytesRecv)=0
bool BindListenPort(const CService &bindAddr, std::string &strError, bool fWhitelisted=false)
TierTwoConnMan * GetTierTwoConnMan()
Unique tier two connections manager.
void RecordBytesRecv(uint64_t bytes)
std::vector< AddedNodeInfo > GetAddedNodeInfo()
void GetNodeStats(std::vector< CNodeStats > &vstats)
constexpr static const CFullyConnectedOnly FullyConnectedOnly
bool InitBinds(const std::vector< CService > &binds, const std::vector< CService > &whiteBinds)
std::vector< CNode * > vNodes
unsigned int nSendBufferMaxSize
void RemoveAskFor(const uint256 &invHash, int invType)
NetEventsInterface * m_msgproc
void UpdateQuorumRelayMemberIfNeeded(CNode *pnode)
Update the node to be a iqr member if needed.
void SetBanned(const banmap_t &banmap)
std::atomic< bool > fNetworkActive
RecursiveMutex cs_setBanned
void ForEachNode(Callable &&func)
CConnman(uint64_t seed0, uint64_t seed1)
bool ForEachNodeContinueIf(Callable &&func)
uint64_t nTotalBytesSent GUARDED_BY(cs_totalBytesSent)=0
bool AddNode(const std::string &node)
std::thread threadSocketHandler
uint64_t CalculateKeyedNetGroup(const CAddress &ad)
bool RemoveAddedNode(const std::string &node)
void AddOneShot(const std::string &strDest)
CNode * ConnectNode(const CAddress &addrConnect)
bool IsWhitelistedRange(const CNetAddr &addr)
void AcceptConnection(const ListenSocket &hListenSocket)
static void callCleanup()
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
bool IsAddrV1Compatible() const
Check if the current object can be serialized in pre-ADDRv2/BIP155 format.
CNetMessage(const CMessageHeader::MessageStartChars &pchMessageStartIn, int nTypeIn, int nVersionIn)
int readHeader(const char *pch, unsigned int nBytes)
const uint256 & GetMessageHash() const
void SetVersion(int nVersionIn)
int readData(const char *pch, unsigned int nBytes)
Information about a peer.
RecursiveMutex cs_vProcessMsg
std::atomic< int64_t > nLastSend
CRollingBloomFilter filterInventoryKnown
std::atomic< int > nVersion
void SetSendVersion(int nVersionIn)
std::atomic< bool > m_masternode_connection
std::vector< uint256 > vInventoryBlockToSend
std::deque< std::vector< unsigned char > > vSendMsg
std::atomic_bool fPauseRecv
std::atomic< int64_t > nTimeOffset
RecursiveMutex cs_sendProcessing
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
RecursiveMutex cs_inventory
std::atomic< bool > fPingQueued
int GetSendVersion() const
unsigned int GetTotalRecvSize()
std::list< CNetMessage > vRecvMsg
mapMsgCmdSize mapRecvBytesPerMsgCmd
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
void AskForInvReceived(const uint256 &invHash)
std::atomic_bool fSuccessfullyConnected
ServiceFlags nServicesExpected
bool DisconnectOldProtocol(int nVersionIn, int nVersionRequired)
uint64_t GetLocalNonce() const
std::atomic< ServiceFlags > nServices
CRollingBloomFilter addrKnown
uint256 verifiedProRegTxHash
RecursiveMutex cs_addrLocal
CSemaphoreGrant grantOutbound
const int64_t nTimeConnected
std::string GetAddrName() const
uint256 verifiedPubKeyHash
mapMsgCmdSize mapSendBytesPerMsgCmd
std::atomic< bool > fFirstMessageIsMNAUTH
std::atomic< bool > m_wants_recsigs
const uint64_t nKeyedNetGroup
std::atomic< int > nRefCount
std::atomic< int64_t > m_last_wants_recsigs_recv
void AskFor(const CInv &inv, int64_t doubleRequestDelay=2 *60 *1000000)
RecursiveMutex cs_addrName
int GetMyStartingHeight() const
void CloseSocketDisconnect()
uint256 sentMNAuthChallenge
std::atomic< int > nStartingHeight
std::atomic_bool fPauseSend
std::atomic< bool > fFirstMessageReceived
std::multimap< int64_t, CInv > mapAskFor
std::unique_ptr< CBloomFilter > pfilter
void PushInventory(const CInv &inv)
const ServiceFlags nLocalServices
std::chrono::microseconds m_next_addr_send GUARDED_BY(cs_sendProcessing)
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete)
void copyStats(CNodeStats &stats, const std::vector< bool > &m_asmap)
void MaybeSetAddrName(const std::string &addrNameIn)
Sets the addrName only if it was not previously set.
std::atomic< int64_t > timeLastMempoolReq
void AddAddressKnown(const CAddress &_addr)
std::atomic< int64_t > nLastRecv
void SetRecvVersion(int nVersionIn)
std::deque< CInv > vRecvGetData
uint256 receivedMNAuthChallenge
std::atomic< int64_t > nMinPingUsecTime
std::atomic< uint64_t > nPingNonceSent
RecursiveMutex cs_hSocket
std::vector< CAddress > vAddrToSend
std::set< uint256 > setAskFor
const int nMyStartingHeight
const uint64_t nLocalHostNonce
std::atomic< int64_t > nPingUsecStart
std::chrono::microseconds nNextInvSend
ServiceFlags GetLocalServices() const
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string &addrNameIn="", bool fInboundIn=false)
std::set< uint256 > setKnown
CNode(const CNode &)=delete
std::atomic< int64_t > nPingUsecTime
std::vector< uint256 > vBlockRequested
void AddInventoryKnown(const CInv &inv)
std::atomic< bool > m_masternode_probe_connection
std::list< CNetMessage > vProcessMsg
std::atomic_bool m_wants_addrv2
Whether the peer has signaled support for receiving ADDRv2 (BIP155) messages, implying a preference t...
std::chrono::microseconds m_next_local_addr_send GUARDED_BY(cs_sendProcessing)
std::atomic< bool > m_masternode_iqr_connection
std::atomic_bool fDisconnect
double m_addr_token_bucket
Number of addresses that can be processed from this peer.
CService GetAddrLocal() const
std::vector< CInv > vInventoryTierTwoToSend
std::set< uint256 > setInventoryTxToSend
std::atomic< int > nRecvVersion
CNode & operator=(const CNode &)=delete
std::chrono::microseconds m_addr_token_timestamp
When m_addr_token_bucket was last updated.
bool m_masternode_probe_connection
mapMsgCmdSize mapSendBytesPerMsgCmd
bool m_masternode_iqr_connection
bool m_masternode_connection
uint256 verifiedPubKeyHash
mapMsgCmdSize mapRecvBytesPerMsgCmd
uint256 verifiedProRegTxHash
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
void insert(const std::vector< unsigned char > &vKey)
bool contains(const std::vector< unsigned char > &vKey) const
RAII-style semaphore lock.
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< unsigned char > GetKey() const
The basic transaction that is broadcasted on the network and contained in blocks.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Interface for message handling.
virtual void InitializeNode(CNode *pnode)=0
virtual bool SendMessages(CNode *pnode, std::atomic< bool > &interrupt) EXCLUSIVE_LOCKS_REQUIRED(pnode -> cs_sendProcessing)=0
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
virtual void FinalizeNode(NodeId id, bool &update_connection_time)=0
STL-like map container that only keeps the N elements with the highest value.
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool RemoveLocal(const CService &addr)
bool IsPeerAddrLocalGood(CNode *pnode)
std::map< CNetAddr, LocalServiceInfo > mapLocalHost
void AdvertiseLocal(CNode *pnode)
std::unique_ptr< CConnman > g_connman
bool IsLocal(const CService &addr)
check whether a given address is potentially local
bool AddLocal(const CService &addr, int nScore=LOCAL_NONE)
RecursiveMutex cs_mapLocalHost
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
bool BindListenPort(const CService &bindAddr, std::string &strError, bool fWhitelisted=false)
bool validateMasternodeIP(const std::string &addrStr)
std::map< std::string, uint64_t > mapMsgCmdSize
bool GetLocal(CService &addr, const CNetAddr *paddrPeer=nullptr)
#define DEFAULT_ALLOW_OPTIMISTIC_SEND
void CheckOffsetDisconnectedPeers(const CNetAddr &ip)
limitedmap< CInv, int64_t > mapAlreadyAskedFor
bool IsReachable(enum Network net)
bool SeenLocal(const CService &addr)
vote for a local address
boost::optional< T > Optional
Substitute for C++17 std::optional.
ServiceFlags
nServices flags
AddedNodeInfo(const std::string &_strAddedNode, const CService &_resolvedAddress, bool _fConnected, bool _fInbound)
bool operator()(const CNode *) const
bool operator()(const CNode *pnode) const
ListenSocket(SOCKET socket_, bool whitelisted_)
std::vector< CSubNet > vWhitelistedRange
unsigned int nReceiveFloodSize
CClientUIInterface * uiInterface
std::vector< std::string > m_specified_outgoing
NetEventsInterface * m_msgproc
ServiceFlags nLocalServices
std::vector< bool > m_asmap
std::vector< std::string > m_added_nodes
std::vector< CService > vWhiteBinds
std::vector< CService > vBinds
ServiceFlags nRelevantServices
unsigned int nSendBufferMaxSize
std::vector< std::string > vSeedNodes
bool m_use_addrman_outgoing
CSerializedNetMsg(const CSerializedNetMsg &msg)=delete
CSerializedNetMsg & operator=(const CSerializedNetMsg &)=delete
CSerializedNetMsg()=default
CSerializedNetMsg(CSerializedNetMsg &&)=default
CSerializedNetMsg & operator=(CSerializedNetMsg &&)=default
std::vector< unsigned char > data
bool operator()(I first, I last) const
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.