17
17
from test_framework .test_framework import BitcoinTestFramework
18
18
from test_framework .util import (
19
19
assert_equal ,
20
+ assert_greater_than_or_equal ,
20
21
)
22
+ import os
23
+ import random
21
24
import time
22
25
23
26
@@ -60,6 +63,7 @@ def run_test(self):
60
63
self .relay_tests ()
61
64
self .getaddr_tests ()
62
65
self .blocksonly_mode_tests ()
66
+ self .rate_limit_tests ()
63
67
64
68
def setup_addr_msg (self , num ):
65
69
addrs = []
@@ -76,6 +80,19 @@ def setup_addr_msg(self, num):
76
80
msg .addrs = addrs
77
81
return msg
78
82
83
+ def setup_rand_addr_msg (self , num ):
84
+ addrs = []
85
+ for i in range (num ):
86
+ addr = CAddress ()
87
+ addr .time = self .mocktime + i
88
+ addr .nServices = NODE_NETWORK | NODE_WITNESS
89
+ addr .ip = f"{ random .randrange (128 ,169 )} .{ random .randrange (1 ,255 )} .{ random .randrange (1 ,255 )} .{ random .randrange (1 ,255 )} "
90
+ addr .port = 8333
91
+ addrs .append (addr )
92
+ msg = msg_addr ()
93
+ msg .addrs = addrs
94
+ return msg
95
+
79
96
def send_addr_msg (self , source , msg , receivers ):
80
97
source .send_and_ping (msg )
81
98
# pop m_next_addr_send timer
@@ -208,6 +225,69 @@ def blocksonly_mode_tests(self):
208
225
209
226
self .nodes [0 ].disconnect_p2ps ()
210
227
228
+ def rate_limit_tests (self ):
229
+
230
+ for contype , tokens , no_relay in [("outbound-full-relay" , 1001 , False ), ("block-relay-only" , 0 , True ), ("inbound" , 1 , False )]:
231
+ self .log .info (f'Test rate limiting of addr processing for { contype } peers' )
232
+ self .stop_node (0 )
233
+ os .remove (os .path .join (self .nodes [0 ].datadir , "regtest" , "peers.dat" ))
234
+ self .start_node (0 , [])
235
+ self .mocktime = int (time .time ())
236
+ self .nodes [0 ].setmocktime (self .mocktime )
237
+ if contype == "inbound" :
238
+ peer = self .nodes [0 ].add_p2p_connection (AddrReceiver ())
239
+ else :
240
+ peer = self .nodes [0 ].add_outbound_p2p_connection (AddrReceiver (), p2p_idx = 0 , connection_type = contype )
241
+
242
+ # Check that we start off with empty addrman
243
+ addr_count_0 = len (self .nodes [0 ].getnodeaddresses (0 ))
244
+ assert_equal (addr_count_0 , 0 )
245
+
246
+ # Send 600 addresses. For all but the block-relay-only peer this should result in at least 1 address.
247
+ peer .send_and_ping (self .setup_rand_addr_msg (600 ))
248
+ addr_count_1 = len (self .nodes [0 ].getnodeaddresses (0 ))
249
+ assert_greater_than_or_equal (tokens , addr_count_1 )
250
+ assert_greater_than_or_equal (addr_count_0 + 600 , addr_count_1 )
251
+ assert_equal (addr_count_1 > addr_count_0 , tokens > 0 )
252
+
253
+ # Send 600 more addresses. For the outbound-full-relay peer (which we send a GETADDR, and thus will
254
+ # process up to 1001 incoming addresses), this means more entries will appear.
255
+ peer .send_and_ping (self .setup_rand_addr_msg (600 ))
256
+ addr_count_2 = len (self .nodes [0 ].getnodeaddresses (0 ))
257
+ assert_greater_than_or_equal (tokens , addr_count_2 )
258
+ assert_greater_than_or_equal (addr_count_1 + 600 , addr_count_2 )
259
+ assert_equal (addr_count_2 > addr_count_1 , tokens > 600 )
260
+
261
+ # Send 10 more. As we reached the processing limit for all nodes, this should have no effect.
262
+ peer .send_and_ping (self .setup_rand_addr_msg (10 ))
263
+ addr_count_3 = len (self .nodes [0 ].getnodeaddresses (0 ))
264
+ assert_greater_than_or_equal (tokens , addr_count_3 )
265
+ assert_equal (addr_count_2 , addr_count_3 )
266
+
267
+ # Advance the time by 100 seconds, permitting the processing of 10 more addresses. Send 200,
268
+ # but verify that no more than 10 are processed.
269
+ self .mocktime += 100
270
+ self .nodes [0 ].setmocktime (self .mocktime )
271
+ new_tokens = 0 if no_relay else 10
272
+ tokens += new_tokens
273
+ peer .send_and_ping (self .setup_rand_addr_msg (200 ))
274
+ addr_count_4 = len (self .nodes [0 ].getnodeaddresses (0 ))
275
+ assert_greater_than_or_equal (tokens , addr_count_4 )
276
+ assert_greater_than_or_equal (addr_count_3 + new_tokens , addr_count_4 )
277
+
278
+ # Advance the time by 1000 seconds, permitting the processing of 100 more addresses. Send 200,
279
+ # but verify that no more than 100 are processed (and at least some).
280
+ self .mocktime += 1000
281
+ self .nodes [0 ].setmocktime (self .mocktime )
282
+ new_tokens = 0 if no_relay else 100
283
+ tokens += new_tokens
284
+ peer .send_and_ping (self .setup_rand_addr_msg (200 ))
285
+ addr_count_5 = len (self .nodes [0 ].getnodeaddresses (0 ))
286
+ assert_greater_than_or_equal (tokens , addr_count_5 )
287
+ assert_greater_than_or_equal (addr_count_4 + new_tokens , addr_count_5 )
288
+ assert_equal (addr_count_5 > addr_count_4 , not no_relay )
289
+
290
+ self .nodes [0 ].disconnect_p2ps ()
211
291
212
292
if __name__ == '__main__' :
213
293
AddrTest ().main ()
0 commit comments