def test_proof_prefix_only_prefix_nodes(): node_trie = Trie(PersistentDB(KeyValueStorageInMemory())) client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) prefix = 'abcdefgh' keys_suffices = set() while len(keys_suffices) != 20: keys_suffices.add(randint(25, 25000)) key_vals = {'{}{}'.format(prefix, k): str(randint(3000, 5000)) for k in keys_suffices} for k, v in key_vals.items(): node_trie.update(k.encode(), rlp_encode([v])) proof_nodes, val = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=True) encoded = {k.encode(): rlp_encode([v]) for k, v in key_vals.items()} # Check returned values match the actual values assert encoded == val assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Check without value proof_nodes = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=False) assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes)
def test_proof_multiple_prefix_nodes(): node_trie = Trie(PersistentDB(KeyValueStorageInMemory())) prefix_1 = 'abcdefgh' prefix_2 = 'abcdefxy' # Prefix overlaps with previous prefix_3 = 'pqrstuvw' prefix_4 = 'mnoptuvw' # Suffix overlaps all_prefixes = (prefix_1, prefix_2, prefix_3, prefix_4) other_nodes_count = 1000 prefix_nodes_count = 100 # Some nodes before prefix nodes for _ in range(other_nodes_count): k, v = randomString(randint(8, 19)).encode(), rlp_encode( [randomString(15)]) node_trie.update(k, v) keys_suffices = set() while len(keys_suffices) != prefix_nodes_count: keys_suffices.add(randint(25, 250000)) key_vals = { '{}{}'.format(prefix, k): str(randint(3000, 5000)) for prefix in all_prefixes for k in keys_suffices } for k, v in key_vals.items(): node_trie.update(k.encode(), rlp_encode([v])) # Some nodes after prefix nodes for _ in range(other_nodes_count): node_trie.update( randomString(randint(8, 19)).encode(), rlp_encode([randomString(15)])) for prefix in all_prefixes: client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) proof_nodes, val = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=True) encoded = { k.encode(): rlp_encode([v]) for k, v in key_vals.items() if k.startswith(prefix) } # Check returned values match the actual values assert encoded == val assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Check without value proof_nodes = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=False) assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Verify keys with a different prefix encoded = { k.encode(): rlp_encode([v]) for k, v in key_vals.items() if not k.startswith(prefix) } assert not client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes)
def test_proof_prefix_only_prefix_nodes(): node_trie = Trie(PersistentDB(KeyValueStorageInMemory())) client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) prefix = 'abcdefgh' keys_suffices = set() while len(keys_suffices) != 20: keys_suffices.add(randint(25, 25000)) key_vals = { '{}{}'.format(prefix, k): str(randint(3000, 5000)) for k in keys_suffices } for k, v in key_vals.items(): node_trie.update(k.encode(), rlp_encode([v])) proof_nodes, val = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=True) encoded = {k.encode(): rlp_encode([v]) for k, v in key_vals.items()} # Check returned values match the actual values assert encoded == val assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Check without value proof_nodes = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=False) assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes)
def test_proof_multiple_prefix_nodes(): node_trie = Trie(PersistentDB(KeyValueStorageInMemory())) prefix_1 = 'abcdefgh' prefix_2 = 'abcdefxy' # Prefix overlaps with previous prefix_3 = 'pqrstuvw' prefix_4 = 'mnoptuvw' # Suffix overlaps all_prefixes = (prefix_1, prefix_2, prefix_3, prefix_4) other_nodes_count = 1000 prefix_nodes_count = 100 # Some nodes before prefix nodes for _ in range(other_nodes_count): k, v = randomString(randint(8, 19)).encode(), rlp_encode([randomString(15)]) node_trie.update(k, v) keys_suffices = set() while len(keys_suffices) != prefix_nodes_count: keys_suffices.add(randint(25, 250000)) key_vals = {'{}{}'.format(prefix, k): str(randint(3000, 5000)) for prefix in all_prefixes for k in keys_suffices} for k, v in key_vals.items(): node_trie.update(k.encode(), rlp_encode([v])) # Some nodes after prefix nodes for _ in range(other_nodes_count): node_trie.update(randomString(randint(8, 19)).encode(), rlp_encode([randomString(15)])) for prefix in all_prefixes: client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) proof_nodes, val = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=True) encoded = {k.encode(): rlp_encode([v]) for k, v in key_vals.items() if k.startswith(prefix)} # Check returned values match the actual values assert encoded == val assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Check without value proof_nodes = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=False) assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Verify keys with a different prefix encoded = {k.encode(): rlp_encode([v]) for k, v in key_vals.items() if not k.startswith(prefix)} assert not client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes)
def test_proof_prefix_with_other_nodes(): node_trie = Trie(PersistentDB(KeyValueStorageInMemory())) client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) prefix = 'abcdefgh' other_nodes_count = 1000 prefix_nodes_count = 100 # Some nodes before prefix node for _ in range(other_nodes_count): node_trie.update( randomString(randint(8, 19)).encode(), rlp_encode([randomString(15)])) keys_suffices = set() while len(keys_suffices) != prefix_nodes_count: keys_suffices.add(randint(25, 250000)) key_vals = { '{}{}'.format(prefix, k): str(randint(3000, 5000)) for k in keys_suffices } for k, v in key_vals.items(): node_trie.update(k.encode(), rlp_encode([v])) # Some nodes after prefix node for _ in range(other_nodes_count): node_trie.update( randomString(randint(8, 19)).encode(), rlp_encode([randomString(15)])) proof_nodes, val = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=True) encoded = {k.encode(): rlp_encode([v]) for k, v in key_vals.items()} # Check returned values match the actual values assert encoded == val assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Check without value proof_nodes = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=False) assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Change value of one of any random key encoded_new = deepcopy(encoded) random_key = next(iter(encoded_new.keys())) encoded_new[random_key] = rlp_encode( [rlp_decode(encoded_new[random_key])[0] + b'2212']) assert not client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded_new, proof_nodes)
def test_proof_prefix_with_other_nodes(): node_trie = Trie(PersistentDB(KeyValueStorageInMemory())) client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) prefix = 'abcdefgh' other_nodes_count = 1000 prefix_nodes_count = 100 # Some nodes before prefix node for _ in range(other_nodes_count): node_trie.update(randomString(randint(8, 19)).encode(), rlp_encode([randomString(15)])) keys_suffices = set() while len(keys_suffices) != prefix_nodes_count: keys_suffices.add(randint(25, 250000)) key_vals = {'{}{}'.format(prefix, k): str(randint(3000, 5000)) for k in keys_suffices} for k, v in key_vals.items(): node_trie.update(k.encode(), rlp_encode([v])) # Some nodes after prefix node for _ in range(other_nodes_count): node_trie.update(randomString(randint(8, 19)).encode(), rlp_encode([randomString(15)])) proof_nodes, val = node_trie.generate_state_proof_for_keys_with_prefix(prefix.encode(), get_value=True) encoded = {k.encode(): rlp_encode([v]) for k, v in key_vals.items()} # Check returned values match the actual values assert encoded == val assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Check without value proof_nodes = node_trie.generate_state_proof_for_keys_with_prefix( prefix.encode(), get_value=False) assert client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded, proof_nodes) # Change value of one of any random key encoded_new = deepcopy(encoded) random_key = next(iter(encoded_new.keys())) encoded_new[random_key] = rlp_encode([rlp_decode(encoded_new[random_key])[0] + b'2212']) assert not client_trie.verify_spv_proof_multi(node_trie.root_hash, encoded_new, proof_nodes)
def verify_state_proof_multi(root, key_values, proof_nodes, serialized=False): encoded_key_values = dict( PruningState.encode_kv_for_verification(k, v) for k, v in key_values.items()) return Trie.verify_spv_proof_multi(root, encoded_key_values, proof_nodes, serialized)
def test_proof_prefix_only_prefix_nodes(): node_trie = Trie(PersistentDB(KeyValueStorageInMemory())) client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) prefix = 'abcdefgh' keys_suffices = set() while len(keys_suffices) != 20: keys_suffices.add(randint(25, 25000)) key_vals = {'{}{}'.format(prefix, k): str(randint(3000, 5000)) for k in keys_suffices} for k, v in key_vals.items(): node_trie.update(k.encode(), rlp_encode([v])) proof_nodes = node_trie.generate_state_proof_for_key_prfx(prefix.encode()) assert client_trie.verify_spv_proof_multi(node_trie.root_hash, {k.encode(): rlp_encode([v]) for k, v in key_vals.items()}, proof_nodes)
def test_state_proof(public_minting, looper, # noqa sdk_pool_handle, sdk_wallet_client, seller_token_wallet, seller_address, user1_token_wallet, user1_address): res = send_get_utxo(looper, seller_address, sdk_wallet_client, sdk_pool_handle) update_token_wallet_with_result(seller_token_wallet, res) # Do 20 XFER txns for _ in range(20): utxos = [_ for lst in seller_token_wallet.get_all_wallet_utxos().values() for _ in lst] seq_no, amount = utxos[0] inputs = [[seller_token_wallet, seller_address, seq_no]] outputs = [{"address": user1_address, "amount": 1}, {"address": seller_address, "amount": amount-1}] res = send_xfer(looper, inputs, outputs, sdk_pool_handle) update_token_wallet_with_result(seller_token_wallet, res) res = send_get_utxo(looper, seller_address, sdk_wallet_client, sdk_pool_handle) update_token_wallet_with_result(seller_token_wallet, res) res = send_get_utxo(looper, user1_address, sdk_wallet_client, sdk_pool_handle) update_token_wallet_with_result(user1_token_wallet, res) res = send_get_utxo(looper, user1_address, sdk_wallet_client, sdk_pool_handle) # Check presence of state proof assert res[STATE_PROOF] encoded = {} outputs = res[OUTPUTS] for out in outputs: state_key = TokenStaticHelper.create_state_key(out["address"], out["seqNo"]) encoded[state_key] = rlp_encode([str(out["amount"])]) proof_nodes = decode_proof(res[STATE_PROOF][PROOF_NODES]) client_trie = Trie(PersistentDB(KeyValueStorageInMemory())) assert client_trie.verify_spv_proof_multi( state_roots_serializer.deserialize(res[STATE_PROOF][ROOT_HASH]), encoded, proof_nodes)
def verify_state_proof_multi(root, key_values, proof_nodes, serialized=False): encoded_key_values = dict(PruningState.encode_kv_for_verification(k, v) for k, v in key_values.items()) return Trie.verify_spv_proof_multi(root, encoded_key_values, proof_nodes, serialized)
def verify_state_proof_multi(root, key_values, proof_nodes, serialized=False): encoded_key_values = {k: rlp_encode([v]) if v is not None else b'' for k, v in key_values.items()} return Trie.verify_spv_proof_multi(root, encoded_key_values, proof_nodes, serialized)