66Test addr relay
77"""
88
9- import time
10-
119from test_framework .messages import (
1210 CAddress ,
1311 NODE_NETWORK ,
1412 msg_addr ,
1513)
1614from test_framework .mininode import (
1715 P2PInterface ,
16+ mininode_lock
1817)
1918from test_framework .test_framework import PivxTestFramework
20- from test_framework .util import (
21- assert_equal ,
22- )
19+ from test_framework .util import assert_equal
20+
21+ import random
22+ import time
2323
2424ADDRS = []
2525for i in range (10 ):
3232
3333
3434class AddrReceiver (P2PInterface ):
35+ _tokens = 10
3536 def on_addr (self , message ):
3637 for addr in message .addrs :
3738 assert_equal (addr .nServices , 1 )
3839 assert addr .ip .startswith ('123.123.123.' )
3940 assert (8333 <= addr .port < 8343 )
4041
42+ def on_getaddr (self , message ):
43+ # When the node sends us a getaddr, it increments the addr relay tokens for the connection by 1000
44+ self ._tokens += 1000
45+
46+ @property
47+ def tokens (self ):
48+ with mininode_lock :
49+ return self ._tokens
50+
51+ def increment_tokens (self , n ):
52+ # When we move mocktime forward, the node increments the addr relay tokens for its peers
53+ with mininode_lock :
54+ self ._tokens += n
55+
4156
4257class AddrTest (PivxTestFramework ):
4358 def set_test_params (self ):
4459 self .setup_clean_chain = False
4560 self .num_nodes = 1
61+ self .extra_args = [["-whitelist=127.0.0.1" ]]
4662
4763 def run_test (self ):
4864 self .log .info ('Create connection that sends addr messages' )
@@ -57,6 +73,8 @@ def run_test(self):
5773 self .log .info ('Check that addr message content is relayed and added to addrman' )
5874 addr_receiver = self .nodes [0 ].add_p2p_connection (AddrReceiver ())
5975 msg .addrs = ADDRS
76+ self .mocktime += 10
77+ self .nodes [0 ].setmocktime (self .mocktime )
6078 with self .nodes [0 ].assert_debug_log ([
6179 'Added 10 addresses from 127.0.0.1: 0 tried' ,
6280 'received: addr (301 bytes) peer=0' ,
@@ -65,6 +83,71 @@ def run_test(self):
6583 addr_source .send_and_ping (msg )
6684 self .nodes [0 ].setmocktime (int (time .time ()) + 30 * 60 )
6785 addr_receiver .sync_with_ping ()
86+ self .rate_limit_tests ()
87+
88+ def setup_rand_addr_msg (self , num ):
89+ addrs = []
90+ for i in range (num ):
91+ addr = CAddress ()
92+ addr .time = self .mocktime + i
93+ addr .nServices = NODE_NETWORK
94+ addr .ip = f"{ random .randrange (128 ,169 )} .{ random .randrange (1 ,255 )} .{ random .randrange (1 ,255 )} .{ random .randrange (1 ,255 )} "
95+ addr .port = 8333
96+ addrs .append (addr )
97+ msg = msg_addr ()
98+ msg .addrs = addrs
99+ return msg
100+
101+ def send_addrs_and_test_rate_limiting (self , peer , new_addrs , total_addrs ):
102+ """Send an addr message and check that the number of addresses processed and rate-limited is as expected"""
103+
104+ peer .send_and_ping (self .setup_rand_addr_msg (new_addrs ))
105+
106+ peerinfo = self .nodes [0 ].getpeerinfo ()[2 ]
107+ addrs_processed = peerinfo ['addr_processed' ]
108+ addrs_rate_limited = peerinfo ['addr_rate_limited' ]
109+ self .log .info (f'addrs_processed = { addrs_processed } , addrs_rate_limited = { addrs_rate_limited } ' )
110+ self .log .info (f'peer_tokens = { peer .tokens } ' )
111+
112+ assert_equal (addrs_processed , min (total_addrs , peer .tokens ))
113+ assert_equal (addrs_rate_limited , max (0 , total_addrs - peer .tokens ))
114+
115+ def rate_limit_tests (self ):
116+
117+ self .mocktime = int (time .time ())
118+ self .nodes [0 ].setmocktime (self .mocktime )
119+
120+ peer = self .nodes [0 ].add_p2p_connection (AddrReceiver ())
121+
122+ self .log .info (f'Test rate limiting of addr processing for inbound peers' )
123+
124+ # Send 600 addresses.
125+ self .send_addrs_and_test_rate_limiting (peer , 600 , 600 )
126+
127+ # Send 400 more addresses.
128+ self .send_addrs_and_test_rate_limiting (peer , 400 , 1000 )
129+
130+ # Send 10 more. As we reached the processing limit for nodes, no more addresses should be procesesd.
131+ self .send_addrs_and_test_rate_limiting (peer , 10 , 1010 )
132+
133+ # Advance the time by 100 seconds, permitting the processing of 10 more addresses.
134+ # Send 200 and verify that 10 are processed.
135+ self .mocktime += 100
136+ self .nodes [0 ].setmocktime (self .mocktime )
137+ peer .increment_tokens (10 )
138+
139+ self .send_addrs_and_test_rate_limiting (peer , 200 , 1210 )
140+
141+ # Advance the time by 1000 seconds, permitting the processing of 100 more addresses.
142+ # Send 200 and verify that 100 are processed.
143+ self .mocktime += 1000
144+ self .nodes [0 ].setmocktime (self .mocktime )
145+ peer .increment_tokens (100 )
146+
147+ self .send_addrs_and_test_rate_limiting (peer , 200 , 1410 )
148+
149+ self .nodes [0 ].disconnect_p2ps ()
150+
68151
69152
70153if __name__ == '__main__' :
0 commit comments