Ejemplo n.º 1
0
    def setUp(self):
        m_state = Mock(name='A Mock State', autospec=State)
        m_state.get_address_state.return_value = Mock(
            name='A Mock AddressState', autospec=OptimizedAddressState)

        self.chain_manager = Mock(autospec=ChainManager)
        self.chain_manager._state = m_state

        tx_attrs = {
            'validate.return_value':
            True,  # Custom validation for different Transaction Types
            'validate_extended.return_value':
            True,  # Master/slave XMSS tree validation; balance & fee, OTS key reuse
            'validate_transaction_pool.return_value':
            True  # checks for OTS key reuse within TransactionPool only
        }
        self.tx1 = make_tx(name='Mock TX 1', **tx_attrs)
        self.tx2 = make_tx(name='Mock TX 2', **tx_attrs)
        self.tx3 = make_tx(name='Mock TX 3', **tx_attrs)
        self.tx4 = make_tx(name='Mock TX 4', **tx_attrs)

        self.m_txpool = Mock(autospec=TransactionPool)
        self.m_txpool.get_pending_transaction.side_effect = [
            (self.tx1, replacement_getTime()), (self.tx2,
                                                replacement_getTime()),
            (self.tx3, replacement_getTime()),
            (self.tx4, replacement_getTime())
        ]

        self.m_broadcast_tx = Mock(autospec=P2PFactory.broadcast_tx)
        self.txnprocessor = TxnProcessor(chain_manager=self.chain_manager,
                                         transaction_pool_obj=self.m_txpool,
                                         broadcast_tx=self.m_broadcast_tx)
Ejemplo n.º 2
0
    def test_validate_transaction_pool_reusing_ots_index(self, m_logger):
        """
        Two different TransferTransactions. They are signed with the same OTS indexe, from the same public key.
        Therefore they should conflict.
        :return:
        """
        tx = self.tx
        tx2 = TransferTransaction.create(addrs_to=[self.bob.address],
                                         amounts=[100],
                                         message_data=None,
                                         fee=5,
                                         xmss_pk=self.alice.pk)

        # alice_clone's OTS index is still at 10, while self.alice will be at 11 after signing.
        alice_clone = get_alice_xmss()
        alice_clone.set_ots_index(10)
        tx.sign(self.alice)
        tx2.sign(alice_clone)

        tx_info = Mock(autospec=TransactionInfo, transaction=tx)
        tx2_info = Mock(autospec=TransactionInfo, transaction=tx2)
        transaction_pool = [(replacement_getTime(), tx_info),
                            (replacement_getTime(), tx2_info)]

        result = tx.validate_transaction_pool(transaction_pool)
        self.assertFalse(result)
Ejemplo n.º 3
0
    def test_is_future_block(self):
        self.blockheader.timestamp = replacement_getTime() + config.dev.block_max_drift + 1
        result = self.block.is_future_block(config.dev)
        self.assertTrue(result)

        self.blockheader.timestamp = replacement_getTime()
        result = self.block.is_future_block(config.dev)
        self.assertFalse(result)
Ejemplo n.º 4
0
    def test_is_full_transaction_pool(self, m_config):
        m_config.user.transaction_pool_size = 2

        result = self.txpool.is_full_transaction_pool()
        self.assertFalse(result)

        tx1 = make_tx(fee=1)
        tx2 = make_tx(fee=2)

        self.txpool.add_tx_to_pool(tx1, 1, replacement_getTime())
        self.txpool.add_tx_to_pool(tx2, 1, replacement_getTime())

        result = self.txpool.is_full_transaction_pool()
        self.assertTrue(result)
Ejemplo n.º 5
0
    def test_create_block_does_not_include_invalid_txs_from_txpool(
            self, m_create, m_logger):
        self.mock_new_state_container()
        m_tx = Mock(autospec=TransferTransaction,
                    name='mock TransferTransaction')
        m_tx.validate_all.return_value = False
        m_tx.configure_mock(**self.m_tx_args)

        m_create.return_value = Mock(autospec=Block,
                                     name='mock Block',
                                     size=205)

        self.txpool.add_tx_to_pool(m_tx, 1, replacement_getTime())

        self.miner.create_block(last_block=self.parent_block,
                                mining_nonce=0,
                                tx_pool=self.txpool,
                                miner_address=self.m_mining_address)

        seed_block = self.chain_manager.get_block_by_number(
            self.miner._qn.get_seed_height(self.parent_block.block_number + 1))
        m_create.assert_called_with(dev_config=config.dev,
                                    block_number=1,
                                    prev_headerhash=b'',
                                    prev_timestamp=0,
                                    transactions=[],
                                    miner_address=alice.address,
                                    seed_height=seed_block.block_number,
                                    seed_hash=seed_block.headerhash)
Ejemplo n.º 6
0
    def test_get_tx_index_from_pool(self):
        tx1 = make_tx(txhash=b'red')
        tx2 = make_tx(txhash=b'blue')
        tx3 = make_tx(txhash=b'qrlpink')

        self.txpool.add_tx_to_pool(tx1, 1, replacement_getTime())
        self.txpool.add_tx_to_pool(tx2, 1, replacement_getTime())
        self.txpool.add_tx_to_pool(tx3, 1, replacement_getTime())

        idx = self.txpool.get_tx_index_from_pool(b'qrlpink')
        self.assertEqual(idx, 2)

        idx = self.txpool.get_tx_index_from_pool(b'red')
        self.assertEqual(idx, 0)

        idx = self.txpool.get_tx_index_from_pool(b'ultraviolet')
        self.assertEqual(idx, -1)
Ejemplo n.º 7
0
    def test_remove_tx_from_pool(self):
        tx1 = make_tx(txhash=b'red')
        tx2 = make_tx(txhash=b'blue')
        tx3 = make_tx(txhash=b'qrlpink')

        self.txpool.add_tx_to_pool(tx1, 1, replacement_getTime())

        # If we try to remove a tx that wasn't there, the transaction pool should be untouched
        self.assertEqual(len(self.txpool.transaction_pool), 1)
        self.txpool.remove_tx_from_pool(tx2)
        self.assertEqual(len(self.txpool.transaction_pool), 1)

        # Now let's remove a tx from the heap. The size should decrease.
        self.txpool.add_tx_to_pool(tx2, 1, replacement_getTime())
        self.txpool.add_tx_to_pool(tx3, 1, replacement_getTime())

        self.assertEqual(len(self.txpool.transaction_pool), 3)
        self.txpool.remove_tx_from_pool(tx2)
        self.assertEqual(len(self.txpool.transaction_pool), 2)
Ejemplo n.º 8
0
 def test_validate_transaction_pool(self, m_logger):
     """
     Two TransferTransactions. Although they're the same, they are signed with different OTS indexes.
     Therefore they should not conflict when they are both in the TransactionPool.
     :return:
     """
     tx = self.tx
     tx2 = TransferTransaction.create(addrs_to=[self.bob.address],
                                      amounts=[100],
                                      fee=1,
                                      xmss_pk=self.alice.pk)
     tx.sign(self.alice)
     tx2.sign(self.alice)
     tx_info = Mock(autospec=TransactionInfo, transaction=tx)
     tx2_info = Mock(autospec=TransactionInfo, transaction=tx2)
     transaction_pool = [(replacement_getTime(), tx_info),
                         (replacement_getTime(), tx2_info)]
     result = tx.validate_transaction_pool(transaction_pool)
     self.assertTrue(result)
Ejemplo n.º 9
0
    def test_update_pending_tx_pool_tx_already_validated(self, m_is_full_pending_transaction_pool):
        """
        If the tx is already in TransactionPool.transaction_pool, do not add it to pending_tx_pool.
        """
        tx1 = make_tx()
        ip = '127.0.0.1'
        m_is_full_pending_transaction_pool.return_value = False

        self.txpool.add_tx_to_pool(tx1, 1, replacement_getTime())

        result = self.txpool.update_pending_tx_pool(tx1, ip)
        self.assertFalse(result)
Ejemplo n.º 10
0
    def test_create_block_with_one_transaction(self, m_create, m_logger):
        m_tx = Mock(autospec=TransferTransaction, name='mock TransferTransaction')
        m_tx.configure_mock(**self.m_tx_args)

        m_create.return_value = Mock(autospec=Block, name='mock Block', size=205)

        self.txpool.add_tx_to_pool(m_tx, 1, replacement_getTime())

        self.miner.create_block(last_block=self.parent_block, mining_nonce=0, tx_pool=self.txpool,
                                miner_address=self.m_mining_address)

        m_create.assert_called_with(block_number=1, prev_headerhash=b'', prev_timestamp=0, transactions=[m_tx],
                                    miner_address=alice.address)
Ejemplo n.º 11
0
    def test_validate_transaction_pool_different_pk_same_ots_index(
            self, m_logger):
        """
        Two TransferTransactions. They are signed with the same OTS indexes, but from different public keys.
        Therefore they should NOT conflict.
        :return:
        """
        tx = self.tx
        tx2 = TransferTransaction.create(addrs_to=[self.bob.address],
                                         amounts=[100],
                                         fee=1,
                                         xmss_pk=self.bob.pk)

        tx.sign(self.alice)
        tx2.sign(self.bob)

        tx_info = Mock(autospec=TransactionInfo, transaction=tx)
        tx2_info = Mock(autospec=TransactionInfo, transaction=tx2)
        transaction_pool = [(replacement_getTime(), tx_info),
                            (replacement_getTime(), tx2_info)]

        result = tx.validate_transaction_pool(transaction_pool)
        self.assertTrue(result)
Ejemplo n.º 12
0
def create_m_block(block_number, previous_block, miner_address):
    mock_block = Mock(autospec=Block,
                      name="Mock Block {}".format(block_number),
                      block_number=block_number,
                      prev_headerhash=previous_block.headerhash,
                      prev_block_timestamp=previous_block.timestamp,
                      transactions=[],
                      miner_address=miner_address,
                      headerhash="Mock Block {} {}".format(
                          block_number, urandom(6)).encode(),
                      timestamp=replacement_getTime())
    mock_block.serialize.return_value = "Mock Block {}".format(
        block_number).encode()
    return mock_block
Ejemplo n.º 13
0
    def test_get_fork_point_failure_modes(self):
        block_0 = create_m_block(
            0, Mock(headerhash=b'Fake Genesis',
                    timestamp=replacement_getTime()), alice.address)
        block_1 = create_m_block(1, block_0, alice.address)
        block_2 = create_m_block(2, block_1, alice.address)

        # If _get_fork_point() ever reaches block_number 0, that means the genesis block is different!
        # Mock self.state leads us back to block_0
        self.state.get_block.side_effect = [block_2, block_1, block_0]

        with self.assertRaises(Exception):
            self.chain_manager._get_fork_point(block_2)

        # If _get_fork_point() cannot find a particular block while walking back to the fork point, something has gone
        # very wrong
        # Mock self.state leads us back through a broken chain
        self.state.get_block.side_effect = [block_2, None, block_0]

        with self.assertRaises(Exception):
            self.chain_manager._get_fork_point(block_2)
Ejemplo n.º 14
0
 def test_add_tx_to_pool_while_full(self, m_is_full_func):
     m_is_full_func.return_value = True
     tx = make_tx()
     result = self.txpool.add_tx_to_pool(tx, 1, replacement_getTime())
     self.assertFalse(result)  # refused to add to the pool
     self.assertEqual(len(self.txpool.transactions), 0)  # remains untouched
Ejemplo n.º 15
0
 def test_add_tx_to_pool(self):
     tx = make_tx()
     result = self.txpool.add_tx_to_pool(tx, 1, replacement_getTime())
     self.assertTrue(result)
     self.assertEqual(len(self.txpool.transactions), 1)