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
6
+ import random
6
7
from enum import Enum
7
8
8
9
from test_framework .messages import MAGIC_BYTES
9
10
from test_framework .p2p import P2PInterface
10
11
from test_framework .test_framework import BGLTestFramework
11
- from test_framework .v2_p2p import EncryptedP2PState
12
+ from test_framework .v2_p2p import (
13
+ EncryptedP2PState ,
14
+ MAX_GARBAGE_LEN ,
15
+ )
12
16
13
17
14
18
class TestType (Enum ):
15
19
""" Scenarios to be tested:
16
20
17
21
1. EARLY_KEY_RESPONSE - The responder needs to wait until one byte is received which does not match the 16 bytes
18
22
consisting of network magic followed by "version\x00 \x00 \x00 \x00 \x00 " before sending out its ellswift + garbage bytes
23
+ 2. EXCESS_GARBAGE - Disconnection happens when > MAX_GARBAGE_LEN bytes garbage is sent
19
24
"""
20
25
EARLY_KEY_RESPONSE = 0
26
+ EXCESS_GARBAGE = 1
21
27
22
28
23
29
class EarlyKeyResponseState (EncryptedP2PState ):
@@ -32,6 +38,13 @@ def initiate_v2_handshake(self):
32
38
return b""
33
39
34
40
41
+ class ExcessGarbageState (EncryptedP2PState ):
42
+ """Generate > MAX_GARBAGE_LEN garbage bytes"""
43
+ def generate_keypair_and_garbage (self ):
44
+ garbage_len = MAX_GARBAGE_LEN + random .randrange (1 , MAX_GARBAGE_LEN + 1 )
45
+ return super ().generate_keypair_and_garbage (garbage_len )
46
+
47
+
35
48
class MisbehavingV2Peer (P2PInterface ):
36
49
"""Custom implementation of P2PInterface which uses modified v2 P2P protocol functions for testing purposes."""
37
50
def __init__ (self , test_type ):
@@ -41,6 +54,8 @@ def __init__(self, test_type):
41
54
def connection_made (self , transport ):
42
55
if self .test_type == TestType .EARLY_KEY_RESPONSE :
43
56
self .v2_state = EarlyKeyResponseState (initiating = True , net = 'regtest' )
57
+ elif self .test_type == TestType .EXCESS_GARBAGE :
58
+ self .v2_state = ExcessGarbageState (initiating = True , net = 'regtest' )
44
59
super ().connection_made (transport )
45
60
46
61
def data_received (self , t ):
@@ -58,6 +73,7 @@ def set_test_params(self):
58
73
59
74
def run_test (self ):
60
75
self .test_earlykeyresponse ()
76
+ self .test_v2disconnection ()
61
77
62
78
def test_earlykeyresponse (self ):
63
79
self .log .info ('Sending ellswift bytes in parts to ensure that response from responder is received only when' )
@@ -75,6 +91,21 @@ def test_earlykeyresponse(self):
75
91
peer1 .wait_for_disconnect (timeout = 5 )
76
92
self .log .info ('successful disconnection since modified ellswift was sent as response' )
77
93
94
+ def test_v2disconnection (self ):
95
+ # test v2 disconnection scenarios
96
+ node0 = self .nodes [0 ]
97
+ expected_debug_message = [
98
+ [], # EARLY_KEY_RESPONSE
99
+ ["V2 transport error: missing garbage terminator, peer=1" ], # EXCESS_GARBAGE
100
+ ]
101
+ for test_type in TestType :
102
+ if test_type == TestType .EARLY_KEY_RESPONSE :
103
+ continue
104
+ with node0 .assert_debug_log (expected_debug_message [test_type .value ], timeout = 5 ):
105
+ peer = node0 .add_p2p_connection (MisbehavingV2Peer (test_type ), wait_for_verack = False , send_version = False , supports_v2_p2p = True , expect_success = False )
106
+ peer .wait_for_disconnect ()
107
+ self .log .info (f"Expected disconnection for { test_type .name } " )
108
+
78
109
79
110
if __name__ == '__main__' :
80
111
EncryptedP2PMisbehaving ().main ()
0 commit comments