Exemplo n.º 1
0
    def test_prepare_address_list(self):
        with set_qrl_dir('no_data'):
            with State() as state:
                block = Block.create(block_number=10,
                                     prev_headerhash=b'',
                                     prev_timestamp=10,
                                     transactions=[],
                                     miner_address=get_some_address(1))
                # Test Case: without any transactions of block
                self.assertEqual(state.prepare_address_list(block),
                                 {config.dev.coinbase_address, get_some_address(1)})

                alice_xmss = get_alice_xmss()
                block = Block.create(block_number=10,
                                     prev_headerhash=b'',
                                     prev_timestamp=10,
                                     transactions=[TransferTransaction.create(addrs_to=[get_some_address(2),
                                                                                        get_some_address(3)],
                                                                              amounts=[100, 100],
                                                                              fee=0,
                                                                              xmss_pk=alice_xmss.pk)],
                                     miner_address=get_some_address(1))

                # Test Case, with one Transaction
                self.assertEqual(state.prepare_address_list(block),
                                 {config.dev.coinbase_address,
                                  get_some_address(1),
                                  get_some_address(2),
                                  get_some_address(3),
                                  alice_xmss.address})
Exemplo n.º 2
0
    def create_block(self,
                     last_block,
                     mining_nonce,
                     tx_pool: TransactionPool,
                     miner_address) -> Optional[Block]:
        # TODO: Persistence will move to rocksdb
        # FIXME: Difference between this and create block?????????????

        dummy_block = Block.create(block_number=last_block.block_number + 1,
                                   prevblock_headerhash=last_block.headerhash,
                                   transactions=[],
                                   miner_address=miner_address)
        dummy_block.set_nonces(mining_nonce, 0)

        t_pool2 = tx_pool.transactions

        addresses_set = set()
        for tx_set in t_pool2:
            tx = tx_set[1]
            tx.set_effected_address(addresses_set)

        addresses_state = dict()
        for address in addresses_set:
            addresses_state[address] = self.state.get_address(address)

        block_size = dummy_block.size
        block_size_limit = self.state.get_block_size_limit(last_block)

        transactions = []
        for tx_set in t_pool2:
            tx = tx_set[1]
            # Skip Transactions for later, which doesn't fit into block
            if block_size + tx.size + config.dev.tx_extra_overhead > block_size_limit:
                continue

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

            if not tx.validate_extended(addresses_state[tx.addr_from], addr_from_pk_state):
                logger.warning('Txn validation failed for tx in tx_pool')
                tx_pool.remove_tx_from_pool(tx)
                continue

            tx.apply_on_state(addresses_state)

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

        block = Block.create(block_number=last_block.block_number + 1,
                             prevblock_headerhash=last_block.headerhash,
                             transactions=transactions,
                             miner_address=miner_address)

        return block
Exemplo n.º 3
0
    def create_block(self, last_block, mining_nonce, tx_pool: TransactionPool,
                     miner_address) -> Optional[Block]:
        dummy_block = Block.create(block_number=last_block.block_number + 1,
                                   prev_headerhash=last_block.headerhash,
                                   prev_timestamp=last_block.timestamp,
                                   transactions=[],
                                   miner_address=miner_address)
        dummy_block.set_nonces(mining_nonce, 0)

        t_pool2 = tx_pool.transactions

        addresses_set = set()
        for tx_set in t_pool2:
            tx = tx_set[1].transaction
            tx.set_affected_address(addresses_set)

        addresses_state = dict()
        for address in addresses_set:
            addresses_state[address] = self._chain_manager.get_address_state(
                address)

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

        transactions = []
        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 + config.dev.tx_extra_overhead > block_size_limit:
                continue

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

            if not tx.validate_extended(addresses_state[tx.addr_from],
                                        addr_from_pk_state):
                logger.warning('Txn validation failed for tx in tx_pool')
                tx_pool.remove_tx_from_pool(tx)
                continue

            tx.apply_state_changes(addresses_state)

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

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

        return block
Exemplo n.º 4
0
    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))
Exemplo n.º 5
0
    def test_getBlock(self):
        with set_qrl_dir('no_data'):
            db_state = State()

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

            chain_manager = ChainManager(db_state)

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

            service = PublicAPIService(qrlnode)

            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 = qrl_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)
Exemplo n.º 6
0
    def test_mining_blob(self):
        alice_xmss = get_alice_xmss()
        block = Block.create(block_number=5,
                             prevblock_headerhash=bytes(sha2_256(b'test')),
                             transactions=[],
                             miner_address=alice_xmss.address)

        block.set_nonces(mining_nonce=5, extra_nonce=4)

        mining_blob = block.mining_blob
        self.assertEqual(len(mining_blob), config.dev.mining_blob_size)
        mining_nonce_bytes = mining_blob[config.dev.mining_nonce_offset:config.
                                         dev.mining_nonce_offset + 4]
        extra_nonce_bytes = mining_blob[config.dev.extra_nonce_offset:config.
                                        dev.extra_nonce_offset + 8]

        mining_nonce = int.from_bytes(mining_nonce_bytes,
                                      byteorder='big',
                                      signed=False)
        extra_nonce = int.from_bytes(extra_nonce_bytes,
                                     byteorder='big',
                                     signed=False)

        self.assertEqual(mining_nonce, 5)
        self.assertEqual(extra_nonce, 4)
Exemplo n.º 7
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)
Exemplo n.º 8
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['nonce'] = 0
        address_states = self.generate_address_states(
            self.alice_addrstate_attrs, {}, self.slave_addrstate_attrs)

        block = Block.create(**self.block_attrs)
        result = block.apply_state_changes(address_states)
        self.assertFalse(result)
        self.slave_addrstate_attrs['nonce'] = 5

        # Now we pretend that Alice's OTS key has been reused.
        self.alice_addrstate_attrs['ots_key_reuse.return_value'] = True
        address_states = self.generate_address_states(
            self.alice_addrstate_attrs, {}, self.slave_addrstate_attrs)
        result = block.apply_state_changes(address_states)
        self.assertFalse(result)
        self.alice_addrstate_attrs['ots_key_reuse.return_value'] = False

        # Now we pretend that Slave's OTS key has been reused.
        self.slave_addrstate_attrs['ots_key_reuse.return_value'] = True
        address_states = self.generate_address_states(
            self.alice_addrstate_attrs, {}, self.slave_addrstate_attrs)
        result = block.apply_state_changes(address_states)
        self.assertFalse(result)
Exemplo n.º 9
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('qrl.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)
Exemplo n.º 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.qrlnode.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(block_number=block_idx,
                                 prev_headerhash=block_prev.headerhash,
                                 prev_timestamp=block_prev.timestamp,
                                 transactions=transactions,
                                 miner_address=mining_address)

        while not self.qrlnode._chain_manager.validate_mining_nonce(blockheader=block_new.blockheader):
            block_new.set_nonces(block_new.mining_nonce + 1, 0)

        return block_new
Exemplo n.º 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([qrl_pb2.GenesisBalance(address=config.dev.coinbase_address,
                                                               balance=105000000000000000)])

    with open('genesis.yml', 'w') as f:
        yaml.dump(json.loads(block.to_json()), f)
Exemplo n.º 12
0
    def create_block(self, prev_hash):
        transactions = []
        block_prev = self.qrlnode.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]

        self.time_mock.return_value = self.time_mock.return_value + 60
        self.ntp_mock.return_value = self.ntp_mock.return_value + 60

        block_new = Block.create(block_number=block_idx,
                                 prevblock_headerhash=block_prev.headerhash,
                                 transactions=transactions,
                                 miner_address=self.alice_xmss.address)

        while not PoWValidator().validate_mining_nonce(state=self.qrlnode._chain_manager.state,
                                                       blockheader=block_new.blockheader,
                                                       enable_logging=False):
            block_new.set_mining_nonce(block_new.mining_nonce + 1)

        return block_new
Exemplo n.º 13
0
    def test_simple_add_block(self, time_mock):
        # Simply test that adding a block on top of the genesis block works.
        self.chain_manager._difficulty_tracker.get.return_value = ask_difficulty_tracker(
            '2')
        self.chain_manager.load(self.genesis_block)

        time_mock.return_value = 1615270948  # Very high to get an easy difficulty

        block_1 = Block.create(block_number=1,
                               prev_headerhash=self.genesis_block.headerhash,
                               prev_timestamp=self.genesis_block.timestamp,
                               transactions=[],
                               miner_address=alice.address)
        block_1.set_nonces(201, 0)

        # Uncomment only to determine the correct mining_nonce of above blocks
        # from qrl.core.PoWValidator import PoWValidator
        # while not PoWValidator().validate_mining_nonce(self.state, block_1.blockheader, False):
        #     block_1.set_nonces(block_1.mining_nonce + 1)
        #     print(block_1.mining_nonce)
        self.assertTrue(block_1.validate(self.chain_manager, {}))
        result = self.chain_manager.add_block(block_1)

        self.assertTrue(result)
        self.assertEqual(self.chain_manager.last_block, block_1)
Exemplo n.º 14
0
    def test_last_block(self):
        with set_wallet_dir("test_wallet"):
            with State() as state:
                self.assertIsNotNone(state)

                chain = Chain(state)
                alice_xmss = get_alice_xmss()
                staking_address = bytes(alice_xmss.get_address().encode())

                address_state_dict = dict()
                address_state_dict[staking_address] = AddressState.create(address=staking_address,
                                                                          nonce=0,
                                                                          balance=100,
                                                                          pubhashes=[])

                tmp_block1 = Block.create(staking_address=staking_address,
                                          block_number=0,
                                          reveal_hash=bytes(),
                                          prevblock_headerhash=bytes(),
                                          transactions=[],
                                          duplicate_transactions=OrderedDict(),
                                          vote=VoteMetadata(),
                                          signing_xmss=alice_xmss,
                                          nonce=address_state_dict[staking_address].nonce + 1)

                res = chain.add_block(tmp_block1, address_state_dict, None)
                address_state_dict[staking_address].increase_nonce()
                address_state_dict[staking_address].balance += tmp_block1.block_reward
                self.assertTrue(res)
                self.assertEqual(0, chain.height)           # FIXME: wrong name, it is not height but max_index

                last_block = chain.get_last_block()
                self.assertEqual(tmp_block1, last_block)
Exemplo n.º 15
0
    def test_getBlockByNumber(self):
        db_state = Mock(spec=State)
        db_state.get_tx_metadata = MagicMock(return_value=None)
        db_state.get_block = MagicMock(return_value=None)

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

        chain_manager = ChainManager(db_state)

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

        service = PublicAPIService(qrlnode)

        alice_xmss = get_alice_xmss()
        b = Block.create(block_number=1,
                         prev_headerhash=sha256(b'reveal'),
                         prev_timestamp=10,
                         transactions=[],
                         miner_address=alice_xmss.address)
        db_state.get_block_by_number = MagicMock(return_value=b)

        context = Mock(spec=ServicerContext)
        request = qrl_pb2.GetBlockByNumberReq(block_number=b.block_number)
        response = service.GetBlockByNumber(request=request, context=context)
        context.set_code.assert_not_called()
        self.assertEqual(1, response.block.header.block_number)
Exemplo n.º 16
0
def qrlnode_with_mock_blockchain(num_blocks):
    start_time = time.time()
    with mock.patch('qrl.core.misc.ntp.getTime') as ntp_mock, \
            set_data_dir('no_data'), \
            State() as state, \
            mock.patch('time.time') as time_mock:  # noqa
        time_mock.return_value = start_time
        ntp_mock.return_value = start_time

        state.get_measurement = MagicMock(return_value=10000000)

        required_height = ceil(log(num_blocks, 2))
        required_height = int(required_height + required_height % 2)

        alice_xmss = get_alice_xmss(xmss_height=required_height)
        bob_xmss = get_bob_xmss()

        genesis_block = GenesisBlock()
        chain_manager = ChainManager(state)
        chain_manager.load(genesis_block)

        chain_manager._difficulty_tracker = Mock()
        dt = DifficultyTracker()
        tmp_difficulty = StringToUInt256('2')
        tmp_target = dt.get_target(tmp_difficulty)

        chain_manager._difficulty_tracker.get = MagicMock(return_value=(tmp_difficulty, tmp_target))

        block_prev = state.get_block(genesis_block.headerhash)

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

            time_mock.return_value = time_mock.return_value + 60
            ntp_mock.return_value = ntp_mock.return_value + 60

            block_new = Block.create(block_number=block_idx,
                                     prevblock_headerhash=block_prev.headerhash,
                                     transactions=transactions,
                                     miner_address=alice_xmss.address)

            while not PoWValidator().validate_mining_nonce(state, block_new.blockheader, False):
                block_new.set_nonces(block_new.mining_nonce + 1, 0)

            chain_manager.add_block(block_new)
            block_prev = block_new

        qrlnode = QRLNode(state, mining_credit_wallet=alice_xmss.address)
        qrlnode.set_chain_manager(chain_manager)

        yield qrlnode
Exemplo n.º 17
0
 def test_verify_blob(self):
     alice_xmss = get_alice_xmss()
     block = Block.create(block_number=5,
                          prevblock_headerhash=bytes(sha2_256(b'test')),
                          transactions=[],
                          miner_address=alice_xmss.address)
     mining_blob = block.mining_blob
     self.assertTrue(block.blockheader.verify_blob(mining_blob))
Exemplo n.º 18
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)
Exemplo n.º 19
0
    def test_all_ok(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)

        block = Block.create(**self.block_attrs)
        result = block.apply_state_changes(address_states)
        self.assertTrue(result)
Exemplo n.º 20
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)
Exemplo n.º 21
0
 def test_write_batch(self):
     batch = self.state.batch
     block = Block.create(block_number=10,
                          prev_headerhash=b'aa',
                          prev_timestamp=10,
                          transactions=[],
                          miner_address=b'aa')
     self.state.put_block(block, batch)
     self.assertIsNone(self.state.get_block(block.headerhash))
     self.state.write_batch(batch)
     block2 = self.state.get_block(block.headerhash)
     self.assertEqual(block.headerhash, block2.headerhash)
Exemplo n.º 22
0
 def test_write_batch(self):
     with set_qrl_dir('no_data'):
         with State() as state:
             batch = state.get_batch()
             block = Block.create(block_number=10,
                                  prevblock_headerhash=b'aa',
                                  transactions=[],
                                  miner_address=b'aa')
             state.put_block(block, batch)
             self.assertIsNone(state.get_block(block.headerhash))
             state.write_batch(batch)
             block2 = state.get_block(block.headerhash)
             self.assertEqual(block.headerhash, block2.headerhash)
Exemplo n.º 23
0
 def test_set_mining_nonce_from_blob(self):
     alice_xmss = get_alice_xmss()
     block = Block.create(block_number=5,
                          prevblock_headerhash=bytes(sha2_256(b'test')),
                          transactions=[],
                          miner_address=alice_xmss.address)
     current_mining_nonce = block.mining_nonce
     current_headerhash = block.headerhash
     mining_blob = block.mining_blob
     block.blockheader.set_mining_nonce_from_blob(mining_blob)
     self.assertEqual(block.blockheader.mining_nonce, current_mining_nonce)
     self.assertEqual(block.headerhash, current_headerhash)
     self.assertEqual(block.blockheader.mining_blob, mining_blob)
Exemplo n.º 24
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)
Exemplo n.º 25
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(block_number=5,
                                  prev_headerhash=bytes(sha2_256(b'test')),
                                  prev_timestamp=10,
                                  transactions=[],
                                  miner_address=alice.address)
        self.block.blockheader = self.blockheader
Exemplo n.º 26
0
    def test_multi_output_transaction_add_block(self, time_mock):
        # Test that adding block with a multi-output Transaction updates everybody's balances correctly.
        self.chain_manager.load(self.genesis_block)

        extended_seed = "010300cebc4e25553afa0aab899f7838e59e18a48852fa9dfd5" \
                        "ae78278c371902aa9e6e9c1fa8a196d2dba0cbfd2f2d212d16c"
        random_xmss = XMSS.from_extended_seed(hstr2bin(extended_seed))

        transfer_transaction = TransferTransaction.create(
            addrs_to=[alice.address, random_xmss.address],
            amounts=[
                40 * int(config.dev.shor_per_quanta),
                59 * int(config.dev.shor_per_quanta)
            ],
            fee=1 * config.dev.shor_per_quanta,
            xmss_pk=bob.pk)
        transfer_transaction._data.nonce = 1
        transfer_transaction.sign(bob)

        time_mock.return_value = 1615270948  # Very high to get an easy difficulty

        block_1 = Block.create(block_number=1,
                               prev_headerhash=self.genesis_block.headerhash,
                               prev_timestamp=self.genesis_block.timestamp,
                               transactions=[transfer_transaction],
                               miner_address=alice.address)
        block_1.set_nonces(129, 0)

        # Uncomment only to determine the correct mining_nonce of above blocks
        # from qrl.core.PoWValidator import PoWValidator
        # while not PoWValidator().validate_mining_nonce(self.state, block_1.blockheader, False):
        #     block_1.set_nonces(block_1.mining_nonce + 1)
        #     print(block_1.mining_nonce)
        self.assertTrue(block_1.validate(self.chain_manager, {}))
        result = self.chain_manager.add_block(block_1)

        self.assertTrue(result)
        self.assertEqual(self.chain_manager.last_block, block_1)

        bob_addr_state = self.state.get_address_state(bob.address)
        alice_addr_state = self.state.get_address_state(alice.address)
        random_addr_state = self.state.get_address_state(random_xmss.address)

        self.assertEqual(bob_addr_state.balance, 0)
        self.assertEqual(
            alice_addr_state.balance, 140 * int(config.dev.shor_per_quanta) +
            block_1.block_reward + block_1.fee_reward)
        self.assertEqual(random_addr_state.balance,
                         159 * int(config.dev.shor_per_quanta))
Exemplo n.º 27
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)
Exemplo n.º 28
0
    def test_add_many_and_save(self):
        with set_wallet_dir("test_wallet"):
            with State() as state:
                self.assertIsNotNone(state)

                chain = Chain(state)
                alice_xmss = get_alice_xmss()
                staking_address = bytes(alice_xmss.get_address().encode())

                with patch('qrl.core.config.dev.disk_writes_after_x_blocks'):
                    qrl.core.config.dev.disk_writes_after_x_blocks = 4

                    prev = bytes()
                    address_state_dict = dict()
                    address_state_dict[staking_address] = AddressState.create(
                        address=staking_address,
                        nonce=0,
                        balance=100,
                        pubhashes=[])
                    for i in range(10):
                        tmp_block1 = Block.create(
                            staking_address=staking_address,
                            block_number=i,
                            reveal_hash=bytes(),
                            prevblock_headerhash=prev,
                            transactions=[],
                            duplicate_transactions=OrderedDict(),
                            vote=VoteMetadata(),
                            signing_xmss=alice_xmss,
                            nonce=address_state_dict[staking_address].nonce +
                            1)
                        prev = tmp_block1.headerhash

                        res = chain.add_block(tmp_block1, address_state_dict,
                                              StakeValidatorsTracker(),
                                              b'1001', alice_xmss)

                        address_state_dict[staking_address].increase_nonce()
                        address_state_dict[
                            staking_address].balance += tmp_block1.block_reward

                        self.assertEqual(
                            i, chain.height
                        )  # FIXME: wrong name, it is not height but max_index

                        self.assertTrue(res)

                print(qrl.core.config.dev.disk_writes_after_x_blocks)
Exemplo n.º 29
0
 def test_update_mining_address(self):
     alice_xmss = get_alice_xmss()
     bob_xmss = get_bob_xmss()
     block = Block.create(block_number=5,
                          prev_headerhash=bytes(sha2_256(b'test')),
                          prev_timestamp=10,
                          transactions=[],
                          miner_address=alice_xmss.address)
     block.update_mining_address(mining_address=bob_xmss.address)
     coinbase_tx = Transaction.from_pbdata(block.transactions[0])
     self.assertTrue(isinstance(coinbase_tx, CoinBase))
     self.assertEqual(coinbase_tx.addr_to, bob_xmss.address)
     hashedtransactions = []
     for tx in block.transactions:
         hashedtransactions.append(tx.transaction_hash)
     self.assertEqual(block.blockheader.tx_merkle_root,
                      merkle_tx_hash(hashedtransactions))
Exemplo n.º 30
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)
Exemplo n.º 31
0
    def test_add_block(self):
        """
        Testing add_block, with fork logic
        :return:
        """
        with set_data_dir('no_data'):
            with State() as state:
                state.get_measurement = MagicMock(return_value=10000000)

                alice_xmss = get_alice_xmss()
                bob_xmss = get_bob_xmss()

                genesis_block = GenesisBlock()
                chain_manager = ChainManager(state)
                chain_manager.load(genesis_block)

                chain_manager._difficulty_tracker = Mock()
                dt = DifficultyTracker()
                tmp_difficulty = StringToUInt256('2')
                tmp_boundary = dt.get_boundary(tmp_difficulty)
                chain_manager._difficulty_tracker.get = MagicMock(return_value=(tmp_difficulty, tmp_boundary))

                block = state.get_block(genesis_block.headerhash)
                self.assertIsNotNone(block)

                slave_tx = SlaveTransaction.create(addr_from=alice_xmss.get_address(),
                                                   slave_pks=[bob_xmss.pk()],
                                                   access_types=[0],
                                                   fee=0,
                                                   xmss_pk=alice_xmss.pk(),
                                                   xmss_ots_index=alice_xmss.get_index())
                slave_tx.sign(alice_xmss)
                slave_tx._data.nonce = 2
                self.assertTrue(slave_tx.validate())
                with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                    time_mock.return_value = 1615270948  # Very high to get an easy difficulty

                    block_1 = Block.create(mining_nonce=10,
                                           block_number=1,
                                           prevblock_headerhash=genesis_block.headerhash,
                                           transactions=[slave_tx],
                                           signing_xmss=alice_xmss,
                                           master_address=alice_xmss.get_address(),
                                           nonce=1)

                    while not chain_manager.validate_mining_nonce(block_1, False):
                        block_1.set_mining_nonce(block_1.mining_nonce + 1)

                    result = chain_manager.add_block(block_1)

                self.assertTrue(result)
                self.assertEqual(chain_manager.last_block, block_1)

                alice_state = chain_manager.get_address(alice_xmss.get_address())

                self.assertEqual(len(alice_state.slave_pks_access_type), 1)
                self.assertTrue(str(bob_xmss.pk()) in alice_state.slave_pks_access_type)

                with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                    time_mock.return_value = 1715270948  # Very high to get an easy difficulty
                    block = Block.create(mining_nonce=15,
                                         block_number=1,
                                         prevblock_headerhash=genesis_block.headerhash,
                                         transactions=[],
                                         signing_xmss=bob_xmss,
                                         master_address=bob_xmss.get_address(),
                                         nonce=1)

                    while not chain_manager.validate_mining_nonce(block, False):
                        block.set_mining_nonce(block.mining_nonce + 1)

                    result = chain_manager.add_block(block)

                self.assertTrue(result)
                self.assertEqual(chain_manager.last_block, block_1)

                block = state.get_block(block.headerhash)
                self.assertIsNotNone(block)

                with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                    time_mock.return_value = 1815270948  # Very high to get an easy difficulty
                    block_2 = Block.create(mining_nonce=15,
                                           block_number=2,
                                           prevblock_headerhash=block.headerhash,
                                           transactions=[],
                                           signing_xmss=bob_xmss,
                                           master_address=bob_xmss.get_address(),
                                           nonce=2)

                    while not chain_manager.validate_mining_nonce(block_2, False):
                        block_2.set_mining_nonce(block_2.mining_nonce + 1)

                    result = chain_manager.add_block(block_2)

                self.assertTrue(result)
                self.assertEqual(chain_manager.last_block.block_number, block_2.block_number)
                self.assertEqual(chain_manager.last_block.to_json(), block_2.to_json())
Exemplo n.º 32
0
    def test_orphan_block(self):
        """
        Testing add_block logic in case of orphan_blocks
        :return:
        """
        with mock.patch('qrl.core.config.DevConfig') as devconfig:
            devconfig.genesis_difficulty = 2
            devconfig.minimum_minting_delay = 10
            with set_data_dir('no_data'):
                with State() as state:  # FIXME: Move state to temporary directory
                    state.get_measurement = MagicMock(return_value=10000000)
                    genesis_block = GenesisBlock()

                    chain_manager = ChainManager(state)
                    chain_manager.load(genesis_block)

                    chain_manager._difficulty_tracker = Mock()
                    dt = DifficultyTracker()
                    tmp_difficulty = StringToUInt256('2')
                    tmp_boundary = dt.get_boundary(tmp_difficulty)
                    chain_manager._difficulty_tracker.get = MagicMock(return_value=(tmp_difficulty, tmp_boundary))

                    block = state.get_block(genesis_block.headerhash)
                    self.assertIsNotNone(block)
                    alice_xmss = get_alice_xmss()

                    with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                        time_mock.return_value = 1615270948  # Very high to get an easy difficulty
                        block_1 = Block.create(mining_nonce=10,
                                               block_number=1,
                                               prevblock_headerhash=genesis_block.headerhash,
                                               transactions=[],
                                               signing_xmss=alice_xmss,
                                               master_address=alice_xmss.get_address(),
                                               nonce=1)
                        block_1.set_mining_nonce(10)

                        while not chain_manager.validate_mining_nonce(block_1, False):
                            block_1.set_mining_nonce(block_1.mining_nonce + 1)

                        result = chain_manager.add_block(block_1)

                    self.assertTrue(result)
                    self.assertEqual(chain_manager.last_block, block_1)

                    bob_xmss = get_bob_xmss()

                    with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                        time_mock.return_value = 1615270948 + devconfig.minimum_minting_delay * 2
                        block = Block.create(mining_nonce=18,
                                             block_number=1,
                                             prevblock_headerhash=genesis_block.headerhash,
                                             transactions=[],
                                             signing_xmss=bob_xmss,
                                             master_address=bob_xmss.get_address(),
                                             nonce=1)
                        block.set_mining_nonce(18)

                        while not chain_manager.validate_mining_nonce(block, False):
                            block.set_mining_nonce(block.mining_nonce + 1)

                    with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                        time_mock.return_value = 1615270948 + devconfig.minimum_minting_delay * 3
                        block_2 = Block.create(mining_nonce=17,
                                               block_number=2,
                                               prevblock_headerhash=block.headerhash,
                                               transactions=[],
                                               signing_xmss=bob_xmss,
                                               master_address=bob_xmss.get_address(),
                                               nonce=2)
                        block_2.set_mining_nonce(17)

                    result = chain_manager.add_block(block_2)
                    self.assertTrue(result)

                    result = chain_manager.add_block(block)
                    self.assertTrue(result)

                    block = state.get_block(block.headerhash)
                    self.assertIsNotNone(block)

                    self.assertEqual(chain_manager.last_block.block_number, block_1.block_number)
                    self.assertEqual(chain_manager.last_block.headerhash, block_1.headerhash)
Exemplo n.º 33
0
Arquivo: Miner.py Projeto: fanff/QRL
    def create_block(self, last_block, mining_nonce, tx_pool, signing_xmss, master_address) -> Optional[Block]:
        # TODO: Persistence will move to rocksdb
        # FIXME: Difference between this and create block?????????????

        # FIXME: Break encapsulation
        dummy_block = Block.create(mining_nonce=mining_nonce,
                                   block_number=last_block.block_number + 1,
                                   prevblock_headerhash=last_block.headerhash,
                                   transactions=[],
                                   signing_xmss=signing_xmss,
                                   master_address=master_address,
                                   nonce=0)
        dummy_block.set_mining_nonce(mining_nonce)
        signing_xmss.set_index(signing_xmss.get_index() - 1)

        t_pool2 = copy.deepcopy(tx_pool.transaction_pool)
        del tx_pool.transaction_pool[:]
        ######

        # recreate the transaction pool as in the tx_hash_list, ordered by txhash..
        total_txn = len(t_pool2)
        txnum = 0
        addresses_set = set()
        while txnum < total_txn:
            tx = t_pool2[txnum]
            tx.set_effected_address(addresses_set)
            txnum += 1

        addresses_state = dict()
        for address in addresses_set:
            addresses_state[address] = self.state.get_address(address)

        block_size = dummy_block.size
        block_size_limit = self.state.get_block_size_limit(last_block)
        txnum = 0
        while txnum < total_txn:
            tx = t_pool2[txnum]
            # Skip Transactions for later, which doesn't fit into block
            if block_size + tx.size + config.dev.tx_extra_overhead > block_size_limit:
                txnum += 1
                continue

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

            if tx.ots_key_reuse(addr_from_pk_state, tx.ots_key):
                del t_pool2[txnum]
                total_txn -= 1
                continue

            if tx.subtype == qrl_pb2.Transaction.TRANSFER:
                if addresses_state[tx.txfrom].balance < tx.amount + tx.fee:
                    logger.warning('%s %s exceeds balance, invalid tx', tx, tx.txfrom)
                    logger.warning('subtype: %s', tx.subtype)
                    logger.warning('Buffer State Balance: %s  Transfer Amount %s', addresses_state[tx.txfrom].balance,
                                   tx.amount)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if tx.subtype == qrl_pb2.Transaction.MESSAGE:
                if addresses_state[tx.txfrom].balance < tx.fee:
                    logger.warning('%s %s exceeds balance, invalid message tx', tx, tx.txfrom)
                    logger.warning('subtype: %s', tx.subtype)
                    logger.warning('Buffer State Balance: %s  Free %s', addresses_state[tx.txfrom].balance, tx.fee)
                    total_txn -= 1
                    continue

            if tx.subtype == qrl_pb2.Transaction.TOKEN:
                if addresses_state[tx.txfrom].balance < tx.fee:
                    logger.warning('%s %s exceeds balance, invalid tx', tx, tx.txfrom)
                    logger.warning('subtype: %s', tx.subtype)
                    logger.warning('Buffer State Balance: %s  Fee %s',
                                   addresses_state[tx.txfrom].balance,
                                   tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if tx.subtype == qrl_pb2.Transaction.TRANSFERTOKEN:
                if addresses_state[tx.txfrom].balance < tx.fee:
                    logger.warning('%s %s exceeds balance, invalid tx', tx, tx.txfrom)
                    logger.warning('subtype: %s', tx.subtype)
                    logger.warning('Buffer State Balance: %s  Transfer Amount %s',
                                   addresses_state[tx.txfrom].balance,
                                   tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

                if bin2hstr(tx.token_txhash).encode() not in addresses_state[tx.txfrom].tokens:
                    logger.warning('%s doesnt own any token with token_txnhash %s', tx.txfrom,
                                   bin2hstr(tx.token_txhash).encode())
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

                if addresses_state[tx.txfrom].tokens[bin2hstr(tx.token_txhash).encode()] < tx.amount:
                    logger.warning('Token Transfer amount exceeds available token')
                    logger.warning('Token Txhash %s', bin2hstr(tx.token_txhash).encode())
                    logger.warning('Available Token Amount %s',
                                   addresses_state[tx.txfrom].tokens[bin2hstr(tx.token_txhash).encode()])
                    logger.warning('Transaction Amount %s', tx.amount)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if tx.subtype == qrl_pb2.Transaction.LATTICE:
                if addresses_state[tx.txfrom].balance < tx.fee:
                    logger.warning('Lattice TXN %s %s exceeds balance, invalid tx', tx, tx.txfrom)
                    logger.warning('subtype: %s', tx.subtype)
                    logger.warning('Buffer State Balance: %s  Transfer Amount %s',
                                   addresses_state[tx.txfrom].balance,
                                   tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            if tx.subtype == qrl_pb2.Transaction.SLAVE:
                if addresses_state[tx.txfrom].balance < tx.fee:
                    logger.warning('Slave TXN %s %s exceeds balance, invalid tx', tx, tx.txfrom)
                    logger.warning('subtype: %s', tx.subtype)
                    logger.warning('Buffer State Balance: %s  Transfer Amount %s',
                                   addresses_state[tx.txfrom].balance,
                                   tx.fee)
                    del t_pool2[txnum]
                    total_txn -= 1
                    continue

            tx.apply_on_state(addresses_state)

            tx_pool.add_tx_to_pool(tx)
            tx._data.nonce = addresses_state[tx.txfrom].nonce
            txnum += 1
            block_size += tx.size + config.dev.tx_extra_overhead

        coinbase_nonce = self.state.get_address(signing_xmss.get_address()).nonce
        if signing_xmss.get_address() in addresses_state:
            coinbase_nonce = addresses_state[signing_xmss.get_address()].nonce + 1

        block = Block.create(mining_nonce=mining_nonce,
                             block_number=last_block.block_number + 1,
                             prevblock_headerhash=last_block.headerhash,
                             transactions=t_pool2,
                             signing_xmss=signing_xmss,
                             master_address=master_address,
                             nonce=coinbase_nonce)

        return block