def test_block_hold_timeout(self): block = btc_block() block_hash = block.block_hash() block_hold_msg_bytes = BlockHoldingMessage(block_hash, 1).rawbytes() helpers.receive_node_message(self.node1, self.gateway_fileno, block_hold_msg_bytes) helpers.receive_node_message(self.node1, self.blockchain_fileno, block.rawbytes()) block_hold_msg_bytes_to_send = self.node1.get_bytes_to_send(self.relay_fileno) self.assertEqual(block_hold_msg_bytes_to_send, block_hold_msg_bytes) self.assertEqual(1, len(self.node1.block_processing_service._holds.contents)) self.node1.on_bytes_sent(self.relay_fileno, len(block_hold_msg_bytes_to_send)) time.time = MagicMock( return_value=time.time() + self.node1.block_processing_service._compute_hold_timeout(block)) self.node1.alarm_queue.fire_alarms() # send ciphertext from node1, receipt from node2, key from node1 relayed_block = self.node1.get_bytes_to_send(self.relay_fileno) self.assertIn(BroadcastMessage.MESSAGE_TYPE, relayed_block.tobytes()) self.node1.on_bytes_sent(self.relay_fileno, len(relayed_block)) helpers.receive_node_message(self.node2, self.relay_fileno, relayed_block) block_receipt = self.node2.get_bytes_to_send(self.gateway_fileno) self.assertIn(BlockReceivedMessage.MESSAGE_TYPE, block_receipt.tobytes()) helpers.receive_node_message(self.node1, self.gateway_fileno, block_receipt) key_message = self.node1.get_bytes_to_send(self.relay_fileno) self.assertIn(KeyMessage.MESSAGE_TYPE, key_message.tobytes()) self.assertNotEqual(OutputBuffer.EMPTY, bytearray(key_message.tobytes())) helpers.receive_node_message(self.node2, self.relay_fileno, key_message) bytes_to_blockchain = self.node2.get_bytes_to_send(self.blockchain_fileno) block_bytes = block.rawbytes().tobytes() self.assertEqual(block_bytes, bytes_to_blockchain[0:len(block_bytes)].tobytes())
def test_send_receive_block_decrypted(self): self.node1.opts.encrypt_blocks = False send_block = btc_block(int(time.time())) self._populate_transaction_services(send_block) # propagate block helpers.receive_node_message(self.node1, self.blockchain_fileno, send_block.rawbytes()) block_hold_msg = self.node1.get_bytes_to_send(self.relay_fileno) self.assertIn(BlockHoldingMessage.MESSAGE_TYPE, block_hold_msg.tobytes()) self.node1.on_bytes_sent(self.relay_fileno, len(block_hold_msg)) relayed_block = self.node1.get_bytes_to_send(self.relay_fileno) self.assertIn(BroadcastMessage.MESSAGE_TYPE, relayed_block.tobytes()) self.node1.on_bytes_sent(self.relay_fileno, len(relayed_block)) # block directly propagated helpers.receive_node_message(self.node2, self.relay_fileno, relayed_block) bytes_to_blockchain = self.node2.get_bytes_to_send(self.blockchain_fileno) self.assertEqual(len(send_block.rawbytes()), len(bytes_to_blockchain)) received_block = BlockBtcMessage(buf=bytearray(bytes_to_blockchain)) self.assertEqual(send_block.magic(), received_block.magic()) self.assertEqual(send_block.version(), received_block.version()) self.assertEqual(send_block.timestamp(), received_block.timestamp()) self.assertEqual(send_block.bits(), received_block.bits()) self.assertEqual(send_block.nonce(), received_block.nonce())
def test_send_receive_block_and_key_encrypted(self): send_block = btc_block(int(time.time())) received_block = self.send_received_block_and_key(send_block) self.assertEqual(send_block.magic(), received_block.magic()) self.assertEqual(send_block.version(), received_block.version()) self.assertEqual(send_block.timestamp(), received_block.timestamp()) self.assertEqual(send_block.bits(), received_block.bits()) self.assertEqual(send_block.nonce(), received_block.nonce())
def test_send_receive_block_and_key_real_block_2(self): self.node1.opts.blockchain_ignore_block_interval_count = 99999 received_block = self.send_received_block_and_key( block=btc_block(real_block=RealBtcBlocks.BLOCK_WITNESS_REJECT)) self.assertEqual(9613, len(received_block.rawbytes())) self.assertEqual(536870912, received_block.version()) self.assertEqual("66bbbabedebee6c045284299069c407cdaa493166e64fe92ae03f358e96c7164", convert.bytes_to_hex(received_block.merkle_root().binary)) self.assertEqual(47, len(received_block.txns()))
def send_received_block_and_key(self, block=None): if block is None: block = btc_block() self._populate_transaction_services(block) # propagate block helpers.receive_node_message(self.node1, self.blockchain_fileno, block.rawbytes()) block_hold_request_relay = self.node1.get_bytes_to_send( self.relay_fileno) self.assertIn(BlockHoldingMessage.MESSAGE_TYPE, block_hold_request_relay.tobytes()) self.node1.on_bytes_sent(self.relay_fileno, len(block_hold_request_relay)) relayed_block = self.node1.get_bytes_to_send(self.relay_fileno) self.assertIn(BroadcastMessage.MESSAGE_TYPE, relayed_block.tobytes()) self.node1.on_bytes_sent(self.relay_fileno, len(relayed_block)) # block hold sent out block_hold_request_gateway = self.node1.get_bytes_to_send( self.gateway_fileno) self.assertIsNotNone(block_hold_request_gateway) self.assertIn(BlockHoldingMessage.MESSAGE_TYPE, block_hold_request_gateway.tobytes()) self.clear_all_buffers() # key not available until receipt key_not_yet_available = self.node1.get_bytes_to_send(self.relay_fileno) self.assertEqual(OutputBuffer.EMPTY, key_not_yet_available) # send receipt helpers.receive_node_message(self.node2, self.relay_fileno, relayed_block) block_receipt = self.node2.get_bytes_to_send(self.gateway_fileno) self.assertIn(BlockReceivedMessage.MESSAGE_TYPE, block_receipt.tobytes()) # send key helpers.receive_node_message(self.node1, self.gateway_fileno, block_receipt) key_message = self.node1.get_bytes_to_send(self.relay_fileno) self.assertIn(KeyMessage.MESSAGE_TYPE, key_message.tobytes()) helpers.receive_node_message(self.node2, self.relay_fileno, key_message) bytes_to_blockchain = self.node2.get_bytes_to_send( self.blockchain_fileno) self.assertEqual(len(block.rawbytes()), len(bytes_to_blockchain)) return BlockBtcMessage(buf=bytearray(bytes_to_blockchain))
def test_send_receive_block_and_key_block_hold_removed(self): block = btc_block() block_hash = block.block_hash() block_hold_msg_bytes = BlockHoldingMessage(block_hash, 1).rawbytes() helpers.receive_node_message(self.node1, self.gateway_fileno, block_hold_msg_bytes) helpers.receive_node_message(self.node1, self.blockchain_fileno, block.rawbytes()) bytes_to_send = self.node1.get_bytes_to_send(self.relay_fileno) self.assertEqual(bytes_to_send, block_hold_msg_bytes) self.assertEqual( 1, len(self.node1.block_processing_service._holds.contents)) # node 2 encrypts and sends over block helpers.receive_node_message(self.node2, self.blockchain_fileno, block.rawbytes()) block_hold_request_relay = self.node2.get_bytes_to_send( self.relay_fileno) self.assertIn(BlockHoldingMessage.MESSAGE_TYPE, block_hold_request_relay.tobytes()) self.node2.on_bytes_sent(self.relay_fileno, len(block_hold_request_relay)) relayed_block = self.node2.get_bytes_to_send(self.relay_fileno) self.assertIn(BroadcastMessage.MESSAGE_TYPE, relayed_block.tobytes()) self.node2.on_bytes_sent(self.relay_fileno, len(relayed_block)) # send receipt helpers.receive_node_message(self.node1, self.relay_fileno, relayed_block) block_receipt = self.node1.get_bytes_to_send(self.gateway_fileno) self.assertIn(BlockReceivedMessage.MESSAGE_TYPE, block_receipt.tobytes()) # send key helpers.receive_node_message(self.node2, self.gateway_fileno, block_receipt) key_message = self.node2.get_bytes_to_send(self.relay_fileno) self.assertIn(KeyMessage.MESSAGE_TYPE, key_message.tobytes()) # receive key and lift hold helpers.receive_node_message(self.node1, self.relay_fileno, key_message) inv_message = self.node1.get_bytes_to_send(self.blockchain_fileno) self.assertIn(InvBtcMessage.MESSAGE_TYPE, inv_message.tobytes()) self.assertEqual( 0, len(self.node1.block_processing_service._holds.contents))
def test_send_receive_block_and_key_real_block_1(self): self.node1.opts.blockchain_ignore_block_interval_count = 99999 send_block = btc_block(real_block=RealBtcBlocks.BLOCK1) block_hash = "000000000000d76febe49ae1033fa22afebe6ac46ea255640268d7ede1084e6f" self.assertEqual(block_hash, convert.bytes_to_hex(send_block.block_hash().binary)) received_block = self.send_received_block_and_key(block=send_block) self.assertEqual(9772, len(received_block.rawbytes())) self.assertEqual(536870912, received_block.version()) self.assertEqual("bbb1f6f3a9324ab86ad23642994eac6624a9c9ef454d2f6e3bf68e3b094e0343", convert.bytes_to_hex(received_block.merkle_root().binary)) self.assertEqual(38, len(received_block.txns())) block_hash_object = Sha256Hash(binary=convert.hex_to_bytes(block_hash)) self.assertEqual(1, len(self.node1.blocks_seen.contents)) self.assertIn(block_hash_object, self.node1.blocks_seen.contents) self.assertEqual(1, len(self.node2.blocks_seen.contents)) self.assertIn(block_hash_object, self.node2.blocks_seen.contents)
def test_request_block_propagation(self): block = btc_block().rawbytes() # propagate block helpers.receive_node_message(self.node1, self.blockchain_fileno, block) block_hold_request_relay = self.node1.get_bytes_to_send( self.relay_fileno) self.assertIn(BlockHoldingMessage.MESSAGE_TYPE, block_hold_request_relay.tobytes()) self.node1.on_bytes_sent(self.relay_fileno, len(block_hold_request_relay)) relayed_block = self.node1.get_bytes_to_send(self.relay_fileno) self.assertIn(BroadcastMessage.MESSAGE_TYPE, relayed_block.tobytes()) block_hold_request_gateway = self.node1.get_bytes_to_send( self.gateway_fileno) self.assertIn(BlockHoldingMessage.MESSAGE_TYPE, block_hold_request_gateway.tobytes()) self.clear_all_buffers() # receipt timeout time.time = MagicMock( return_value=time.time() + gateway_constants.NEUTRALITY_BROADCAST_BLOCK_TIMEOUT_S) self.node1.alarm_queue.fire_alarms() key_msg_gateway = self.node1.get_bytes_to_send(self.gateway_fileno) self.assertIn(KeyMessage.MESSAGE_TYPE, key_msg_gateway.tobytes()) self.node1.on_bytes_sent(self.gateway_fileno, len(key_msg_gateway)) block_prop_request = self.node1.get_bytes_to_send(self.gateway_fileno) self.assertIn(BlockPropagationRequestMessage.MESSAGE_TYPE, block_prop_request.tobytes()) self.clear_all_buffers() # get new block to send helpers.receive_node_message(self.node2, self.gateway_fileno, block_prop_request) new_relayed_block = self.node2.get_bytes_to_send(self.relay_fileno) self.assertIn(BroadcastMessage.MESSAGE_TYPE, new_relayed_block.tobytes()) helpers.clear_node_buffer(self.node2, self.relay_fileno) # receive new block helpers.receive_node_message(self.node1, self.relay_fileno, new_relayed_block) block_receipt = self.node1.get_bytes_to_send(self.gateway_fileno) self.assertIn(BlockReceivedMessage.MESSAGE_TYPE, block_receipt.tobytes()) # receive block receipt helpers.receive_node_message(self.node2, self.gateway_fileno, block_receipt) key_message = self.node2.get_bytes_to_send(self.relay_fileno) self.assertIn(KeyMessage.MESSAGE_TYPE, key_message.tobytes()) # receive key, but already seen so dont forward to blockchain helpers.receive_node_message(self.node1, self.relay_fileno, key_message) bytes_to_blockchain = self.node1.get_bytes_to_send( self.blockchain_fileno) self.assertEqual(OutputBuffer.EMPTY, bytes_to_blockchain) # clear blocks seen, rereceive self.node1.blocks_seen = ExpiringSet( self.node1.alarm_queue, gateway_constants.GATEWAY_BLOCKS_SEEN_EXPIRATION_TIME_S, "testset") helpers.receive_node_message(self.node1, self.relay_fileno, key_message) # ignore key message even if block is not in "blocks_seen" bytes_to_blockchain = self.node1.get_bytes_to_send( self.blockchain_fileno) self.assertEqual(OutputBuffer.EMPTY, bytes_to_blockchain)