Skip to content
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

complex proof (binary tree hash). #81

Open
wants to merge 77 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
401bc2e
complex proof (binary tree hash).
cheme Feb 26, 2020
7ae42ff
remove warnings
cheme Apr 6, 2020
86dae18
use a hashes plan for additional hash, this is an iterator, no need to
cheme Apr 6, 2020
63b899b
Decode for proof.
cheme Apr 6, 2020
5d68157
split encoding functions.
cheme Apr 6, 2020
59d8399
renaming
cheme Apr 6, 2020
79f155b
hash only variant
cheme Apr 6, 2020
cf1e95f
codec encode function
cheme Apr 7, 2020
02b149e
use new encode_proof method
cheme Apr 7, 2020
1aeeb79
remove unneeded param and do not write ommited children in proof
cheme Apr 7, 2020
7762b8d
wrong approach, we are not including ommitted node to the proof.
cheme Apr 7, 2020
2c66cc2
skip some hash round from HashRoot, still missing some cases.
cheme Apr 7, 2020
ecc8513
correct skip of round, if key is start of one of target key we can skip.
cheme Apr 7, 2020
037db16
fix and small change, generally new_key need rewrite (the second read
cheme Apr 7, 2020
1a4295d
some todos fixed.
cheme Apr 7, 2020
80efb76
some cleaning and renaming.
cheme Apr 7, 2020
b01b2dc
A quite involve fix (KeyNode trait needs additional documentation).
cheme Apr 7, 2020
7a0ff5b
quick mesg
cheme Apr 7, 2020
d421e41
Merge branch 'master' into complex_proof
cheme Apr 7, 2020
bad03f5
add rstd vec
cheme Apr 7, 2020
24fb5a4
fix
cheme Apr 7, 2020
e359578
rename ChildRootHeader to ChildProofHeader
cheme Apr 8, 2020
c3da9e6
Renaming from complex to hybrid.
cheme Apr 8, 2020
5154c64
codec decode renaming (indicates it is related to compact proof).
cheme Apr 8, 2020
123c207
reexport, this need refacto, but for quick test in substrate
cheme Apr 8, 2020
972a5a3
moving binaryhasher trait
cheme Apr 8, 2020
00e5f7b
default trie config function using hybrid trie_iter variants.
cheme Apr 8, 2020
4fa7807
update fuzzer dependencies
cheme Apr 8, 2020
38185b4
restoring correct number of test in random testing find errors.
cheme Apr 8, 2020
7d5cf1d
actually no extension works for this ammount, seems related to extension
cheme Apr 8, 2020
ea7ec16
test how to rebuild a proof from encoded nodes only.
cheme Apr 9, 2020
e2dd371
Move trait from ordered trie to hash db, now the hybrid implementatio…
cheme May 12, 2020
8d8cb3a
rename reference keccak hash to RefHasher
cheme May 12, 2020
6b89dc7
Using internal hasher instead of buffer.
cheme May 12, 2020
a6c2bc3
Running test on blake2b like in substrate.
cheme May 12, 2020
3439dad
Clean up unused code in unordered trie
cheme May 12, 2020
1c27a54
allow using two different hasher with same output size in hybrid trie
cheme May 12, 2020
9411f44
- remove inline node from compact encoded when not in value to prove
cheme May 13, 2020
f196e7d
actually remove the deps from previous refactor
cheme May 14, 2020
91c48d8
return none on wrong encoded value for insert hybrid
cheme May 14, 2020
22a4ef5
correct db traits
cheme May 14, 2020
f72d451
removing bit of redundancy in api
cheme May 14, 2020
9ce8226
removed unused offset field
cheme May 14, 2020
2568922
removed unused offset field
cheme May 14, 2020
694af92
ordered trie more cleaning
cheme May 14, 2020
1fbe9e6
ordered trie more cleaning
cheme May 14, 2020
d94d2e1
removing access to node range
cheme May 14, 2020
e965a2d
revert trait changes
cheme May 14, 2020
d91a03b
removing unused registration
cheme May 14, 2020
9c3bf30
change error
cheme May 14, 2020
abd126e
get rid of ordered trie hasher reference
cheme May 15, 2020
4fa4658
removing more adapter unused code
cheme May 15, 2020
0ed5286
start switch test to generic use
cheme May 15, 2020
fe0fed3
fix fuzz
cheme May 15, 2020
f7d54c8
continue test refactor, plus very important fix for iter_build
cheme May 15, 2020
1b619fa
finish paremeterizing tests with trie layouts.
cheme May 17, 2020
dfba7bc
Move macro to test-support
cheme May 18, 2020
f974353
remove dup macro
cheme May 18, 2020
44adeb6
iterbuild prefix fix
cheme May 18, 2020
ecba565
parameterize compact proof tests
cheme May 18, 2020
9407998
invalid proof parameterized
cheme May 18, 2020
9e234f4
use non hybrid when needed
cheme May 18, 2020
77072c3
exe to get some number
cheme May 29, 2020
6ae3e37
bench related to compaction processing.
cheme May 29, 2020
a0a344e
restore deleted adapter
cheme Jun 1, 2020
3109fe5
std test
cheme Jun 1, 2020
dedc928
fix
cheme Jun 1, 2020
f6e5bc3
Also check content from unpacked nodes in compare_proof_size
cheme Jun 22, 2020
08a1411
change bound to allow 100% run
cheme Jun 23, 2020
9edf0cf
Merge branch 'master' into complex_proof
cheme Mar 2, 2021
92ff0e4
Merge branch 'complex_proof' of github.com:cheme/trie into complex_proof
cheme Mar 2, 2021
a9a1764
fix merges and tests
cheme Mar 2, 2021
86e1dcd
comment
cheme Mar 10, 2021
aa53745
fix bench check
cheme Mar 10, 2021
6f20f37
fix bench
cheme Mar 10, 2021
43a758f
blak3 bin hasher is broken
cheme Mar 26, 2021
55dc53c
fix binary hasher
cheme Mar 26, 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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ members = [
"hash-db",
"memory-db",
"hash256-std-hasher",
"ordered-trie",
"test-support/keccak-hasher",
"test-support/reference-trie",
"test-support/trie-standardmap",
Expand Down
119 changes: 119 additions & 0 deletions hash-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,48 @@ pub trait Hasher: Sync + Send {
fn hash(x: &[u8]) -> Self::Out;
}

/// Small trait for to allow using buffer of type [u8; H::LENGTH * 2].
pub trait BinaryHasher: Hasher {
/// Hash for the empty content (is hash(&[])).
const NULL_HASH: &'static [u8];

/// State buffer for hashing.
type Buffer;

fn init_buffer() -> Self::Buffer;
fn reset_buffer(buf: &mut Self::Buffer);
fn buffer_hash(buff: &mut Self::Buffer, x: &[u8]);

/// After calling `buffer_finalize`, one do not have to call `reset_buffer`.
fn buffer_finalize(buff: &mut Self::Buffer) -> Self::Out;
}

#[cfg(feature = "std")]
/// Test function to use on any binary buffer implementation.
pub fn test_binary_hasher<H: BinaryHasher>() {
let size = <H as Hasher>::LENGTH * 2;
let half_size = <H as Hasher>::LENGTH / 2;
let mut val = vec![0u8; size];
val[0] = 1;
let mut buf = <H as BinaryHasher>::init_buffer();
H::buffer_hash(&mut buf, &val[..half_size]);
H::buffer_hash(&mut buf, &val[half_size..<H as Hasher>::LENGTH]);
let three = core::cmp::min(3, half_size);
H::buffer_hash(&mut buf, &val[<H as Hasher>::LENGTH..<H as Hasher>::LENGTH + three]);
H::buffer_hash(&mut buf, &val[<H as Hasher>::LENGTH + three..]);
let h = H::buffer_finalize(&mut buf);
let h2 = H::hash(&val[..]);
assert_eq!(h, h2);
H::buffer_hash(&mut buf, &val[..]);
let h = H::buffer_finalize(&mut buf);
assert_eq!(h, h2);
let null_hash = H::hash(&[]);
H::reset_buffer(&mut buf);
let null_hash2 = H::buffer_finalize(&mut buf);
assert_eq!(H::NULL_HASH, null_hash.as_ref());
assert_eq!(H::NULL_HASH, null_hash2.as_ref());
}

/// Trait modelling a plain datastore whose key is a fixed type.
/// The caller should ensure that a key only corresponds to
/// one value.
Expand Down Expand Up @@ -185,3 +227,80 @@ impl<'a, K, V> AsPlainDB<K, V> for &'a mut dyn PlainDB<K, V> {
fn as_plain_db(&self) -> &dyn PlainDB<K, V> { &**self }
fn as_plain_db_mut<'b>(&'b mut self) -> &'b mut (dyn PlainDB<K, V> + 'b) { &mut **self }
}

/// Same as HashDB but can modify the value upon storage, and apply
/// `HasherHybrid`.
pub trait HashDBHybrid<H: HasherHybrid, T>: Send + Sync + HashDB<H, T> {
/// `HashDB` is often use to load content from encoded node.
/// This will not preserve insertion done through `insert_branch_hybrid` calls
/// and break the proof.
/// This function allows to use a callback (usually the call back
/// will check the encoded value with codec and for branch it will
/// emplace over the hash_hybrid key) for changing key of some content.
/// Callback is allow to fail (since it will decode some node this indicates
/// invalid content earlier), in this case we return false.
fn insert_hybrid(
&mut self,
prefix: Prefix,
value: &[u8],
callback: fn(&[u8]) -> core::result::Result<Option<H::Out>, ()>,
) -> bool;

/// Insert a datum item into the DB and return the datum's hash for a later lookup. Insertions
/// are counted and the equivalent number of `remove()`s must be performed before the data
/// is considered dead.
fn insert_branch_hybrid<
I: Iterator<Item = Option<H::Out>>,
>(
&mut self,
prefix: Prefix,
value: &[u8],
no_child_value: &[u8],
nb_children: usize,
children: I,
buffer: &mut <H::InnerHasher as BinaryHasher>::Buffer,
) -> H::Out;

/// Insert with data from a proof.
/// As a result, this function can fail.
fn insert_branch_hybrid_proof<
I: Iterator<Item = Option<H::Out>>,
I2: Iterator<Item = H::Out>,
>(
&mut self,
prefix: Prefix,
value: &[u8],
no_child_value: &[u8],
nb_children: usize,
children: I,
additional_hashes: I2,
buffer: &mut <H::InnerHasher as BinaryHasher>::Buffer,
) -> Option<H::Out>;
}

pub trait HasherHybrid: BinaryHasher {
type InnerHasher: BinaryHasher<Out = Self::Out>;

/// Alternate hash with hybrid hashing allowed.
fn hash_hybrid<
I: Iterator<Item = Option<<Self as Hasher>::Out>>,
>(
encoded_node: &[u8],
nb_children: usize,
children: I,
buffer: &mut <Self::InnerHasher as BinaryHasher>::Buffer,
) -> Self::Out;

/// Calculate hash from a proof, this can fail.
fn hash_hybrid_proof<
I: Iterator<Item = Option<<Self as Hasher>::Out>>,
I2: Iterator<Item = <Self::InnerHasher as Hasher>::Out>,
>(
x: &[u8],
nb_children: usize,
children: I,
additional_hashes: I2,
buffer: &mut <Self::InnerHasher as BinaryHasher>::Buffer,
) -> Option<Self::Out>;

}
85 changes: 84 additions & 1 deletion memory-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ mod malloc_size_of;
pub use malloc_size_of::*;

use hash_db::{HashDB, HashDBRef, PlainDB, PlainDBRef, Hasher as KeyHasher,
AsHashDB, AsPlainDB, Prefix};
AsHashDB, AsPlainDB, Prefix, HashDBHybrid, HasherHybrid, BinaryHasher};
use parity_util_mem::{MallocSizeOf, MallocSizeOfOps, MallocShallowSizeOf};
#[cfg(feature = "std")]
use std::{
Expand All @@ -34,6 +34,7 @@ use std::{
marker::PhantomData,
cmp::Eq,
borrow::Borrow,
result,
};

#[cfg(not(feature = "std"))]
Expand All @@ -49,6 +50,8 @@ use core::{
marker::PhantomData,
cmp::Eq,
borrow::Borrow,
ops::Range,
result,
};

#[cfg(not(feature = "std"))]
Expand Down Expand Up @@ -625,6 +628,86 @@ where
}
}

impl<H, KF, T, M> HashDBHybrid<H, T> for MemoryDB<H, KF, T, M>
where
H: HasherHybrid,
T: Default + PartialEq<T> + for<'a> From<&'a [u8]> + Clone + Send + Sync,
KF: Send + Sync + KeyFunction<H>,
M: MemTracker<T> + Send + Sync,
{
fn insert_hybrid(
&mut self,
prefix: Prefix,
value: &[u8],
callback: fn(&[u8]) -> result::Result<Option<H::Out>, ()>,
) -> bool {
if let Ok(result) = callback(value) {
if let Some(key) = result {
<Self as HashDB<H, T>>::emplace(self, key, prefix, T::from(value));
} else {
<Self as HashDB<H, T>>::insert(self, prefix, value);
}
true
} else {
false
}
}

fn insert_branch_hybrid<
I: Iterator<Item = Option<H::Out>>,
> (
&mut self,
prefix: Prefix,
value: &[u8],
child_proof_header: &[u8],
nb_children: usize,
children: I,
buff: &mut <H::InnerHasher as BinaryHasher>::Buffer,
) -> H::Out {
if T::from(value) == self.null_node_data {
return self.hashed_null_node.clone();
}

let key = H::hash_hybrid(
child_proof_header,
nb_children,
children,
buff,
);
HashDB::emplace(self, key, prefix, value.into());
key
}

fn insert_branch_hybrid_proof<
I: Iterator<Item = Option<H::Out>>,
I2: Iterator<Item = H::Out>,
> (
&mut self,
prefix: Prefix,
value: &[u8],
child_proof_header: &[u8],
nb_children: usize,
children: I,
additional_hashes: I2,
buff: &mut <H::InnerHasher as BinaryHasher>::Buffer,
) -> Option<H::Out> {
if T::from(value) == self.null_node_data {
return Some(self.hashed_null_node.clone());
}

H::hash_hybrid_proof(
child_proof_header,
nb_children,
children,
additional_hashes,
buff,
).map(|key| {
HashDB::emplace(self, key, prefix, value.into());
key
})
}
}

impl<H, KF, T, M> HashDBRef<H, T> for MemoryDB<H, KF, T, M>
where
H: KeyHasher,
Expand Down
23 changes: 23 additions & 0 deletions ordered-trie/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "ordered-trie"
version = "0.19.2"
authors = ["Parity Technologies <[email protected]>"]
description = "Binary tree generic for ordered values (stack or fifo)"
repository = "https://github.com/paritytech/trie"
license = "Apache-2.0"
edition = "2018"

[dependencies]
hash-db = { path = "../hash-db", default-features = false, version = "0.15.2"}
smallvec = "1.0.0"

[dev-dependencies]
keccak-hasher = { path = "../test-support/keccak-hasher", version = "0.15.2"}
#criterion = "0.2.8"


[features]
default = ["std"]
std = [
"hash-db/std",
]
Loading