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)
Exemple #8
0
    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)