コード例 #1
0
    def test_handle_message_transaction(self, m_Transaction):
        """
        This handler handles a MessageTransaction type Transaction.
        :param m_Transaction:
        :return:
        """
        m_Transaction.from_pbdata.return_value = Mock(
            autospec=MessageTransaction, txhash=b'12345')
        self.channel.factory.master_mr.isRequested.return_value = True  # Yes, this is a Message which we have requested
        self.channel.factory.buffered_chain.tx_pool.pending_tx_pool_hash = [
        ]  # No, we haven't processed this TX before

        mtData = qrl_pb2.Transaction()
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MT,
                           mtData=mtData)

        P2PTxManagement.handle_message_transaction(self.channel, msg)

        self.channel.factory.add_unprocessed_txn.assert_called()

        # What if we ended up parsing a Transaction that we never requested in the first place?
        self.channel.factory.add_unprocessed_txn.reset_mock()
        self.channel.factory.master_mr.isRequested.return_value = False
        P2PTxManagement.handle_message_transaction(self.channel, msg)
        self.channel.factory.add_unprocessed_txn.assert_not_called()
コード例 #2
0
    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()
コード例 #3
0
 def test_handle_slave_error_parsing_transaction(self, m_Transaction,
                                                 m_logger):
     m_Transaction.from_pbdata.side_effect = Exception
     msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.SL,
                        slData=qrl_pb2.Transaction())
     P2PTxManagement.handle_slave(self.channel, msg)
     self.channel.factory.add_unprocessed_txn.assert_not_called()
     m_logger.exception.assert_called()
     self.channel.loseConnection.assert_called()
コード例 #4
0
    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()
コード例 #5
0
    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()
コード例 #6
0
    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()
コード例 #7
0
    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)
コード例 #8
0
    def __init__(self, db_state: State, mining_address: bytes):
        self.start_time = time.time()
        self.db_state = db_state
        self._sync_state = SyncState()

        self.peer_manager = P2PPeerManager()
        self.peer_manager.load_peer_addresses()
        self.peer_manager.register(P2PPeerManager.EventType.NO_PEERS,
                                   self.connect_peers)

        self.p2pchain_manager = P2PChainManager()

        self.tx_manager = P2PTxManagement()

        self._chain_manager = None  # FIXME: REMOVE. This is temporary
        self._p2pfactory = None  # FIXME: REMOVE. This is temporary

        self._pow = None

        self.mining_address = mining_address

        banned_peers_filename = os.path.join(config.user.wallet_dir,
                                             config.dev.banned_peers_filename)
        self._banned_peers = ExpiringSet(
            expiration_time=config.user.ban_minutes * 60,
            filename=banned_peers_filename)

        reactor.callLater(10, self.monitor_chain_state)
コード例 #9
0
    def test_handle_message_transaction_invalid_transaction(
            self, m_Transaction, logger):
        """
        If the Transaction was so malformed that parsing it caused an exception, the peer should be disconnected.
        :param m_Transaction:
        :param logger:
        :return:
        """
        m_Transaction.from_pbdata.side_effect = Exception

        mtData = qrl_pb2.Transaction()
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MT,
                           mtData=mtData)

        P2PTxManagement.handle_message_transaction(self.channel, msg)

        self.channel.loseConnection.assert_called()
コード例 #10
0
    def test_count_registrations(self):
        channel = Mock()
        channel.register = Mock()

        self.tx_manager = P2PTxManagement()
        self.tx_manager.new_channel(channel)
        channel.register.assert_called()

        self.assertEquals(8, channel.register.call_count)
コード例 #11
0
    def test_handle_full_message_request(self):
        """
        A peer has requested a full message that corresponds to a MessageReceipt.
        This function checks if we actually have the full message for the given hash.
        If it does, send to peer, otherwise ignore.
        """

        # We do have the Message the peer requested.
        mrData = qrllegacy_pb2.MRData(type=qrllegacy_pb2.LegacyMessage.SL)
        msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.MR,
                           mrData=mrData)
        P2PTxManagement.handle_full_message_request(self.channel, msg)
        self.channel.send.assert_called()

        # We don't have the Message the peer requested.
        self.channel.send.reset_mock()
        self.channel.factory.master_mr.get.return_value = None
        P2PTxManagement.handle_full_message_request(self.channel, msg)
        self.channel.send.assert_not_called()
コード例 #12
0
    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)
コード例 #13
0
    def test_notification_no_observer(self):
        source = Mock()
        channel = Observable(source)

        self.tx_manager = P2PTxManagement()
        self.tx_manager.new_channel(channel)

        event = ObservableEvent("event_id")

        with self.assertRaisesRegexp(RuntimeError, "Observer not registered for"):
            channel.notify(event, force_delivery=True)
コード例 #14
0
    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()
コード例 #15
0
ファイル: qrlnode.py プロジェクト: theQRL/QRL
    def __init__(self, mining_address: bytes):
        self.start_time = ntp.getTime()
        self._sync_state = SyncState()

        self.peer_manager = P2PPeerManager()
        self.peer_manager.load_peer_addresses()

        self.p2pchain_manager = P2PChainManager()

        self.tx_manager = P2PTxManagement()

        self._chain_manager = None  # FIXME: REMOVE. This is temporary
        self._p2pfactory = None  # FIXME: REMOVE. This is temporary

        self._pow = None

        self.mining_address = mining_address

        reactor.callLater(10, self.monitor_chain_state)
コード例 #16
0
    def test_bad_tx(self):
        source = Mock()
        source.factory = Mock()
        source.factory.master_mr = Mock()
        source.factory.master_mr.isRequested = Mock()
        source.factory.add_unprocessed_txn = Mock()

        channel = Observable(source)

        self.tx_manager = P2PTxManagement()
        self.tx_manager.new_channel(channel)

        tx = SlaveTransaction.create([], [], 1, bytes(100))
        event = qrllegacy_pb2.LegacyMessage(func_name=qrllegacy_pb2.LegacyMessage.TX,
                                            txData=tx.pbdata)

        channel.notify(event, force_delivery=True)
        source.factory.master_mr.isRequested.assert_not_called()
        source.factory.add_unprocessed_txn.assert_not_called()
コード例 #17
0
    def test_notification(self):
        source = Mock()
        source.factory = Mock()
        source.factory.master_mr = Mock()
        source.factory.master_mr.isRequested = Mock()
        source.factory.add_unprocessed_txn = Mock()

        channel = Observable(source)

        self.tx_manager = P2PTxManagement()
        self.tx_manager.new_channel(channel)

        tx = TransferTransaction.create(addrs_to=[get_some_address()],
                                        amounts=[1],
                                        fee=10,
                                        xmss_pk=bytes(67))

        event = qrllegacy_pb2.LegacyMessage(
            func_name=qrllegacy_pb2.LegacyMessage.TX, txData=tx.pbdata)

        channel.notify(event, force_delivery=True)
        source.factory.master_mr.isRequested.assert_called()
        source.factory.add_unprocessed_txn.assert_called()
コード例 #18
0
 def test_observable(self):
     channel = Observable(None)
     self.tx_manager = P2PTxManagement()
     self.tx_manager.new_channel(channel)
     self.assertEquals(8, channel.observers_count)
コード例 #19
0
 def test_handle_slave(self, m_Transaction, m_logger):
     msg = make_message(func_name=qrllegacy_pb2.LegacyMessage.SL,
                        slData=qrl_pb2.Transaction())
     P2PTxManagement.handle_slave(self.channel, msg)
     self.channel.factory.add_unprocessed_txn.assert_called()