Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Switch to shiny new fast, RLP-less trie #795

Merged
merged 21 commits into from
Sep 25, 2018
Merged

Switch to shiny new fast, RLP-less trie #795

merged 21 commits into from
Sep 25, 2018

Conversation

gavofyork
Copy link
Member

@gavofyork gavofyork commented Sep 24, 2018

Closes #664

Also expunges RLP from the codebase. There's not really any new logic outside of the substrate-trie crate.

The codebase is no longer generic over NodeCodec; the reason for this twofold: firstly, trie node format allows for much less opinionated selection than the hashing algorithm. Formats do not significantly change in terms of security. Performance tweaks are non-controversial and are easily folded in over time. Secondly, it would require a two generic parameters, not one as before.

@rphmeier rphmeier added the A3-in_progress Pull request is in progress. No review needed at this stage. label Sep 24, 2018
assert_eq!(changes_trie_nodes, Some(vec![
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]),
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]),
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]),

InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@svyatonik I had to change this to make the tests work. any idea why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gavofyork I'm getting an error "Error while iterating by prefix: Database missing expected key: 0x9500103000000000000000464cfe10021c011404000000001c01140401000000" here. So:

  1. too bad that this error is discarded - will note this && prepare PR when other is done;
  2. this seems like a similar issue when we have moved from KeccakHasher to Blake2Hasher, but this time I'm not sure where this constant cames from (probably it is in )

That said, this change ([1, 3] -> [1] + similar) is wrong.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok if it's an issue with the iterator, then it would be good to have a test where i can reproduce it...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's the test: 93e13a8

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. that's fixed now, but the fix didn't invalidate the changes here...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nm false alarm. tests confirm fix.

InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]),
InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]),
InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@svyatonik here, too

assert_eq!(changes_trie_nodes, Some(vec![
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![100] }, vec![0, 2, 3]),
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![101] }, vec![1]),
InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 4, key: vec![103] }, vec![0, 1]),

InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1, 3]),
InputPair::DigestIndex(DigestIndex { block: 4, key: vec![100] }, vec![1]),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@svyatonik ...and here...

InputPair::DigestIndex(DigestIndex { block: 4, key: vec![101] }, vec![1]),
InputPair::DigestIndex(DigestIndex { block: 4, key: vec![102] }, vec![2]),
InputPair::DigestIndex(DigestIndex { block: 4, key: vec![105] }, vec![1, 3]),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@svyatonik ...and here

@gavofyork
Copy link
Member Author

@svyatonik quite a few of the change-trie tests include raw roots. there's little i can do except to replace with the expected root. i don't know how to ensure these trie changes haven't broken their logic.

@svyatonik
Copy link
Contributor

@gavofyork The same is true for Header::state_root - it always changes when storage is altered => https://github.com/paritytech/substrate/blob/master/node/executor/src/lib.rs is updated often too. I'll take a look at the reason of "I had to change this to make the tests work. any idea why?", but generally I assume that the same steps should be taken with changes_trie_root.

@gavofyork gavofyork added A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Sep 24, 2018
@gavofyork
Copy link
Member Author

@svyatonik yeah the hashes i'm less bothered about (though it is rather tedious). however, those four changes i pointed to above are switching out some of the structure's values, which is concerning.

@@ -0,0 +1,635 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs are missing in this file/crate

}

/*
// TODO: Remove
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

committing commented code

use trie_standardmap::{Alphabet, ValueMode, StandardMap};

fn check_equivalent(input: &Vec<(&[u8], &[u8])>) {
/* {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too

twox-hash = "1.1.0"
lazy_static = "1.0"
parking_lot = "*"
log = "0.3"
hashdb = "0.2.1"
hash-db = { git = "https://github.com/paritytech/trie" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kind of unfortunate that we are moving back off of crates.io deps and into GitHub land

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once it stablises (i.e. sometime between now and 1.0 final), i'm happy to publish and move back.

fn leaf_node(partial: &[u8], value: &[u8]) -> Vec<u8> {
let mut output = partial_to_key(partial, LEAF_NODE_OFFSET, LEAF_NODE_BIG);
value.encode_to(&mut output);
// println!("leaf_node: {:#x?}", output);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stray println commented here

ChildReference::Inline(inline_data, len) =>
(&AsRef::<[u8]>::as_ref(&inline_data)[..len]).encode_to(&mut output),
};
// println!("ext_node: {:#x?}", output);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

None => false,
}));
output[0..3].copy_from_slice(&prefix[..]);
// println!("branch_node: {:#x?}", output);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here

// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

//! `NodeCodec` implementation for Rlp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this "alt" implementation for RLP for Parity Codec?

@@ -0,0 +1,2 @@
This crate provides utility functions to validate and initialize tries using flexible input.
It is used extensively in `parity-ethereum` to validate blocks (mostly transactions and receipt roots).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks irrelevant.

Null,
Branch(bool),
Extension(usize),
Leaf(usize),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usize? Is it supposed to be platform-dependent? u32 should probably enough

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is mostly being assigned/compared to sizes of Vecs and has a custom Decode/Encode. switching to u32 would necessitate most casting but wouldn't provide any material benefit.

@@ -0,0 +1,421 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs updating?

@arkpar arkpar merged commit e4c07ba into master Sep 25, 2018
@arkpar arkpar deleted the gav-compact branch September 25, 2018 14:32
@@ -0,0 +1,2 @@
This crate provides utility functions to validate and initialize tries using flexible input.
It is used extensively in `parity-ethereum` to validate blocks (mostly transactions and receipt roots).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to remove this line.

}

/// Determine a trie root node's data given its ordered contents, closed form.
pub fn unhashed_trie<H: Hasher, I, A, B>(input: I) -> Vec<u8> where
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this method used for anything outside tests?

// NOTE: what we'd really like here is:
// `impl<H: Hasher> NodeCodec<H> for RlpNodeCodec<H> where H::Out: Decodable`
// but due to the current limitations of Rust const evaluation we can't
// do `const HASHED_NULL_NODE: H::Out = H::Out( … … )`. Perhaps one day soon?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is probably not helpful anymore.

_ => {
// println!("[append_substream] would have hashed, because data.len() = {}", data.len());
// data.encode_to(&mut self.buffer)
// TODO: re-enable hashing before merging
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some cleanup to do in this file.

liuchengxu pushed a commit to chainx-org/substrate that referenced this pull request Aug 23, 2021
helin6 pushed a commit to boolnetwork/substrate that referenced this pull request Jul 25, 2023
* Remove Cargo.lock from gitignore

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cargo: Add `Cargo.lock`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update the releasing process

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants