示例#1
0
    def test_revert_coinbase_txn(self, m_logger):
        """
        Alice earned some coins. Undo this.
        """
        tx = CoinBase.create(config.dev, self.amount, self.alice.address, self.mock_blockheader.block_number)
        addresses_state = {
            config.dev.coinbase_address: OptimizedAddressState.get_default(config.dev.coinbase_address),
            self.alice.address: OptimizedAddressState.get_default(self.alice.address),
        }
        addresses_state[config.dev.coinbase_address].pbdata.balance = 1000000

        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=self.mock_blockheader.block_number,
                                         total_coin_supply=100,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)

        self.assertEqual(1000000, addresses_state[config.dev.coinbase_address].balance)

        storage_key = state_container.paginated_tx_hash.generate_key(config.dev.coinbase_address, 1)
        self.assertEqual([], state_container.paginated_tx_hash.key_value[storage_key])
        self.assertEqual(0, addresses_state[self.alice.address].balance)

        storage_key = state_container.paginated_tx_hash.generate_key(config.dev.coinbase_address, 1)
        self.assertEqual([], state_container.paginated_tx_hash.key_value[storage_key])
示例#2
0
    def test_revert_state_changes(self, m_logger):
        """
        Alice earned some coins. Undo this.
        """
        tx = CoinBase.create(self.amount, self.alice.address, self.mock_blockheader.block_number)
        addresses_state = {
            config.dev.coinbase_address: Mock(autospec=AddressState, name='CoinBase AddressState',
                                              transaction_hashes=[tx.txhash], balance=1000000 - self.amount),
            self.alice.address: Mock(autospec=AddressState, name='alice AddressState', transaction_hashes=[tx.txhash],
                                     balance=self.amount),
        }
        unused_chain_manager_mock = Mock(autospec=ChainManager, name='unused ChainManager')

        tx.revert_state_changes(addresses_state, unused_chain_manager_mock)

        self.assertEqual(1000000, addresses_state[config.dev.coinbase_address].balance)
        self.assertEqual([], addresses_state[config.dev.coinbase_address].transaction_hashes)
        self.assertEqual(0, addresses_state[self.alice.address].balance)
        self.assertEqual([], addresses_state[self.alice.address].transaction_hashes)

        # A blank addresses_state doesn't get modified at all (but in practice, every node should have an AddressState
        # for the CoinBase addr
        addresses_state_empty = {}
        tx.revert_state_changes(addresses_state_empty, unused_chain_manager_mock)
        self.assertEqual({}, addresses_state_empty)
示例#3
0
 def test_affected_address(self, m_logger):
     # This transaction can only involve 2 addresses.
     affected_addresses = set()
     tx = CoinBase.create(config.dev, self.amount, self.alice.address,
                          self.mock_blockheader.block_number)
     tx.set_affected_address(affected_addresses)
     self.assertEqual(2, len(affected_addresses))
示例#4
0
    def test_get_mini_transactions_by_address(self, mock_get_tx_metadata,
                                              mock_get_optimized_address_state,
                                              mock_get_paginated_data):
        """
        QRLNode.get_transactions_by_address() returns all the changes in balance caused by a transaction.
        """
        get_tx_metadata = GetTXMetadata()

        xmss = get_alice_xmss()
        xmss2 = get_random_xmss()
        addr_state = OptimizedAddressState.get_default(xmss.address)
        addr_state.pbdata.balance = 100
        addr_state.pbdata.transaction_hash_count = 3
        mock_get_optimized_address_state.return_value = addr_state

        tx1 = CoinBase.create(config.dev, 100, xmss.address, 5)
        get_tx_metadata.register_tx_metadata(tx1, 1)

        tx2 = TransferTransaction.create(addrs_to=[xmss2.address],
                                         amounts=[10],
                                         message_data=None,
                                         fee=1,
                                         xmss_pk=xmss.pk)
        tx2.sign(xmss)
        get_tx_metadata.register_tx_metadata(tx2, 1)

        tx3 = TransferTransaction.create(addrs_to=[xmss.address],
                                         amounts=[100],
                                         message_data=None,
                                         fee=1,
                                         xmss_pk=xmss2.pk)
        tx3.sign(xmss)
        get_tx_metadata.register_tx_metadata(tx3, 2)

        mock_get_paginated_data.return_value = [
            tx1.txhash, tx2.txhash, tx3.txhash
        ]
        mock_get_tx_metadata.side_effect = get_tx_metadata.get_tx_metadata
        response = self.qrlnode.get_mini_transactions_by_address(
            alice.address, 3, 1)
        result, balance = response.mini_transactions, response.balance
        self.assertEqual(len(result), 3)

        self.assertEqual(result[0].amount, 100)
        self.assertEqual(result[0].out, False)

        self.assertEqual(result[1].amount, 11)
        self.assertEqual(result[1].out, True)

        self.assertEqual(result[2].amount, 100)
        self.assertEqual(result[2].out, False)

        self.assertEqual(balance, 100)
示例#5
0
    def test_validate_custom(self, m_logger):
        """
        CoinBase _validate_custom() only checks if fee == 0
        """
        tx = CoinBase.create(self.amount, self.alice.address, self.mock_blockheader.block_number)
        tx._data.fee = 1
        result = tx._validate_custom()
        self.assertFalse(result)

        tx._data.fee = 0
        result = tx._validate_custom()
        self.assertTrue(result)
示例#6
0
    def test_from_txdict(self, m_logger):
        amount = self.mock_blockheader.block_reward + self.mock_blockheader.fee_reward
        tx = CoinBase.create(amount, self.alice.address, self.mock_blockheader.block_number)
        self.assertIsInstance(tx, CoinBase)

        # Test that common Transaction components were copied over.
        self.assertEqual(self.mock_blockheader.block_number + 1, tx.nonce)
        self.assertEqual('010300a1da274e68c88b0ccf448e0b1916fa789b01eb2ed4e9ad565ce264c9390782a9c61ac02f',
                         bin2hstr(tx.addr_to))

        self.assertEqual('222460cc57ab8683b46f1831fe6cf1832c7e3134baf74d33bfaf91741e19cba2', bin2hstr(tx.txhash))
        self.assertEqual(tx.amount, 90)
示例#7
0
    def test_extra_coinbase_tx(self, m_TransferTransaction_validate,
                               m_TransferTransaction_validate_extended,
                               m_TransferTransaction_apply_state_changes,
                               m_CoinBase_apply_state_changes):
        address_states = self.generate_address_states(
            self.alice_addrstate_attrs, {}, self.slave_addrstate_attrs)

        coinbase_extra = CoinBase.create(500, self.alice.address, 5)
        self.block_attrs["transactions"] = [self.tx1, coinbase_extra, self.tx2]

        block = Block.create(**self.block_attrs)
        result = block.apply_state_changes(address_states)
        self.assertFalse(result)
示例#8
0
    def test_get_transactions_by_address(self):
        """
        QRLNode.get_transactions_by_address() returns all the changes in balance caused by a transaction.
        """
        mock_get_tx_metadata = GetTXMetadata()

        xmss = get_alice_xmss()
        xmss2 = get_random_xmss()
        addr_state = AddressState.get_default(xmss.address)
        addr_state.pbdata.balance = 100

        tx1 = CoinBase.create(100, xmss.address, 5)
        mock_get_tx_metadata.register_tx_metadata(tx1, 5)
        addr_state.transaction_hashes.append(tx1.txhash)

        tx2 = TransferTransaction.create(addrs_to=[xmss2.address],
                                         amounts=[10],
                                         fee=1,
                                         xmss_pk=xmss.pk)
        tx2.sign(xmss)
        mock_get_tx_metadata.register_tx_metadata(tx2, 99)
        addr_state.transaction_hashes.append(tx2.txhash)

        tx3 = TransferTransaction.create(addrs_to=[xmss.address],
                                         amounts=[100],
                                         fee=1,
                                         xmss_pk=xmss2.pk)
        tx3.sign(xmss)
        mock_get_tx_metadata.register_tx_metadata(tx3, 101)
        addr_state.transaction_hashes.append(tx3.txhash)

        self.db_state.get_address_state.return_value = addr_state
        self.db_state.get_tx_metadata = mock_get_tx_metadata.get_tx_metadata
        result, balance = self.qrlnode.get_transactions_by_address(
            alice.address)
        self.assertEqual(len(result), 3)

        self.assertEqual(result[0].amount, 100)
        self.assertEqual(result[0].out, False)

        self.assertEqual(result[1].amount, 11)
        self.assertEqual(result[1].out, True)

        self.assertEqual(result[2].amount, 100)
        self.assertEqual(result[2].out, False)

        self.assertEqual(balance, 189)
示例#9
0
    def create(dev_config: DevConfig, block_number: int,
               prev_headerhash: bytes, prev_timestamp: int, transactions: list,
               miner_address: bytes, seed_height: Optional[int],
               seed_hash: Optional[bytes]):

        block = Block()

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee

        # Prepare coinbase tx
        total_reward_amount = BlockHeader.block_reward_calc(
            block_number, dev_config) + fee_reward
        coinbase_tx = CoinBase.create(dev_config, total_reward_amount,
                                      miner_address, block_number)
        hashedtransactions.append(coinbase_tx.txhash)
        Block._copy_tx_pbdata_into_block(
            block, coinbase_tx)  # copy memory rather than sym link

        for tx in transactions:
            hashedtransactions.append(tx.txhash)
            Block._copy_tx_pbdata_into_block(
                block, tx)  # copy memory rather than sym link

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(dev_config=dev_config,
                                             blocknumber=block_number,
                                             prev_headerhash=prev_headerhash,
                                             prev_timestamp=prev_timestamp,
                                             hashedtransactions=txs_hash,
                                             fee_reward=fee_reward,
                                             seed_height=seed_height,
                                             seed_hash=seed_hash)

        block.blockheader = tmp_blockheader

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        block.set_nonces(dev_config, 0, 0)

        return block
示例#10
0
    def test_extra_coinbase_tx(self,
                               m_TransferTransaction_validate,
                               m_TransferTransaction_validate_extended,
                               m_TransferTransaction_apply_state_changes,
                               m_CoinBase_apply_state_changes):
        get_optimized_address_state = MockFunction()
        get_optimized_address_state.put(self.coinbase_addrstate_attrs.address, self.coinbase_addrstate_attrs)
        get_optimized_address_state.put(self.bob_addrstate_attrs.address, self.bob_addrstate_attrs)
        get_optimized_address_state.put(self.alice_addrstate_attrs.address, self.alice_addrstate_attrs)
        get_optimized_address_state.put(self.slave_addrstate_attrs.address, self.slave_addrstate_attrs)

        coinbase_extra = CoinBase.create(config.dev, 500, self.alice.address, 5)
        self.block_attrs["transactions"] = [self.tx1, coinbase_extra, self.tx2]

        block = Block.create(**self.block_attrs)
        result = self.chain_manager._apply_state_changes(block, None)
        self.assertFalse(result)
示例#11
0
    def test_validate_extended(self, m_logger):
        """
        CoinBase validate_extended() checks for
        1. valid coinbase address (the coinbase address must be config.dev.coinbase_address)
        2. valid addr_to
        then calls _validate_custom()
        """
        tx = CoinBase.create(config.dev, self.amount, self.alice.address,
                             self.mock_blockheader.block_number)
        tx._data.master_addr = self.alice.address

        addresses_state = {
            config.dev.coinbase_address:
            OptimizedAddressState.get_default(config.dev.coinbase_address),
            self.alice.address:
            OptimizedAddressState.get_default(self.alice.address),
        }
        addresses_state[config.dev.coinbase_address].pbdata.balance = 1000000

        state_container = StateContainer(
            addresses_state=addresses_state,
            tokens=Indexer(b'token', None),
            slaves=Indexer(b'slave', None),
            lattice_pk=Indexer(b'lattice_pk', None),
            multi_sig_spend_txs=dict(),
            votes_stats=dict(),
            block_number=self.mock_blockheader.block_number,
            total_coin_supply=100,
            current_dev_config=config.dev,
            write_access=True,
            my_db=self.state._db,
            batch=None)

        result = tx._validate_extended(state_container)
        self.assertFalse(result)

        tx._data.master_addr = config.dev.coinbase_address
        with patch('qrl.core.txs.CoinBase.CoinBase.addr_to',
                   new_callable=PropertyMock) as m_addr_to:
            m_addr_to.return_value = b'Fake Address'
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        result = tx._validate_extended(state_container)
        self.assertTrue(result)
示例#12
0
    def create(block_number: int, prev_headerhash: bytes, prev_timestamp: int,
               transactions: list, miner_address: bytes):

        block = Block()

        # Process transactions
        hashedtransactions = []
        fee_reward = 0

        for tx in transactions:
            fee_reward += tx.fee

        # Prepare coinbase tx
        total_reward_amount = BlockHeader.block_reward_calc(
            block_number) + fee_reward
        coinbase_tx = CoinBase.create(total_reward_amount, miner_address,
                                      block_number)
        hashedtransactions.append(coinbase_tx.txhash)
        block._data.transactions.extend([coinbase_tx.pbdata
                                         ])  # copy memory rather than sym link

        for tx in transactions:
            hashedtransactions.append(tx.txhash)
            block._data.transactions.extend(
                [tx.pbdata])  # copy memory rather than sym link

        txs_hash = merkle_tx_hash(
            hashedtransactions)  # FIXME: Find a better name, type changes

        tmp_blockheader = BlockHeader.create(blocknumber=block_number,
                                             prev_headerhash=prev_headerhash,
                                             prev_timestamp=prev_timestamp,
                                             hashedtransactions=txs_hash,
                                             fee_reward=fee_reward)

        block.blockheader = tmp_blockheader

        block._data.header.MergeFrom(tmp_blockheader.pbdata)

        block.set_nonces(0, 0)

        return block
示例#13
0
    def test_validate_extended(self, m_logger):
        """
        CoinBase validate_extended() checks for
        1. valid coinbase address (the coinbase address must be config.dev.coinbase_address)
        2. valid addr_to
        then calls _validate_custom()
        """
        tx = CoinBase.create(self.amount, self.alice.address, self.mock_blockheader.block_number)
        tx._data.master_addr = self.alice.address

        result = tx.validate_extended(self.mock_blockheader.block_number)
        self.assertFalse(result)

        tx._data.master_addr = config.dev.coinbase_address
        with patch('qrl.core.txs.CoinBase.CoinBase.addr_to', new_callable=PropertyMock) as m_addr_to:
            m_addr_to.return_value = b'Fake Address'
            result = tx.validate_extended(self.mock_blockheader.block_number)
            self.assertFalse(result)

        result = tx.validate_extended(self.mock_blockheader.block_number)
        self.assertTrue(result)
示例#14
0
    def test_apply_state_changes(self, m_logger):
        """
        Alice earned some coins.
        """
        addresses_state = {
            config.dev.coinbase_address: Mock(autospec=AddressState, name='CoinBase AddressState',
                                              transaction_hashes=[], balance=1000000),
            self.alice.address: Mock(autospec=AddressState, name='alice AddressState', transaction_hashes=[],
                                     balance=0),
        }
        tx = CoinBase.create(self.amount, self.alice.address, self.mock_blockheader.block_number)

        tx.apply_state_changes(addresses_state)

        self.assertEqual(1000000 - tx.amount, addresses_state[config.dev.coinbase_address].balance)
        self.assertEqual([tx.txhash], addresses_state[config.dev.coinbase_address].transaction_hashes)
        self.assertEqual(tx.amount, addresses_state[self.alice.address].balance)
        self.assertEqual([tx.txhash], addresses_state[self.alice.address].transaction_hashes)

        # A blank addresses_state doesn't get modified at all (but in practice, every node should have an AddressState
        # for the CoinBase addr
        addresses_state_empty = {}
        tx.apply_state_changes(addresses_state_empty)
        self.assertEqual({}, addresses_state_empty)
示例#15
0
 def test_to_json(self, m_logger):
     amount = self.mock_blockheader.block_reward + self.mock_blockheader.fee_reward
     tx = CoinBase.create(amount, self.alice.address, self.mock_blockheader.block_number)
     txjson = tx.to_json()
     self.assertEqual(json.loads(test_json_CoinBase), json.loads(txjson))
示例#16
0
 def test_create(self, m_logger):
     tx = CoinBase.create(self.amount, self.alice.address, self.mock_blockheader.block_number)
     self.assertIsInstance(tx, CoinBase)