Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc-invalid-message.py
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/bin/env python3 | |||||
# Copyright (c) 2019 The Bitcoin developers | |||||
# Distributed under the MIT software license, see the accompanying | |||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
"""ABC Invalid Message Test | |||||
Test that invalid messages get rejected and/or ban the sender as expected for | |||||
each case. | |||||
""" | |||||
import struct | |||||
from test_framework.mininode import ( | |||||
NetworkThread, | |||||
NodeConn, | |||||
NodeConnCB, | |||||
msg_ping, | |||||
mininode_lock, | |||||
) | |||||
from test_framework.test_framework import BitcoinTestFramework | |||||
from test_framework.util import p2p_port, wait_until | |||||
def msg_bad_checksum(connection, original_message): | |||||
message_data = bytearray(connection.format_message(original_message)) | |||||
command = original_message.command | |||||
data = original_message.serialize() | |||||
i = 0 | |||||
i += len(connection.MAGIC_BYTES[connection.network]) | |||||
i += len(command) | |||||
i += len(b"\x00" * (12 - len(command))) | |||||
deadalnix: It seems to be that these two line always add up to 12. | |||||
i += len(struct.pack("<I", len(data))) | |||||
# Make the checksum invalid | |||||
message_data[i] = (message_data[i] ^ message_data[i]) & 0xFF | |||||
deadalnixUnsubmitted Done Inline Actionsmessage_data[i] ^ message_data[i] is always 0 so I do not think this is a good test. Xoring with a constant is preferable. I also do not thing the masking helps as binary ops cannot increase the size of the number to something that is out of bounds, by definition. deadalnix: `message_data[i] ^ message_data[i]` is always `0` so I do not think this is a good test. Xoring… | |||||
jasonbcoxAuthorUnsubmitted Done Inline Actionsxor resulting in 0 is my bad... jasonbcox: xor resulting in 0 is my bad...
the mask was necessary when xor used to be an inversion, as… | |||||
return message_data | |||||
class InvalidMessageTest(BitcoinTestFramework): | |||||
def set_test_params(self): | |||||
self.setup_clean_chain = False | |||||
self.num_nodes = 1 | |||||
def run_test(self): | |||||
# Create a P2P connection to one of the nodes | |||||
callback = NodeConnCB() | |||||
connection = NodeConn('127.0.0.1', p2p_port(0), | |||||
self.nodes[0], callback) | |||||
callback.add_connection(connection) | |||||
NetworkThread().start() | |||||
callback.wait_for_verack() | |||||
# Create a valid message | |||||
valid_message = msg_ping(callback.ping_counter) | |||||
def wait_for_ping(): | |||||
def check_ping(): | |||||
if not callback.last_message.get("pong"): | |||||
return False | |||||
return callback.last_message["pong"].nonce == callback.ping_counter | |||||
wait_until(check_ping, lock=mininode_lock) | |||||
callback.ping_counter += 1 | |||||
# The valid message is accepted | |||||
callback.send_message(valid_message) | |||||
wait_for_ping() | |||||
# Make an invalid copy of the valid message with an invalid checksum | |||||
invalid_message = msg_bad_checksum(connection, valid_message) | |||||
# The invalid message should cause a disconnect because we are now | |||||
# banned | |||||
callback.send_raw_message(invalid_message) | |||||
callback.wait_for_disconnect() | |||||
if __name__ == '__main__': | |||||
InvalidMessageTest().main() |
It seems to be that these two line always add up to 12.