-
Notifications
You must be signed in to change notification settings - Fork 72
Trie without extension node #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Note about // branch = value - 1 in extension size -> val 85 branch 84
const EMPTY_TRIE: u8 = 0;
const LEAF_NODE_OFFSET: u8 = 1; // (1 to 86) = max nbl l 85
const BRANCH_NODE_NODE_OFFSET: u8 = 87; // (87 to 171) max 84
const BRANCH_NODE_WITH_VALUE_OFFSET: u8 = 172; // (172 to 255) max 84Problem, some scheme in substrate (double storage map) requires length > 32 bytes (from current code there is a 8 bit prefix + 128 bit twox hash + 256 bit blake so a nibble length of 96 (more than the 85 allowed above)). |
are currently broken, expect lot of non working things to.
(probably some shifting to analyze)
And an additional malleability safe guard. Tests involving `Lookup` are currently broken.
specific constant that will be use for merging code of NoExt with previous one. Furthermore could be use in multitrie implementation (no constant use but fn ). Currently only done for Mut (non mut will wait to see if merging goes well).
benefit from constant.
awkward for some unresolved types.
|
@cheme when you're certain that both all the reported issues, and the typical issues (bad naming, missing docs, low-quality docs) are fixed, please ping @arkpar and @svyatonik to get a final review. |
|
@arkpar, @svyatonik I went other bad naming and try to go over the doc again this morning. There is still things I can do to reduce code review size:
|
|
@cheme please remove as much as you can to keep the review size down |
|
@arkpar @svyatonik would be great if we could get this reviewed again |
And replacing ReferenceError by CodecError.
|
Fuzzing and benching may be left as is. |
Using 'GenericNoExtensionLayout' for 'NoExtensionLayout'.
|
@cheme couple of questions there... @arkpar @svyatonik are you guys ok with the PR otherwise? |
trie-db/src/nibble/mod.rs
Outdated
| pub fn biggest_depth(v1: &[u8], v2: &[u8]) -> usize { | ||
| // sorted assertion preventing out of bound | ||
| for a in 0..v1.len() { | ||
| if v1[a] == v2[a] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that always correct that v1.len() <= v2.len() (otherwise it'll panic)? I have found the only usage of the biggest_depth() from the trie_visit(). I assume that input there is ordered in some manner? If it sorted using BTreeMap, then given that e.g. vec![5, ,5] < vec![20], this could panic, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact there is no verification of the ordering, iter_build code does not support unordered input.
I can prevent this failing, but I will need to propagate the error, that seems pretty quick to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry - I mean that even if input is ordered (lexicographically, I suppose), then this could panic, because lexicographically vec of larger len could came before vec of smaller len. No need to propagate error imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes (I just realized, I just got to min the loop bound).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I think you also need to update this line: return v1.len() * NIBBLE_PER_BYTE; below to use cmp::min() instead of v1.len())
|
I've verified that the implementation matches the spec and there's sufficient test coverage. So "looksgood" from me. |
This PR implement new codec spec from polkadot-re-spec:
The main change is the removal of trie extension node. This is triggered by switching an associated constant in
TrieLayout.Other changes are:
I did rework nibbleslice a bit: replacing
encodebyleftandright.basically encode was copying and aligning bytes, this is mostly starting from
the spec description.
Prefixand is encoded with padding at the end whennumber of nibble does not fit
this is used for prefix for key db : this is a breaking change but it got the nice property to allow iteration on key in db (for contract child trie for instance where we only got key of contract or in case kvdb evolves to allow collection specifics).
Also note that this change in prefix also include the number of padding (needed to iterate correctly).
Partialthis is similar to existing naming of variable andis what is encoded into trie nodes: the padding is at start.
This allow leaf to avoid shifting bytes for its partial. That is not the case for branch.
I believe leaf is more prone to use long partial (especially if key is resulting from a hash).
Actually the optional last bytes is (u8,u8) to allow other layout.
Note that some of the code could revert to slower usage of
atfunction to be easier to code check.It also solve the existing TODO about removing header from encoding (see code in
ethereum branch where a code impact is visible (in substrate it is all fine)).
An enveloppe trait over the trie layout to keep all implementation details at one place.
It also use experimental (few test) alternate trie layout (other radix only for aligned key and in a single byte
which limit to 4 variant).
iter_build algorithm
I write this at a time I did not see
trie_rootcrate, I included it in the PR as I think it is not really hard to maintain and I used it a lot in testing.Note that this PR does not update
trie_rootto use TrieLayOuttest branch from other project
https://github.com/cheme/parity-ethereum/tree/simple-codec : there are quite some change in codec, mainly related to the removal of nibble hpe
https://github.com/cheme/substrate/tree/simple-codec