Example #1
0
 def test_generate_bitfield_key(self):
     with set_qrl_dir('no_data'):
         state = State()
         paginated_bitfield = PaginatedBitfield(True, state._db)
         address = b'addr1'
         page = 1
         expected_key = b'bitfield_' + address + b'_' + page.to_bytes(8, byteorder='big', signed=False)
         found_key = paginated_bitfield.generate_bitfield_key(address, page)
         self.assertEqual(expected_key, found_key)
Example #2
0
    def test_update_used_page_in_address_state(self):
        alice_xmss = get_alice_xmss(4)
        address = alice_xmss.address
        address_state = OptimizedAddressState.get_default(address)
        addresses_state = {address: address_state}
        paginated_bitfield = PaginatedBitfield(True, self.state._db)
        key = paginated_bitfield.generate_bitfield_key(address, 1)
        paginated_bitfield.update_used_page_in_address_state(address, addresses_state, 1)
        self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(0, 16):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            if i != 15:
                self.assertEqual(address_state.ots_bitfield_used_page, 0)
            else:
                self.assertEqual(address_state.ots_bitfield_used_page, 1)

        for i in range(0, 16):
            ots_bitfield = paginated_bitfield.key_value[key]
            ots_key_index = i % config.dev.ots_tracking_per_page
            offset = ots_key_index >> 3
            relative = ots_key_index % 8
            bitfield = bytearray(ots_bitfield[offset])
            self.assertEqual(bytes([bitfield[0] >> relative & 1]), b'\x01')

        self.assertEqual(address_state.ots_bitfield_used_page, 1)
Example #3
0
    def test_unset_ots_key3(self, mock_ots_bitfield_size, mock_ots_tracking_per_page):
        """
        Features Tested
        - Sequentially marking OTS indexes as used
        - Sequentially marking OTS indexes as unused
        - ots_bitfield_used_page value with each OTS index being used

        Expectation
        - The ots_bitfield_used_page must increase by 1 for every sequential 1024 (ots_tracking_per_page) ots indexes
          marked as used

        :param mock_ots_bitfield_size:
        :param mock_ots_tracking_per_page:
        :return:
        """
        with set_qrl_dir('no_data'):
            state = State()
            mock_ots_bitfield_size.return_value = ceil(config.dev.ots_tracking_per_page / 8)

            alice_xmss = get_alice_xmss(12)
            address = alice_xmss.address
            address_state = OptimizedAddressState.get_default(address)
            addresses_state = {address: address_state}
            paginated_bitfield = PaginatedBitfield(True, state._db)
            paginated_bitfield.update_used_page_in_address_state(address, addresses_state, 1)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

            total_ots = 2 ** alice_xmss.height
            for i in range(0, total_ots + 1):
                paginated_bitfield.set_ots_key(addresses_state, address, i)
                self.assertEqual(address_state.ots_bitfield_used_page, (i + 1) // config.dev.ots_tracking_per_page)

            self.assertEqual(address_state.ots_bitfield_used_page,
                             total_ots // config.dev.ots_tracking_per_page)
            self.assertEqual(total_ots // config.dev.ots_tracking_per_page, 4)

            paginated_bitfield.unset_ots_key(addresses_state, address, total_ots - 1)
            self.assertEqual(address_state.ots_bitfield_used_page, 3)

            for i in range(total_ots - 2, -1, -1):
                paginated_bitfield.unset_ots_key(addresses_state, address, i)
                self.assertEqual(address_state.ots_bitfield_used_page, i // config.dev.ots_tracking_per_page)
Example #4
0
    def test_set_ots_key2(self, mock_ots_bitfield_size, mock_ots_tracking_per_page):
        """
        Randomly using OTS key
        :return:
        """
        with set_qrl_dir('no_data'):
            state = State()
            mock_ots_bitfield_size.return_value = ceil(config.dev.ots_tracking_per_page / 8)

            alice_xmss = get_alice_xmss(12)
            address = alice_xmss.address
            address_state = OptimizedAddressState.get_default(address)
            addresses_state = {address: address_state}
            paginated_bitfield = PaginatedBitfield(True, state._db)
            paginated_bitfield.update_used_page_in_address_state(address, addresses_state, 1)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

            ots_indexes = list(range(0, 2**alice_xmss.height))
            random.shuffle(ots_indexes)
            for i in ots_indexes:
                paginated_bitfield.set_ots_key(addresses_state, address, i)
                if i == ots_indexes[-1]:
                    self.assertEqual(address_state.ots_bitfield_used_page, 4)

            self.assertEqual(address_state.ots_bitfield_used_page, 4)
Example #5
0
    def __init__(self, addresses_state: dict, tokens: Indexer, slaves: Indexer,
                 lattice_pk: Indexer, multi_sig_spend_txs: dict,
                 votes_stats: dict, block_number: int, total_coin_supply: int,
                 current_dev_config: DevConfig, write_access: bool, my_db: db,
                 batch):
        self.delete_keys = set()
        self.paginated_bitfield = PaginatedBitfield(write_access, my_db)
        self.paginated_tx_hash = PaginatedData(b'p_tx_hash', write_access,
                                               my_db)
        self.paginated_tokens_hash = PaginatedData(b'p_tokens', write_access,
                                                   my_db)
        self.paginated_slaves_hash = PaginatedData(b'p_slaves', write_access,
                                                   my_db)
        self.paginated_lattice_pk = PaginatedData(b'p_lattice_pk',
                                                  write_access, my_db)
        self.paginated_multisig_address = PaginatedData(
            b'p_multisig_address', write_access, my_db)
        self.paginated_multi_sig_spend = PaginatedData(b'p_multi_sig_spend',
                                                       write_access, my_db)
        self.paginated_inbox_message = PaginatedData(b'p_inbox_message',
                                                     write_access, my_db)

        self.addresses_state = addresses_state

        self.tokens = tokens
        self.slaves = slaves
        self.lattice_pk = lattice_pk
        self.multi_sig_spend_txs = multi_sig_spend_txs
        self.votes_stats = votes_stats
        self.block_number = block_number  # Block number that is being processed
        self.block_reward = int(block_reward(block_number, current_dev_config))
        self.batch = batch
        self.db = my_db
        self.current_dev_config = current_dev_config

        # Keeps track of last update so that it can be reverted
        self.last_addresses_state = dict()
        self.last_tokens = Indexer(b'token', self.db)
        self.last_slaves = Indexer(b'slave', self.db)
        self.last_lattice_pk = Indexer(b'lattice_pk', self.db)
        self.last_multi_sig_spend_txs = dict()
        self.last_votes_stats = dict()

        self._total_coin_supply = total_coin_supply  # TODO: Coinbase transaction of current block is not included
Example #6
0
 def test_load_bitfield_and_ots_key_reuse(self):
     with set_qrl_dir('no_data'):
         state = State()
         alice_xmss = get_alice_xmss(4)
         paginated_bitfield = PaginatedBitfield(True, state._db)
         self.assertFalse(paginated_bitfield.load_bitfield_and_ots_key_reuse(alice_xmss.address,
                                                                             0))
         addresses_state = {
             alice_xmss.address: OptimizedAddressState.get_default(alice_xmss.address)
         }
         paginated_bitfield.set_ots_key(addresses_state, alice_xmss.address, 0)
         self.assertTrue(paginated_bitfield.load_bitfield_and_ots_key_reuse(alice_xmss.address,
                                                                            0))
Example #7
0
    def test_update_used_page_in_address_state2(self, mock_ots_bitfield_size, mock_ots_tracking_per_page):
        mock_ots_bitfield_size.return_value = ceil(config.dev.ots_tracking_per_page / 8)

        alice_xmss = get_alice_xmss(12)
        address = alice_xmss.address
        address_state = OptimizedAddressState.get_default(address)
        addresses_state = {address: address_state}
        paginated_bitfield = PaginatedBitfield(True, self.state._db)
        paginated_bitfield.update_used_page_in_address_state(address, addresses_state, 1)
        self.assertEqual(address_state.ots_bitfield_used_page, 0)

        factor = min(config.dev.ots_tracking_per_page, 2 ** alice_xmss.height)
        for i in range(0, 2 ** alice_xmss.height):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            self.assertEqual(address_state.ots_bitfield_used_page, (i + 1) // factor)

        self.assertEqual(address_state.ots_bitfield_used_page, 4)
Example #8
0
    def test_getOTS(self):
        with set_qrl_dir('no_data'):
            db_state = State()
            alice_xmss = get_alice_xmss()
            optimized_address_state = OptimizedAddressState.create(address=alice_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)
            addresses_state = {optimized_address_state.address: optimized_address_state}
            AddressState.put_addresses_state(db_state, addresses_state)

            p2p_factory = Mock(spec=P2PFactory)
            chain_manager = ChainManager(db_state)

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

            service = PublicAPIService(qrlnode)

            context = Mock(spec=ServicerContext)
            request = qrl_pb2.GetOTSReq(address=alice_xmss.address)
            response = service.GetOTS(request=request, context=context)
            context.set_code.assert_not_called()

            self.assertEqual(0, response.next_unused_ots_index)

            paginated_bitfield = PaginatedBitfield(True, db_state._db)
            paginated_bitfield.set_ots_key(addresses_state, optimized_address_state.address, 0)
            paginated_bitfield.put_addresses_bitfield(None)

            response = service.GetOTS(request=request, context=context)
            context.set_code.assert_not_called()

            self.assertEqual(1, response.next_unused_ots_index)
Example #9
0
    def test_ots_key_reuse(self, mock_ots_bitfield_size, mock_ots_tracking_per_page):
        """
        Randomly using OTS key
        :return:
        """
        with set_qrl_dir('no_data'):
            state = State()

            mock_ots_bitfield_size.return_value = ceil(config.dev.ots_tracking_per_page / 8)
            paginated_bitfield = PaginatedBitfield(True, state._db)

            alice_xmss = get_alice_xmss(12)
            address = alice_xmss.address
            address_state = OptimizedAddressState.get_default(address)
            addresses_state = {address: address_state}
            bitfield_data = paginated_bitfield.get_paginated_data(address, 1)
            self.assertFalse(paginated_bitfield.ots_key_reuse(bitfield_data, 0))

            paginated_bitfield.set_ots_key(addresses_state, address, 0)
            bitfield_data = paginated_bitfield.get_paginated_data(address, 1)
            # False, as bitfield has been set but has not been written to state.
            self.assertFalse(paginated_bitfield.ots_key_reuse(bitfield_data, 0))

            # Writing bitfield to the state.
            paginated_bitfield.put_addresses_bitfield(None)
            bitfield_data = paginated_bitfield.get_paginated_data(address, 1)
            self.assertTrue(paginated_bitfield.ots_key_reuse(bitfield_data, 0))
Example #10
0
    def test_update_used_page_in_address_state4(self, mock_ots_bitfield_size, mock_ots_tracking_per_page):
        mock_ots_bitfield_size.return_value = ceil(config.dev.ots_tracking_per_page / 8)

        alice_xmss = get_alice_xmss(12)
        address = alice_xmss.address
        address_state = OptimizedAddressState.get_default(address)
        addresses_state = {address: address_state}
        paginated_bitfield = PaginatedBitfield(True, self.state._db)
        paginated_bitfield.update_used_page_in_address_state(address, addresses_state, 1)
        self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(2048, 3072):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(1024, 2048):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            self.assertEqual(address_state.ots_bitfield_used_page, 0)

        for i in range(0, 1024):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            if i + 1 == 1024:
                self.assertEqual(address_state.ots_bitfield_used_page, 3)

        for i in range(3072, 2 ** alice_xmss.height):
            paginated_bitfield.set_ots_key(addresses_state, address, i)
            if i + 1 == 2 ** alice_xmss.height:
                self.assertEqual(address_state.ots_bitfield_used_page, 4)
            else:
                self.assertEqual(address_state.ots_bitfield_used_page, 3)

        self.assertEqual(address_state.ots_bitfield_used_page, 4)