@@ -183,6 +183,8 @@ static constexpr double MAX_ADDR_RATE_PER_SECOND{0.1};
183
183
* based increments won't go above this, but the MAX_ADDR_TO_SEND increment following GETADDR
184
184
* is exempt from this limit). */
185
185
static constexpr size_t MAX_ADDR_PROCESSING_TOKEN_BUCKET{MAX_ADDR_TO_SEND};
186
+ /* * The compactblocks version we support. See BIP 152. */
187
+ static constexpr uint64_t CMPCTBLOCKS_VERSION{1 };
186
188
187
189
struct COrphanTx {
188
190
// When modifying, adapt the copy of this definition in tests/DoS_tests.
@@ -777,15 +779,10 @@ struct CNodeState {
777
779
bool fPreferHeaders {false };
778
780
// ! Whether this peer wants invs or compressed headers (when possible) for block announcements.
779
781
bool fPreferHeadersCompressed {false };
780
- // ! Whether this peer wants invs or cmpctblocks (when possible) for block announcements.
781
- bool fPreferHeaderAndIDs {false };
782
- // ! Whether this peer will send us cmpctblocks if we request them
783
- bool fProvidesHeaderAndIDs {false };
784
- /* *
785
- * If we've announced last version to this peer: whether the peer sends last version in cmpctblocks/blocktxns,
786
- * otherwise: whether this peer sends non-last version in cmpctblocks/blocktxns.
787
- */
788
- bool fSupportsDesiredCmpctVersion {false };
782
+ /* * Whether this peer wants invs or cmpctblocks (when possible) for block announcements. */
783
+ bool m_requested_hb_cmpctblocks{false };
784
+ /* * Whether this peer will send us cmpctblocks if we request them. */
785
+ bool m_provides_cmpctblocks{false };
789
786
790
787
/* * State used to enforce CHAIN_SYNC_TIMEOUT and EXTRA_PEER_CHECK_INTERVAL logic.
791
788
*
@@ -1059,54 +1056,52 @@ void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid)
1059
1056
if (m_ignore_incoming_txs) return ;
1060
1057
1061
1058
CNodeState* nodestate = State (nodeid);
1062
- if (!nodestate || !nodestate->fSupportsDesiredCmpctVersion ) {
1063
- // Never ask from peers who can't provide desired version.
1059
+ if (!nodestate || !nodestate->m_provides_cmpctblocks ) {
1060
+ // Don't request compact blocks if the peer has not signalled support
1064
1061
return ;
1065
1062
}
1066
- if (nodestate->fProvidesHeaderAndIDs ) {
1067
- int num_outbound_hb_peers = 0 ;
1068
- for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin (); it != lNodesAnnouncingHeaderAndIDs.end (); it++) {
1069
- if (*it == nodeid) {
1070
- lNodesAnnouncingHeaderAndIDs.erase (it);
1071
- lNodesAnnouncingHeaderAndIDs.push_back (nodeid);
1072
- return ;
1073
- }
1074
- CNodeState *state = State (*it);
1075
- if (state != nullptr && !state->m_is_inbound ) ++num_outbound_hb_peers;
1076
- }
1077
- if (nodestate->m_is_inbound ) {
1078
- // If we're adding an inbound HB peer, make sure we're not removing
1079
- // our last outbound HB peer in the process.
1080
- if (lNodesAnnouncingHeaderAndIDs.size () >= 3 && num_outbound_hb_peers == 1 ) {
1081
- CNodeState *remove_node = State (lNodesAnnouncingHeaderAndIDs.front ());
1082
- if (remove_node != nullptr && !remove_node->m_is_inbound ) {
1083
- // Put the HB outbound peer in the second slot, so that it
1084
- // doesn't get removed.
1085
- std::swap (lNodesAnnouncingHeaderAndIDs.front (), *std::next (lNodesAnnouncingHeaderAndIDs.begin ()));
1086
- }
1087
- }
1063
+
1064
+ int num_outbound_hb_peers = 0 ;
1065
+ for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin (); it != lNodesAnnouncingHeaderAndIDs.end (); it++) {
1066
+ if (*it == nodeid) {
1067
+ lNodesAnnouncingHeaderAndIDs.erase (it);
1068
+ lNodesAnnouncingHeaderAndIDs.push_back (nodeid);
1069
+ return ;
1088
1070
}
1089
- m_connman.ForNode (nodeid, [this ](CNode* pfrom){
1090
- LockAssertion lock (::cs_main);
1091
- uint64_t nCMPCTBLOCKVersion = 1 ;
1092
- if (lNodesAnnouncingHeaderAndIDs.size () >= 3 ) {
1093
- // As per BIP152, we only get 3 of our peers to announce
1094
- // blocks using compact encodings.
1095
- m_connman.ForNode (lNodesAnnouncingHeaderAndIDs.front (), [this , nCMPCTBLOCKVersion](CNode* pnodeStop){
1096
- m_connman.PushMessage (pnodeStop, CNetMsgMaker (pnodeStop->GetCommonVersion ()).Make (NetMsgType::SENDCMPCT, /* fAnnounceUsingCMPCTBLOCK=*/ false , nCMPCTBLOCKVersion));
1097
- // save BIP152 bandwidth state: we select peer to be low-bandwidth
1098
- pnodeStop->m_bip152_highbandwidth_to = false ;
1099
- return true ;
1100
- });
1101
- lNodesAnnouncingHeaderAndIDs.pop_front ();
1071
+ CNodeState *state = State (*it);
1072
+ if (state != nullptr && !state->m_is_inbound ) ++num_outbound_hb_peers;
1073
+ }
1074
+ if (nodestate->m_is_inbound ) {
1075
+ // If we're adding an inbound HB peer, make sure we're not removing
1076
+ // our last outbound HB peer in the process.
1077
+ if (lNodesAnnouncingHeaderAndIDs.size () >= 3 && num_outbound_hb_peers == 1 ) {
1078
+ CNodeState *remove_node = State (lNodesAnnouncingHeaderAndIDs.front ());
1079
+ if (remove_node != nullptr && !remove_node->m_is_inbound ) {
1080
+ // Put the HB outbound peer in the second slot, so that it
1081
+ // doesn't get removed.
1082
+ std::swap (lNodesAnnouncingHeaderAndIDs.front (), *std::next (lNodesAnnouncingHeaderAndIDs.begin ()));
1102
1083
}
1103
- m_connman.PushMessage (pfrom, CNetMsgMaker (pfrom->GetCommonVersion ()).Make (NetMsgType::SENDCMPCT, /* fAnnounceUsingCMPCTBLOCK=*/ true , nCMPCTBLOCKVersion));
1104
- // save BIP152 bandwidth state: we select peer to be high-bandwidth
1105
- pfrom->m_bip152_highbandwidth_to = true ;
1106
- lNodesAnnouncingHeaderAndIDs.push_back (pfrom->GetId ());
1107
- return true ;
1108
- });
1084
+ }
1109
1085
}
1086
+ m_connman.ForNode (nodeid, [this ](CNode* pfrom) EXCLUSIVE_LOCKS_REQUIRED (::cs_main) {
1087
+ AssertLockHeld (::cs_main);
1088
+ if (lNodesAnnouncingHeaderAndIDs.size () >= 3 ) {
1089
+ // As per BIP152, we only get 3 of our peers to announce
1090
+ // blocks using compact encodings.
1091
+ m_connman.ForNode (lNodesAnnouncingHeaderAndIDs.front (), [this ](CNode* pnodeStop){
1092
+ m_connman.PushMessage (pnodeStop, CNetMsgMaker (pnodeStop->GetCommonVersion ()).Make (NetMsgType::SENDCMPCT, /* high_bandwidth=*/ false , /* version=*/ CMPCTBLOCKS_VERSION));
1093
+ // save BIP152 bandwidth state: we select peer to be low-bandwidth
1094
+ pnodeStop->m_bip152_highbandwidth_to = false ;
1095
+ return true ;
1096
+ });
1097
+ lNodesAnnouncingHeaderAndIDs.pop_front ();
1098
+ }
1099
+ m_connman.PushMessage (pfrom, CNetMsgMaker (pfrom->GetCommonVersion ()).Make (NetMsgType::SENDCMPCT, /* high_bandwidth=*/ true , /* version=*/ CMPCTBLOCKS_VERSION));
1100
+ // save BIP152 bandwidth state: we select peer to be high-bandwidth
1101
+ pfrom->m_bip152_highbandwidth_to = true ;
1102
+ lNodesAnnouncingHeaderAndIDs.push_back (pfrom->GetId ());
1103
+ return true ;
1104
+ });
1110
1105
}
1111
1106
1112
1107
bool PeerManagerImpl::TipMayBeStale ()
@@ -2024,9 +2019,7 @@ void PeerManagerImpl::NewPoWValidBlock(const CBlockIndex *pindex, const std::sha
2024
2019
CNodeState &state = *State (pnode->GetId ());
2025
2020
// If the peer has, or we announced to them the previous block already,
2026
2021
// but we don't think they have this one, go ahead and announce it
2027
- if (state.fPreferHeaderAndIDs &&
2028
- !PeerHasHeader (&state, pindex) && PeerHasHeader (&state, pindex->pprev )) {
2029
-
2022
+ if (state.m_requested_hb_cmpctblocks && !PeerHasHeader (&state, pindex) && PeerHasHeader (&state, pindex->pprev )) {
2030
2023
LogPrint (BCLog::NET, " %s sending header-and-ids %s to peer=%d\n " , " PeerManager::NewPoWValidBlock" ,
2031
2024
hashBlock.ToString (), pnode->GetId ());
2032
2025
m_connman.PushMessage (pnode, msgMaker.Make (NetMsgType::CMPCTBLOCK, *pcmpctblock));
@@ -2757,7 +2750,6 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, const CBlock& block, c
2757
2750
}
2758
2751
resp.txn [i] = block.vtx [req.indexes [i]];
2759
2752
}
2760
- LOCK (cs_main);
2761
2753
CNetMsgMaker msgMaker (pfrom.GetCommonVersion ());
2762
2754
m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::BLOCKTXN, resp));
2763
2755
}
@@ -2904,7 +2896,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, const Peer& peer,
2904
2896
}
2905
2897
if (vGetData.size () > 0 ) {
2906
2898
if (!m_ignore_incoming_txs &&
2907
- nodestate->fSupportsDesiredCmpctVersion &&
2899
+ nodestate->m_provides_cmpctblocks &&
2908
2900
vGetData.size () == 1 &&
2909
2901
mapBlocksInFlight.size () == 1 &&
2910
2902
pindexLast->pprev ->IsValid (BLOCK_VALID_CHAIN)) {
@@ -3533,14 +3525,12 @@ void PeerManagerImpl::ProcessMessage(
3533
3525
m_connman.PushMessage (&pfrom, msgMaker.Make ((pfrom.nServices & NODE_HEADERS_COMPRESSED) ? NetMsgType::SENDHEADERS2 : NetMsgType::SENDHEADERS));
3534
3526
3535
3527
if (pfrom.CanRelay ()) {
3536
- // Tell our peer we are willing to provide version- 1 cmpctblocks
3528
+ // Tell our peer we are willing to provide version 1 cmpctblocks.
3537
3529
// However, we do not request new block announcements using
3538
3530
// cmpctblock messages.
3539
3531
// We send this to non-NODE NETWORK peers as well, because
3540
3532
// they may wish to request compact blocks from us
3541
- bool fAnnounceUsingCMPCTBLOCK = false ;
3542
- uint64_t nCMPCTBLOCKVersion = 1 ;
3543
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK , nCMPCTBLOCKVersion));
3533
+ m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::SENDCMPCT, /* high_bandwidth=*/ false , /* version=*/ CMPCTBLOCKS_VERSION));
3544
3534
}
3545
3535
3546
3536
if (!fBlocksOnly ) {
@@ -3570,18 +3560,19 @@ void PeerManagerImpl::ProcessMessage(
3570
3560
}
3571
3561
3572
3562
if (msg_type == NetMsgType::SENDCMPCT) {
3573
- bool fAnnounceUsingCMPCTBLOCK = false ;
3574
- uint64_t nCMPCTBLOCKVersion = 1 ;
3575
- vRecv >> fAnnounceUsingCMPCTBLOCK >> nCMPCTBLOCKVersion;
3576
- if (nCMPCTBLOCKVersion == 1 ) {
3577
- LOCK (cs_main);
3578
- State (pfrom.GetId ())->fProvidesHeaderAndIDs = true ;
3579
- State (pfrom.GetId ())->fPreferHeaderAndIDs = fAnnounceUsingCMPCTBLOCK ;
3580
- State (pfrom.GetId ())->fSupportsDesiredCmpctVersion = true ;
3581
- // save whether peer selects us as BIP152 high-bandwidth peer
3582
- // (receiving sendcmpct(1) signals high-bandwidth, sendcmpct(0) low-bandwidth)
3583
- pfrom.m_bip152_highbandwidth_from = fAnnounceUsingCMPCTBLOCK ;
3584
- }
3563
+ bool sendcmpct_hb{false };
3564
+ uint64_t sendcmpct_version{0 };
3565
+ vRecv >> sendcmpct_hb >> sendcmpct_version;
3566
+
3567
+ if (sendcmpct_version != CMPCTBLOCKS_VERSION) return ;
3568
+
3569
+ LOCK (cs_main);
3570
+ CNodeState *nodestate = State (pfrom.GetId ());
3571
+ nodestate->m_provides_cmpctblocks = true ;
3572
+ nodestate->m_requested_hb_cmpctblocks = sendcmpct_hb;
3573
+ // save whether peer selects us as BIP152 high-bandwidth peer
3574
+ // (receiving sendcmpct(1) signals high-bandwidth, sendcmpct(0) low-bandwidth)
3575
+ pfrom.m_bip152_highbandwidth_from = sendcmpct_hb;
3585
3576
return ;
3586
3577
}
3587
3578
@@ -3976,9 +3967,7 @@ void PeerManagerImpl::ProcessMessage(
3976
3967
// expensive disk reads, because it will require the peer to
3977
3968
// actually receive all the data read from disk over the network.
3978
3969
LogPrint (BCLog::NET, " Peer %d sent us a getblocktxn for a block > %i deep\n " , pfrom.GetId (), MAX_BLOCKTXN_DEPTH);
3979
- CInv inv;
3980
- WITH_LOCK (cs_main, inv.type = MSG_BLOCK);
3981
- inv.hash = req.blockhash ;
3970
+ CInv inv{MSG_BLOCK, req.blockhash };
3982
3971
WITH_LOCK (peer->m_getdata_requests_mutex , peer->m_getdata_requests .push_back (inv));
3983
3972
// The message processing loop will go around again (without pausing) and we'll respond then (without cs_main)
3984
3973
return ;
@@ -5449,7 +5438,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
5449
5438
LOCK (peer->m_block_inv_mutex );
5450
5439
std::vector<CBlock> vHeaders;
5451
5440
bool fRevertToInv = ((!state.fPreferHeaders && !state.fPreferHeadersCompressed &&
5452
- (!state.fPreferHeaderAndIDs || peer->m_blocks_for_headers_relay .size () > 1 )) ||
5441
+ (!state.m_requested_hb_cmpctblocks || peer->m_blocks_for_headers_relay .size () > 1 )) ||
5453
5442
peer->m_blocks_for_headers_relay .size () > MAX_BLOCKS_TO_ANNOUNCE);
5454
5443
const CBlockIndex *pBestIndex = nullptr ; // last header queued for delivery
5455
5444
ProcessBlockAvailability (pto->GetId ()); // ensure pindexBestKnownBlock is up-to-date
@@ -5511,7 +5500,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
5511
5500
}
5512
5501
}
5513
5502
if (!fRevertToInv && !vHeaders.empty ()) {
5514
- if (vHeaders.size () == 1 && state.fPreferHeaderAndIDs ) {
5503
+ if (vHeaders.size () == 1 && state.m_requested_hb_cmpctblocks ) {
5515
5504
// We only send up to 1 block as header-and-ids, as otherwise
5516
5505
// probably means we're doing an initial-ish-sync or they're slow
5517
5506
LogPrint (BCLog::NET, " %s sending header-and-ids %s to peer=%d\n " , __func__,
0 commit comments