Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 804 Lines • ▼ Show 20 Lines | connman.ForNode(nodeid, [&connman](CNode *pfrom) { | ||||
if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { | if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { | ||||
// As per BIP152, we only get 3 of our peers to announce | // As per BIP152, we only get 3 of our peers to announce | ||||
// blocks using compact encodings. | // blocks using compact encodings. | ||||
connman.ForNode( | connman.ForNode( | ||||
lNodesAnnouncingHeaderAndIDs.front(), | lNodesAnnouncingHeaderAndIDs.front(), | ||||
[&connman, nCMPCTBLOCKVersion](CNode *pnodeStop) { | [&connman, nCMPCTBLOCKVersion](CNode *pnodeStop) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
connman.PushMessage( | connman.PushMessage( | ||||
pnodeStop, CNetMsgMaker(pnodeStop->GetSendVersion()) | pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion()) | ||||
.Make(NetMsgType::SENDCMPCT, | .Make(NetMsgType::SENDCMPCT, | ||||
/*fAnnounceUsingCMPCTBLOCK=*/false, | /*fAnnounceUsingCMPCTBLOCK=*/false, | ||||
nCMPCTBLOCKVersion)); | nCMPCTBLOCKVersion)); | ||||
return true; | return true; | ||||
}); | }); | ||||
lNodesAnnouncingHeaderAndIDs.pop_front(); | lNodesAnnouncingHeaderAndIDs.pop_front(); | ||||
} | } | ||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()) | connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()) | ||||
.Make(NetMsgType::SENDCMPCT, | .Make(NetMsgType::SENDCMPCT, | ||||
/*fAnnounceUsingCMPCTBLOCK=*/true, | /*fAnnounceUsingCMPCTBLOCK=*/true, | ||||
nCMPCTBLOCKVersion)); | nCMPCTBLOCKVersion)); | ||||
lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId()); | lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId()); | ||||
return true; | return true; | ||||
}); | }); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 770 Lines • ▼ Show 20 Lines | uint256 hashBlock(pblock->GetHash()); | ||||
most_recent_compact_block = pcmpctblock; | most_recent_compact_block = pcmpctblock; | ||||
} | } | ||||
m_connman.ForEachNode([this, &pcmpctblock, pindex, &msgMaker, | m_connman.ForEachNode([this, &pcmpctblock, pindex, &msgMaker, | ||||
&hashBlock](CNode *pnode) { | &hashBlock](CNode *pnode) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// TODO: Avoid the repeated-serialization here | // TODO: Avoid the repeated-serialization here | ||||
if (pnode->nVersion < INVALID_CB_NO_BAN_VERSION || pnode->fDisconnect) { | if (pnode->GetCommonVersion() < INVALID_CB_NO_BAN_VERSION || | ||||
pnode->fDisconnect) { | |||||
return; | return; | ||||
} | } | ||||
ProcessBlockAvailability(pnode->GetId()); | ProcessBlockAvailability(pnode->GetId()); | ||||
CNodeState &state = *State(pnode->GetId()); | CNodeState &state = *State(pnode->GetId()); | ||||
// If the peer has, or we announced to them the previous block already, | // If the peer has, or we announced to them the previous block already, | ||||
// but we don't think they have this one, go ahead and announce it. | // but we don't think they have this one, go ahead and announce it. | ||||
if (state.fPreferHeaderAndIDs && !PeerHasHeader(&state, pindex) && | if (state.fPreferHeaderAndIDs && !PeerHasHeader(&state, pindex) && | ||||
PeerHasHeader(&state, pindex->pprev)) { | PeerHasHeader(&state, pindex->pprev)) { | ||||
▲ Show 20 Lines • Show All 226 Lines • ▼ Show 20 Lines | if (pindex) { | ||||
send = BlockRequestAllowed(pindex, consensusParams); | send = BlockRequestAllowed(pindex, consensusParams); | ||||
if (!send) { | if (!send) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"%s: ignoring request from peer=%i for old " | "%s: ignoring request from peer=%i for old " | ||||
"block that isn't in the main chain\n", | "block that isn't in the main chain\n", | ||||
__func__, pfrom.GetId()); | __func__, pfrom.GetId()); | ||||
} | } | ||||
} | } | ||||
const CNetMsgMaker msgMaker(pfrom.GetSendVersion()); | const CNetMsgMaker msgMaker(pfrom.GetCommonVersion()); | ||||
// Disconnect node in case we have reached the outbound limit for serving | // Disconnect node in case we have reached the outbound limit for serving | ||||
// historical blocks. | // historical blocks. | ||||
// Never disconnect whitelisted nodes. | // Never disconnect whitelisted nodes. | ||||
if (send && connman.OutboundTargetReached(true) && | if (send && connman.OutboundTargetReached(true) && | ||||
(((pindexBestHeader != nullptr) && | (((pindexBestHeader != nullptr) && | ||||
(pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() > | (pindexBestHeader->GetBlockTime() - pindex->GetBlockTime() > | ||||
HISTORICAL_BLOCK_AGE)) || | HISTORICAL_BLOCK_AGE)) || | ||||
inv.type == MSG_FILTERED_BLOCK) && | inv.type == MSG_FILTERED_BLOCK) && | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | |||||
static void ProcessGetData(const Config &config, CNode &pfrom, | static void ProcessGetData(const Config &config, CNode &pfrom, | ||||
CConnman &connman, CTxMemPool &mempool, | CConnman &connman, CTxMemPool &mempool, | ||||
const std::atomic<bool> &interruptMsgProc) | const std::atomic<bool> &interruptMsgProc) | ||||
LOCKS_EXCLUDED(cs_main) { | LOCKS_EXCLUDED(cs_main) { | ||||
AssertLockNotHeld(cs_main); | AssertLockNotHeld(cs_main); | ||||
std::deque<CInv>::iterator it = pfrom.vRecvGetData.begin(); | std::deque<CInv>::iterator it = pfrom.vRecvGetData.begin(); | ||||
std::vector<CInv> vNotFound; | std::vector<CInv> vNotFound; | ||||
const CNetMsgMaker msgMaker(pfrom.GetSendVersion()); | const CNetMsgMaker msgMaker(pfrom.GetCommonVersion()); | ||||
// mempool entries added before this time have likely expired from mapRelay | // mempool entries added before this time have likely expired from mapRelay | ||||
const std::chrono::seconds longlived_mempool_time = | const std::chrono::seconds longlived_mempool_time = | ||||
GetTime<std::chrono::seconds>() - RELAY_TX_CACHE_TIME; | GetTime<std::chrono::seconds>() - RELAY_TX_CACHE_TIME; | ||||
// Get last mempool request time | // Get last mempool request time | ||||
const std::chrono::seconds mempool_req = | const std::chrono::seconds mempool_req = | ||||
pfrom.m_tx_relay != nullptr | pfrom.m_tx_relay != nullptr | ||||
? pfrom.m_tx_relay->m_last_mempool_req.load() | ? pfrom.m_tx_relay->m_last_mempool_req.load() | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < req.indices.size(); i++) { | ||||
if (req.indices[i] >= block.vtx.size()) { | if (req.indices[i] >= block.vtx.size()) { | ||||
Misbehaving(pfrom, 100, | Misbehaving(pfrom, 100, | ||||
"getblocktxn with out-of-bounds tx indices"); | "getblocktxn with out-of-bounds tx indices"); | ||||
return; | return; | ||||
} | } | ||||
resp.txn[i] = block.vtx[req.indices[i]]; | resp.txn[i] = block.vtx[req.indices[i]]; | ||||
} | } | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CNetMsgMaker msgMaker(pfrom.GetSendVersion()); | const CNetMsgMaker msgMaker(pfrom.GetCommonVersion()); | ||||
int nSendFlags = 0; | int nSendFlags = 0; | ||||
m_connman.PushMessage( | m_connman.PushMessage( | ||||
&pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp)); | &pfrom, msgMaker.Make(nSendFlags, NetMsgType::BLOCKTXN, resp)); | ||||
} | } | ||||
void PeerManager::ProcessHeadersMessage( | void PeerManager::ProcessHeadersMessage( | ||||
const Config &config, CNode &pfrom, | const Config &config, CNode &pfrom, | ||||
const std::vector<CBlockHeader> &headers, bool via_compact_block) { | const std::vector<CBlockHeader> &headers, bool via_compact_block) { | ||||
const CNetMsgMaker msgMaker(pfrom.GetSendVersion()); | const CNetMsgMaker msgMaker(pfrom.GetCommonVersion()); | ||||
size_t nCount = headers.size(); | size_t nCount = headers.size(); | ||||
if (nCount == 0) { | if (nCount == 0) { | ||||
// Nothing interesting. Stop asking this peers for more headers. | // Nothing interesting. Stop asking this peers for more headers. | ||||
return; | return; | ||||
} | } | ||||
bool received_new_header = false; | bool received_new_header = false; | ||||
▲ Show 20 Lines • Show All 400 Lines • ▼ Show 20 Lines | if (!filter_index->LookupFilterRange(start_height, stop_index, filters)) { | ||||
"Failed to find block filter in index: filter_type=%s, " | "Failed to find block filter in index: filter_type=%s, " | ||||
"start_height=%d, stop_hash=%s\n", | "start_height=%d, stop_hash=%s\n", | ||||
BlockFilterTypeName(filter_type), start_height, | BlockFilterTypeName(filter_type), start_height, | ||||
stop_hash.ToString()); | stop_hash.ToString()); | ||||
return; | return; | ||||
} | } | ||||
for (const auto &filter : filters) { | for (const auto &filter : filters) { | ||||
CSerializedNetMsg msg = CNetMsgMaker(peer.GetSendVersion()) | CSerializedNetMsg msg = CNetMsgMaker(peer.GetCommonVersion()) | ||||
.Make(NetMsgType::CFILTER, filter); | .Make(NetMsgType::CFILTER, filter); | ||||
connman.PushMessage(&peer, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Handle a cfheaders request. | * Handle a cfheaders request. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (!filter_index->LookupFilterHashRange(start_height, stop_index, | ||||
"Failed to find block filter hashes in index: filter_type=%s, " | "Failed to find block filter hashes in index: filter_type=%s, " | ||||
"start_height=%d, stop_hash=%s\n", | "start_height=%d, stop_hash=%s\n", | ||||
BlockFilterTypeName(filter_type), start_height, | BlockFilterTypeName(filter_type), start_height, | ||||
stop_hash.ToString()); | stop_hash.ToString()); | ||||
return; | return; | ||||
} | } | ||||
CSerializedNetMsg msg = | CSerializedNetMsg msg = | ||||
CNetMsgMaker(peer.GetSendVersion()) | CNetMsgMaker(peer.GetCommonVersion()) | ||||
.Make(NetMsgType::CFHEADERS, filter_type_ser, | .Make(NetMsgType::CFHEADERS, filter_type_ser, | ||||
stop_index->GetBlockHash(), prev_header, filter_hashes); | stop_index->GetBlockHash(), prev_header, filter_hashes); | ||||
connman.PushMessage(&peer, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
/** | /** | ||||
* Handle a getcfcheckpt request. | * Handle a getcfcheckpt request. | ||||
* | * | ||||
Show All 37 Lines | for (int i = headers.size() - 1; i >= 0; i--) { | ||||
"Failed to find block filter header in index: " | "Failed to find block filter header in index: " | ||||
"filter_type=%s, block_hash=%s\n", | "filter_type=%s, block_hash=%s\n", | ||||
BlockFilterTypeName(filter_type), | BlockFilterTypeName(filter_type), | ||||
block_index->GetBlockHash().ToString()); | block_index->GetBlockHash().ToString()); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
CSerializedNetMsg msg = CNetMsgMaker(peer.GetSendVersion()) | CSerializedNetMsg msg = CNetMsgMaker(peer.GetCommonVersion()) | ||||
.Make(NetMsgType::CFCHECKPT, filter_type_ser, | .Make(NetMsgType::CFCHECKPT, filter_type_ser, | ||||
stop_index->GetBlockHash(), headers); | stop_index->GetBlockHash(), headers); | ||||
connman.PushMessage(&peer, std::move(msg)); | connman.PushMessage(&peer, std::move(msg)); | ||||
} | } | ||||
void PeerManager::ProcessMessage(const Config &config, CNode &pfrom, | void PeerManager::ProcessMessage(const Config &config, CNode &pfrom, | ||||
const std::string &msg_type, | const std::string &msg_type, | ||||
CDataStream &vRecv, | CDataStream &vRecv, | ||||
Show All 27 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
int64_t nTime; | int64_t nTime; | ||||
CAddress addrMe; | CAddress addrMe; | ||||
CAddress addrFrom; | CAddress addrFrom; | ||||
uint64_t nNonce = 1; | uint64_t nNonce = 1; | ||||
uint64_t nServiceInt; | uint64_t nServiceInt; | ||||
ServiceFlags nServices; | ServiceFlags nServices; | ||||
int nVersion; | int nVersion; | ||||
int nSendVersion; | |||||
std::string cleanSubVer; | std::string cleanSubVer; | ||||
int nStartingHeight = -1; | int nStartingHeight = -1; | ||||
bool fRelay = true; | bool fRelay = true; | ||||
uint64_t nExtraEntropy = 1; | uint64_t nExtraEntropy = 1; | ||||
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe; | vRecv >> nVersion >> nServiceInt >> nTime >> addrMe; | ||||
nSendVersion = std::min(nVersion, PROTOCOL_VERSION); | |||||
nServices = ServiceFlags(nServiceInt); | nServices = ServiceFlags(nServiceInt); | ||||
if (!pfrom.IsInboundConn()) { | if (!pfrom.IsInboundConn()) { | ||||
m_connman.SetServices(pfrom.addr, nServices); | m_connman.SetServices(pfrom.addr, nServices); | ||||
} | } | ||||
if (pfrom.ExpectServicesFromConn() && | if (pfrom.ExpectServicesFromConn() && | ||||
!HasAllDesirableServiceFlags(nServices)) { | !HasAllDesirableServiceFlags(nServices)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"peer=%d does not offer the expected services " | "peer=%d does not offer the expected services " | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
SeenLocal(addrMe); | SeenLocal(addrMe); | ||||
} | } | ||||
// Be shy and don't send version until we hear | // Be shy and don't send version until we hear | ||||
if (pfrom.IsInboundConn()) { | if (pfrom.IsInboundConn()) { | ||||
PushNodeVersion(config, pfrom, m_connman, GetAdjustedTime()); | PushNodeVersion(config, pfrom, m_connman, GetAdjustedTime()); | ||||
} | } | ||||
// Change version | |||||
const int greatest_common_version = | |||||
std::min(nVersion, PROTOCOL_VERSION); | |||||
pfrom.SetCommonVersion(greatest_common_version); | |||||
pfrom.nVersion = nVersion; | |||||
m_connman.PushMessage( | m_connman.PushMessage( | ||||
&pfrom, CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERACK)); | &pfrom, | ||||
CNetMsgMaker(greatest_common_version).Make(NetMsgType::VERACK)); | |||||
pfrom.nServices = nServices; | pfrom.nServices = nServices; | ||||
pfrom.SetAddrLocal(addrMe); | pfrom.SetAddrLocal(addrMe); | ||||
{ | { | ||||
LOCK(pfrom.cs_SubVer); | LOCK(pfrom.cs_SubVer); | ||||
pfrom.cleanSubVer = cleanSubVer; | pfrom.cleanSubVer = cleanSubVer; | ||||
} | } | ||||
pfrom.nStartingHeight = nStartingHeight; | pfrom.nStartingHeight = nStartingHeight; | ||||
Show All 9 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
(!(nServices & NODE_NETWORK) && (nServices & NODE_NETWORK_LIMITED)); | (!(nServices & NODE_NETWORK) && (nServices & NODE_NETWORK_LIMITED)); | ||||
if (pfrom.m_tx_relay != nullptr) { | if (pfrom.m_tx_relay != nullptr) { | ||||
LOCK(pfrom.m_tx_relay->cs_filter); | LOCK(pfrom.m_tx_relay->cs_filter); | ||||
// set to true after we get the first filter* message | // set to true after we get the first filter* message | ||||
pfrom.m_tx_relay->fRelayTxes = fRelay; | pfrom.m_tx_relay->fRelayTxes = fRelay; | ||||
} | } | ||||
// Change version | |||||
pfrom.SetSendVersion(nSendVersion); | |||||
pfrom.nVersion = nVersion; | |||||
pfrom.nRemoteHostNonce = nNonce; | pfrom.nRemoteHostNonce = nNonce; | ||||
pfrom.nRemoteExtraEntropy = nExtraEntropy; | pfrom.nRemoteExtraEntropy = nExtraEntropy; | ||||
// Potentially mark this peer as a preferred download peer. | // Potentially mark this peer as a preferred download peer. | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
UpdatePreferredDownload(pfrom, State(pfrom.GetId())); | UpdatePreferredDownload(pfrom, State(pfrom.GetId())); | ||||
} | } | ||||
Show All 14 Lines | if (msg_type == NetMsgType::VERSION) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"ProcessMessages: advertising address %s\n", | "ProcessMessages: advertising address %s\n", | ||||
addr.ToString()); | addr.ToString()); | ||||
pfrom.PushAddress(addr, insecure_rand); | pfrom.PushAddress(addr, insecure_rand); | ||||
} | } | ||||
} | } | ||||
// Get recent addresses | // Get recent addresses | ||||
m_connman.PushMessage( | m_connman.PushMessage(&pfrom, CNetMsgMaker(greatest_common_version) | ||||
&pfrom, CNetMsgMaker(nSendVersion).Make(NetMsgType::GETADDR)); | .Make(NetMsgType::GETADDR)); | ||||
pfrom.fGetAddr = true; | pfrom.fGetAddr = true; | ||||
m_connman.MarkAddressGood(pfrom.addr); | m_connman.MarkAddressGood(pfrom.addr); | ||||
} | } | ||||
std::string remoteAddr; | std::string remoteAddr; | ||||
if (fLogIPs) { | if (fLogIPs) { | ||||
remoteAddr = ", peeraddr=" + pfrom.addr.ToString(); | remoteAddr = ", peeraddr=" + pfrom.addr.ToString(); | ||||
} | } | ||||
Show All 26 Lines | void PeerManager::ProcessMessage(const Config &config, CNode &pfrom, | ||||
if (pfrom.nVersion == 0) { | if (pfrom.nVersion == 0) { | ||||
// Must have a version message before anything else | // Must have a version message before anything else | ||||
Misbehaving(pfrom, 10, "non-version message before version handshake"); | Misbehaving(pfrom, 10, "non-version message before version handshake"); | ||||
return; | return; | ||||
} | } | ||||
// At this point, the outgoing message serialization version can't change. | // At this point, the outgoing message serialization version can't change. | ||||
const CNetMsgMaker msgMaker(pfrom.GetSendVersion()); | const CNetMsgMaker msgMaker(pfrom.GetCommonVersion()); | ||||
if (msg_type == NetMsgType::VERACK) { | if (msg_type == NetMsgType::VERACK) { | ||||
pfrom.SetRecvVersion(std::min(pfrom.nVersion.load(), PROTOCOL_VERSION)); | |||||
if (!pfrom.IsInboundConn()) { | if (!pfrom.IsInboundConn()) { | ||||
// Mark this node as currently connected, so we update its timestamp | // Mark this node as currently connected, so we update its timestamp | ||||
// later. | // later. | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
State(pfrom.GetId())->fCurrentlyConnected = true; | State(pfrom.GetId())->fCurrentlyConnected = true; | ||||
LogPrintf( | LogPrintf( | ||||
"New outbound peer connected: version: %d, blocks=%d, " | "New outbound peer connected: version: %d, blocks=%d, " | ||||
"peer=%d%s (%s)\n", | "peer=%d%s (%s)\n", | ||||
pfrom.nVersion.load(), pfrom.nStartingHeight, pfrom.GetId(), | pfrom.nVersion.load(), pfrom.nStartingHeight, pfrom.GetId(), | ||||
(fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToString()) | (fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToString()) | ||||
: ""), | : ""), | ||||
pfrom.m_tx_relay == nullptr ? "block-relay" : "full-relay"); | pfrom.m_tx_relay == nullptr ? "block-relay" : "full-relay"); | ||||
} | } | ||||
if (pfrom.nVersion >= SENDHEADERS_VERSION) { | if (pfrom.GetCommonVersion() >= SENDHEADERS_VERSION) { | ||||
// Tell our peer we prefer to receive headers rather than inv's | // Tell our peer we prefer to receive headers rather than inv's | ||||
// We send this to non-NODE NETWORK peers as well, because even | // We send this to non-NODE NETWORK peers as well, because even | ||||
// non-NODE NETWORK peers can announce blocks (such as pruning | // non-NODE NETWORK peers can announce blocks (such as pruning | ||||
// nodes) | // nodes) | ||||
m_connman.PushMessage(&pfrom, | m_connman.PushMessage(&pfrom, | ||||
msgMaker.Make(NetMsgType::SENDHEADERS)); | msgMaker.Make(NetMsgType::SENDHEADERS)); | ||||
} | } | ||||
if (pfrom.nVersion >= SHORT_IDS_BLOCKS_VERSION) { | if (pfrom.GetCommonVersion() >= SHORT_IDS_BLOCKS_VERSION) { | ||||
// Tell our peer we are willing to provide version 1 or 2 | // Tell our peer we are willing to provide version 1 or 2 | ||||
// cmpctblocks. However, we do not request new block announcements | // cmpctblocks. However, we do not request new block announcements | ||||
// using cmpctblock messages. We send this to non-NODE NETWORK peers | // using cmpctblock messages. We send this to non-NODE NETWORK peers | ||||
// as well, because they may wish to request compact blocks from us. | // as well, because they may wish to request compact blocks from us. | ||||
bool fAnnounceUsingCMPCTBLOCK = false; | bool fAnnounceUsingCMPCTBLOCK = false; | ||||
uint64_t nCMPCTBLOCKVersion = 1; | uint64_t nCMPCTBLOCKVersion = 1; | ||||
m_connman.PushMessage(&pfrom, | m_connman.PushMessage(&pfrom, | ||||
msgMaker.Make(NetMsgType::SENDCMPCT, | msgMaker.Make(NetMsgType::SENDCMPCT, | ||||
▲ Show 20 Lines • Show All 1,290 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::MEMPOOL) { | ||||
if (pfrom.m_tx_relay != nullptr) { | if (pfrom.m_tx_relay != nullptr) { | ||||
LOCK(pfrom.m_tx_relay->cs_tx_inventory); | LOCK(pfrom.m_tx_relay->cs_tx_inventory); | ||||
pfrom.m_tx_relay->fSendMempool = true; | pfrom.m_tx_relay->fSendMempool = true; | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::PING) { | if (msg_type == NetMsgType::PING) { | ||||
if (pfrom.nVersion > BIP0031_VERSION) { | if (pfrom.GetCommonVersion() > BIP0031_VERSION) { | ||||
uint64_t nonce = 0; | uint64_t nonce = 0; | ||||
vRecv >> nonce; | vRecv >> nonce; | ||||
// Echo the message back with the nonce. This allows for two useful | // Echo the message back with the nonce. This allows for two useful | ||||
// features: | // features: | ||||
// | // | ||||
// 1) A remote node can quickly check if the connection is | // 1) A remote node can quickly check if the connection is | ||||
// operational. | // operational. | ||||
// 2) Remote nodes can measure the latency of the network thread. If | // 2) Remote nodes can measure the latency of the network thread. If | ||||
▲ Show 20 Lines • Show All 289 Lines • ▼ Show 20 Lines | std::list<CNetMessage> msgs; | ||||
pfrom->vProcessMsg.begin()); | pfrom->vProcessMsg.begin()); | ||||
pfrom->nProcessQueueSize -= msgs.front().m_raw_message_size; | pfrom->nProcessQueueSize -= msgs.front().m_raw_message_size; | ||||
pfrom->fPauseRecv = | pfrom->fPauseRecv = | ||||
pfrom->nProcessQueueSize > m_connman.GetReceiveFloodSize(); | pfrom->nProcessQueueSize > m_connman.GetReceiveFloodSize(); | ||||
fMoreWork = !pfrom->vProcessMsg.empty(); | fMoreWork = !pfrom->vProcessMsg.empty(); | ||||
} | } | ||||
CNetMessage &msg(msgs.front()); | CNetMessage &msg(msgs.front()); | ||||
msg.SetVersion(pfrom->GetRecvVersion()); | msg.SetVersion(pfrom->GetCommonVersion()); | ||||
// Check network magic | // Check network magic | ||||
if (!msg.m_valid_netmagic) { | if (!msg.m_valid_netmagic) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", | "PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", | ||||
SanitizeString(msg.m_command), pfrom->GetId()); | SanitizeString(msg.m_command), pfrom->GetId()); | ||||
// Make sure we discourage where that come from for some time. | // Make sure we discourage where that come from for some time. | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | bool PeerManager::ProcessMessages(const Config &config, CNode *pfrom, | ||||
return fMoreWork; | return fMoreWork; | ||||
} | } | ||||
void PeerManager::ConsiderEviction(CNode &pto, int64_t time_in_seconds) { | void PeerManager::ConsiderEviction(CNode &pto, int64_t time_in_seconds) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
CNodeState &state = *State(pto.GetId()); | CNodeState &state = *State(pto.GetId()); | ||||
const CNetMsgMaker msgMaker(pto.GetSendVersion()); | const CNetMsgMaker msgMaker(pto.GetCommonVersion()); | ||||
if (!state.m_chain_sync.m_protect && pto.IsOutboundOrBlockRelayConn() && | if (!state.m_chain_sync.m_protect && pto.IsOutboundOrBlockRelayConn() && | ||||
state.fSyncStarted) { | state.fSyncStarted) { | ||||
// This is an outbound peer subject to disconnection if they don't | // This is an outbound peer subject to disconnection if they don't | ||||
// announce a block with as much work as the current tip within | // announce a block with as much work as the current tip within | ||||
// CHAIN_SYNC_TIMEOUT + HEADERS_RESPONSE_TIME seconds (note: if their | // CHAIN_SYNC_TIMEOUT + HEADERS_RESPONSE_TIME seconds (note: if their | ||||
// chain has more work than ours, we should sync to it, unless it's | // chain has more work than ours, we should sync to it, unless it's | ||||
// invalid, in which case we should find that out and disconnect from | // invalid, in which case we should find that out and disconnect from | ||||
▲ Show 20 Lines • Show All 208 Lines • ▼ Show 20 Lines | bool PeerManager::SendMessages(const Config &config, CNode *pto, | ||||
// Don't send anything until the version handshake is complete | // Don't send anything until the version handshake is complete | ||||
if (!pto->fSuccessfullyConnected || pto->fDisconnect) { | if (!pto->fSuccessfullyConnected || pto->fDisconnect) { | ||||
return true; | return true; | ||||
} | } | ||||
// If we get here, the outgoing message serialization version is set and | // If we get here, the outgoing message serialization version is set and | ||||
// can't change. | // can't change. | ||||
const CNetMsgMaker msgMaker(pto->GetSendVersion()); | const CNetMsgMaker msgMaker(pto->GetCommonVersion()); | ||||
// | // | ||||
// Message: ping | // Message: ping | ||||
// | // | ||||
bool pingSend = false; | bool pingSend = false; | ||||
if (pto->fPingQueued) { | if (pto->fPingQueued) { | ||||
// RPC ping request by user | // RPC ping request by user | ||||
pingSend = true; | pingSend = true; | ||||
} | } | ||||
if (pto->nPingNonceSent == 0 && pto->m_ping_start.load() + PING_INTERVAL < | if (pto->nPingNonceSent == 0 && pto->m_ping_start.load() + PING_INTERVAL < | ||||
GetTime<std::chrono::microseconds>()) { | GetTime<std::chrono::microseconds>()) { | ||||
// Ping automatically sent as a latency probe & keepalive. | // Ping automatically sent as a latency probe & keepalive. | ||||
pingSend = true; | pingSend = true; | ||||
} | } | ||||
if (pingSend) { | if (pingSend) { | ||||
uint64_t nonce = 0; | uint64_t nonce = 0; | ||||
while (nonce == 0) { | while (nonce == 0) { | ||||
GetRandBytes((uint8_t *)&nonce, sizeof(nonce)); | GetRandBytes((uint8_t *)&nonce, sizeof(nonce)); | ||||
} | } | ||||
pto->fPingQueued = false; | pto->fPingQueued = false; | ||||
pto->m_ping_start = GetTime<std::chrono::microseconds>(); | pto->m_ping_start = GetTime<std::chrono::microseconds>(); | ||||
if (pto->nVersion > BIP0031_VERSION) { | if (pto->GetCommonVersion() > BIP0031_VERSION) { | ||||
pto->nPingNonceSent = nonce; | pto->nPingNonceSent = nonce; | ||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING, nonce)); | m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING, nonce)); | ||||
} else { | } else { | ||||
// Peer is too old to support ping command with nonce, pong will | // Peer is too old to support ping command with nonce, pong will | ||||
// never arrive. | // never arrive. | ||||
pto->nPingNonceSent = 0; | pto->nPingNonceSent = 0; | ||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING)); | m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::PING)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 634 Lines • ▼ Show 20 Lines | if (pingSend) { | ||||
msgMaker.Make(NetMsgType::GETDATA, vGetData)); | msgMaker.Make(NetMsgType::GETDATA, vGetData)); | ||||
} | } | ||||
// | // | ||||
// Message: feefilter | // Message: feefilter | ||||
// | // | ||||
// We don't want white listed peers to filter txs to us if we have | // We don't want white listed peers to filter txs to us if we have | ||||
// -whitelistforcerelay | // -whitelistforcerelay | ||||
if (pto->m_tx_relay != nullptr && pto->nVersion >= FEEFILTER_VERSION && | if (pto->m_tx_relay != nullptr && | ||||
pto->GetCommonVersion() >= FEEFILTER_VERSION && | |||||
gArgs.GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && | gArgs.GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && | ||||
!pto->HasPermission(PF_FORCERELAY)) { | !pto->HasPermission(PF_FORCERELAY)) { | ||||
Amount currentFilter = | Amount currentFilter = | ||||
m_mempool | m_mempool | ||||
.GetMinFee( | .GetMinFee( | ||||
gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | ||||
1000000) | 1000000) | ||||
.GetFeePerK(); | .GetFeePerK(); | ||||
▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines |