31#include <condition_variable>
109 std::vector<unsigned char>
data;
348 hdrbuf(nTypeIn, nVersionIn),
349 vRecv(nTypeIn, nVersionIn)
371 msg_bytes = msg_bytes.
subspan(ret);
578 std::atomic<std::chrono::microseconds>
m_min_ping_time{std::chrono::microseconds::max()};
639 m_tx_relay->filterInventoryKnown.insert(hash);
647 if (!
m_tx_relay->filterInventoryKnown.contains(hash)) {
648 m_tx_relay->setInventoryTxToSend.insert(hash);
827 for (
auto&&
node : vNodes) {
836 for (
auto&&
node : vNodes) {
850 std::vector<CAddress>
GetAddresses(
size_t max_addresses,
size_t max_pct, std::optional<Network> network)
const;
857 std::vector<CAddress>
GetAddresses(
CNode& requestor,
size_t max_addresses,
size_t max_pct);
898 void GetNodeStats(std::vector<CNodeStats>& vstats)
const;
942 std::chrono::microseconds
PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval);
986 bool GenerateSelectSet(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
987 void SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set);
1185std::chrono::microseconds
PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval);
1213[[nodiscard]] std::optional<NodeId>
SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates);
int64_t CAmount
Amount in satoshis (Can be negative)
#define Assume(val)
Assume is the identity function.
Stochastic address manager.
A CService with information about it as peer.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Signals for UI communication.
void CreateNodeFromAcceptedSocket(SOCKET hSocket, NetPermissionFlags permissionFlags, const CAddress &addr_bind, const CAddress &addr)
Create a CNode object from a socket that has just been accepted and add the node to the vNodes member...
std::condition_variable condMsgProc
uint64_t nTotalBytesSent GUARDED_BY(cs_totalBytesSent)
std::chrono::seconds nMaxOutboundCycleStartTime GUARDED_BY(cs_totalBytesSent)
std::thread threadMessageHandler
void ForEachNode(const NodeFn &func)
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const
returns the time left in the current max outbound cycle in case of no limit, it will always return 0
void ThreadOpenAddedConnections()
bool OutboundTargetReached(bool historicalBlockServingLimit) const
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
CClientUIInterface * m_client_interface
size_t SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
void ForEachNode(const NodeFn &func) const
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
std::vector< AddedNodeInfo > GetAddedNodeInfo() const
bool AddConnection(const std::string &address, ConnectionType conn_type)
Attempts to open a connection.
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
void DeleteNode(CNode *pnode)
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
bool GetNetworkActive() const
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
void AddAddrFetch(const std::string &strDest)
ServiceFlags nLocalServices
Services this instance offers.
bool GetTryNewOutboundPeer() const
int m_max_outbound_block_relay
std::thread threadI2PAcceptIncoming
void SetTryNewOutboundPeer(bool flag)
std::atomic< bool > flagInterruptMsgProc
unsigned int GetReceiveFloodSize() const
std::list< CNode * > vNodesDisconnected
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
std::unique_ptr< CSemaphore > semAddnode
std::atomic< NodeId > nLastNodeId
std::atomic< std::chrono::microseconds > m_next_send_inv_to_incoming
bool ShouldRunInactivityChecks(const CNode &node, int64_t secs_now) const
Return true if we should disconnect the peer for failing an inactivity check.
void RecordBytesSent(uint64_t bytes)
bool fMsgProcWake GUARDED_BY(mutexMsgProc)
flag for waking the message processor.
int GetExtraBlockRelayCount() const
BanMan * m_banman
Pointer to this node's banman.
uint64_t GetOutboundTargetBytesLeft() const
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
std::thread threadDNSAddressSeed
std::vector< std::string > vAddedNodes GUARDED_BY(cs_vAddedNodes)
void ThreadOpenConnections(std::vector< std::string > connect)
void ThreadI2PAcceptIncoming()
void StartExtraBlockRelayPeers()
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
RecursiveMutex m_addr_fetches_mutex
std::chrono::seconds GetMaxOutboundTimeframe() const
unsigned int nPrevNodeCount
void NotifyNumConnectionsChanged()
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
bool DisconnectNode(const std::string &node)
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of m_max_outbound_full_relay This t...
bool InitBinds(const Options &options)
uint64_t nMaxOutboundTotalBytesSentInCycle GUARDED_BY(cs_totalBytesSent)
std::vector< ListenSocket > vhListenSocket
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
uint64_t GetMaxOutboundTarget() const
std::unique_ptr< CSemaphore > semOutbound
std::vector< NetWhitelistPermissions > vWhitelistedRange
void ThreadSocketHandler()
RecursiveMutex cs_totalBytesSent
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
std::thread threadOpenConnections
size_t GetNodeCount(ConnectionDirection) const
int64_t m_peer_connect_timeout
std::vector< CNode * > vNodes GUARDED_BY(cs_vNodes)
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
CNode * FindNode(const CNetAddr &ip)
void Init(const Options &connOptions)
void GetNodeStats(std::vector< CNodeStats > &vstats) const
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
unsigned int nReceiveFloodSize
int GetExtraFullOutboundCount() const
uint64_t GetTotalBytesRecv() const
RecursiveMutex cs_totalBytesRecv
static bool NodeFullyConnected(const CNode *pnode)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
uint64_t nTotalBytesRecv GUARDED_BY(cs_totalBytesRecv)
void WakeMessageHandler()
void SetNetworkActive(bool active)
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
std::deque< std::string > m_addr_fetches GUARDED_BY(m_addr_fetches_mutex)
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
bool Start(CScheduler &scheduler, const Options &options)
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
void ThreadDNSAddressSeed()
void ThreadMessageHandler()
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
bool fAddressesInitialized
std::chrono::microseconds PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval)
Attempts to obfuscate tx time through exponentially distributed emitting.
RecursiveMutex cs_vAddedNodes
std::thread threadOpenAddedConnections
friend struct CConnmanTest
bool CheckIncomingNonce(uint64_t nonce)
int m_max_outbound_full_relay
void RecordBytesRecv(uint64_t bytes)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
bool GetUseAddrmanOutgoing() const
unsigned int nSendBufferMaxSize
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
bool m_use_addrman_outgoing
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
std::function< void(CNode *)> NodeFn
NetEventsInterface * m_msgproc
uint64_t nMaxOutboundLimit GUARDED_BY(cs_totalBytesSent)
std::atomic< bool > fNetworkActive
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
CConnman(uint64_t seed0, uint64_t seed1, AddrMan &addrman, bool network_active=true)
std::vector< CService > m_onion_binds
A vector of -bind=<address>:<port>=onion arguments each of which is an address and port that are desi...
bool AddNode(const std::string &node)
std::thread threadSocketHandler
uint64_t GetTotalBytesSent() const
bool RemoveAddedNode(const std::string &node)
void AcceptConnection(const ListenSocket &hListenSocket)
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
Double ended buffer combining vector and stream-like interfaces.
void resize(size_type n, value_type c=0)
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
Transport protocol agnostic message container.
CNetMessage(CDataStream &&recv_in)
uint32_t m_message_size
size of the payload
std::chrono::microseconds m_time
time of message receipt
CDataStream m_recv
received message data
void SetVersion(int nVersionIn)
uint32_t m_raw_message_size
used wire size of the message (including header/checksum)
Information about a peer.
RecursiveMutex cs_vProcessMsg
std::atomic< int64_t > nLastSend
bool IsFeelerConn() const
mapMsgCmdSize mapSendBytesPerMsgCmd GUARDED_BY(cs_vSend)
bool ExpectServicesFromConn() const
std::atomic< int > nVersion
uint64_t nRecvBytes GUARDED_BY(cs_vRecv)
bool IsInboundConn() const
bool HasPermission(NetPermissionFlags permission) const
std::atomic_bool fPauseRecv
bool IsOutboundOrBlockRelayConn() const
bool IsManualConn() const
void PushTxInventory(const uint256 &hash)
std::atomic< int64_t > nTimeOffset
RecursiveMutex cs_sendProcessing
const std::string m_addr_name
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv)
CNode & operator=(const CNode &)=delete
std::deque< std::vector< unsigned char > > vSendMsg GUARDED_BY(cs_vSend)
std::string ConnectionTypeAsString() const
void SetCommonVersion(int greatest_common_version)
std::atomic< bool > m_bip152_highbandwidth_to
std::list< CNetMessage > vRecvMsg
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
std::atomic< bool > m_bip152_highbandwidth_from
void PongReceived(std::chrono::microseconds ping_time)
A ping-pong round trip has completed successfully.
std::atomic_bool fSuccessfullyConnected
fSuccessfullyConnected is set to true on receiving VERACK from the peer.
bool IsAddrFetchConn() const
uint64_t GetLocalNonce() const
std::atomic< ServiceFlags > nServices
bool ReceiveMsgBytes(Span< const uint8_t > msg_bytes, bool &complete)
Receive bytes from the buffer and deserialize them into messages.
RecursiveMutex cs_addrLocal
CSemaphoreGrant grantOutbound
const int64_t nTimeConnected
Unix epoch time at peer connection, in seconds.
const uint64_t nKeyedNetGroup
void CopyStats(CNodeStats &stats)
std::atomic< int > nRefCount
std::atomic< int > m_greatest_common_version
bool IsBlockOnlyConn() const
void CloseSocketDisconnect()
int GetCommonVersion() const
bool IsFullOutboundConn() const
std::unique_ptr< TransportSerializer > m_serializer
std::atomic_bool fPauseSend
SOCKET hSocket GUARDED_BY(cs_hSocket)
const ServiceFlags nLocalServices
Services offered to this peer.
std::unique_ptr< TxRelay > m_tx_relay
std::unique_ptr< TransportDeserializer > m_deserializer
size_t nSendOffset GUARDED_BY(cs_vSend)
Offset inside the first vSendMsg already sent.
NetPermissionFlags m_permissionFlags
std::atomic< int64_t > nLastRecv
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
const ConnectionType m_conn_type
Network ConnectedThroughNetwork() const
Get network the peer connected through.
CService addrLocal GUARDED_BY(cs_addrLocal)
const uint64_t nLocalHostNonce
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
CNode(NodeId id, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
size_t nSendSize GUARDED_BY(cs_vSend)
Total size of all vSendMsg entries.
ServiceFlags GetLocalServices() const
std::string cleanSubVer GUARDED_BY(cs_SubVer)
cleanSubVer is a sanitized string of the user agent byte array we read from the wire.
CNode(const CNode &)=delete
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e. connected via our Tor onion service.
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
void AddKnownTx(const uint256 &hash)
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
uint64_t nSendBytes GUARDED_BY(cs_vSend)
std::atomic_bool fDisconnect
CService GetAddrLocal() const
std::list< CNetMessage > vProcessMsg GUARDED_BY(cs_vProcessMsg)
mapMsgCmdSize mapSendBytesPerMsgCmd
std::chrono::microseconds m_last_ping_time
ConnectionType m_conn_type
std::chrono::microseconds m_min_ping_time
bool m_bip152_highbandwidth_from
bool m_bip152_highbandwidth_to
mapMsgCmdSize mapRecvBytesPerMsgCmd
NetPermissionFlags m_permissionFlags
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
Simple class for background tasks that should be run periodically or once "after a while".
RAII-style semaphore lock.
A combination of a network address (CNetAddr) and a (TCP) port.
Interface for message handling.
virtual void FinalizeNode(const CNode &node)=0
Handle removal of a peer (clear state)
virtual void InitializeNode(CNode *pnode)=0
Initialize a peer (setup state, queue any initial messages)
virtual bool SendMessages(CNode *pnode) EXCLUSIVE_LOCKS_REQUIRED(pnode -> cs_sendProcessing)=0
Send queued protocol messages to a given node.
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
Process protocol messages received from a given node.
~NetEventsInterface()=default
Protected destructor so that instances can only be deleted by derived classes.
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
A Span is an object that can refer to a contiguous sequence of objects.
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
The TransportDeserializer takes care of holding and deserializing the network receive buffer.
virtual ~TransportDeserializer()
virtual bool Complete() const =0
virtual CNetMessage GetMessage(std::chrono::microseconds time, bool &reject_message)=0
virtual int Read(Span< const uint8_t > &msg_bytes)=0
read and deserialize data, advances msg_bytes data pointer
virtual void SetVersion(int version)=0
The TransportSerializer prepares messages for the network transport.
virtual void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header)=0
virtual ~TransportSerializer()
const CChainParams & m_chain_params
CNetMessage GetMessage(std::chrono::microseconds time, bool &reject_message) override
const uint256 & GetMessageHash() const
int Read(Span< const uint8_t > &msg_bytes) override
read and deserialize data, advances msg_bytes data pointer
V1TransportDeserializer(const CChainParams &chain_params, const NodeId node_id, int nTypeIn, int nVersionIn)
void SetVersion(int nVersionIn) override
int readData(Span< const uint8_t > msg_bytes)
int readHeader(Span< const uint8_t > msg_bytes)
bool Complete() const override
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) override
static CService ip(uint32_t i)
#define LogPrint(category,...)
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool IsPeerAddrLocalGood(CNode *pnode)
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS
The maximum number of peer connections to maintain.
bool IsLocal(const CService &addr)
check whether a given address is potentially local
void RemoveLocal(const CService &addr)
static const unsigned int MAX_SUBVERSION_LENGTH
Maximum length of the user agent string in version message.
static const int MAX_ADDNODE_CONNECTIONS
Maximum number of addnode outgoing nodes.
bool AddLocal(const CService &addr, int nScore=LOCAL_NONE)
static const size_t DEFAULT_MAXSENDBUFFER
static const int NUM_FDS_MESSAGE_CAPTURE
Number of file descriptors required for message capture.
static constexpr bool DEFAULT_FIXEDSEEDS
static const bool DEFAULT_BLOCKSONLY
Default for blocks only.
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
RecursiveMutex cs_mapLocalHost
static constexpr uint64_t DEFAULT_MAX_UPLOAD_TARGET
The default for -maxuploadtarget.
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
static const size_t DEFAULT_MAXRECEIVEBUFFER
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(cs_mapLocalHost)
const std::string NET_MESSAGE_COMMAND_OTHER
static const int TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
void CaptureMessage(const CAddress &addr, const std::string &msg_type, const Span< const unsigned char > &data, bool is_incoming)
Dump binary message to file, with timestamp.
std::optional< CAddress > GetLocalAddrForPeer(CNode *pnode)
Returns a local address that we should advertise to this peer.
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
static constexpr bool DEFAULT_FORCEDNSSEED
ConnectionType
Different types of connections to a peer.
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
@ MANUAL
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
@ INBOUND
Inbound connections are those initiated by a peer.
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
static constexpr bool DEFAULT_DNSSEED
std::map< std::string, uint64_t > mapMsgCmdSize
static const int MAX_FEELER_CONNECTIONS
Maximum number of feeler connections.
static const bool DEFAULT_LISTEN
-listen default
bool GetLocal(CService &addr, const CNetAddr *paddrPeer=nullptr)
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
static const int64_t DEFAULT_PEER_CONNECT_TIMEOUT
-peertimeout default
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &vEvictionCandidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS
Maximum number of automatic outgoing nodes over which we'll relay everything (blocks,...
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
bool IsReachable(enum Network net)
bool SeenLocal(const CService &addr)
vote for a local address
std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
ServiceFlags
nServices flags
Cache responses to addr requests to minimize privacy leak.
std::chrono::microseconds m_cache_entry_expiration
std::vector< CAddress > m_addrs_response_cache
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
ListenSocket(SOCKET socket_, NetPermissionFlags permissions_)
NetPermissionFlags m_permissions
int m_max_outbound_block_relay
unsigned int nReceiveFloodSize
int m_max_outbound_full_relay
std::vector< NetWhitebindPermissions > vWhiteBinds
uint64_t nMaxOutboundLimit
std::vector< NetWhitelistPermissions > vWhitelistedRange
CClientUIInterface * uiInterface
std::vector< CService > onion_binds
std::vector< std::string > m_specified_outgoing
NetEventsInterface * m_msgproc
ServiceFlags nLocalServices
std::vector< std::string > m_added_nodes
int64_t m_peer_connect_timeout
std::vector< CService > vBinds
unsigned int nSendBufferMaxSize
bool m_i2p_accept_incoming
std::vector< std::string > vSeedNodes
bool m_use_addrman_outgoing
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0....
CRollingBloomFilter filterInventoryKnown GUARDED_BY(cs_tx_inventory)
std::set< uint256 > setInventoryTxToSend
CAmount lastSentFeeFilter
std::chrono::microseconds m_next_send_feefilter
std::unique_ptr< CBloomFilter > pfilter PT_GUARDED_BY(cs_filter) GUARDED_BY(cs_filter)
std::chrono::microseconds nNextInvSend
bool fSendMempool GUARDED_BY(cs_tx_inventory)
std::atomic< CAmount > minFeeFilter
Minimum fee rate with which to filter inv's to this node.
std::atomic< std::chrono::seconds > m_last_mempool_req
bool fRelayTxes GUARDED_BY(cs_filter)
RecursiveMutex cs_tx_inventory
CSerializedNetMsg(const CSerializedNetMsg &msg)=delete
CSerializedNetMsg & operator=(CSerializedNetMsg &&)=default
CSerializedNetMsg & operator=(const CSerializedNetMsg &)=delete
CSerializedNetMsg()=default
CSerializedNetMsg(CSerializedNetMsg &&)=default
std::vector< unsigned char > data
std::chrono::microseconds m_min_ping_time
#define EXCLUSIVE_LOCKS_REQUIRED(...)
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation