def test_generate_bitfield_key(self): with set_xrd_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)
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_xrd_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)
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)
def test_set_ots_key2(self, mock_ots_bitfield_size, mock_ots_tracking_per_page): """ Randomly using OTS key :return: """ with set_xrd_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)
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)
def test_load_bitfield_and_ots_key_reuse(self): with set_xrd_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))
def test_getOTS(self): with set_xrd_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) xrdnode = xrdNode(mining_address=b'') xrdnode.set_chain_manager(chain_manager) xrdnode._p2pfactory = p2p_factory xrdnode._peer_addresses = ['127.0.0.1', '192.168.1.1'] service = PublicAPIService(xrdnode) context = Mock(spec=ServicerContext) request = xrd_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)
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)
def test_ots_key_reuse(self, mock_ots_bitfield_size, mock_ots_tracking_per_page): """ Randomly using OTS key :return: """ with set_xrd_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))