def test_handle_message_received_ignores_unknown_message_types(self):
        mrData = qrllegacy_pb2.MRData(type=999)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)

        P2PTxManagement.handle_message_received(self.channel, msg)

        self.channel.factory.request_full_message.assert_not_called()
    def test_handle_message_received_ignores_messages_it_already_has(self):
        self.channel.factory.master_mr.contains.return_value = True

        mrData = qrllegacy_pb2.MRData(type=qrllegacy_pb2.LegacyMessage.SL)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)

        P2PTxManagement.handle_message_received(self.channel, msg)

        self.channel.factory.request_full_message.assert_not_called()
    def test_handle_message_received_transactions_ignored_while_unsynced(self):
        self.channel.factory.sync_state.state = ESyncState.syncing

        mrData = qrllegacy_pb2.MRData(type=qrllegacy_pb2.LegacyMessage.TX)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)

        P2PTxManagement.handle_message_received(self.channel, msg)

        self.channel.factory.request_full_message.assert_not_called()
    def test_handle_message_received_ignores_messages_it_already_has_requested(
            self):
        self.channel.factory.master_mr.contains.return_value = False  # No, we don't have this message yet.
        self.channel.factory.master_mr.is_callLater_active.return_value = True  # Yes, we have requested it.

        mrData = qrllegacy_pb2.MRData(type=qrllegacy_pb2.LegacyMessage.SL)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)

        P2PTxManagement.handle_message_received(self.channel, msg)

        self.channel.factory.request_full_message.assert_not_called()
    def test_handle_message_received_ignores_blocks(self):
        """
        handle_message_received() should ignore MessageReceipts for blocks that are too far away from our current block
        height, or if it's an orphan block.
        """
        self.channel.factory.chain_height = 10  # Right now, our node is on block 10.
        self.channel.factory.master_mr.contains.return_value = False  # No, we do not already have this Message.
        self.channel.factory.master_mr.is_callLater_active.return_value = False  # No, we haven't requested this Message yet.

        # Ignore blocks that are config.dev_max_margin_block_number ahead.
        mrData = qrllegacy_pb2.MRData(type=qrllegacy_pb2.LegacyMessage.BK,
                                      block_number=10 +
                                      config.dev.max_margin_block_number + 1)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)
        P2PTxManagement.handle_message_received(self.channel, msg)
        self.channel.factory.request_full_message.assert_not_called()

        # Ignore blocks that are config.dev_min_margin_block_number behind
        msg.mrData.block_number = 2
        P2PTxManagement.handle_message_received(self.channel, msg)
        self.channel.factory.request_full_message.assert_not_called()

        msg.mrData.block_number = 10  # Yes, it's another block 10!
        self.channel.factory.is_block_present.return_value = False  # But we don't have its previous block.
        P2PTxManagement.handle_message_received(self.channel, msg)
        self.channel.factory.request_full_message.assert_not_called()

        msg.mrData.block_number = 11  # now we have a follow-up block.
        self.channel.factory.is_block_present.return_value = True  # We do have its previous block.
        P2PTxManagement.handle_message_received(self.channel, msg)
        self.channel.factory.request_full_message.assert_called_once_with(
            msg.mrData)
    def test_handle_message_received(self):
        """
        handle_message_received() handles MessageReceipts. MessageReceipts are metadata for Messages, so peers know
        which peer has which blocks/transactions/whatever, but can request the full Message at their discretion.
        :return:
        """
        mrData = qrllegacy_pb2.MRData(type=qrllegacy_pb2.LegacyMessage.SL)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)

        # No, we do not already have this particular TX.
        self.channel.factory.master_mr.contains.return_value = False
        # No, we have not already requested the Message behind this MessageReceipt.
        self.channel.factory.master_mr.is_callLater_active.return_value = False

        P2PTxManagement.handle_message_received(self.channel, msg)

        self.channel.factory.request_full_message.assert_called_once_with(
            mrData)
    def test_handle_message_received_transactions_ignored_while_mempool_full(
            self, mock_logger):
        self.channel.factory.sync_state.state = ESyncState.synced
        self.channel.factory.master_mr.contains.return_value = False  # No, we do not already have this Message.
        self.channel.factory.master_mr.is_callLater_active.return_value = False  # No, we haven't requested this Message yet.

        # First, test when the mempool is NOT full
        self.channel.factory._chain_manager.tx_pool.is_full_pending_transaction_pool.return_value = False
        mrData = qrllegacy_pb2.MRData(type=qrllegacy_pb2.LegacyMessage.TX)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)

        P2PTxManagement.handle_message_received(self.channel, msg)

        self.channel.factory.request_full_message.assert_called()

        # Now, test when the mempool IS full
        self.channel.factory.request_full_message.reset_mock()
        self.channel.factory._chain_manager.tx_pool.is_full_pending_transaction_pool.return_value = True

        P2PTxManagement.handle_message_received(self.channel, msg)

        self.channel.factory.request_full_message.assert_not_called()