@@ -432,8 +432,6 @@ struct CNodeState {
432
432
bool m_requested_hb_cmpctblocks{false };
433
433
/* * Whether this peer will send us cmpctblocks if we request them. */
434
434
bool m_provides_cmpctblocks{false };
435
- // ! Whether this peer can give us witnesses
436
- bool fHaveWitness {false };
437
435
438
436
/* * State used to enforce CHAIN_SYNC_TIMEOUT and EXTRA_PEER_CHECK_INTERVAL logic.
439
437
*
@@ -514,7 +512,8 @@ class PeerManagerImpl final : public PeerManager
514
512
/* * Implement PeerManager */
515
513
void StartScheduledTasks (CScheduler& scheduler) override ;
516
514
void CheckForStaleTipAndEvictPeers () override ;
517
- std::optional<std::string> FetchBlock (NodeId peer_id, const CBlockIndex& block_index) override ;
515
+ std::optional<std::string> FetchBlock (NodeId peer_id, const CBlockIndex& block_index) override
516
+ EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
518
517
bool GetNodeStateStats (NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
519
518
bool IgnoresIncomingTxs () override { return m_ignore_incoming_txs; }
520
519
void SendPings () override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
@@ -600,7 +599,7 @@ class PeerManagerImpl final : public PeerManager
600
599
*/
601
600
bool MaybeSendGetHeaders (CNode& pfrom, const CBlockLocator& locator, Peer& peer);
602
601
/* * Potentially fetch blocks from this peer upon receipt of a new headers tip */
603
- void HeadersDirectFetchBlocks (CNode& pfrom, const CBlockIndex* pindexLast);
602
+ void HeadersDirectFetchBlocks (CNode& pfrom, const Peer& peer, const CBlockIndex* pindexLast);
604
603
/* * Update peer state based on received headers message */
605
604
void UpdatePeerStateForReceivedHeaders (CNode& pfrom, const CBlockIndex *pindexLast, bool received_new_header, bool may_have_more_headers);
606
605
@@ -679,7 +678,7 @@ class PeerManagerImpl final : public PeerManager
679
678
/* * Get a pointer to a mutable CNodeState. */
680
679
CNodeState* State (NodeId pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
681
680
682
- uint32_t GetFetchFlags (const CNode& pfrom ) const EXCLUSIVE_LOCKS_REQUIRED(cs_main) ;
681
+ uint32_t GetFetchFlags (const Peer& peer ) const ;
683
682
684
683
std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
685
684
@@ -800,7 +799,7 @@ class PeerManagerImpl final : public PeerManager
800
799
/* * Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
801
800
* at most count entries.
802
801
*/
803
- void FindNextBlocksToDownload (NodeId nodeid , unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
802
+ void FindNextBlocksToDownload (const Peer& peer , unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
804
803
805
804
std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight GUARDED_BY (cs_main);
806
805
@@ -991,6 +990,12 @@ static bool IsLimitedPeer(const Peer& peer)
991
990
(peer.m_their_services & NODE_NETWORK_LIMITED));
992
991
}
993
992
993
+ /* * Whether this peer can serve us witness data */
994
+ static bool CanServeWitnesses (const Peer& peer)
995
+ {
996
+ return peer.m_their_services & NODE_WITNESS;
997
+ }
998
+
994
999
std::chrono::microseconds PeerManagerImpl::NextInvToInbounds (std::chrono::microseconds now,
995
1000
std::chrono::seconds average_interval)
996
1001
{
@@ -1184,17 +1189,17 @@ void PeerManagerImpl::UpdateBlockAvailability(NodeId nodeid, const uint256 &hash
1184
1189
}
1185
1190
}
1186
1191
1187
- void PeerManagerImpl::FindNextBlocksToDownload (NodeId nodeid , unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller)
1192
+ void PeerManagerImpl::FindNextBlocksToDownload (const Peer& peer , unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller)
1188
1193
{
1189
1194
if (count == 0 )
1190
1195
return ;
1191
1196
1192
1197
vBlocks.reserve (vBlocks.size () + count);
1193
- CNodeState *state = State (nodeid );
1198
+ CNodeState *state = State (peer. m_id );
1194
1199
assert (state != nullptr );
1195
1200
1196
1201
// Make sure pindexBestKnownBlock is up to date, we'll need it.
1197
- ProcessBlockAvailability (nodeid );
1202
+ ProcessBlockAvailability (peer. m_id );
1198
1203
1199
1204
if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock ->nChainWork < m_chainman.ActiveChain ().Tip ()->nChainWork || state->pindexBestKnownBlock ->nChainWork < nMinimumChainWork) {
1200
1205
// This peer has nothing interesting.
@@ -1242,7 +1247,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
1242
1247
// We consider the chain that this peer is on invalid.
1243
1248
return ;
1244
1249
}
1245
- if (!State (nodeid)-> fHaveWitness && DeploymentActiveAt (*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
1250
+ if (!CanServeWitnesses (peer) && DeploymentActiveAt (*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) {
1246
1251
// We wouldn't download this block or its descendants from this peer.
1247
1252
return ;
1248
1253
}
@@ -1253,7 +1258,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count
1253
1258
// The block is not already downloaded, and not yet in flight.
1254
1259
if (pindex->nHeight > nWindowEnd) {
1255
1260
// We reached the end of the window.
1256
- if (vBlocks.size () == 0 && waitingfor != nodeid ) {
1261
+ if (vBlocks.size () == 0 && waitingfor != peer. m_id ) {
1257
1262
// We aren't able to fetch anything, but we would be if the download window was one larger.
1258
1263
nodeStaller = waitingfor;
1259
1264
}
@@ -1621,12 +1626,14 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
1621
1626
if (fImporting ) return " Importing..." ;
1622
1627
if (fReindex ) return " Reindexing..." ;
1623
1628
1624
- LOCK (cs_main);
1625
1629
// Ensure this peer exists and hasn't been disconnected
1626
- CNodeState* state = State (peer_id);
1627
- if (state == nullptr ) return " Peer does not exist" ;
1630
+ PeerRef peer = GetPeerRef (peer_id);
1631
+ if (peer == nullptr ) return " Peer does not exist" ;
1632
+
1628
1633
// Ignore pre-segwit peers
1629
- if (!state->fHaveWitness ) return " Pre-SegWit peer" ;
1634
+ if (!CanServeWitnesses (*peer)) return " Pre-SegWit peer" ;
1635
+
1636
+ LOCK (cs_main);
1630
1637
1631
1638
// Mark block as in-flight unless it already is (for this peer).
1632
1639
// If a block was already in-flight for a different peer, its BLOCKTXN
@@ -2227,10 +2234,10 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
2227
2234
}
2228
2235
}
2229
2236
2230
- uint32_t PeerManagerImpl::GetFetchFlags (const CNode& pfrom ) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
2237
+ uint32_t PeerManagerImpl::GetFetchFlags (const Peer& peer ) const
2231
2238
{
2232
2239
uint32_t nFetchFlags = 0 ;
2233
- if (State (pfrom. GetId ())-> fHaveWitness ) {
2240
+ if (CanServeWitnesses (peer) ) {
2234
2241
nFetchFlags |= MSG_WITNESS_FLAG;
2235
2242
}
2236
2243
return nFetchFlags;
@@ -2325,7 +2332,7 @@ bool PeerManagerImpl::MaybeSendGetHeaders(CNode& pfrom, const CBlockLocator& loc
2325
2332
* We require that the given tip have at least as much work as our tip, and for
2326
2333
* our current tip to be "close to synced" (see CanDirectFetch()).
2327
2334
*/
2328
- void PeerManagerImpl::HeadersDirectFetchBlocks (CNode& pfrom, const CBlockIndex* pindexLast)
2335
+ void PeerManagerImpl::HeadersDirectFetchBlocks (CNode& pfrom, const Peer& peer, const CBlockIndex* pindexLast)
2329
2336
{
2330
2337
const CNetMsgMaker msgMaker (pfrom.GetCommonVersion ());
2331
2338
@@ -2340,7 +2347,7 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex*
2340
2347
while (pindexWalk && !m_chainman.ActiveChain ().Contains (pindexWalk) && vToFetch.size () <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
2341
2348
if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) &&
2342
2349
!IsBlockRequested (pindexWalk->GetBlockHash ()) &&
2343
- (!DeploymentActiveAt (*pindexWalk, m_chainman, Consensus::DEPLOYMENT_SEGWIT) || State (pfrom. GetId ())-> fHaveWitness )) {
2350
+ (!DeploymentActiveAt (*pindexWalk, m_chainman, Consensus::DEPLOYMENT_SEGWIT) || CanServeWitnesses (peer) )) {
2344
2351
// We don't have this block, and it's not yet in flight.
2345
2352
vToFetch.push_back (pindexWalk);
2346
2353
}
@@ -2362,7 +2369,7 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex*
2362
2369
// Can't download any more from this peer
2363
2370
break ;
2364
2371
}
2365
- uint32_t nFetchFlags = GetFetchFlags (pfrom );
2372
+ uint32_t nFetchFlags = GetFetchFlags (peer );
2366
2373
vGetData.push_back (CInv (MSG_BLOCK | nFetchFlags, pindex->GetBlockHash ()));
2367
2374
BlockRequested (pfrom.GetId (), *pindex);
2368
2375
LogPrint (BCLog::NET, " Requesting block %s from peer=%d\n " ,
@@ -2507,7 +2514,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
2507
2514
UpdatePeerStateForReceivedHeaders (pfrom, pindexLast, received_new_header, nCount == MAX_HEADERS_RESULTS);
2508
2515
2509
2516
// Consider immediately downloading blocks.
2510
- HeadersDirectFetchBlocks (pfrom, pindexLast);
2517
+ HeadersDirectFetchBlocks (pfrom, peer, pindexLast);
2511
2518
2512
2519
return ;
2513
2520
}
@@ -2901,12 +2908,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
2901
2908
if (fRelay ) pfrom.m_relays_txs = true ;
2902
2909
}
2903
2910
2904
- if ((nServices & NODE_WITNESS))
2905
- {
2906
- LOCK (cs_main);
2907
- State (pfrom.GetId ())->fHaveWitness = true ;
2908
- }
2909
-
2910
2911
// Potentially mark this peer as a preferred download peer.
2911
2912
{
2912
2913
LOCK (cs_main);
@@ -3789,7 +3790,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3789
3790
// We requested this block for some reason, but our mempool will probably be useless
3790
3791
// so we just grab the block via normal getdata
3791
3792
std::vector<CInv> vInv (1 );
3792
- vInv[0 ] = CInv (MSG_BLOCK | GetFetchFlags (pfrom ), cmpctblock.header .GetHash ());
3793
+ vInv[0 ] = CInv (MSG_BLOCK | GetFetchFlags (*peer ), cmpctblock.header .GetHash ());
3793
3794
m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::GETDATA, vInv));
3794
3795
}
3795
3796
return ;
@@ -3825,7 +3826,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3825
3826
} else if (status == READ_STATUS_FAILED) {
3826
3827
// Duplicate txindexes, the block is now in-flight, so just request it
3827
3828
std::vector<CInv> vInv (1 );
3828
- vInv[0 ] = CInv (MSG_BLOCK | GetFetchFlags (pfrom ), cmpctblock.header .GetHash ());
3829
+ vInv[0 ] = CInv (MSG_BLOCK | GetFetchFlags (*peer ), cmpctblock.header .GetHash ());
3829
3830
m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::GETDATA, vInv));
3830
3831
return ;
3831
3832
}
@@ -3868,7 +3869,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3868
3869
// We requested this block, but its far into the future, so our
3869
3870
// mempool will probably be useless - request the block normally
3870
3871
std::vector<CInv> vInv (1 );
3871
- vInv[0 ] = CInv (MSG_BLOCK | GetFetchFlags (pfrom ), cmpctblock.header .GetHash ());
3872
+ vInv[0 ] = CInv (MSG_BLOCK | GetFetchFlags (*peer ), cmpctblock.header .GetHash ());
3872
3873
m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::GETDATA, vInv));
3873
3874
return ;
3874
3875
} else {
@@ -3952,7 +3953,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3952
3953
} else if (status == READ_STATUS_FAILED) {
3953
3954
// Might have collided, fall back to getdata now :(
3954
3955
std::vector<CInv> invs;
3955
- invs.push_back (CInv (MSG_BLOCK | GetFetchFlags (pfrom ), resp.blockhash ));
3956
+ invs.push_back (CInv (MSG_BLOCK | GetFetchFlags (*peer ), resp.blockhash ));
3956
3957
m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::GETDATA, invs));
3957
3958
} else {
3958
3959
// Block is either okay, or possibly we received
@@ -5266,9 +5267,9 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
5266
5267
if (CanServeBlocks (*peer) && ((sync_blocks_and_headers_from_peer && !IsLimitedPeer (*peer)) || !m_chainman.ActiveChainstate ().IsInitialBlockDownload ()) && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
5267
5268
std::vector<const CBlockIndex*> vToDownload;
5268
5269
NodeId staller = -1 ;
5269
- FindNextBlocksToDownload (pto-> GetId () , MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight , vToDownload, staller);
5270
+ FindNextBlocksToDownload (*peer , MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight , vToDownload, staller);
5270
5271
for (const CBlockIndex *pindex : vToDownload) {
5271
- uint32_t nFetchFlags = GetFetchFlags (*pto );
5272
+ uint32_t nFetchFlags = GetFetchFlags (*peer );
5272
5273
vGetData.push_back (CInv (MSG_BLOCK | nFetchFlags, pindex->GetBlockHash ()));
5273
5274
BlockRequested (pto->GetId (), *pindex);
5274
5275
LogPrint (BCLog::NET, " Requesting block %s (%d) peer=%d\n " , pindex->GetBlockHash ().ToString (),
@@ -5295,7 +5296,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
5295
5296
if (!AlreadyHaveTx (gtxid)) {
5296
5297
LogPrint (BCLog::NET, " Requesting %s %s peer=%d\n " , gtxid.IsWtxid () ? " wtx" : " tx" ,
5297
5298
gtxid.GetHash ().ToString (), pto->GetId ());
5298
- vGetData.emplace_back (gtxid.IsWtxid () ? MSG_WTX : (MSG_TX | GetFetchFlags (*pto )), gtxid.GetHash ());
5299
+ vGetData.emplace_back (gtxid.IsWtxid () ? MSG_WTX : (MSG_TX | GetFetchFlags (*peer )), gtxid.GetHash ());
5299
5300
if (vGetData.size () >= MAX_GETDATA_SZ) {
5300
5301
m_connman.PushMessage (pto, msgMaker.Make (NetMsgType::GETDATA, vGetData));
5301
5302
vGetData.clear ();
0 commit comments