@@ -105,10 +105,10 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
105105 peerLogic->FinalizeNode (dummyNode1);
106106}
107107
108- static void AddRandomOutboundPeer (std::vector<CNode*>& vNodes, PeerManager& peerLogic, ConnmanTestMsg& connman)
108+ static void AddRandomOutboundPeer (std::vector<CNode*>& vNodes, PeerManager& peerLogic, ConnmanTestMsg& connman, ConnectionType connType )
109109{
110110 CAddress addr (ip (g_insecure_rand_ctx.randbits (32 )), NODE_NONE);
111- vNodes.emplace_back (new CNode (id++, ServiceFlags (NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr, /* nKeyedNetGroupIn=*/ 0 , /* nLocalHostNonceIn=*/ 0 , CAddress (), /* addrNameIn=*/ " " , ConnectionType::OUTBOUND_FULL_RELAY , /* inbound_onion=*/ false ));
111+ vNodes.emplace_back (new CNode (id++, ServiceFlags (NODE_NETWORK | NODE_WITNESS), INVALID_SOCKET, addr, /* nKeyedNetGroupIn=*/ 0 , /* nLocalHostNonceIn=*/ 0 , CAddress (), /* addrNameIn=*/ " " , connType , /* inbound_onion=*/ false ));
112112 CNode &node = *vNodes.back ();
113113 node.SetCommonVersion (PROTOCOL_VERSION);
114114
@@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
136136
137137 // Mock some outbound peers
138138 for (int i = 0 ; i < max_outbound_full_relay; ++i) {
139- AddRandomOutboundPeer (vNodes, *peerLogic, *connman);
139+ AddRandomOutboundPeer (vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY );
140140 }
141141
142142 peerLogic->CheckForStaleTipAndEvictPeers ();
@@ -161,7 +161,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
161161 // If we add one more peer, something should get marked for eviction
162162 // on the next check (since we're mocking the time to be in the future, the
163163 // required time connected check should be satisfied).
164- AddRandomOutboundPeer (vNodes, *peerLogic, *connman);
164+ AddRandomOutboundPeer (vNodes, *peerLogic, *connman, ConnectionType::OUTBOUND_FULL_RELAY );
165165
166166 peerLogic->CheckForStaleTipAndEvictPeers ();
167167 for (int i = 0 ; i < max_outbound_full_relay; ++i) {
@@ -190,6 +190,68 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
190190 connman->ClearTestNodes ();
191191}
192192
193+ BOOST_AUTO_TEST_CASE (block_relay_only_eviction)
194+ {
195+ const CChainParams& chainparams = Params ();
196+ auto connman = std::make_unique<ConnmanTestMsg>(0x1337 , 0x1337 , *m_node.addrman );
197+ auto peerLogic = PeerManager::make (chainparams, *connman, *m_node.addrman , nullptr ,
198+ *m_node.chainman , *m_node.mempool , false );
199+
200+ constexpr int max_outbound_block_relay{MAX_BLOCK_RELAY_ONLY_CONNECTIONS};
201+ constexpr int64_t MINIMUM_CONNECT_TIME{30 };
202+ CConnman::Options options;
203+ options.nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS;
204+ options.m_max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
205+ options.m_max_outbound_block_relay = max_outbound_block_relay;
206+
207+ connman->Init (options);
208+ std::vector<CNode*> vNodes;
209+
210+ // Add block-relay-only peers up to the limit
211+ for (int i = 0 ; i < max_outbound_block_relay; ++i) {
212+ AddRandomOutboundPeer (vNodes, *peerLogic, *connman, ConnectionType::BLOCK_RELAY);
213+ }
214+ peerLogic->CheckForStaleTipAndEvictPeers ();
215+
216+ for (int i = 0 ; i < max_outbound_block_relay; ++i) {
217+ BOOST_CHECK (vNodes[i]->fDisconnect == false );
218+ }
219+
220+ // Add an extra block-relay-only peer breaking the limit (mocks logic in ThreadOpenConnections)
221+ AddRandomOutboundPeer (vNodes, *peerLogic, *connman, ConnectionType::BLOCK_RELAY);
222+ peerLogic->CheckForStaleTipAndEvictPeers ();
223+
224+ // The extra peer should only get marked for eviction after MINIMUM_CONNECT_TIME
225+ for (int i = 0 ; i < max_outbound_block_relay; ++i) {
226+ BOOST_CHECK (vNodes[i]->fDisconnect == false );
227+ }
228+ BOOST_CHECK (vNodes.back ()->fDisconnect == false );
229+
230+ SetMockTime (GetTime () + MINIMUM_CONNECT_TIME + 1 );
231+ peerLogic->CheckForStaleTipAndEvictPeers ();
232+ for (int i = 0 ; i < max_outbound_block_relay; ++i) {
233+ BOOST_CHECK (vNodes[i]->fDisconnect == false );
234+ }
235+ BOOST_CHECK (vNodes.back ()->fDisconnect == true );
236+
237+ // Update the last block time for the extra peer,
238+ // and check that the next youngest peer gets evicted.
239+ vNodes.back ()->fDisconnect = false ;
240+ vNodes.back ()->nLastBlockTime = GetTime ();
241+
242+ peerLogic->CheckForStaleTipAndEvictPeers ();
243+ for (int i = 0 ; i < max_outbound_block_relay - 1 ; ++i) {
244+ BOOST_CHECK (vNodes[i]->fDisconnect == false );
245+ }
246+ BOOST_CHECK (vNodes[max_outbound_block_relay - 1 ]->fDisconnect == true );
247+ BOOST_CHECK (vNodes.back ()->fDisconnect == false );
248+
249+ for (const CNode* node : vNodes) {
250+ peerLogic->FinalizeNode (*node);
251+ }
252+ connman->ClearTestNodes ();
253+ }
254+
193255BOOST_AUTO_TEST_CASE (peer_discouragement)
194256{
195257 const CChainParams& chainparams = Params ();
0 commit comments