def __init__(self, sock: AbstractSocketConnectionProtocol, node: Node) -> None: super(InternalNodeConnection, self).__init__(sock, node) # Enable buffering only on internal connections self.enable_buffered_send = node.opts.enable_buffered_send self.outputbuf = OutputBuffer( enable_buffering=self.enable_buffered_send) self.network_num = node.network_num self.version_manager = bloxroute_version_manager # Setting default protocol version; override when hello message received self.protocol_version = self.version_manager.CURRENT_PROTOCOL_VERSION self.pong_message = PongMessage() self.ack_message = AckMessage() self.can_send_pings = True self.pong_timeout_enabled = True self.ping_message_timestamps = ExpiringDict( self.node.alarm_queue, constants.REQUEST_EXPIRATION_TIME, f"{str(self)}_ping_timestamps") self.sync_ping_latencies: Dict[int, Optional[float]] = {} self._nonce_to_network_num: Dict[int, int] = {} self.message_validator = BloxrouteMessageValidator( None, self.protocol_version) self.tx_sync_service = TxSyncService(self) self.inbound_peer_latency: float = time.time()
def __init__(self, sock: AbstractSocketConnectionProtocol, node: "AbstractGatewayNode"): super(AbstractRelayConnection, self).__init__(sock, node) hello_msg = HelloMessage(protocol_version=self.protocol_version, network_num=self.network_num, node_id=self.node.opts.node_id) self.enqueue_msg(hello_msg) self.hello_messages = constants.BLOXROUTE_HELLO_MESSAGES self.header_size = constants.STARTING_SEQUENCE_BYTES_LEN + constants.BX_HDR_COMMON_OFF self.message_handlers = { BloxrouteMessageType.HELLO: self.msg_hello, BloxrouteMessageType.PING: self.msg_ping, BloxrouteMessageType.PONG: self.msg_pong, BloxrouteMessageType.ACK: self.msg_ack, BloxrouteMessageType.BROADCAST: self.msg_broadcast, BloxrouteMessageType.KEY: self.msg_key, BloxrouteMessageType.TRANSACTION: self.msg_tx, BloxrouteMessageType.TRANSACTIONS: self.msg_txs, BloxrouteMessageType.COMPRESSED_BLOCK_TXS: self.msg_compressed_block_txs, BloxrouteMessageType.BLOCK_HOLDING: self.msg_block_holding, BloxrouteMessageType.DISCONNECT_RELAY_PEER: self.msg_disconnect_relay_peer, BloxrouteMessageType.TX_SERVICE_SYNC_TXS: self.tx_sync_service.msg_tx_service_sync_txs, BloxrouteMessageType.TX_SERVICE_SYNC_COMPLETE: self.tx_sync_service.msg_tx_service_sync_complete, BloxrouteMessageType.BLOCK_CONFIRMATION: self.msg_cleanup, BloxrouteMessageType.TRANSACTION_CLEANUP: self.msg_cleanup, BloxrouteMessageType.NOTIFICATION: self.msg_notify, BloxrouteMessageType.REFRESH_BLOCKCHAIN_NETWORK: self.msg_refresh_blockchain_network } msg_size_validation_settings = MessageSizeValidationSettings( self.node.network.max_block_size_bytes, self.node.network.max_tx_size_bytes) self.message_validator = BloxrouteMessageValidator( msg_size_validation_settings, self.protocol_version) self.check_matching_relay_connection_alarm_id: Optional[AlarmId] = None
def __init__(self, sock, address, node, from_me=False): super(InternalNodeConnection, self).__init__(sock, address, node, from_me) # Enable buffering only on internal connections self.enable_buffered_send = node.opts.enable_buffered_send self.outputbuf = OutputBuffer(enable_buffering=self.enable_buffered_send) self.network_num = node.network_num self.version_manager = bloxroute_version_manager # Setting default protocol version and message factory; override when hello message received self.message_factory = bloxroute_message_factory self.protocol_version = self.version_manager.CURRENT_PROTOCOL_VERSION self.ping_message = PingMessage() self.pong_message = PongMessage() self.ack_message = AckMessage() self.can_send_pings = True self.ping_message_timestamps = ExpiringDict(self.node.alarm_queue, constants.REQUEST_EXPIRATION_TIME) self.message_validator = BloxrouteMessageValidator(None, self.protocol_version)
def setUp(self) -> None: self.message_validation_settings = MessageSizeValidationSettings(max_block_size_bytes=100000, max_tx_size_bytes=50000) self.message_validator = BloxrouteMessageValidator(self.message_validation_settings, protocol_version.PROTOCOL_VERSION)
class TestBloxrouteMessageValidator(AbstractTestCase): def setUp(self) -> None: self.message_validation_settings = MessageSizeValidationSettings(max_block_size_bytes=100000, max_tx_size_bytes=50000) self.message_validator = BloxrouteMessageValidator(self.message_validation_settings, protocol_version.PROTOCOL_VERSION) def test_is_valid_starting_sequence__invalid(self): message_bytes = bytearray(1000) input_buffer = InputBuffer() input_buffer.add_bytes(message_bytes) self.assertRaises(MessageValidationError, self.message_validator.validate, False, BloxrouteMessageType.TRANSACTION, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_tx_size_bytes, input_buffer) def test_is_valid_starting_sequence__valid(self): message_bytes = bytearray(1000) message_bytes[:constants.STARTING_SEQUENCE_BYTES_LEN] = constants.STARTING_SEQUENCE_BYTES input_buffer = InputBuffer() input_buffer.add_bytes(message_bytes) self.message_validator.validate(False, BloxrouteMessageType.TRANSACTION, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_tx_size_bytes, input_buffer) def test_is_valid_payload_len(self): message_bytes = bytearray(1000) message_bytes[:constants.STARTING_SEQUENCE_BYTES_LEN] = constants.STARTING_SEQUENCE_BYTES input_buffer = InputBuffer() input_buffer.add_bytes(message_bytes) # Transaction message tests self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.TRANSACTION, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_tx_size_bytes, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.TRANSACTION, constants.BX_HDR_COMMON_OFF, 0, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.TRANSACTION, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_tx_size_bytes - 1, input_buffer)) self.assertRaises(MessageValidationError, self.message_validator.validate, False, BloxrouteMessageType.TRANSACTION, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_tx_size_bytes + 1, input_buffer) # Broadcast message tests self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.BROADCAST, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_block_size_bytes, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.BROADCAST, constants.BX_HDR_COMMON_OFF, 0, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.BROADCAST, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_block_size_bytes - 1, input_buffer)) self.assertRaises(MessageValidationError, self.message_validator.validate, False, BloxrouteMessageType.BROADCAST, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_block_size_bytes + 1, input_buffer) # Transactions message self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.TRANSACTIONS, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_block_size_bytes, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.TRANSACTIONS, constants.BX_HDR_COMMON_OFF, 0, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.TRANSACTIONS, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_block_size_bytes - 1, input_buffer)) self.assertRaises(MessageValidationError, self.message_validator.validate, False, BloxrouteMessageType.TRANSACTIONS, constants.BX_HDR_COMMON_OFF, self.message_validation_settings.max_block_size_bytes + 1, input_buffer) # Other types of messages self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.HELLO, constants.BX_HDR_COMMON_OFF, constants.DEFAULT_MAX_PAYLOAD_LEN_BYTES, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.HELLO, constants.BX_HDR_COMMON_OFF, 0, input_buffer)) self.assertIsNone( self.message_validator.validate(False, BloxrouteMessageType.HELLO, constants.BX_HDR_COMMON_OFF, constants.DEFAULT_MAX_PAYLOAD_LEN_BYTES - 1, input_buffer)) self.assertRaises(MessageValidationError, self.message_validator.validate, False, BloxrouteMessageType.HELLO, constants.BX_HDR_COMMON_OFF, constants.DEFAULT_MAX_PAYLOAD_LEN_BYTES + 1, input_buffer) def test_is_valid_control_flag__invalid(self): message_len = 1000 message_bytes = bytearray(message_len) message_bytes[:constants.STARTING_SEQUENCE_BYTES_LEN] = constants.STARTING_SEQUENCE_BYTES input_buffer = InputBuffer() input_buffer.add_bytes(message_bytes) payload_len = message_len - constants.STARTING_SEQUENCE_BYTES_LEN - constants.BX_HDR_COMMON_OFF # valid payload len self.assertRaises(ControlFlagValidationError, self.message_validator.validate, True, BloxrouteMessageType.TRANSACTION, constants.STARTING_SEQUENCE_BYTES_LEN + constants.BX_HDR_COMMON_OFF, payload_len, input_buffer) # invalid payload len - too long self.assertRaises(MessageValidationError, self.message_validator.validate, True, BloxrouteMessageType.TRANSACTION, constants.STARTING_SEQUENCE_BYTES_LEN + constants.BX_HDR_COMMON_OFF, message_len, input_buffer) def test_is_valid_control_flag__valid(self): message_len = 1000 message_bytes = bytearray(message_len) message_bytes[:constants.STARTING_SEQUENCE_BYTES_LEN] = constants.STARTING_SEQUENCE_BYTES message_bytes[-1] = BloxrouteMessageControlFlags.VALID input_buffer = InputBuffer() input_buffer.add_bytes(message_bytes) # adding random bytes to the end of intput buffer input_buffer.add_bytes(helpers.generate_bytearray(10)) payload_len = message_len - constants.STARTING_SEQUENCE_BYTES_LEN - constants.BX_HDR_COMMON_OFF # valid payload len self.message_validator.validate(True, BloxrouteMessageType.TRANSACTION, constants.STARTING_SEQUENCE_BYTES_LEN + constants.BX_HDR_COMMON_OFF, payload_len, input_buffer) # invalid payload len - too long self.assertRaises(MessageValidationError, self.message_validator.validate, True, BloxrouteMessageType.TRANSACTION, constants.STARTING_SEQUENCE_BYTES_LEN + constants.BX_HDR_COMMON_OFF, message_len, input_buffer)