Example #1
0
    def test_tx_validation_fails(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)

        block = Block.create(**self.block_attrs)

        m_TransferTransaction_validate.return_value = False
        result = self.chain_manager._apply_state_changes(block, None)
        self.assertFalse(result)
        m_TransferTransaction_validate.return_value = True

        m_TransferTransaction_validate_extended.return_value = False
        result = self.chain_manager._apply_state_changes(block, None)
        self.assertFalse(result)
        m_TransferTransaction_validate_extended.return_value = True

        with patch('xrd.core.txs.CoinBase.CoinBase._validate_extended'
                   ) as m_validate_extended:
            m_validate_extended.return_value = False
            result = self.chain_manager._apply_state_changes(block, None)
            self.assertFalse(result)
Example #2
0
    def test_getBlock(self):
        with set_xrd_dir('no_data'):
            db_state = State()

            p2p_factory = Mock(spec=P2PFactory)
            p2p_factory.pow = Mock(spec=POW)

            chain_manager = ChainManager(db_state)

            xrdnode = xrdNode(mining_address=b'')
            xrdnode.set_chain_manager(chain_manager)
            xrdnode._p2pfactory = p2p_factory
            xrdnode._pow = p2p_factory.pow
            xrdnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

            service = PublicAPIService(xrdnode)

            alice_xmss = get_alice_xmss()
            b = Block.create(dev_config=config.dev,
                             block_number=1,
                             prev_headerhash=sha256(b'reveal'),
                             prev_timestamp=10,
                             transactions=[],
                             miner_address=alice_xmss.address,
                             seed_height=0,
                             seed_hash=None)
            Block.put_block(db_state, b, None)
            db_state.get_block = MagicMock(return_value=b)

            context = Mock(spec=ServicerContext)
            request = xrd_pb2.GetBlockReq(header_hash=b.headerhash)
            response = service.GetBlock(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertEqual(1, response.block.header.block_number)
Example #3
0
    def test_bad_nonce_or_ots_reused(self, m_TransferTransaction_validate,
                                     m_TransferTransaction_validate_extended,
                                     m_TransferTransaction_apply_state_changes,
                                     m_CoinBase_apply_state_changes):
        # If a TX was signed by a Slave XMSS, apply_state_changes() should check against the Slave's AddressState.nonce.
        # In this case, tx.nonce = 3 but slave addrstate.nonce = 0
        self.slave_addrstate_attrs.pbdata.nonce = 0
        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)

        block = Block.create(**self.block_attrs)
        result = self.chain_manager._apply_state_changes(block, None)
        self.assertFalse(result)
        self.slave_addrstate_attrs.pbdata.nonce = 5

        # Now we pretend that Alice's OTS key has been reused.
        result = self.chain_manager._apply_state_changes(block, None)
        self.assertFalse(result)

        # Now we pretend that Slave's OTS key has been reused.
        result = self.chain_manager._apply_state_changes(block, None)
        self.assertFalse(result)
    def test_rollback_tx_metadata(self):
        alice_xmss = get_alice_xmss()

        tx1 = TransferTransaction.create(
            addrs_to=[get_some_address(1),
                      get_some_address(2)],
            amounts=[1, 2],
            message_data=None,
            fee=0,
            xmss_pk=alice_xmss.pk)

        block = Block.create(dev_config=config.dev,
                             block_number=5,
                             prev_headerhash=b'',
                             prev_timestamp=10,
                             transactions=[tx1],
                             miner_address=b'',
                             seed_height=0,
                             seed_hash=None)

        TransactionMetadata.update_tx_metadata(self.state,
                                               block=block,
                                               batch=None)

        tx_metadata = TransactionMetadata.get_tx_metadata(
            self.state, tx1.txhash)

        self.assertEqual(tx_metadata[0].to_json(), tx1.to_json())
        TransactionMetadata.rollback_tx_metadata(self.state, block, None)
        self.assertIsNone(
            TransactionMetadata.get_tx_metadata(self.state, tx1.txhash))
Example #5
0
 def setUp(self):
     self.block = Block.create(dev_config=config.dev,
                               block_number=5,
                               prev_headerhash=bytes(sha2_256(b'test')),
                               prev_timestamp=10,
                               transactions=[],
                               miner_address=alice.address,
                               seed_height=0,
                               seed_hash=None)
Example #6
0
 def test_write_batch(self):
     batch = self.state.batch
     block = Block.create(dev_config=config.dev,
                          block_number=10,
                          prev_headerhash=b'aa',
                          prev_timestamp=10,
                          transactions=[],
                          miner_address=b'aa',
                          seed_height=0,
                          seed_hash=None)
     Block.put_block(self.state, block, batch)
     self.assertIsNone(Block.get_block(self.state, block.headerhash))
     self.state.write_batch(batch)
     block2 = Block.get_block(self.state, block.headerhash)
     self.assertEqual(block.headerhash, block2.headerhash)
Example #7
0
    def setUp(self):
        self.blockheader = Mock(name='mock BlockHeader',
                                autospec=BlockHeader,
                                block_number=5,
                                headerhash=bytes(sha2_256(b'mock headerhash')),
                                prev_headerhash=bytes(sha2_256(b'test')))

        self.block = Block.create(dev_config=config.dev,
                                  block_number=5,
                                  prev_headerhash=bytes(sha2_256(b'test')),
                                  prev_timestamp=10,
                                  transactions=[],
                                  miner_address=alice.address,
                                  seed_height=0,
                                  seed_hash=None)
        self.block.blockheader = self.blockheader
Example #8
0
    def test_all_ok(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)

        self.chain_manager.get_optimized_address_state = get_optimized_address_state.get
        block = Block.create(**self.block_attrs)
        result = self.chain_manager._apply_state_changes(block, None)
        self.assertTrue(result)
Example #9
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)
Example #10
0
    def create_block(self, prev_hash, mining_address=None):
        if not mining_address:
            mining_address = self.alice_xmss.address
        transactions = []
        block_prev = self.xrdnode.get_block_from_hash(prev_hash)
        block_idx = block_prev.block_number + 1

        if block_idx == 1:
            slave_tx = SlaveTransaction.create(slave_pks=[self.bob_xmss.pk],
                                               access_types=[0],
                                               fee=0,
                                               xmss_pk=self.alice_xmss.pk)
            slave_tx.sign(self.alice_xmss)
            slave_tx._data.nonce = 1
            transactions = [slave_tx]

        time_offset = 60
        if block_idx % 2 == 0:
            time_offset += 2

        self.time_mock.return_value = self.time_mock.return_value + time_offset
        self.ntp_mock.return_value = self.ntp_mock.return_value + time_offset

        block_new = Block.create(dev_config=config.dev,
                                 block_number=block_idx,
                                 prev_headerhash=block_prev.headerhash,
                                 prev_timestamp=block_prev.timestamp,
                                 transactions=transactions,
                                 miner_address=mining_address,
                                 seed_height=0,
                                 seed_hash=None)

        dev_config = self.xrdnode._chain_manager.get_config_by_block_number(
            block_new.block_number)
        while not self.xrdnode._chain_manager.validate_mining_nonce(
                blockheader=block_new.blockheader, dev_config=dev_config):
            block_new.set_nonces(config.dev, block_new.mining_nonce + 1, 0)

        return block_new
Example #11
0
def main():
    if len(sys.argv) > 2:
        print("Unexpected arguments")
        sys.exit(0)
    elif len(sys.argv) == 1:
        print("Missing Filename")
        sys.exit(0)

    filename = sys.argv[1]

    if sys.version_info.major > 2:
        seed = bytes(hstr2bin(input('Enter extended hexseed: ')))
    else:
        seed = bytes(hstr2bin(raw_input('Enter extended hexseed: ')))  # noqa

    dist_xmss = XMSS.from_extended_seed(seed)

    transactions = get_migration_transactions(signing_xmss=dist_xmss,
                                              filename=filename)

    block = Block.create(dev_config=config.dev,
                         block_number=0,
                         prev_headerhash=config.user.genesis_prev_headerhash,
                         prev_timestamp=config.user.genesis_timestamp,
                         transactions=transactions,
                         miner_address=dist_xmss.address,
                         seed_height=None,
                         seed_hash=None)

    block.set_nonces(config.dev, 0, 0)

    block._data.genesis_balance.extend([
        xrd_pb2.GenesisBalance(address=config.dev.coinbase_address,
                               balance=105000000000000000)
    ])

    with open('genesis.yml', 'w') as f:
        yaml.dump(json.loads(block.to_json()), f)
Example #12
0
def gen_blocks(block_count, state, miner_address):
    blocks = []
    block = None
    with mock.patch('xrd.core.misc.ntp.getTime') as time_mock:
        time_mock.return_value = 1615270948
        addresses_state = dict()
        for i in range(0, block_count):
            if i == 0:
                block = GenesisBlock()
                for genesis_balance in GenesisBlock().genesis_balance:
                    bytes_addr = genesis_balance.address
                    addresses_state[
                        bytes_addr] = OptimizedAddressState.get_default(
                            bytes_addr)
                    addresses_state[
                        bytes_addr]._data.balance = genesis_balance.balance
            else:
                block = Block.create(dev_config=config.dev,
                                     block_number=i,
                                     prev_headerhash=block.headerhash,
                                     prev_timestamp=block.timestamp,
                                     transactions=[],
                                     miner_address=miner_address,
                                     seed_height=None,
                                     seed_hash=None)
                addresses_set = ChainManager.set_affected_address(block)
                coin_base_tx = Transaction.from_pbdata(block.transactions[0])
                coin_base_tx.set_affected_address(addresses_set)

                chain_manager = ChainManager(state)
                state_container = chain_manager.new_state_container(
                    addresses_set, block.block_number, False, None)
                coin_base_tx.apply(state, state_container)

                for tx_idx in range(1, len(block.transactions)):
                    tx = Transaction.from_pbdata(block.transactions[tx_idx])
                    if not chain_manager.update_state_container(
                            tx, state_container):
                        return False
                    tx.apply(state, state_container)

                block.set_nonces(dev_config=config.dev,
                                 mining_nonce=10,
                                 extra_nonce=0)
            blocks.append(block)

            metadata = BlockMetadata()
            metadata.set_block_difficulty(StringToUInt256('256'))
            BlockMetadata.put_block_metadata(state, block.headerhash, metadata,
                                             None)

            Block.put_block(state, block, None)
            bm = xrd_pb2.BlockNumberMapping(
                headerhash=block.headerhash,
                prev_headerhash=block.prev_headerhash)

            Block.put_block_number_mapping(state, block.block_number, bm, None)
            state.update_mainchain_height(block.block_number, None)
            OptimizedAddressState.put_optimized_addresses_state(
                state, addresses_state)

    return blocks
Example #13
0
    def test_getMiniTransactionsByAddress(self, mock_dev_config):
        mock_dev_config.data_per_page = 5
        with set_xrd_dir('no_data'):
            db_state = State()

            p2p_factory = Mock(spec=P2PFactory)
            p2p_factory.pow = Mock(spec=POW)

            chain_manager = ChainManager(db_state)

            xrdnode = xrdNode(mining_address=b'')
            xrdnode.set_chain_manager(chain_manager)
            xrdnode._p2pfactory = p2p_factory
            xrdnode._pow = p2p_factory.pow
            xrdnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

            service = PublicAPIService(xrdnode)

            # Find a transaction
            alice_xmss = get_alice_xmss(8)

            context = Mock(spec=ServicerContext)
            bob_xmss = get_bob_xmss(4)
            txs = []
            for i in range(0, 100):
                tx = TransferTransaction.create(addrs_to=[bob_xmss.address],
                                                amounts=[10],
                                                message_data=None,
                                                fee=0,
                                                xmss_pk=alice_xmss.pk)
                tx.sign(alice_xmss)
                txs.append(tx)
            addresses_set = {bob_xmss.address, alice_xmss.address}
            block = Block.create(config.dev, 10, b'', 100000000, txs,
                                 alice_xmss.address, seed_height=0, seed_hash=None)
            state_container = chain_manager.new_state_container(addresses_set,
                                                                5,
                                                                True,
                                                                None)
            for tx in txs:
                chain_manager.update_state_container(tx, state_container)

                address_state = state_container.addresses_state[tx.addr_from]
                state_container.paginated_tx_hash.insert(address_state, tx.txhash)

                address_state = state_container.addresses_state[tx.addrs_to[0]]
                state_container.paginated_tx_hash.insert(address_state, tx.txhash)
            state_container.paginated_tx_hash.put_paginated_data(None)
            OptimizedAddressState.put_optimized_addresses_state(db_state, state_container.addresses_state)

            TransactionMetadata.update_tx_metadata(db_state, block, None)
            request = xrd_pb2.GetMiniTransactionsByAddressReq(address=alice_xmss.address,
                                                              item_per_page=10,
                                                              page_number=1)
            response = service.GetMiniTransactionsByAddress(request=request, context=context)
            context.set_code.assert_not_called()

            self.assertEqual(len(response.mini_transactions), 10)
            for i in range(0, 10):
                self.assertEqual(bin2hstr(txs[len(txs) - i - 1].txhash),
                                 response.mini_transactions[i].transaction_hash)
            self.assertEqual(response.balance, 0)

            TransactionMetadata.update_tx_metadata(db_state, block, None)
            request = xrd_pb2.GetMiniTransactionsByAddressReq(address=alice_xmss.address,
                                                              item_per_page=8,
                                                              page_number=3)
            response = service.GetMiniTransactionsByAddress(request=request, context=context)
            context.set_code.assert_not_called()

            self.assertEqual(len(response.mini_transactions), 8)
            for i in range(0, 8):
                self.assertEqual(bin2hstr(txs[len(txs) - i - 17].txhash),
                                 response.mini_transactions[i].transaction_hash)
            self.assertEqual(response.balance, 0)
Example #14
0
    def test_getLatestData(self):
        with set_xrd_dir('no_data'):
            db_state = State()
            chain_manager = ChainManager(db_state)
            blocks = []
            txs = []
            alice_xmss = get_alice_xmss()
            bob_xmss = get_bob_xmss()
            for i in range(0, 4):
                for j in range(1, 3):
                    txs.append(TransferTransaction.create(addrs_to=[bob_xmss.address],
                                                          amounts=[i * 100 + j],
                                                          message_data=None,
                                                          fee=j,
                                                          xmss_pk=alice_xmss.pk))

                blocks.append(Block.create(dev_config=config.dev,
                                           block_number=i,
                                           prev_headerhash=sha256(b'reveal'),
                                           prev_timestamp=10,
                                           transactions=txs,
                                           miner_address=alice_xmss.address,
                                           seed_height=10,
                                           seed_hash=None))
                block = blocks[i]
                Block.put_block(db_state,
                                block,
                                None)
                Block.put_block_number_mapping(db_state,
                                               block.block_number,
                                               xrd_pb2.BlockNumberMapping(headerhash=block.headerhash),
                                               None)
                TransactionMetadata.update_tx_metadata(db_state, block, None)
            chain_manager._last_block = blocks[-1]
            txpool = []
            txs = []
            for j in range(10, 15):
                tx = TransferTransaction.create(addrs_to=[bob_xmss.address],
                                                amounts=[1000 + j],
                                                message_data=None,
                                                fee=j,
                                                xmss_pk=get_alice_xmss().pk)
                txpool.append((tx.fee, TransactionInfo(tx, 0)))
                txs.append(tx)

            p2p_factory = Mock(spec=P2PFactory)
            p2p_factory.pow = Mock(spec=POW)

            chain_manager.tx_pool = Mock()
            chain_manager.tx_pool.transactions = heapq.nlargest(len(txpool), txpool)
            chain_manager.tx_pool.transaction_pool = txpool

            xrdnode = xrdNode(mining_address=b'')
            xrdnode.set_chain_manager(chain_manager)
            xrdnode.get_block_from_index = MagicMock(return_value=None)

            xrdnode._p2pfactory = p2p_factory
            xrdnode._pow = p2p_factory.pow

            service = PublicAPIService(xrdnode)
            context = Mock(spec=ServicerContext)

            request = xrd_pb2.GetLatestDataReq(filter=xrd_pb2.GetLatestDataReq.ALL,
                                               offset=0,
                                               quantity=3)

            response = service.GetLatestData(request=request, context=context)

            context.set_code.assert_not_called()
            context.set_details.assert_not_called()

            # Verify blockheaders
            self.assertEqual(3, len(response.blockheaders))
            self.assertEqual(1, response.blockheaders[0].header.block_number)
            self.assertEqual(2, response.blockheaders[1].header.block_number)
            self.assertEqual(3, response.blockheaders[2].header.block_number)

            # Verify transactions_unconfirmed
            self.assertEqual(3, len(response.transactions_unconfirmed))
            # TODO: Verify expected order
            self.assertEqual(1014, response.transactions_unconfirmed[0].tx.transfer.amounts[0])
            self.assertEqual(1013, response.transactions_unconfirmed[1].tx.transfer.amounts[0])
            self.assertEqual(1012, response.transactions_unconfirmed[2].tx.transfer.amounts[0])

            # Verify transactions
            self.assertEqual(3, len(response.transactions))
            self.assertEqual(2, response.transactions[0].tx.fee)
            self.assertEqual(1, response.transactions[1].tx.fee)
            self.assertEqual(2, response.transactions[2].tx.fee)

            self.assertEqual(302, response.transactions[0].tx.transfer.amounts[0])
            self.assertEqual(301, response.transactions[1].tx.transfer.amounts[0])
            self.assertEqual(202, response.transactions[2].tx.transfer.amounts[0])
Example #15
0
    def test_getObject(self):
        SOME_ODD_HASH = sha256(b'this should not be found')

        with set_xrd_dir('no_data'):
            db_state = State()

            p2p_factory = Mock(spec=P2PFactory)
            p2p_factory.pow = Mock(spec=POW)

            chain_manager = ChainManager(db_state)

            xrdnode = xrdNode(mining_address=b'')
            xrdnode.set_chain_manager(chain_manager)
            xrdnode._p2pfactory = p2p_factory
            xrdnode._pow = p2p_factory.pow
            xrdnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

            service = PublicAPIService(xrdnode)

            # First try an empty request
            context = Mock(spec=ServicerContext)
            request = xrd_pb2.GetObjectReq()
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            context.set_details.assert_not_called()
            self.assertFalse(response.found)

            # Some odd address
            context = Mock(spec=ServicerContext)
            request = xrd_pb2.GetObjectReq()
            request.query = SOME_ODD_HASH
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertFalse(response.found)

            # Find an address
            bob_xmss = get_bob_xmss()
            addr1_state = OptimizedAddressState.create(address=bob_xmss.address,
                                                       nonce=25,
                                                       balance=10,
                                                       ots_bitfield_used_page=0,
                                                       transaction_hash_count=0,
                                                       tokens_count=0,
                                                       lattice_pk_count=0,
                                                       slaves_count=0,
                                                       multi_sig_address_count=0)

            AddressState.put_address_state(db_state, addr1_state, None)

            context = Mock(spec=ServicerContext)
            request = xrd_pb2.GetObjectReq()
            request.query = bob_xmss.address
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertTrue(response.found)
            self.assertIsNotNone(response.address_state)

            self.assertEqual(bob_xmss.address, response.address_state.address)
            self.assertEqual(25, response.address_state.nonce)
            self.assertEqual(10, response.address_state.balance)

            # Find a transaction
            alice_xmss = get_alice_xmss()
            db_state.address_used = MagicMock(return_value=False)
            tx1 = TransferTransaction.create(
                addrs_to=[bob_xmss.address],
                amounts=[125],
                message_data=None,
                fee=19,
                xmss_pk=bob_xmss.pk,
                master_addr=alice_xmss.address)

            chain_manager.tx_pool.transaction_pool = [(0, TransactionInfo(tx1, 0))]

            context = Mock(spec=ServicerContext)
            request = xrd_pb2.GetObjectReq()
            request.query = tx1.txhash
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertTrue(response.found)
            self.assertIsNotNone(response.transaction)
            self.assertEqual('transfer', response.transaction.tx.WhichOneof('transactionType'))
            self.assertEqual(alice_xmss.address, response.transaction.tx.master_addr)
            self.assertEqual(bob_xmss.pk, response.transaction.tx.public_key)
            self.assertEqual(tx1.txhash, response.transaction.tx.transaction_hash)
            self.assertEqual(b'', response.transaction.tx.signature)

            self.assertEqual(bob_xmss.address, response.transaction.tx.transfer.addrs_to[0])
            self.assertEqual(125, response.transaction.tx.transfer.amounts[0])
            self.assertEqual(19, response.transaction.tx.fee)

            alice_xmss = get_alice_xmss()
            # Find a block
            block = Block.create(dev_config=config.dev,
                                 block_number=1,
                                 prev_headerhash=sha256(b'reveal'),
                                 prev_timestamp=10,
                                 transactions=[],
                                 miner_address=alice_xmss.address,
                                 seed_height=0,
                                 seed_hash=None)

            Block.put_block(db_state, block, None)
            Block.put_block_number_mapping(db_state,
                                           block.block_number,
                                           xrd_pb2.BlockNumberMapping(headerhash=block.headerhash),
                                           None)
            context = Mock(spec=ServicerContext)
            request = xrd_pb2.GetObjectReq()
            request.query = bytes(str2bin('1'))
            response = service.GetObject(request=request, context=context)
            context.set_code.assert_not_called()
            self.assertTrue(response.found)
            self.assertIsNotNone(response.block_extended)
            self.assertEqual(1, response.block_extended.header.block_number)
Example #16
0
    def create_block(self, last_block, mining_nonce, tx_pool: TransactionPool,
                     miner_address) -> Optional[Block]:
        seed_block = self._chain_manager.get_block_by_number(
            self._qn.get_seed_height(last_block.block_number + 1))
        dev_config = self._chain_manager.get_config_by_block_number(
            block_number=last_block.block_number + 1)

        dummy_block = Block.create(dev_config=dev_config,
                                   block_number=last_block.block_number + 1,
                                   prev_headerhash=last_block.headerhash,
                                   prev_timestamp=last_block.timestamp,
                                   transactions=[],
                                   miner_address=miner_address,
                                   seed_height=seed_block.block_number,
                                   seed_hash=seed_block.headerhash)
        dummy_block.set_nonces(dev_config, mining_nonce, 0)

        t_pool2 = tx_pool.transactions

        block_size = dummy_block.size
        block_size_limit = self._chain_manager.get_block_size_limit(
            last_block, dev_config)

        transactions = []
        state_container = self._chain_manager.new_state_container(
            set(), last_block.block_number, True, None)
        for tx_set in t_pool2:
            tx = tx_set[1].transaction

            # Skip Transactions for later, which doesn't fit into block
            if block_size + tx.size + dev_config.tx_extra_overhead > block_size_limit:
                continue

            if not self._chain_manager.update_state_container(
                    tx, state_container):
                logger.error("[create_block] Error updating state_container")
                return None

            if not tx.validate_all(state_container, check_nonce=False):
                if not state_container.revert_update():
                    return None
                tx_pool.remove_tx_from_pool(tx)
                continue
            if not self._chain_manager.apply_txn(tx, state_container):
                logger.error("[create_block] Failed to apply txn")
                if not state_container.revert_update():
                    return None
                continue

            addr_from_pk_state = state_container.addresses_state[tx.addr_from]
            addr_from_pk = Transaction.get_slave(tx)
            if addr_from_pk:
                addr_from_pk_state = state_container.addresses_state[
                    addr_from_pk]

            tx._data.nonce = addr_from_pk_state.nonce
            block_size += tx.size + dev_config.tx_extra_overhead
            transactions.append(tx)

        block = Block.create(dev_config=dev_config,
                             block_number=last_block.block_number + 1,
                             prev_headerhash=last_block.headerhash,
                             prev_timestamp=last_block.timestamp,
                             transactions=transactions,
                             miner_address=miner_address,
                             seed_height=seed_block.block_number,
                             seed_hash=seed_block.headerhash)

        return block