@@ -3097,7 +3097,7 @@ void PeerManagerImpl::ProcessMessage(
3097
3097
LogPrintf (" New outbound peer connected: version: %d, blocks=%d, peer=%d%s (%s)\n " ,
3098
3098
pfrom.nVersion .load (), pfrom.nStartingHeight ,
3099
3099
pfrom.GetId (), (fLogIPs ? strprintf (" , peeraddr=%s" , pfrom.addr .ToString ()) : " " ),
3100
- pfrom.RelayAddrsWithConn ()? " full -relay" : " block -relay" );
3100
+ pfrom.IsBlockOnlyConn ()? " block -relay" : " full -relay" );
3101
3101
}
3102
3102
3103
3103
if (!pfrom.m_masternode_probe_connection ) {
@@ -4607,11 +4607,54 @@ void PeerManagerImpl::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
4607
4607
4608
4608
void PeerManagerImpl::EvictExtraOutboundPeers (int64_t time_in_seconds)
4609
4609
{
4610
- // Check whether we have too many outbound peers
4611
- int extra_peers = m_connman.GetExtraOutboundCount ();
4612
- if (extra_peers > 0 ) {
4613
- // If we have more outbound peers than we target, disconnect one.
4614
- // Pick the outbound peer that least recently announced
4610
+ // If we have any extra block-relay-only peers, disconnect the youngest unless
4611
+ // it's given us a block -- in which case, compare with the second-youngest, and
4612
+ // out of those two, disconnect the peer who least recently gave us a block.
4613
+ // The youngest block-relay-only peer would be the extra peer we connected
4614
+ // to temporarily in order to sync our tip; see net.cpp.
4615
+ // Note that we use higher nodeid as a measure for most recent connection.
4616
+ if (m_connman.GetExtraBlockRelayCount () > 0 ) {
4617
+ std::pair<NodeId, int64_t > youngest_peer{-1 , 0 }, next_youngest_peer{-1 , 0 };
4618
+
4619
+ m_connman.ForEachNode ([&](CNode* pnode) {
4620
+ if (!pnode->IsBlockOnlyConn () || pnode->fDisconnect ) return ;
4621
+ if (pnode->GetId () > youngest_peer.first ) {
4622
+ next_youngest_peer = youngest_peer;
4623
+ youngest_peer.first = pnode->GetId ();
4624
+ youngest_peer.second = pnode->nLastBlockTime ;
4625
+ }
4626
+ });
4627
+ NodeId to_disconnect = youngest_peer.first ;
4628
+ if (youngest_peer.second > next_youngest_peer.second ) {
4629
+ // Our newest block-relay-only peer gave us a block more recently;
4630
+ // disconnect our second youngest.
4631
+ to_disconnect = next_youngest_peer.first ;
4632
+ }
4633
+ m_connman.ForNode (to_disconnect, [&](CNode* pnode) EXCLUSIVE_LOCKS_REQUIRED (::cs_main) {
4634
+ AssertLockHeld (::cs_main);
4635
+ // Make sure we're not getting a block right now, and that
4636
+ // we've been connected long enough for this eviction to happen
4637
+ // at all.
4638
+ // Note that we only request blocks from a peer if we learn of a
4639
+ // valid headers chain with at least as much work as our tip.
4640
+ CNodeState *node_state = State (pnode->GetId ());
4641
+ if (node_state == nullptr ||
4642
+ (time_in_seconds - pnode->nTimeConnected >= MINIMUM_CONNECT_TIME && node_state->nBlocksInFlight == 0 )) {
4643
+ pnode->fDisconnect = true ;
4644
+ LogPrint (BCLog::NET, " disconnecting extra block-relay-only peer=%d (last block received at time %d)\n " , pnode->GetId (), pnode->nLastBlockTime );
4645
+ return true ;
4646
+ } else {
4647
+ LogPrint (BCLog::NET, " keeping block-relay-only peer=%d chosen for eviction (connect time: %d, blocks_in_flight: %d)\n " ,
4648
+ pnode->GetId (), pnode->nTimeConnected , node_state->nBlocksInFlight );
4649
+ }
4650
+ return false ;
4651
+ });
4652
+ }
4653
+
4654
+ // Check whether we have too many OUTBOUND_FULL_RELAY peers
4655
+ if (m_connman.GetExtraFullOutboundCount () > 0 ) {
4656
+ // If we have more OUTBOUND_FULL_RELAY peers than we target, disconnect one.
4657
+ // Pick the OUTBOUND_FULL_RELAY peer that least recently announced
4615
4658
// us a new block, with ties broken by choosing the more recent
4616
4659
// connection (higher node id)
4617
4660
NodeId worst_peer = -1 ;
@@ -4622,14 +4665,13 @@ void PeerManagerImpl::EvictExtraOutboundPeers(int64_t time_in_seconds)
4622
4665
4623
4666
// Don't disconnect masternodes just because they were slow in block announcement
4624
4667
if (pnode->m_masternode_connection ) return ;
4625
- // Ignore non-outbound peers, or nodes marked for disconnect already
4626
- if (!pnode->IsOutboundOrBlockRelayConn () || pnode->fDisconnect ) return ;
4668
+ // Only consider OUTBOUND_FULL_RELAY peers that are not already
4669
+ // marked for disconnection
4670
+ if (!pnode->IsFullOutboundConn () || pnode->fDisconnect ) return ;
4627
4671
CNodeState *state = State (pnode->GetId ());
4628
4672
if (state == nullptr ) return ; // shouldn't be possible, but just in case
4629
4673
// Don't evict our protected peers
4630
4674
if (state->m_chain_sync .m_protect ) return ;
4631
- // Don't evict our block-relay-only peers.
4632
- if (!pnode->RelayAddrsWithConn ()) return ;
4633
4675
if (state->m_last_block_announcement < oldest_block_announcement || (state->m_last_block_announcement == oldest_block_announcement && pnode->GetId () > worst_peer)) {
4634
4676
worst_peer = pnode->GetId ();
4635
4677
oldest_block_announcement = state->m_last_block_announcement ;
@@ -4685,6 +4727,11 @@ void PeerManagerImpl::CheckForStaleTipAndEvictPeers()
4685
4727
}
4686
4728
m_stale_tip_check_time = time_in_seconds + STALE_CHECK_INTERVAL;
4687
4729
}
4730
+
4731
+ if (!m_initial_sync_finished && CanDirectFetch (m_chainparams.GetConsensus ())) {
4732
+ m_connman.StartExtraBlockRelayPeers ();
4733
+ m_initial_sync_finished = true ;
4734
+ }
4688
4735
}
4689
4736
4690
4737
namespace {
@@ -4757,6 +4804,15 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
4757
4804
if (fListen && pto->RelayAddrsWithConn () &&
4758
4805
!m_chainman.ActiveChainstate ().IsInitialBlockDownload () &&
4759
4806
pto->m_next_local_addr_send < current_time) {
4807
+ // If we've sent before, clear the bloom filter for the peer, so that our
4808
+ // self-announcement will actually go out.
4809
+ // This might be unnecessary if the bloom filter has already rolled
4810
+ // over since our last self-announcement, but there is only a small
4811
+ // bandwidth cost that we can incur by doing this (which happens
4812
+ // once a day on average).
4813
+ if (pto->m_next_local_addr_send != std::chrono::microseconds::zero ()) {
4814
+ pto->m_addr_known ->reset ();
4815
+ }
4760
4816
if (std::optional<CAddress> local_addr = GetLocalAddrForPeer (pto)) {
4761
4817
FastRandomContext insecure_rand;
4762
4818
pto->PushAddress (*local_addr, insecure_rand);
0 commit comments