Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
22b8699
validation extension in sp_io
cheme Jan 27, 2021
4de9f7a
need paths
cheme Jan 27, 2021
f0ea2af
arc impl
cheme Jan 27, 2021
71202a9
missing host function in executor
cheme Jan 28, 2021
f848b44
io to pkdot
cheme Feb 1, 2021
1979b6a
decode function.
cheme Feb 1, 2021
927a096
encode primitive.
cheme Feb 1, 2021
b034ec0
trailing tab
cheme Feb 1, 2021
757ff30
multiple patch
cheme Feb 1, 2021
7dba01b
fix child trie logic
cheme Feb 2, 2021
1a2a637
Merge branch 'master' into validation_io, and revert skip value specific
cheme Apr 8, 2021
c948254
Merge branch 'master' into validation_io
cheme Apr 8, 2021
7ef5a41
restore master versionning
cheme Apr 8, 2021
360c324
bench compact proof size
cheme Apr 8, 2021
4edc38a
trie-db 22.3 is needed
cheme Apr 8, 2021
6f899c0
line width
cheme Apr 8, 2021
d3eb91c
split line
cheme Apr 8, 2021
4475edd
fixes for bench (additional root may not be needed as original issue was
cheme Apr 9, 2021
e6e4682
Merge branch 'master' into validation_io
cheme May 3, 2021
dba397c
Merge branch 'validation_io' of github.com:cheme/substrate into valid…
cheme May 3, 2021
c0fc8fd
revert compact from block size calculation.
cheme May 3, 2021
8f353dd
Merge branch 'master' into validation_io
cheme May 28, 2021
7ebb54d
Merge branch 'master' into validation_io
cheme Jun 4, 2021
bf91187
New error type for compression.
cheme Jun 4, 2021
c37046e
Adding test (incomplete (failing)).
cheme Jun 4, 2021
7daabb3
Merge branch 'master' into validation_io
cheme Jun 4, 2021
cfd923a
There is currently no proof recording utility in sp_trie, removing
cheme Jun 4, 2021
f25fc34
small test of child root in proof without a child proof.
cheme Jun 4, 2021
19c132e
remove empty test.
cheme Jun 6, 2021
515c2fd
remove non compact proof size
cheme Jun 6, 2021
8aadbf1
Merge branch 'master' into validation_io
cheme Jun 6, 2021
f867d7f
Missing revert.
cheme Jun 6, 2021
d639940
proof method to encode decode.
cheme Jun 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
decode function.
  • Loading branch information
cheme committed Feb 1, 2021
commit 1979b6a2e2f34be00f4f27572453beea811e4a70
8 changes: 3 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,7 @@ zeroize = { opt-level = 3 }
[profile.release]
# Substrate runtime requires unwinding.
panic = "unwind"

[patch.crates-io]
trie-db = { git = 'https://github.com/cheme/trie', branch = 'skip_compact_values_alt' }
hash-db = { git = 'https://github.com/cheme/trie', branch = 'skip_compact_values_alt' }
2 changes: 1 addition & 1 deletion primitives/trie/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ harness = false
codec = { package = "parity-scale-codec", version = "1.3.6", default-features = false }
sp-std = { version = "2.0.0", default-features = false, path = "../std" }
hash-db = { version = "0.15.2", default-features = false }
trie-db = { version = "0.22.2", default-features = false }
trie-db = { version = "0.22.3", default-features = false }
trie-root = { version = "0.16.0", default-features = false }
memory-db = { version = "0.25.0", default-features = false }
sp-core = { version = "2.0.0", default-features = false, path = "../core" }
Expand Down
5 changes: 5 additions & 0 deletions primitives/trie/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mod error;
mod node_header;
mod node_codec;
mod storage_proof;
mod trie_codec;
mod trie_stream;

use sp_std::{boxed::Box, marker::PhantomData, vec::Vec, borrow::Borrow};
Expand All @@ -39,12 +40,16 @@ pub use storage_proof::StorageProof;
/// Various re-exports from the `trie-db` crate.
pub use trie_db::{
Trie, TrieMut, DBValue, Recorder, CError, Query, TrieLayout, TrieConfiguration, nibble_ops, TrieDBIterator,
LazyFetcher,
};
/// Various re-exports from the `memory-db` crate.
pub use memory_db::KeyFunction;
pub use memory_db::prefixed_key;
/// Various re-exports from the `hash-db` crate.
pub use hash_db::{HashDB as HashDBT, EMPTY_PREFIX};
/// Trie codec reexport, mainly child trie support
/// for trie compact proof.
pub use trie_codec::{decode_compact};

#[derive(Default)]
/// substrate trie layout
Expand Down
140 changes: 140 additions & 0 deletions primitives/trie/src/trie_codec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// This file is part of Substrate.

// Copyright (C) 2015-2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Compact proof support.
//!
//! This uses compact proof from trie crate and extends
//! it to substrate specific layout and child trie system.

use crate::{EMPTY_PREFIX, HashDBT, LazyFetcher,
TrieHash, TrieError, TrieConfiguration};

type VerifyError<L> = crate::VerifyError<TrieHash<L>, Box<TrieError<L>>>;

fn verify_error<L: TrieConfiguration>(error: Box<TrieError<L>>) -> VerifyError<L> {
VerifyError::<L>::DecodeError(error)
}

/// Decode a compact proof.
///
/// Takes as input a destination `db` for decoded node and `encoded`
/// an iterator of compact encoded nodes.
///
/// Also allows optionally injecting specified value in
/// top trie proof with `know_keys` and the lazy
/// associated `fetcher`.
///
/// Child trie are decoded in order of child trie root present
/// in the top trie.
pub fn decode_compact<'a, L, DB, I, F, K>(
db: &mut DB,
encoded: I,
fetcher: F,
known_keys: Option<K>,
expected_root: Option<&TrieHash<L>>,
) -> Result<TrieHash<L>, VerifyError<L>>
where
L: TrieConfiguration,
DB: HashDBT<L::Hash, trie_db::DBValue> + hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
I: IntoIterator<Item = &'a [u8]>,
F: LazyFetcher<'a>,
K: IntoIterator<Item = &'a [u8]>,
{
let mut nodes_iter = encoded.into_iter();
let (top_root, _nb_used) = if let Some(known_keys) = known_keys {
trie_db::decode_compact_with_known_values::<L, _, _, _, _, _>(
db,
&mut nodes_iter,
fetcher,
known_keys,
false, // current use of compact do to escape empty value.
).map_err(verify_error::<L>)?
} else {
trie_db::decode_compact_from_iter::<L, _, _, _>(
db,
&mut nodes_iter,
).map_err(verify_error::<L>)?
};

if let Some(expected_root) = expected_root {
if expected_root != &top_root {
return Err(VerifyError::<L>::RootMismatch(expected_root.clone()));
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if let Some(expected_root) = expected_root {
if expected_root != &top_root {
return Err(VerifyError::<L>::RootMismatch(expected_root.clone()));
}
}
if expected_root != top_root {
return Err(VerifyError::<L>::RootMismatch(expected_root.clone()));
}


let mut child_tries = Vec::new();
{
// fetch child trie roots
let trie = crate::TrieDB::<L>::new(db, &top_root).map_err(verify_error::<L>)?;

use trie_db::Trie;
let mut iter = trie.iter().map_err(verify_error::<L>)?;

let childtrie_roots = sp_core::storage::well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX;
if iter.seek(childtrie_roots).is_ok() {
loop {
match iter.next() {
Some(Ok((key, value))) if key.starts_with(childtrie_roots) => {
// we expect all default child trie root to be correctly encoded.
// see other child trie functions.
let mut root = TrieHash::<L>::default();
// still in a proof so prevent panic
if root.as_mut().len() != value.as_slice().len() {
return Err(VerifyError::<L>::RootMismatch(Default::default()));
Copy link
Member

Choose a reason for hiding this comment

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

Here you use root mismatch.. Weird

}
root.as_mut().copy_from_slice(value.as_ref());
child_tries.push(root);
},
// allow incomplete database error: we only
// require access to data in the proof.
Some(Err(error)) => match *error {
trie_db::TrieError::IncompleteDatabase(..) => (),
e => panic!("{:?}", e),
},
_ => break,
}
}
}
}

if !HashDBT::<L::Hash, _>::contains(db, &top_root, EMPTY_PREFIX) {
return Err(VerifyError::<L>::IncompleteProof);
}

for child_root in child_tries.into_iter() {
if !HashDBT::<L::Hash, _>::contains(db, &child_root, EMPTY_PREFIX) {
// child proof are allowed to be missing (unused root can be included
// due to trie structure modification).
continue;
}

let (top_root, _nb_used) = trie_db::decode_compact_from_iter::<L, _, _, _>(
db,
&mut nodes_iter,
).map_err(verify_error::<L>)?;

if child_root != top_root {
return Err(VerifyError::<L>::RootMismatch(child_root));
}
}

if nodes_iter.next().is_some() {
return Err(VerifyError::<L>::ExtraneousNode);
}

Ok(top_root)
}