def _normalize_branch_node(self, node): """ A branch node which is left with only a single non-blank item should be turned into either a leaf or extension node. """ iter_node = iter(node) if any(iter_node) and any(iter_node): return node if node[16]: return [compute_leaf_key([]), node[16]] sub_node_idx, sub_node_hash = next( (idx, v) for idx, v in enumerate(node[:16]) if v) sub_node = self.get_node(sub_node_hash) sub_node_type = get_node_type(sub_node) self._prune_node(sub_node) if sub_node_type in {NODE_TYPE_LEAF, NODE_TYPE_EXTENSION}: new_subnode_key = encode_nibbles( tuple( itertools.chain( [sub_node_idx], decode_nibbles(sub_node[0]), ))) return [new_subnode_key, sub_node[1]] elif sub_node_type == NODE_TYPE_BRANCH: subnode_hash = self._persist_node(sub_node) return [encode_nibbles([sub_node_idx]), subnode_hash] else: raise Exception("Invariant: this code block should be unreachable")
def serialize(self) -> bytes: # encode nibbles to a bytes value, to compress this down a bit prefixes = [ encode_nibbles(nibbles) for nibbles in self._unexplored_prefixes ] return f"HexaryTrieFog:{prefixes!r}".encode()
def _delete_kv_node(self, node, trie_key): current_key = extract_key(node) if not key_starts_with(trie_key, current_key): # key not present?.... return node node_type = get_node_type(node) if node_type == NODE_TYPE_LEAF: if trie_key == current_key: return BLANK_NODE else: return node sub_node_key = trie_key[len(current_key):] sub_node = self.get_node(node[1]) new_sub_node = self._delete(sub_node, sub_node_key) encoded_new_sub_node = self._persist_node(new_sub_node) if encoded_new_sub_node == node[1]: return node if new_sub_node == BLANK_NODE: return BLANK_NODE new_sub_node_type = get_node_type(new_sub_node) if new_sub_node_type in {NODE_TYPE_LEAF, NODE_TYPE_EXTENSION}: self._prune_node(new_sub_node) new_key = current_key + decode_nibbles(new_sub_node[0]) return [encode_nibbles(new_key), new_sub_node[1]] if new_sub_node_type == NODE_TYPE_BRANCH: return [encode_nibbles(current_key), encoded_new_sub_node] raise Exception("Invariant, this code path should not be reachable")