1212 P2PDataStore ,
1313 P2PInterface ,
1414)
15+ from test_framework .messages import CTxIn , COutPoint , msg_mnping
1516from test_framework .test_framework import PivxTestFramework
1617from test_framework .util import (
18+ assert_equal ,
1719 hex_str_to_bytes ,
1820)
21+ from random import getrandbits
1922
2023MSG_LIMIT = 2 * 1024 * 1024 # 2MB, per MAX_PROTOCOL_MESSAGE_LENGTH
2124VALID_DATA_LIMIT = MSG_LIMIT - 5 # Account for the 5-byte length prefix
@@ -39,6 +42,19 @@ class SenderOfAddrV2(P2PInterface):
3942 def wait_for_sendaddrv2 (self ):
4043 self .wait_until (lambda : 'sendaddrv2' in self .last_message )
4144
45+ class InvReceiver (P2PInterface ):
46+
47+ def __init__ (self ):
48+ super ().__init__ ()
49+ self .vec_mnp = {}
50+ self .getdata_count = 0
51+
52+ def on_getdata (self , message ):
53+ for inv in message .inv :
54+ if inv .type == 15 : # MNPING
55+ self .send_message (self .vec_mnp [inv .hash ])
56+ self .getdata_count += 1
57+
4258class InvalidMessagesTest (PivxTestFramework ):
4359 def set_test_params (self ):
4460 self .num_nodes = 1
@@ -55,6 +71,7 @@ def run_test(self):
5571 self .test_addrv2_unrecognized_network ()
5672 self .test_large_inv ()
5773 self .test_resource_exhaustion ()
74+ self .test_fill_askfor ()
5875
5976 def test_magic_bytes (self ):
6077 conn = self .nodes [0 ].add_p2p_connection (P2PDataStore ())
@@ -187,6 +204,33 @@ def test_large_inv(self):
187204 conn .send_and_ping (msg )
188205 self .nodes [0 ].disconnect_p2ps ()
189206
207+ def test_fill_askfor (self ):
208+ self .nodes [0 ].generate (1 ) # IBD
209+ conn = self .nodes [0 ].add_p2p_connection (InvReceiver ())
210+ invs = []
211+ blockhash = int (self .nodes [0 ].getbestblockhash (), 16 )
212+ for _ in range (50000 ):
213+ mnp = msg_mnping (CTxIn (COutPoint (getrandbits (256 ))), blockhash , int (time .time ()))
214+ conn .vec_mnp [mnp .get_hash ()] = mnp
215+ invs .append (messages .CInv (15 , mnp .get_hash ()))
216+ assert_equal (len (conn .vec_mnp ), 50000 )
217+ assert_equal (len (invs ), 50000 )
218+ msg = messages .msg_inv (invs )
219+ conn .send_message (msg )
220+
221+ time .sleep (20 ) # wait a bit
222+ assert_equal (conn .getdata_count , 50000 )
223+
224+ # Prior #2611 the node was blocking any follow-up request.
225+ mnp = msg_mnping (CTxIn (COutPoint (getrandbits (256 ))), getrandbits (256 ), int (time .time ()))
226+ conn .vec_mnp [mnp .get_hash ()] = mnp
227+ msg = messages .msg_inv ([messages .CInv (15 , mnp .get_hash ())])
228+ conn .send_and_ping (msg )
229+ time .sleep (3 )
230+
231+ assert_equal (conn .getdata_count , 50001 )
232+ self .nodes [0 ].disconnect_p2ps ()
233+
190234 def test_resource_exhaustion (self ):
191235 conn = self .nodes [0 ].add_p2p_connection (P2PDataStore ())
192236 conn2 = self .nodes [0 ].add_p2p_connection (P2PDataStore ())
0 commit comments