Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
+5 -5
View File
@@ -15,10 +15,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#[cfg(feature="std")]
use std::fmt;
#[cfg(feature="std")]
#[cfg(feature = "std")]
use std::error::Error as StdError;
#[cfg(feature = "std")]
use std::fmt;
#[derive(Debug, PartialEq, Eq, Clone)]
/// Error for trie node decoding.
@@ -35,7 +35,7 @@ impl From<codec::Error> for Error {
}
}
#[cfg(feature="std")]
#[cfg(feature = "std")]
impl StdError for Error {
fn description(&self) -> &str {
match self {
@@ -45,7 +45,7 @@ impl StdError for Error {
}
}
#[cfg(feature="std")]
#[cfg(feature = "std")]
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
+185 -170
View File
@@ -20,35 +20,36 @@
#![cfg_attr(not(feature = "std"), no_std)]
mod error;
mod node_header;
mod node_codec;
mod node_header;
mod storage_proof;
mod trie_codec;
mod trie_stream;
use sp_std::{boxed::Box, marker::PhantomData, vec::Vec, borrow::Borrow};
use hash_db::{Hasher, Prefix};
use trie_db::proof::{generate_proof, verify_proof};
pub use trie_db::proof::VerifyError;
/// Our `NodeCodec`-specific error.
pub use error::Error;
/// The Substrate format implementation of `TrieStream`.
pub use trie_stream::TrieStream;
/// The Substrate format implementation of `NodeCodec`.
pub use node_codec::NodeCodec;
pub use storage_proof::{StorageProof, CompactProof};
/// Various re-exports from the `trie-db` crate.
pub use trie_db::{
Trie, TrieMut, DBValue, Recorder, CError, Query, TrieLayout, TrieConfiguration, nibble_ops, TrieDBIterator,
};
/// 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};
use hash_db::{Hasher, Prefix};
pub use memory_db::prefixed_key;
/// Various re-exports from the `memory-db` crate.
pub use memory_db::KeyFunction;
/// The Substrate format implementation of `NodeCodec`.
pub use node_codec::NodeCodec;
use sp_std::{borrow::Borrow, boxed::Box, marker::PhantomData, vec::Vec};
pub use storage_proof::{CompactProof, StorageProof};
/// Trie codec reexport, mainly child trie support
/// for trie compact proof.
pub use trie_codec::{decode_compact, encode_compact, Error as CompactProofError};
pub use trie_db::proof::VerifyError;
use trie_db::proof::{generate_proof, verify_proof};
/// Various re-exports from the `trie-db` crate.
pub use trie_db::{
nibble_ops, CError, DBValue, Query, Recorder, Trie, TrieConfiguration, TrieDBIterator,
TrieLayout, TrieMut,
};
/// The Substrate format implementation of `TrieStream`.
pub use trie_stream::TrieStream;
#[derive(Default)]
/// substrate trie layout
@@ -62,7 +63,8 @@ impl<H: Hasher> TrieLayout for Layout<H> {
}
impl<H: Hasher> TrieConfiguration for Layout<H> {
fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out where
fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out
where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
@@ -70,7 +72,8 @@ impl<H: Hasher> TrieConfiguration for Layout<H> {
trie_root::trie_root_no_extension::<H, TrieStream, _, _, _>(input)
}
fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8> where
fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8>
where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
@@ -98,19 +101,14 @@ pub type HashDB<'a, H> = dyn hash_db::HashDB<H, trie_db::DBValue> + 'a;
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
/// This uses a `KeyFunction` for prefixing keys internally (avoiding
/// key conflict for non random keys).
pub type PrefixedMemoryDB<H> = memory_db::MemoryDB<
H, memory_db::PrefixedKey<H>, trie_db::DBValue, MemTracker
>;
pub type PrefixedMemoryDB<H> =
memory_db::MemoryDB<H, memory_db::PrefixedKey<H>, trie_db::DBValue, MemTracker>;
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
/// This uses a noops `KeyFunction` (key addressing must be hashed or using
/// an encoding scheme that avoid key conflict).
pub type MemoryDB<H> = memory_db::MemoryDB<
H, memory_db::HashKey<H>, trie_db::DBValue, MemTracker,
>;
pub type MemoryDB<H> = memory_db::MemoryDB<H, memory_db::HashKey<H>, trie_db::DBValue, MemTracker>;
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
pub type GenericMemoryDB<H, KF> = memory_db::MemoryDB<
H, KF, trie_db::DBValue, MemTracker
>;
pub type GenericMemoryDB<H, KF> = memory_db::MemoryDB<H, KF, trie_db::DBValue, MemTracker>;
/// Persistent trie database read-access interface for the a given hasher.
pub type TrieDB<'a, L> = trie_db::TrieDB<'a, L>;
@@ -147,8 +145,9 @@ pub fn generate_trie_proof<'a, L: TrieConfiguration, I, K, DB>(
db: &DB,
root: TrieHash<L>,
keys: I,
) -> Result<Vec<Vec<u8>>, Box<TrieError<L>>> where
I: IntoIterator<Item=&'a K>,
) -> Result<Vec<Vec<u8>>, Box<TrieError<L>>>
where
I: IntoIterator<Item = &'a K>,
K: 'a + AsRef<[u8]>,
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
{
@@ -168,8 +167,9 @@ pub fn verify_trie_proof<'a, L: TrieConfiguration, I, K, V>(
root: &TrieHash<L>,
proof: &[Vec<u8>],
items: I,
) -> Result<(), VerifyError<TrieHash<L>, error::Error>> where
I: IntoIterator<Item=&'a (K, Option<V>)>,
) -> Result<(), VerifyError<TrieHash<L>, error::Error>>
where
I: IntoIterator<Item = &'a (K, Option<V>)>,
K: 'a + AsRef<[u8]>,
V: 'a + AsRef<[u8]>,
{
@@ -180,8 +180,9 @@ pub fn verify_trie_proof<'a, L: TrieConfiguration, I, K, V>(
pub fn delta_trie_root<L: TrieConfiguration, I, A, B, DB, V>(
db: &mut DB,
mut root: TrieHash<L>,
delta: I
) -> Result<TrieHash<L>, Box<TrieError<L>>> where
delta: I,
) -> Result<TrieHash<L>, Box<TrieError<L>>>
where
I: IntoIterator<Item = (A, B)>,
A: Borrow<[u8]>,
B: Borrow<Option<V>>,
@@ -209,7 +210,7 @@ pub fn delta_trie_root<L: TrieConfiguration, I, A, B, DB, V>(
pub fn read_trie_value<L: TrieConfiguration, DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>>(
db: &DB,
root: &TrieHash<L>,
key: &[u8]
key: &[u8],
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
TrieDB::<L>::new(&*db, root)?.get(key).map(|x| x.map(|val| val.to_vec()))
}
@@ -217,15 +218,17 @@ pub fn read_trie_value<L: TrieConfiguration, DB: hash_db::HashDBRef<L::Hash, tri
/// Read a value from the trie with given Query.
pub fn read_trie_value_with<
L: TrieConfiguration,
Q: Query<L::Hash, Item=DBValue>,
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
Q: Query<L::Hash, Item = DBValue>,
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
>(
db: &DB,
root: &TrieHash<L>,
key: &[u8],
query: Q
query: Q,
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
TrieDB::<L>::new(&*db, root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))
TrieDB::<L>::new(&*db, root)?
.get_with(key, query)
.map(|x| x.map(|val| val.to_vec()))
}
/// Determine the empty trie root.
@@ -240,13 +243,11 @@ pub fn empty_child_trie_root<L: TrieConfiguration>() -> <L::Hash as Hasher>::Out
/// Determine a child trie root given its ordered contents, closed form. H is the default hasher,
/// but a generic implementation may ignore this type parameter and use other hashers.
pub fn child_trie_root<L: TrieConfiguration, I, A, B>(
input: I,
) -> <L::Hash as Hasher>::Out
where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
pub fn child_trie_root<L: TrieConfiguration, I, A, B>(input: I) -> <L::Hash as Hasher>::Out
where
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>,
{
L::trie_root(input)
}
@@ -259,33 +260,30 @@ pub fn child_delta_trie_root<L: TrieConfiguration, I, A, B, DB, RD, V>(
root_data: RD,
delta: I,
) -> Result<<L::Hash as Hasher>::Out, Box<TrieError<L>>>
where
I: IntoIterator<Item = (A, B)>,
A: Borrow<[u8]>,
B: Borrow<Option<V>>,
V: Borrow<[u8]>,
RD: AsRef<[u8]>,
DB: hash_db::HashDB<L::Hash, trie_db::DBValue>
where
I: IntoIterator<Item = (A, B)>,
A: Borrow<[u8]>,
B: Borrow<Option<V>>,
V: Borrow<[u8]>,
RD: AsRef<[u8]>,
DB: hash_db::HashDB<L::Hash, trie_db::DBValue>,
{
let mut root = TrieHash::<L>::default();
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_data.as_ref());
let mut db = KeySpacedDBMut::new(&mut *db, keyspace);
delta_trie_root::<L, _, _, _, _, _>(
&mut db,
root,
delta,
)
delta_trie_root::<L, _, _, _, _, _>(&mut db, root, delta)
}
/// Record all keys for a given root.
pub fn record_all_keys<L: TrieConfiguration, DB>(
db: &DB,
root: &TrieHash<L>,
recorder: &mut Recorder<TrieHash<L>>
) -> Result<(), Box<TrieError<L>>> where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
recorder: &mut Recorder<TrieHash<L>>,
) -> Result<(), Box<TrieError<L>>>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
{
let trie = TrieDB::<L>::new(&*db, root)?;
let iter = trie.iter()?;
@@ -307,10 +305,10 @@ pub fn read_child_trie_value<L: TrieConfiguration, DB>(
keyspace: &[u8],
db: &DB,
root_slice: &[u8],
key: &[u8]
key: &[u8],
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
{
let mut root = TrieHash::<L>::default();
// root is fetched from DB, not writable by runtime, so it's always valid.
@@ -321,22 +319,24 @@ pub fn read_child_trie_value<L: TrieConfiguration, DB>(
}
/// Read a value from the child trie with given query.
pub fn read_child_trie_value_with<L: TrieConfiguration, Q: Query<L::Hash, Item=DBValue>, DB>(
pub fn read_child_trie_value_with<L: TrieConfiguration, Q: Query<L::Hash, Item = DBValue>, DB>(
keyspace: &[u8],
db: &DB,
root_slice: &[u8],
key: &[u8],
query: Q
query: Q,
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>
where
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
{
let mut root = TrieHash::<L>::default();
// root is fetched from DB, not writable by runtime, so it's always valid.
root.as_mut().copy_from_slice(root_slice);
let db = KeySpacedDB::new(&*db, keyspace);
TrieDB::<L>::new(&db, &root)?.get_with(key, query).map(|x| x.map(|val| val.to_vec()))
TrieDB::<L>::new(&db, &root)?
.get_with(key, query)
.map(|x| x.map(|val| val.to_vec()))
}
/// `HashDB` implementation that append a encoded prefix (unique id bytes) in addition to the
@@ -358,7 +358,8 @@ fn keyspace_as_prefix_alloc(ks: &[u8], prefix: Prefix) -> (Vec<u8>, Option<u8>)
(result, prefix.1)
}
impl<'a, DB, H> KeySpacedDB<'a, DB, H> where
impl<'a, DB, H> KeySpacedDB<'a, DB, H>
where
H: Hasher,
{
/// instantiate new keyspaced db
@@ -367,7 +368,8 @@ impl<'a, DB, H> KeySpacedDB<'a, DB, H> where
}
}
impl<'a, DB, H> KeySpacedDBMut<'a, DB, H> where
impl<'a, DB, H> KeySpacedDBMut<'a, DB, H>
where
H: Hasher,
{
/// instantiate new keyspaced db
@@ -376,7 +378,8 @@ impl<'a, DB, H> KeySpacedDBMut<'a, DB, H> where
}
}
impl<'a, DB, H, T> hash_db::HashDBRef<H, T> for KeySpacedDB<'a, DB, H> where
impl<'a, DB, H, T> hash_db::HashDBRef<H, T> for KeySpacedDB<'a, DB, H>
where
DB: hash_db::HashDBRef<H, T>,
H: Hasher,
T: From<&'static [u8]>,
@@ -392,7 +395,8 @@ impl<'a, DB, H, T> hash_db::HashDBRef<H, T> for KeySpacedDB<'a, DB, H> where
}
}
impl<'a, DB, H, T> hash_db::HashDB<H, T> for KeySpacedDBMut<'a, DB, H> where
impl<'a, DB, H, T> hash_db::HashDB<H, T> for KeySpacedDBMut<'a, DB, H>
where
DB: hash_db::HashDB<H, T>,
H: Hasher,
T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
@@ -423,12 +427,15 @@ impl<'a, DB, H, T> hash_db::HashDB<H, T> for KeySpacedDBMut<'a, DB, H> where
}
}
impl<'a, DB, H, T> hash_db::AsHashDB<H, T> for KeySpacedDBMut<'a, DB, H> where
impl<'a, DB, H, T> hash_db::AsHashDB<H, T> for KeySpacedDBMut<'a, DB, H>
where
DB: hash_db::HashDB<H, T>,
H: Hasher,
T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
{
fn as_hash_db(&self) -> &dyn hash_db::HashDB<H, T> { &*self }
fn as_hash_db(&self) -> &dyn hash_db::HashDB<H, T> {
&*self
}
fn as_hash_db_mut<'b>(&'b mut self) -> &'b mut (dyn hash_db::HashDB<H, T> + 'b) {
&mut *self
@@ -447,12 +454,12 @@ mod trie_constants {
#[cfg(test)]
mod tests {
use super::*;
use codec::{Encode, Decode, Compact};
use sp_core::Blake2Hasher;
use codec::{Compact, Decode, Encode};
use hash_db::{HashDB, Hasher};
use trie_db::{DBValue, TrieMut, Trie, NodeCodec as NodeCodecT};
use trie_standardmap::{Alphabet, ValueMode, StandardMap};
use hex_literal::hex;
use sp_core::Blake2Hasher;
use trie_db::{DBValue, NodeCodec as NodeCodecT, Trie, TrieMut};
use trie_standardmap::{Alphabet, StandardMap, ValueMode};
type Layout = super::Layout<Blake2Hasher>;
@@ -491,7 +498,8 @@ mod tests {
let t = TrieDB::<T>::new(&mut memdb, &root).unwrap();
assert_eq!(
input.iter().map(|(i, j)| (i.to_vec(), j.to_vec())).collect::<Vec<_>>(),
t.iter().unwrap()
t.iter()
.unwrap()
.map(|x| x.map(|y| (y.0, y.1.to_vec())).unwrap())
.collect::<Vec<_>>()
);
@@ -505,9 +513,11 @@ mod tests {
let mut empty = TrieDBMut::<Layout>::new(&mut db, &mut root);
empty.commit();
let root1 = empty.root().as_ref().to_vec();
let root2: Vec<u8> = Layout::trie_root::<_, Vec<u8>, Vec<u8>>(
std::iter::empty(),
).as_ref().iter().cloned().collect();
let root2: Vec<u8> = Layout::trie_root::<_, Vec<u8>, Vec<u8>>(std::iter::empty())
.as_ref()
.iter()
.cloned()
.collect();
assert_eq!(root1, root2);
}
@@ -528,20 +538,16 @@ mod tests {
#[test]
fn branch_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![
(&[0xaa][..], &[0x10][..]),
(&[0xba][..], &[0x11][..]),
];
let input: Vec<(&[u8], &[u8])> =
vec![(&[0xaa][..], &[0x10][..]), (&[0xba][..], &[0x11][..])];
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
#[test]
fn extension_and_branch_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![
(&[0xaa][..], &[0x10][..]),
(&[0xab][..], &[0x11][..]),
];
let input: Vec<(&[u8], &[u8])> =
vec![(&[0xaa][..], &[0x10][..]), (&[0xab][..], &[0x11][..])];
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
}
@@ -567,7 +573,7 @@ mod tests {
let input: Vec<(&[u8], &[u8])> = vec![
(&[0xaa][..], &[0xa0][..]),
(&[0xaa, 0xaa][..], &[0xaa][..]),
(&[0xaa, 0xbb][..], &[0xab][..])
(&[0xaa, 0xbb][..], &[0xab][..]),
];
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
@@ -590,7 +596,10 @@ mod tests {
#[test]
fn single_long_leaf_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![
(&[0xaa][..], &b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..]),
(
&[0xaa][..],
&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
),
(&[0xba][..], &[0x11][..]),
];
check_equivalent::<Layout>(&input);
@@ -600,8 +609,14 @@ mod tests {
#[test]
fn two_long_leaves_is_equivalent() {
let input: Vec<(&[u8], &[u8])> = vec![
(&[0xaa][..], &b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..]),
(&[0xba][..], &b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..])
(
&[0xaa][..],
&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
),
(
&[0xba][..],
&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
),
];
check_equivalent::<Layout>(&input);
check_iteration::<Layout>(&input);
@@ -610,11 +625,11 @@ mod tests {
fn populate_trie<'db, T: TrieConfiguration>(
db: &'db mut dyn HashDB<T::Hash, DBValue>,
root: &'db mut TrieHash<T>,
v: &[(Vec<u8>, Vec<u8>)]
v: &[(Vec<u8>, Vec<u8>)],
) -> TrieDBMut<'db, T> {
let mut t = TrieDBMut::<T>::new(db, root);
for i in 0..v.len() {
let key: &[u8]= &v[i].0;
let key: &[u8] = &v[i].0;
let val: &[u8] = &v[i].1;
t.insert(key, val).unwrap();
}
@@ -626,7 +641,7 @@ mod tests {
v: &[(Vec<u8>, Vec<u8>)],
) {
for i in v {
let key: &[u8]= &i.0;
let key: &[u8] = &i.0;
t.remove(key).unwrap();
}
}
@@ -644,7 +659,8 @@ mod tests {
journal_key: 0,
value_mode: ValueMode::Index,
count: 100,
}.make_with(seed.as_fixed_bytes_mut());
}
.make_with(seed.as_fixed_bytes_mut());
let real = Layout::trie_root(x.clone());
let mut memdb = MemoryDB::default();
@@ -690,17 +706,18 @@ mod tests {
#[test]
fn codec_trie_single_tuple() {
let input = vec![
(vec![0xaa], vec![0xbb])
];
let input = vec![(vec![0xaa], vec![0xbb])];
let trie = Layout::trie_root_unhashed::<_, _, _>(input);
println!("trie: {:#x?}", trie);
assert_eq!(trie, vec![
0x42, // leaf 0x40 (2^6) with (+) key of 2 nibbles (0x02)
0xaa, // key data
to_compact(1), // length of value in bytes as Compact
0xbb // value data
]);
assert_eq!(
trie,
vec![
0x42, // leaf 0x40 (2^6) with (+) key of 2 nibbles (0x02)
0xaa, // key data
to_compact(1), // length of value in bytes as Compact
0xbb // value data
]
);
}
#[test]
@@ -709,21 +726,21 @@ mod tests {
let trie = Layout::trie_root_unhashed::<_, _, _>(input);
println!("trie: {:#x?}", trie);
let mut ex = Vec::<u8>::new();
ex.push(0x80); // branch, no value (0b_10..) no nibble
ex.push(0x12); // slots 1 & 4 are taken from 0-7
ex.push(0x00); // no slots from 8-15
ex.push(to_compact(0x05)); // first slot: LEAF, 5 bytes long.
ex.push(0x43); // leaf 0x40 with 3 nibbles
ex.push(0x03); // first nibble
ex.push(0x14); // second & third nibble
ex.push(to_compact(0x01)); // 1 byte data
ex.push(0xff); // value data
ex.push(to_compact(0x05)); // second slot: LEAF, 5 bytes long.
ex.push(0x43); // leaf with 3 nibbles
ex.push(0x08); // first nibble
ex.push(0x19); // second & third nibble
ex.push(to_compact(0x01)); // 1 byte data
ex.push(0xfe); // value data
ex.push(0x80); // branch, no value (0b_10..) no nibble
ex.push(0x12); // slots 1 & 4 are taken from 0-7
ex.push(0x00); // no slots from 8-15
ex.push(to_compact(0x05)); // first slot: LEAF, 5 bytes long.
ex.push(0x43); // leaf 0x40 with 3 nibbles
ex.push(0x03); // first nibble
ex.push(0x14); // second & third nibble
ex.push(to_compact(0x01)); // 1 byte data
ex.push(0xff); // value data
ex.push(to_compact(0x05)); // second slot: LEAF, 5 bytes long.
ex.push(0x43); // leaf with 3 nibbles
ex.push(0x08); // first nibble
ex.push(0x19); // second & third nibble
ex.push(to_compact(0x01)); // 1 byte data
ex.push(0xfe); // value data
assert_eq!(trie, ex);
}
@@ -763,27 +780,25 @@ mod tests {
populate_trie::<Layout>(&mut memdb, &mut root, &pairs);
let non_included_key: Vec<u8> = hex!("0909").to_vec();
let proof = generate_trie_proof::<Layout, _, _, _>(
&memdb,
root,
&[non_included_key.clone()]
).unwrap();
let proof =
generate_trie_proof::<Layout, _, _, _>(&memdb, root, &[non_included_key.clone()])
.unwrap();
// Verifying that the K was not included into the trie should work.
assert!(verify_trie_proof::<Layout, _, _, Vec<u8>>(
&root,
&proof,
&[(non_included_key.clone(), None)],
).is_ok()
);
&root,
&proof,
&[(non_included_key.clone(), None)],
)
.is_ok());
// Verifying that the K was included into the trie should fail.
assert!(verify_trie_proof::<Layout, _, _, Vec<u8>>(
&root,
&proof,
&[(non_included_key, Some(hex!("1010").to_vec()))],
).is_err()
);
&root,
&proof,
&[(non_included_key, Some(hex!("1010").to_vec()))],
)
.is_err());
}
#[test]
@@ -797,71 +812,71 @@ mod tests {
let mut root = Default::default();
populate_trie::<Layout>(&mut memdb, &mut root, &pairs);
let proof = generate_trie_proof::<Layout, _, _, _>(
&memdb,
root,
&[pairs[0].0.clone()]
).unwrap();
let proof =
generate_trie_proof::<Layout, _, _, _>(&memdb, root, &[pairs[0].0.clone()]).unwrap();
// Check that a K, V included into the proof are verified.
assert!(verify_trie_proof::<Layout, _, _, _>(
&root,
&proof,
&[(pairs[0].0.clone(), Some(pairs[0].1.clone()))]
).is_ok()
);
&root,
&proof,
&[(pairs[0].0.clone(), Some(pairs[0].1.clone()))]
)
.is_ok());
// Absence of the V is not verified with the proof that has K, V included.
assert!(verify_trie_proof::<Layout, _, _, Vec<u8>>(
&root,
&proof,
&[(pairs[0].0.clone(), None)]
).is_err()
);
&root,
&proof,
&[(pairs[0].0.clone(), None)]
)
.is_err());
// K not included into the trie is not verified.
assert!(verify_trie_proof::<Layout, _, _, _>(
&root,
&proof,
&[(hex!("4242").to_vec(), Some(pairs[0].1.clone()))]
).is_err()
);
&root,
&proof,
&[(hex!("4242").to_vec(), Some(pairs[0].1.clone()))]
)
.is_err());
// K included into the trie but not included into the proof is not verified.
assert!(verify_trie_proof::<Layout, _, _, _>(
&root,
&proof,
&[(pairs[1].0.clone(), Some(pairs[1].1.clone()))]
).is_err()
);
&root,
&proof,
&[(pairs[1].0.clone(), Some(pairs[1].1.clone()))]
)
.is_err());
}
#[test]
fn generate_storage_root_with_proof_works_independently_from_the_delta_order() {
let proof = StorageProof::decode(&mut &include_bytes!("../test-res/proof")[..]).unwrap();
let storage_root = sp_core::H256::decode(
&mut &include_bytes!("../test-res/storage_root")[..],
).unwrap();
let storage_root =
sp_core::H256::decode(&mut &include_bytes!("../test-res/storage_root")[..]).unwrap();
// Delta order that is "invalid" so that it would require a different proof.
let invalid_delta = Vec::<(Vec<u8>, Option<Vec<u8>>)>::decode(
&mut &include_bytes!("../test-res/invalid-delta-order")[..],
).unwrap();
)
.unwrap();
// Delta order that is "valid"
let valid_delta = Vec::<(Vec<u8>, Option<Vec<u8>>)>::decode(
&mut &include_bytes!("../test-res/valid-delta-order")[..],
).unwrap();
)
.unwrap();
let proof_db = proof.into_memory_db::<Blake2Hasher>();
let first_storage_root = delta_trie_root::<Layout, _, _, _, _, _>(
&mut proof_db.clone(),
storage_root,
valid_delta,
).unwrap();
)
.unwrap();
let second_storage_root = delta_trie_root::<Layout, _, _, _, _, _>(
&mut proof_db.clone(),
storage_root,
invalid_delta,
).unwrap();
)
.unwrap();
assert_eq!(first_storage_root, second_storage_root);
}
+43 -44
View File
@@ -17,17 +17,16 @@
//! `NodeCodec` implementation for Substrate's trie format.
use sp_std::marker::PhantomData;
use sp_std::ops::Range;
use sp_std::vec::Vec;
use sp_std::borrow::Borrow;
use codec::{Encode, Decode, Input, Compact};
use super::node_header::{NodeHeader, NodeKind};
use crate::{error::Error, trie_constants};
use codec::{Compact, Decode, Encode, Input};
use hash_db::Hasher;
use trie_db::{self, node::{NibbleSlicePlan, NodePlan, NodeHandlePlan}, ChildReference,
nibble_ops, Partial, NodeCodec as NodeCodecT};
use crate::error::Error;
use crate::trie_constants;
use super::{node_header::{NodeHeader, NodeKind}};
use sp_std::{borrow::Borrow, marker::PhantomData, ops::Range, vec::Vec};
use trie_db::{
self, nibble_ops,
node::{NibbleSlicePlan, NodeHandlePlan, NodePlan},
ChildReference, NodeCodec as NodeCodecT, Partial,
};
/// Helper struct for trie node decoder. This implements `codec::Input` on a byte slice, while
/// tracking the absolute position. This is similar to `std::io::Cursor` but does not implement
@@ -39,15 +38,12 @@ struct ByteSliceInput<'a> {
impl<'a> ByteSliceInput<'a> {
fn new(data: &'a [u8]) -> Self {
ByteSliceInput {
data,
offset: 0,
}
ByteSliceInput { data, offset: 0 }
}
fn take(&mut self, count: usize) -> Result<Range<usize>, codec::Error> {
if self.offset + count > self.data.len() {
return Err("out of data".into());
return Err("out of data".into())
}
let range = self.offset..(self.offset + count);
@@ -58,11 +54,8 @@ impl<'a> ByteSliceInput<'a> {
impl<'a> Input for ByteSliceInput<'a> {
fn remaining_len(&mut self) -> Result<Option<usize>, codec::Error> {
let remaining = if self.offset <= self.data.len() {
Some(self.data.len() - self.offset)
} else {
None
};
let remaining =
if self.offset <= self.data.len() { Some(self.data.len() - self.offset) } else { None };
Ok(remaining)
}
@@ -74,7 +67,7 @@ impl<'a> Input for ByteSliceInput<'a> {
fn read_byte(&mut self) -> Result<u8, codec::Error> {
if self.offset + 1 > self.data.len() {
return Err("out of data".into());
return Err("out of data".into())
}
let byte = self.data[self.offset];
@@ -103,10 +96,11 @@ impl<H: Hasher> NodeCodecT for NodeCodec<H> {
let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
// check that the padding is valid (if any)
if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
return Err(Error::BadFormat);
return Err(Error::BadFormat)
}
let partial = input.take(
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) /
nibble_ops::NIBBLE_PER_BYTE,
)?;
let partial_padding = nibble_ops::number_padding(nibble_count);
let bitmap_range = input.take(BITMAP_LENGTH)?;
@@ -118,8 +112,8 @@ impl<H: Hasher> NodeCodecT for NodeCodec<H> {
None
};
let mut children = [
None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None,
];
for i in 0..nibble_ops::NIBBLE_LENGTH {
if bitmap.value_at(i) {
@@ -137,15 +131,16 @@ impl<H: Hasher> NodeCodecT for NodeCodec<H> {
value,
children,
})
}
},
NodeHeader::Leaf(nibble_count) => {
let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
// check that the padding is valid (if any)
if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
return Err(Error::BadFormat);
return Err(Error::BadFormat)
}
let partial = input.take(
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) /
nibble_ops::NIBBLE_PER_BYTE,
)?;
let partial_padding = nibble_ops::number_padding(nibble_count);
let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
@@ -153,7 +148,7 @@ impl<H: Hasher> NodeCodecT for NodeCodec<H> {
partial: NibbleSlicePlan::new(partial, partial_padding),
value: input.take(count)?,
})
}
},
}
}
@@ -199,26 +194,28 @@ impl<H: Hasher> NodeCodecT for NodeCodec<H> {
};
let bitmap_index = output.len();
let mut bitmap: [u8; BITMAP_LENGTH] = [0; BITMAP_LENGTH];
(0..BITMAP_LENGTH).for_each(|_|output.push(0));
(0..BITMAP_LENGTH).for_each(|_| output.push(0));
if let Some(value) = maybe_value {
value.encode_to(&mut output);
};
Bitmap::encode(children.map(|maybe_child| match maybe_child.borrow() {
Some(ChildReference::Hash(h)) => {
h.as_ref().encode_to(&mut output);
true
}
&Some(ChildReference::Inline(inline_data, len)) => {
inline_data.as_ref()[..len].encode_to(&mut output);
true
}
None => false,
}), bitmap.as_mut());
Bitmap::encode(
children.map(|maybe_child| match maybe_child.borrow() {
Some(ChildReference::Hash(h)) => {
h.as_ref().encode_to(&mut output);
true
},
&Some(ChildReference::Inline(inline_data, len)) => {
inline_data.as_ref()[..len].encode_to(&mut output);
true
},
None => false,
}),
bitmap.as_mut(),
);
output[bitmap_index..bitmap_index + BITMAP_LENGTH]
.copy_from_slice(&bitmap[..BITMAP_LENGTH]);
output
}
}
// utils
@@ -280,11 +277,13 @@ impl Bitmap {
self.0 & (1u16 << i) != 0
}
pub fn encode<I: Iterator<Item = bool>>(has_children: I , dest: &mut [u8]) {
pub fn encode<I: Iterator<Item = bool>>(has_children: I, dest: &mut [u8]) {
let mut bitmap: u16 = 0;
let mut cursor: u16 = 1;
for v in has_children {
if v { bitmap |= cursor }
if v {
bitmap |= cursor
}
cursor <<= 1;
}
dest[0] = (bitmap % 256) as u8;
+12 -14
View File
@@ -18,12 +18,11 @@
//! The node header.
use crate::trie_constants;
use codec::{Encode, Decode, Input, Output};
use codec::{Decode, Encode, Input, Output};
use sp_std::iter::once;
/// A node header
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(sp_core::RuntimeDebug)]
#[derive(Copy, Clone, PartialEq, Eq, sp_core::RuntimeDebug)]
pub(crate) enum NodeHeader {
Null,
Branch(bool, usize),
@@ -41,7 +40,7 @@ impl Encode for NodeHeader {
fn encode_to<T: Output + ?Sized>(&self, output: &mut T) {
match self {
NodeHeader::Null => output.push_byte(trie_constants::EMPTY_TRIE),
NodeHeader::Branch(true, nibble_count) =>
NodeHeader::Branch(true, nibble_count) =>
encode_size_and_prefix(*nibble_count, trie_constants::BRANCH_WITH_MASK, output),
NodeHeader::Branch(false, nibble_count) =>
encode_size_and_prefix(*nibble_count, trie_constants::BRANCH_WITHOUT_MASK, output),
@@ -57,12 +56,14 @@ impl Decode for NodeHeader {
fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
let i = input.read_byte()?;
if i == trie_constants::EMPTY_TRIE {
return Ok(NodeHeader::Null);
return Ok(NodeHeader::Null)
}
match i & (0b11 << 6) {
trie_constants::LEAF_PREFIX_MASK => Ok(NodeHeader::Leaf(decode_size(i, input)?)),
trie_constants::BRANCH_WITHOUT_MASK => Ok(NodeHeader::Branch(false, decode_size(i, input)?)),
trie_constants::BRANCH_WITH_MASK => Ok(NodeHeader::Branch(true, decode_size(i, input)?)),
trie_constants::BRANCH_WITHOUT_MASK =>
Ok(NodeHeader::Branch(false, decode_size(i, input)?)),
trie_constants::BRANCH_WITH_MASK =>
Ok(NodeHeader::Branch(true, decode_size(i, input)?)),
// do not allow any special encoding
_ => Err("Unallowed encoding".into()),
}
@@ -76,11 +77,8 @@ pub(crate) fn size_and_prefix_iterator(size: usize, prefix: u8) -> impl Iterator
let size = sp_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, size);
let l1 = sp_std::cmp::min(62, size);
let (first_byte, mut rem) = if size == l1 {
(once(prefix + l1 as u8), 0)
} else {
(once(prefix + 63), size - l1)
};
let (first_byte, mut rem) =
if size == l1 { (once(prefix + l1 as u8), 0) } else { (once(prefix + 63), size - l1) };
let next_bytes = move || {
if rem > 0 {
if rem < 256 {
@@ -109,13 +107,13 @@ fn encode_size_and_prefix<W: Output + ?Sized>(size: usize, prefix: u8, out: &mut
fn decode_size(first: u8, input: &mut impl Input) -> Result<usize, codec::Error> {
let mut result = (first & 255u8 >> 2) as usize;
if result < 63 {
return Ok(result);
return Ok(result)
}
result -= 1;
while result <= trie_constants::NIBBLE_SIZE_BOUND {
let n = input.read_byte()? as usize;
if n < 255 {
return Ok(result + n + 1);
return Ok(result + n + 1)
}
result += 255;
}
+20 -19
View File
@@ -15,9 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use codec::{Decode, Encode};
use hash_db::{HashDB, Hasher};
use sp_std::vec::Vec;
use codec::{Encode, Decode};
use hash_db::{Hasher, HashDB};
/// A proof that some set of key-value pairs are included in the storage trie. The proof contains
/// the storage values so that the partial storage backend can be reconstructed by a verifier that
@@ -48,9 +48,7 @@ impl StorageProof {
/// An empty proof is capable of only proving trivial statements (ie. that an empty set of
/// key-value pairs exist in storage).
pub fn empty() -> Self {
StorageProof {
trie_nodes: Vec::new(),
}
StorageProof { trie_nodes: Vec::new() }
}
/// Returns whether this is an empty proof.
@@ -76,8 +74,12 @@ impl StorageProof {
/// Merges multiple storage proofs covering potentially different sets of keys into one proof
/// covering all keys. The merged proof output may be smaller than the aggregate size of the input
/// proofs due to deduplication of trie nodes.
pub fn merge<I>(proofs: I) -> Self where I: IntoIterator<Item=Self> {
let trie_nodes = proofs.into_iter()
pub fn merge<I>(proofs: I) -> Self
where
I: IntoIterator<Item = Self>,
{
let trie_nodes = proofs
.into_iter()
.flat_map(|proof| proof.iter_nodes())
.collect::<sp_std::collections::btree_set::BTreeSet<_>>()
.into_iter()
@@ -94,7 +96,7 @@ impl StorageProof {
) -> Result<CompactProof, crate::CompactProofError<crate::Layout<H>>> {
crate::encode_compact::<crate::Layout<H>>(self, root)
}
/// Returns the estimated encoded size of the compact proof.
///
/// Runing this operation is a slow operation (build the whole compact proof) and should only be
@@ -104,7 +106,6 @@ impl StorageProof {
let compact_proof = self.into_compact_proof::<H>(root);
compact_proof.ok().map(|p| p.encoded_size())
}
}
impl CompactProof {
@@ -127,13 +128,15 @@ impl CompactProof {
self.iter_compact_encoded_nodes(),
expected_root,
)?;
Ok((StorageProof::new(db.drain().into_iter().filter_map(|kv|
if (kv.1).1 > 0 {
Some((kv.1).0)
} else {
None
}
).collect()), root))
Ok((
StorageProof::new(
db.drain()
.into_iter()
.filter_map(|kv| if (kv.1).1 > 0 { Some((kv.1).0) } else { None })
.collect(),
),
root,
))
}
}
@@ -145,9 +148,7 @@ pub struct StorageProofNodeIterator {
impl StorageProofNodeIterator {
fn new(proof: StorageProof) -> Self {
StorageProofNodeIterator {
inner: proof.trie_nodes.into_iter(),
}
StorageProofNodeIterator { inner: proof.trie_nodes.into_iter() }
}
}
+29 -38
View File
@@ -21,17 +21,14 @@
//! it to substrate specific layout and child trie system.
use crate::{
EMPTY_PREFIX, HashDBT, TrieHash, TrieError, TrieConfiguration,
CompactProof, StorageProof,
CompactProof, HashDBT, StorageProof, TrieConfiguration, TrieError, TrieHash, EMPTY_PREFIX,
};
use sp_std::boxed::Box;
use sp_std::vec::Vec;
use trie_db::Trie;
#[cfg(feature="std")]
use std::fmt;
#[cfg(feature="std")]
use sp_std::{boxed::Box, vec::Vec};
#[cfg(feature = "std")]
use std::error::Error as StdError;
#[cfg(feature = "std")]
use std::fmt;
use trie_db::Trie;
/// Error for trie node decoding.
pub enum Error<L: TrieConfiguration> {
@@ -55,7 +52,7 @@ impl<L: TrieConfiguration> From<Box<TrieError<L>>> for Error<L> {
}
}
#[cfg(feature="std")]
#[cfg(feature = "std")]
impl<L: TrieConfiguration> StdError for Error<L> {
fn description(&self) -> &str {
match self {
@@ -69,14 +66,14 @@ impl<L: TrieConfiguration> StdError for Error<L> {
}
}
#[cfg(feature="std")]
#[cfg(feature = "std")]
impl<L: TrieConfiguration> fmt::Debug for Error<L> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<Self as fmt::Display>::fmt(&self, f)
}
}
#[cfg(feature="std")]
#[cfg(feature = "std")]
impl<L: TrieConfiguration> fmt::Display for Error<L> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
@@ -84,7 +81,8 @@ impl<L: TrieConfiguration> fmt::Display for Error<L> {
Error::TrieError(e) => write!(f, "Trie error: {}", e),
Error::IncompleteProof => write!(f, "Incomplete proof"),
Error::ExtraneousChildNode => write!(f, "Child node content with no root in proof"),
Error::ExtraneousChildProof(root) => write!(f, "Proof of child trie {:x?} not in parent proof", root.as_ref()),
Error::ExtraneousChildProof(root) =>
write!(f, "Proof of child trie {:x?} not in parent proof", root.as_ref()),
Error::RootMismatch(root, expected) => write!(
f,
"Verification error, root is {:x?}, expected: {:x?}",
@@ -107,21 +105,19 @@ pub fn decode_compact<'a, L, DB, I>(
encoded: I,
expected_root: Option<&TrieHash<L>>,
) -> Result<TrieHash<L>, Error<L>>
where
L: TrieConfiguration,
DB: HashDBT<L::Hash, trie_db::DBValue> + hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
I: IntoIterator<Item = &'a [u8]>,
where
L: TrieConfiguration,
DB: HashDBT<L::Hash, trie_db::DBValue> + hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
I: IntoIterator<Item = &'a [u8]>,
{
let mut nodes_iter = encoded.into_iter();
let (top_root, _nb_used) = trie_db::decode_compact_from_iter::<L, _, _, _>(
db,
&mut nodes_iter,
)?;
let (top_root, _nb_used) =
trie_db::decode_compact_from_iter::<L, _, _, _>(db, &mut nodes_iter)?;
// Only check root if expected root is passed as argument.
if let Some(expected_root) = expected_root {
if expected_root != &top_root {
return Err(Error::RootMismatch(top_root.clone(), expected_root.clone()));
return Err(Error::RootMismatch(top_root.clone(), expected_root.clone()))
}
}
@@ -142,7 +138,7 @@ pub fn decode_compact<'a, L, DB, I>(
let mut root = TrieHash::<L>::default();
// still in a proof so prevent panic
if root.as_mut().len() != value.as_slice().len() {
return Err(Error::InvalidChildRoot(key, value));
return Err(Error::InvalidChildRoot(key, value))
}
root.as_mut().copy_from_slice(value.as_ref());
child_tries.push(root);
@@ -160,16 +156,14 @@ pub fn decode_compact<'a, L, DB, I>(
}
if !HashDBT::<L::Hash, _>::contains(db, &top_root, EMPTY_PREFIX) {
return Err(Error::IncompleteProof);
return Err(Error::IncompleteProof)
}
let mut previous_extracted_child_trie = None;
for child_root in child_tries.into_iter() {
if previous_extracted_child_trie.is_none() {
let (top_root, _) = trie_db::decode_compact_from_iter::<L, _, _, _>(
db,
&mut nodes_iter,
)?;
let (top_root, _) =
trie_db::decode_compact_from_iter::<L, _, _, _>(db, &mut nodes_iter)?;
previous_extracted_child_trie = Some(top_root);
}
@@ -184,11 +178,11 @@ pub fn decode_compact<'a, L, DB, I>(
if let Some(child_root) = previous_extracted_child_trie {
// A child root was read from proof but is not present
// in top trie.
return Err(Error::ExtraneousChildProof(child_root));
return Err(Error::ExtraneousChildProof(child_root))
}
if nodes_iter.next().is_some() {
return Err(Error::ExtraneousChildNode);
return Err(Error::ExtraneousChildNode)
}
Ok(top_root)
@@ -201,12 +195,9 @@ pub fn decode_compact<'a, L, DB, I>(
/// Then parse all child trie root and compress main trie content first
/// then all child trie contents.
/// Child trie are ordered by the order of their roots in the top trie.
pub fn encode_compact<L>(
proof: StorageProof,
root: TrieHash<L>,
) -> Result<CompactProof, Error<L>>
where
L: TrieConfiguration,
pub fn encode_compact<L>(proof: StorageProof, root: TrieHash<L>) -> Result<CompactProof, Error<L>>
where
L: TrieConfiguration,
{
let mut child_tries = Vec::new();
let partial_db = proof.into_memory_db();
@@ -223,7 +214,7 @@ pub fn encode_compact<L>(
let mut root = TrieHash::<L>::default();
if root.as_mut().len() != value.as_slice().len() {
// some child trie root in top trie are not an encoded hash.
return Err(Error::InvalidChildRoot(key.to_vec(), value.to_vec()));
return Err(Error::InvalidChildRoot(key.to_vec(), value.to_vec()))
}
root.as_mut().copy_from_slice(value.as_ref());
child_tries.push(root);
@@ -246,7 +237,7 @@ pub fn encode_compact<L>(
if !HashDBT::<L::Hash, _>::contains(&partial_db, &child_root, EMPTY_PREFIX) {
// child proof are allowed to be missing (unused root can be included
// due to trie structure modification).
continue;
continue
}
let trie = crate::TrieDB::<L>::new(&partial_db, &child_root)?;
+27 -26
View File
@@ -17,13 +17,15 @@
//! `TrieStream` implementation for Substrate's trie format.
use hash_db::Hasher;
use trie_root;
use crate::{
node_codec::Bitmap,
node_header::{size_and_prefix_iterator, NodeKind},
trie_constants,
};
use codec::Encode;
use hash_db::Hasher;
use sp_std::vec::Vec;
use crate::trie_constants;
use crate::node_header::{NodeKind, size_and_prefix_iterator};
use crate::node_codec::Bitmap;
use trie_root;
const BRANCH_NODE_NO_VALUE: u8 = 254;
const BRANCH_NODE_WITH_VALUE: u8 = 255;
@@ -36,41 +38,42 @@ pub struct TrieStream {
impl TrieStream {
// useful for debugging but not used otherwise
pub fn as_raw(&self) -> &[u8] { &self.buffer }
pub fn as_raw(&self) -> &[u8] {
&self.buffer
}
}
fn branch_node_bit_mask(has_children: impl Iterator<Item = bool>) -> (u8, u8) {
let mut bitmap: u16 = 0;
let mut cursor: u16 = 1;
for v in has_children {
if v { bitmap |= cursor }
if v {
bitmap |= cursor
}
cursor <<= 1;
}
((bitmap % 256 ) as u8, (bitmap / 256 ) as u8)
((bitmap % 256) as u8, (bitmap / 256) as u8)
}
/// Create a leaf/branch node, encoding a number of nibbles.
fn fuse_nibbles_node<'a>(nibbles: &'a [u8], kind: NodeKind) -> impl Iterator<Item = u8> + 'a {
let size = sp_std::cmp::min(trie_constants::NIBBLE_SIZE_BOUND, nibbles.len());
let iter_start = match kind {
NodeKind::Leaf => size_and_prefix_iterator(size, trie_constants::LEAF_PREFIX_MASK),
NodeKind::BranchNoValue => size_and_prefix_iterator(size, trie_constants::BRANCH_WITHOUT_MASK),
NodeKind::BranchWithValue => size_and_prefix_iterator(size, trie_constants::BRANCH_WITH_MASK),
NodeKind::BranchNoValue =>
size_and_prefix_iterator(size, trie_constants::BRANCH_WITHOUT_MASK),
NodeKind::BranchWithValue =>
size_and_prefix_iterator(size, trie_constants::BRANCH_WITH_MASK),
};
iter_start
.chain(if nibbles.len() % 2 == 1 { Some(nibbles[0]) } else { None })
.chain(nibbles[nibbles.len() % 2..].chunks(2).map(|ch| ch[0] << 4 | ch[1]))
}
impl trie_root::TrieStream for TrieStream {
fn new() -> Self {
TrieStream {
buffer: Vec::new()
}
TrieStream { buffer: Vec::new() }
}
fn append_empty_data(&mut self) {
@@ -95,7 +98,7 @@ impl trie_root::TrieStream for TrieStream {
self.buffer.extend(fuse_nibbles_node(partial, NodeKind::BranchNoValue));
}
let bm = branch_node_bit_mask(has_children);
self.buffer.extend([bm.0,bm.1].iter());
self.buffer.extend([bm.0, bm.1].iter());
} else {
debug_assert!(false, "trie stream codec only for no extension trie");
self.buffer.extend(&branch_node(maybe_value.is_some(), has_children));
@@ -117,7 +120,9 @@ impl trie_root::TrieStream for TrieStream {
}
}
fn out(self) -> Vec<u8> { self.buffer }
fn out(self) -> Vec<u8> {
self.buffer
}
}
fn branch_node(has_value: bool, has_children: impl Iterator<Item = bool>) -> [u8; 3] {
@@ -126,15 +131,11 @@ fn branch_node(has_value: bool, has_children: impl Iterator<Item = bool>) -> [u8
result
}
fn branch_node_buffered<I>(has_value: bool, has_children: I, output: &mut[u8])
where
I: Iterator<Item = bool>,
fn branch_node_buffered<I>(has_value: bool, has_children: I, output: &mut [u8])
where
I: Iterator<Item = bool>,
{
let first = if has_value {
BRANCH_NODE_WITH_VALUE
} else {
BRANCH_NODE_NO_VALUE
};
let first = if has_value { BRANCH_NODE_WITH_VALUE } else { BRANCH_NODE_NO_VALUE };
output[0] = first;
Bitmap::encode(has_children, &mut output[1..]);
}