diff --git a/test/functional/p2p_v2_misbehaving.py b/test/functional/p2p_v2_misbehaving.py index ae325fa1823..d0e64f57ac7 100755 --- a/test/functional/p2p_v2_misbehaving.py +++ b/test/functional/p2p_v2_misbehaving.py @@ -9,6 +9,7 @@ from enum import Enum from test_framework.messages import MAGIC_BYTES from test_framework.p2p import P2PInterface from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import random_bitflip from test_framework.v2_p2p import ( EncryptedP2PState, MAX_GARBAGE_LEN, @@ -21,9 +22,11 @@ class TestType(Enum): 1. EARLY_KEY_RESPONSE - The responder needs to wait until one byte is received which does not match the 16 bytes consisting of network magic followed by "version\x00\x00\x00\x00\x00" before sending out its ellswift + garbage bytes 2. EXCESS_GARBAGE - Disconnection happens when > MAX_GARBAGE_LEN bytes garbage is sent + 3. WRONG_GARBAGE_TERMINATOR - Disconnection happens when incorrect garbage terminator is sent """ EARLY_KEY_RESPONSE = 0 EXCESS_GARBAGE = 1 + WRONG_GARBAGE_TERMINATOR = 2 class EarlyKeyResponseState(EncryptedP2PState): @@ -45,6 +48,19 @@ class ExcessGarbageState(EncryptedP2PState): return super().generate_keypair_and_garbage(garbage_len) +class WrongGarbageTerminatorState(EncryptedP2PState): + """Add option for sending wrong garbage terminator""" + def generate_keypair_and_garbage(self): + garbage_len = random.randrange(MAX_GARBAGE_LEN//2) + return super().generate_keypair_and_garbage(garbage_len) + + def complete_handshake(self, response): + length, handshake_bytes = super().complete_handshake(response) + # first 16 bytes returned by complete_handshake() is the garbage terminator + wrong_garbage_terminator = random_bitflip(handshake_bytes[:16]) + return length, wrong_garbage_terminator + handshake_bytes[16:] + + class MisbehavingV2Peer(P2PInterface): """Custom implementation of P2PInterface which uses modified v2 P2P protocol functions for testing purposes.""" def __init__(self, test_type): @@ -56,6 +72,8 @@ class MisbehavingV2Peer(P2PInterface): self.v2_state = EarlyKeyResponseState(initiating=True, net='regtest') elif self.test_type == TestType.EXCESS_GARBAGE: self.v2_state = ExcessGarbageState(initiating=True, net='regtest') + elif self.test_type == TestType.WRONG_GARBAGE_TERMINATOR: + self.v2_state = WrongGarbageTerminatorState(initiating=True, net='regtest') super().connection_made(transport) def data_received(self, t): @@ -97,6 +115,7 @@ class EncryptedP2PMisbehaving(BitcoinTestFramework): expected_debug_message = [ [], # EARLY_KEY_RESPONSE ["V2 transport error: missing garbage terminator, peer=1"], # EXCESS_GARBAGE + ["V2 handshake timeout peer=2"], # WRONG_GARBAGE_TERMINATOR ] for test_type in TestType: if test_type == TestType.EARLY_KEY_RESPONSE: