Skip to content

Commit

Permalink
Merge pull request #31 from NIC619/bintrie_update
Browse files Browse the repository at this point in the history
Bintrie update on key-being-prefix-of-another-key problem
  • Loading branch information
pipermerriam authored Jan 26, 2018
2 parents 0acd574 + 60eeb74 commit 4b78035
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 8 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ True
False
```

## BinaryTrie
- Note: One drawback of Binary Trie is that **one key can not be the prefix of another key**. For example,
if you already set the value `value1` with key `key1`, you can not set another value with key `key` or `key11`
and the like.

### BinaryTrie branch and witness helper functions

```python
Expand Down
6 changes: 3 additions & 3 deletions tests/test_bin_trie.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
BLANK_HASH,
)
from trie.exceptions import (
LeafNodeOverrideError,
NodeOverrideError,
)


Expand Down Expand Up @@ -67,7 +67,7 @@ def test_bin_trie_delete_subtrie(kv1, kv2, key_to_be_deleted, will_delete, will_
assert trie.root_hash == BLANK_HASH
else:
if will_rasie_error:
with pytest.raises(LeafNodeOverrideError):
with pytest.raises(NodeOverrideError):
trie.delete_subtrie(key_to_be_deleted)
else:
root_hash_before_delete = trie.root_hash
Expand All @@ -94,7 +94,7 @@ def test_bin_trie_invalid_key(invalide_key, if_error):

assert trie.get(invalide_key) is None
if if_error:
with pytest.raises(LeafNodeOverrideError):
with pytest.raises(NodeOverrideError):
trie.delete(invalide_key)
else:
previous_root_hash = trie.root_hash
Expand Down
16 changes: 12 additions & 4 deletions trie/binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
validate_is_bin_node,
)
from trie.exceptions import (
LeafNodeOverrideError,
NodeOverrideError,
)

from trie.utils.sha3 import (
Expand Down Expand Up @@ -116,9 +116,9 @@ def _set(self, node_hash, keypath, value, if_delete_subtrie=False):
if nodetype == LEAF_TYPE:
# Keypath must match, there should be no remaining keypath
if keypath:
raise LeafNodeOverrideError(
"Existing kv pair is being effaced because"
" it's key is the prefix of the new key")
raise NodeOverrideError(
"Fail to set the value because the prefix of it's key"
" is the same as existing key")
if if_delete_subtrie:
return BLANK_HASH
return self._hash_and_save(encode_leaf_node(value)) if value else BLANK_HASH
Expand Down Expand Up @@ -211,6 +211,10 @@ def _set_kv_node(
# Case 2: keypath prefixes mismatch in the middle, so we need to break
# the keypath in half. We are in case (3), (4), (7), (8)
else:
if len(keypath[common_prefix_len + 1:]) == 0:
raise NodeOverrideError(
"Fail to set the value because it's key"
" is the prefix of other existing key")
valnode = self._hash_and_save(
encode_kv_node(
keypath[common_prefix_len + 1:],
Expand Down Expand Up @@ -256,6 +260,10 @@ def _set_branch_node(
if_delete_subtrie=False):
# Which child node to update? Depends on first bit in keypath
if keypath[:1] == BYTE_0:
if len(keypath[1:]) == 0:
raise NodeOverrideError(
"Fail to set the value because it's key"
" is the prefix of other existing key")
new_left_child = self._set(left_child, keypath[1:], value, if_delete_subtrie)
new_right_child = right_child
else:
Expand Down
2 changes: 1 addition & 1 deletion trie/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class BadTrieProof(Exception):
pass


class LeafNodeOverrideError(Exception):
class NodeOverrideError(Exception):
pass


Expand Down

0 comments on commit 4b78035

Please sign in to comment.