Example #1
0
def test_invalid_TraversedPartialPath_untraversed_nibbles(
        invalid_nibbles, node_key, exception, key_encoding):

    if node_key == ():
        node = annotate_node(b'')
    else:
        node = annotate_node([key_encoding(node_key), b'some-val'])

    # Handle special case: leaf nodes are permitted to have the untraversed tail equal the suffix
    if len(node.suffix) > 0 and node.suffix == invalid_nibbles:
        # So in this one case, make sure we don't raise an exception
        TraversedPartialPath((), node, invalid_nibbles)
    else:
        with pytest.raises(exception):
            TraversedPartialPath((), node, invalid_nibbles)
Example #2
0
def test_valid_TraversedPartialPath_traversed_nibbles(valid_nibbles,
                                                      key_encoding):
    some_node_key = (1, 2)
    node = annotate_node([key_encoding(some_node_key), b'random-value'])
    exception = TraversedPartialPath(valid_nibbles, node, some_node_key[:1])
    assert exception.nibbles_traversed == valid_nibbles
    assert str(Nibbles(valid_nibbles)) in repr(exception)
Example #3
0
 def root_node(self) -> HexaryTrieNode:
     try:
         raw_node = self.get_node(self.root_hash)
     except KeyError:
         raise MissingTraversalNode(self.root_hash, nibbles_traversed=())
     else:
         return annotate_node(raw_node)
Example #4
0
def test_valid_TraversedPartialPath_untraversed_nibbles(
        valid_nibbles, key_encoding):
    # This exception means that the actual node key should have more than the untraversed amount
    # So we simulate some longer key for the given node
    longer_key = valid_nibbles + (0, )
    node = annotate_node([key_encoding(longer_key), b'random-value'])
    exception = TraversedPartialPath((), node, valid_nibbles)
    assert exception.untraversed_tail == valid_nibbles
    assert str(Nibbles(valid_nibbles)) in repr(exception)
Example #5
0
def test_TraversedPartialPath_keeps_node_value(key_encoding):
    node_key = (0, 0xf, 9)
    untraversed_tail = node_key[:1]
    remaining_key = node_key[1:]
    node_value = b'unicorns'
    node = annotate_node([key_encoding(node_key), node_value])
    tpp = TraversedPartialPath(node_key, node, untraversed_tail)
    simulated_node = tpp.simulated_node
    assert simulated_node.raw[1] == node_value
    if key_encoding is compute_leaf_key:
        assert simulated_node.sub_segments == ()
        assert simulated_node.suffix == remaining_key
        assert simulated_node.raw[0] == compute_leaf_key(remaining_key)
        assert simulated_node.value == node_value
    elif key_encoding is compute_extension_key:
        assert simulated_node.sub_segments == (remaining_key, )
        assert simulated_node.suffix == ()
        assert simulated_node.raw[0] == compute_extension_key(remaining_key)
    else:
        raise Exception("Unsupported way to encode keys: {key_encoding}")
Example #6
0
    def traverse(self, trie_key_input: NibblesInput) -> HexaryTrieNode:
        """
        Find the node at the path of nibbles provided. The most trivial example is
        to get the root node, using ``traverse(())``.

        :param trie_key_input: the series of nibbles to traverse to arrive at the node of interest
        :return: annotated node at the given path
        :raises MissingTraversalNode: if a node body is missing from the database
        :raises TraversedPartialPath: if trie key extends part-way down an extension or leaf node
        """
        trie_key = Nibbles(trie_key_input)

        node, remaining_key = self._traverse(self.root_hash, trie_key)

        annotated_node = annotate_node(node)

        if remaining_key:
            path_to_node = trie_key[:len(trie_key) - len(remaining_key)]
            raise TraversedPartialPath(path_to_node, annotated_node)
        else:
            return annotated_node
Example #7
0
    def traverse_from(self, parent_node: HexaryTrieNode,
                      trie_key_input: Nibbles) -> HexaryTrieNode:
        """
        Find the node at the path of nibbles provided. You cannot navigate to the root node
        this way (without already having the root node body, to supply as the argument).

        The trie does *not* re-verify the path/hashes from the node prefix to the node.

        :param trie_key_input: the sub-key used to traverse from the given node to the returned node
        :raises MissingTraversalNode: if a node body is missing from the database
        :raises TraversedPartialPath: if trie key extends part-way down an extension or leaf node
        """
        trie_key = Nibbles(trie_key_input)

        node, remaining_key = self._traverse_from(parent_node.raw, trie_key)

        annotated_node = annotate_node(node)

        if remaining_key:
            path_to_node = trie_key[:len(trie_key) - len(remaining_key)]
            raise TraversedPartialPath(path_to_node, annotated_node)
        else:
            return annotated_node
Example #8
0
def test_invalid_TraversedPartialPath_nibbles(invalid_nibbles, exception):
    with pytest.raises(exception):
        TraversedPartialPath(invalid_nibbles, annotate_node(b''))