3
3
# Distributed under the MIT software license, see the accompanying
4
4
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
5
"""Test node responses to invalid network messages."""
6
+
6
7
from test_framework .messages import (
7
8
CBlockHeader ,
8
9
CInv ,
9
10
msg_getdata ,
10
11
msg_headers ,
11
12
msg_inv ,
13
+ msg_ping ,
12
14
MSG_TX ,
13
15
ser_string ,
14
16
)
17
19
P2PInterface ,
18
20
)
19
21
from test_framework .test_framework import BitcoinTestFramework
22
+ from test_framework .util import (
23
+ assert_equal ,
24
+ wait_until ,
25
+ )
20
26
21
27
MSG_LIMIT = 4 * 1000 * 1000 # 4MB, per MAX_PROTOCOL_MESSAGE_LENGTH
22
28
VALID_DATA_LIMIT = MSG_LIMIT - 5 # Account for the 5-byte length prefix
@@ -42,13 +48,33 @@ def set_test_params(self):
42
48
self .setup_clean_chain = True
43
49
44
50
def run_test (self ):
51
+ self .test_buffer ()
45
52
self .test_magic_bytes ()
46
53
self .test_checksum ()
47
54
self .test_size ()
48
55
self .test_msgtype ()
49
56
self .test_large_inv ()
50
57
self .test_resource_exhaustion ()
51
58
59
+ def test_buffer (self ):
60
+ self .log .info ("Test message with header split across two buffers, should be received" )
61
+ conn = self .nodes [0 ].add_p2p_connection (P2PDataStore ())
62
+ # Create valid message
63
+ msg = conn .build_message (msg_ping (nonce = 12345 ))
64
+ cut_pos = 12 # Chosen at an arbitrary position within the header
65
+ # Send message in two pieces
66
+ before = int (self .nodes [0 ].getnettotals ()['totalbytesrecv' ])
67
+ conn .send_raw_message (msg [:cut_pos ])
68
+ # Wait until node has processed the first half of the message
69
+ wait_until (lambda : int (self .nodes [0 ].getnettotals ()['totalbytesrecv' ]) != before )
70
+ middle = int (self .nodes [0 ].getnettotals ()['totalbytesrecv' ])
71
+ # If this assert fails, we've hit an unlikely race
72
+ # where the test framework sent a message in between the two halves
73
+ assert_equal (middle , before + cut_pos )
74
+ conn .send_raw_message (msg [cut_pos :])
75
+ conn .sync_with_ping (timeout = 1 )
76
+ self .nodes [0 ].disconnect_p2ps ()
77
+
52
78
def test_magic_bytes (self ):
53
79
conn = self .nodes [0 ].add_p2p_connection (P2PDataStore ())
54
80
with self .nodes [0 ].assert_debug_log (['PROCESSMESSAGE: INVALID MESSAGESTART badmsg' ]):
@@ -95,13 +121,13 @@ def test_msgtype(self):
95
121
96
122
def test_large_inv (self ):
97
123
conn = self .nodes [0 ].add_p2p_connection (P2PInterface ())
98
- with self .nodes [0 ].assert_debug_log (['Misbehaving' , 'peer=4 (0 -> 20): message inv size() = 50001' ]):
124
+ with self .nodes [0 ].assert_debug_log (['Misbehaving' , '(0 -> 20): message inv size() = 50001' ]):
99
125
msg = msg_inv ([CInv (MSG_TX , 1 )] * 50001 )
100
126
conn .send_and_ping (msg )
101
- with self .nodes [0 ].assert_debug_log (['Misbehaving' , 'peer=4 (20 -> 40): message getdata size() = 50001' ]):
127
+ with self .nodes [0 ].assert_debug_log (['Misbehaving' , '(20 -> 40): message getdata size() = 50001' ]):
102
128
msg = msg_getdata ([CInv (MSG_TX , 1 )] * 50001 )
103
129
conn .send_and_ping (msg )
104
- with self .nodes [0 ].assert_debug_log (['Misbehaving' , 'peer=4 (40 -> 60): headers message size = 2001' ]):
130
+ with self .nodes [0 ].assert_debug_log (['Misbehaving' , '(40 -> 60): headers message size = 2001' ]):
105
131
msg = msg_headers ([CBlockHeader ()] * 2001 )
106
132
conn .send_and_ping (msg )
107
133
self .nodes [0 ].disconnect_p2ps ()
0 commit comments