def test_hexary_trie_missing_traversal_node(): db = {} trie = HexaryTrie(db, prune=True) key1 = to_bytes(0x0123) trie.set( key1, b'use a value long enough that it must be hashed according to trie spec' ) key2 = to_bytes(0x1234) trie.set(key2, b'val2') # delete first child of the root root_node = trie.root_node.raw first_child_hash = root_node[0] del db[first_child_hash] # Get exception with relevant info about lookup nibbles with pytest.raises(MissingTraversalNode) as exc_info: trie.traverse((0, 1, 2, 3)) exception = exc_info.value assert exception.nibbles_traversed == (0, ) assert encode_hex(first_child_hash) in str(exception) # Other keys are still traversable node = trie.traverse((1, )) assert node.value == b'val2' assert node.sub_segments == ()
def test_hexary_trie_root_node_annotation(): trie = HexaryTrie({}) trie[b'\x41A'] = b'LONG' * 32 trie[b'\xffE'] = b'LONG' * 32 root = trie.root_node assert root == trie.traverse(())
def test_traverse_into_partial_path(trie_items, traverse_key, path_to_node, sub_segments, node_val): """ What happens when you try to traverse into an extension or leaf node """ db = {} trie = HexaryTrie(db) for key, val in trie_items: trie[key] = val with pytest.raises(TraversedPartialPath) as excinfo: trie.traverse(traverse_key) exc = excinfo.value assert exc.nibbles_traversed == path_to_node assert exc.node.sub_segments == sub_segments assert exc.node.value == node_val
def test_traverse_non_matching_leaf(): trie = HexaryTrie({}) EMPTY_NODE = trie.root_node trie[b'\xFFleaf-at-root'] = b'some-value' final_root = trie.root_node # Traversing partway into the leaf raises the TraversedPartialPath exception with pytest.raises(TraversedPartialPath): trie.traverse((0xf, )) with pytest.raises(TraversedPartialPath): trie.traverse_from(final_root, (0xf, )) # But traversing to any *non*-matching nibble should return a blank node, because no # children reside underneath that nibble. Returning the leaf with a mismatched nibble # would be a bug. for nibble in range(0xf): # Note that we do not want to look at the 0xf nibble, because that's the one that # should raise the exception above assert trie.traverse((nibble, )) == EMPTY_NODE assert trie.traverse_from(final_root, (nibble, )) == EMPTY_NODE