Skip to content

Commit 41bae75

Browse files
jimpocheme
authored andcommitted
Upgrade trie-db crate to 0.16.0. (paritytech#4144)
* Upgrade paritytech/trie crates to 0.16.0. * Fix tests and unexpected Cargo.lock change. * Bump trie-bench version.
1 parent 6d243da commit 41bae75

File tree

6 files changed

+112
-70
lines changed

6 files changed

+112
-70
lines changed

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

primitives/state-machine/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ edition = "2018"
99
log = "0.4.8"
1010
parking_lot = "0.9.0"
1111
hash-db = "0.15.2"
12-
trie-db = "0.15.2"
12+
trie-db = "0.16.0"
1313
trie-root = "0.15.2"
1414
trie = { package = "substrate-trie", path = "../trie" }
1515
primitives = { package = "substrate-primitives", path = "../core" }

primitives/trie/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ harness = false
1515
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false }
1616
rstd = { package = "sr-std", path = "../sr-std", default-features = false }
1717
hash-db = { version = "0.15.2", default-features = false }
18-
trie-db = { version = "0.15.2", default-features = false }
18+
trie-db = { version = "0.16.0", default-features = false }
1919
trie-root = { version = "0.15.2", default-features = false }
2020
memory-db = { version = "0.15.2", default-features = false }
2121
primitives = { package = "substrate-primitives", path = "../core", default-features = false }
2222

2323
[dev-dependencies]
24-
trie-bench = "0.16.2"
24+
trie-bench = "0.16.3"
2525
trie-standardmap = "0.15.2"
2626
criterion = "0.2.11"
2727
hex-literal = "0.2.1"

primitives/trie/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ mod tests {
323323
type Layout = super::Layout<Blake2Hasher>;
324324

325325
fn hashed_null_node<T: TrieConfiguration>() -> TrieHash<T> {
326-
<T::Codec as NodeCodecT<_>>::hashed_null_node()
326+
<T::Codec as NodeCodecT>::hashed_null_node()
327327
}
328328

329329
fn check_equivalent<T: TrieConfiguration>(input: &Vec<(&[u8], &[u8])>) {

primitives/trie/src/node_codec.rs

Lines changed: 95 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -17,105 +17,147 @@
1717
//! `NodeCodec` implementation for Substrate's trie format.
1818
1919
use rstd::marker::PhantomData;
20+
use rstd::ops::Range;
2021
use rstd::vec::Vec;
2122
use rstd::borrow::Borrow;
22-
use codec::{Encode, Decode, Compact};
23+
use codec::{Encode, Decode, Input, Compact};
2324
use hash_db::Hasher;
24-
use trie_db::{self, NibbleSlice, node::Node, ChildReference,
25+
use trie_db::{self, node::{NibbleSlicePlan, NodePlan, NodeHandlePlan}, ChildReference,
2526
nibble_ops, Partial, NodeCodec as NodeCodecT};
2627
use crate::error::Error;
2728
use crate::trie_constants;
2829
use super::{node_header::{NodeHeader, NodeKind}};
2930

30-
fn take<'a>(input: &mut &'a[u8], count: usize) -> Option<&'a[u8]> {
31-
if input.len() < count {
32-
return None
31+
/// Helper struct for trie node decoder. This implements `codec::Input` on a byte slice, while
32+
/// tracking the absolute position. This is similar to `std::io::Cursor` but does not implement
33+
/// `Read` and `io` is not in `rstd`.
34+
struct ByteSliceInput<'a> {
35+
data: &'a [u8],
36+
offset: usize,
37+
}
38+
39+
impl<'a> ByteSliceInput<'a> {
40+
fn new(data: &'a [u8]) -> Self {
41+
ByteSliceInput {
42+
data,
43+
offset: 0,
44+
}
45+
}
46+
47+
fn take(&mut self, count: usize) -> Result<Range<usize>, codec::Error> {
48+
if self.offset + count > self.data.len() {
49+
return Err("out of data".into());
50+
}
51+
52+
let range = self.offset..(self.offset + count);
53+
self.offset += count;
54+
Ok(range)
55+
}
56+
}
57+
58+
impl<'a> Input for ByteSliceInput<'a> {
59+
fn remaining_len(&mut self) -> Result<Option<usize>, codec::Error> {
60+
let remaining = if self.offset <= self.data.len() {
61+
Some(self.data.len() - self.offset)
62+
} else {
63+
None
64+
};
65+
Ok(remaining)
66+
}
67+
68+
fn read(&mut self, into: &mut [u8]) -> Result<(), codec::Error> {
69+
let range = self.take(into.len())?;
70+
into.copy_from_slice(&self.data[range]);
71+
Ok(())
72+
}
73+
74+
fn read_byte(&mut self) -> Result<u8, codec::Error> {
75+
if self.offset + 1 > self.data.len() {
76+
return Err("out of data".into());
77+
}
78+
79+
let byte = self.data[self.offset];
80+
self.offset += 1;
81+
Ok(byte)
3382
}
34-
let r = &(*input)[..count];
35-
*input = &(*input)[count..];
36-
Some(r)
3783
}
3884

3985
/// Concrete implementation of a `NodeCodec` with Parity Codec encoding, generic over the `Hasher`
4086
#[derive(Default, Clone)]
4187
pub struct NodeCodec<H>(PhantomData<H>);
4288

43-
impl<H: Hasher> NodeCodecT<H> for NodeCodec<H> {
89+
impl<H: Hasher> NodeCodecT for NodeCodec<H> {
4490
type Error = Error;
91+
type HashOut = H::Out;
4592

4693
fn hashed_null_node() -> <H as Hasher>::Out {
47-
H::hash(<Self as NodeCodecT<_>>::empty_node())
94+
H::hash(<Self as NodeCodecT>::empty_node())
4895
}
4996

50-
fn decode(data: &[u8]) -> rstd::result::Result<Node, Self::Error> {
51-
let input = &mut &*data;
52-
let head = NodeHeader::decode(input)?;
53-
match head {
54-
NodeHeader::Null => Ok(Node::Empty),
97+
fn decode_plan(data: &[u8]) -> rstd::result::Result<NodePlan, Self::Error> {
98+
let mut input = ByteSliceInput::new(data);
99+
match NodeHeader::decode(&mut input)? {
100+
NodeHeader::Null => Ok(NodePlan::Empty),
55101
NodeHeader::Branch(has_value, nibble_count) => {
56102
let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
57103
// check that the padding is valid (if any)
58-
if padding && nibble_ops::pad_left(input[0]) != 0 {
104+
if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
59105
return Err(Error::BadFormat);
60106
}
61-
let nibble_data = take(
62-
input,
107+
let partial = input.take(
63108
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
64-
).ok_or(Error::BadFormat)?;
65-
let nibble_slice = NibbleSlice::new_offset(
66-
nibble_data,
67-
nibble_ops::number_padding(nibble_count),
68-
);
69-
let bitmap_slice = take(input, BITMAP_LENGTH).ok_or(Error::BadFormat)?;
70-
let bitmap = Bitmap::decode(&bitmap_slice[..])?;
109+
)?;
110+
let partial_padding = nibble_ops::number_padding(nibble_count);
111+
let bitmap_range = input.take(BITMAP_LENGTH)?;
112+
let bitmap = Bitmap::decode(&data[bitmap_range])?;
71113
let value = if has_value {
72-
let count = <Compact<u32>>::decode(input)?.0 as usize;
73-
Some(take(input, count).ok_or(Error::BadFormat)?)
114+
let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
115+
Some(input.take(count)?)
74116
} else {
75117
None
76118
};
77-
let mut children = [None; 16];
78-
119+
let mut children = [
120+
None, None, None, None, None, None, None, None,
121+
None, None, None, None, None, None, None, None,
122+
];
79123
for i in 0..nibble_ops::NIBBLE_LENGTH {
80124
if bitmap.value_at(i) {
81-
let count = <Compact<u32>>::decode(input)?.0 as usize;
82-
children[i] = Some(take(input, count).ok_or(Error::BadFormat)?);
125+
let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
126+
let range = input.take(count)?;
127+
children[i] = Some(if count == H::LENGTH {
128+
NodeHandlePlan::Hash(range)
129+
} else {
130+
NodeHandlePlan::Inline(range)
131+
});
83132
}
84133
}
85-
Ok(Node::NibbledBranch(nibble_slice, children, value))
134+
Ok(NodePlan::NibbledBranch {
135+
partial: NibbleSlicePlan::new(partial, partial_padding),
136+
value,
137+
children,
138+
})
86139
}
87140
NodeHeader::Leaf(nibble_count) => {
88141
let padding = nibble_count % nibble_ops::NIBBLE_PER_BYTE != 0;
89142
// check that the padding is valid (if any)
90-
if padding && nibble_ops::pad_left(input[0]) != 0 {
143+
if padding && nibble_ops::pad_left(data[input.offset]) != 0 {
91144
return Err(Error::BadFormat);
92145
}
93-
let nibble_data = take(
94-
input,
146+
let partial = input.take(
95147
(nibble_count + (nibble_ops::NIBBLE_PER_BYTE - 1)) / nibble_ops::NIBBLE_PER_BYTE,
96-
).ok_or(Error::BadFormat)?;
97-
let nibble_slice = NibbleSlice::new_offset(
98-
nibble_data,
99-
nibble_ops::number_padding(nibble_count),
100-
);
101-
let count = <Compact<u32>>::decode(input)?.0 as usize;
102-
Ok(Node::Leaf(nibble_slice, take(input, count).ok_or(Error::BadFormat)?))
148+
)?;
149+
let partial_padding = nibble_ops::number_padding(nibble_count);
150+
let count = <Compact<u32>>::decode(&mut input)?.0 as usize;
151+
Ok(NodePlan::Leaf {
152+
partial: NibbleSlicePlan::new(partial, partial_padding),
153+
value: input.take(count)?,
154+
})
103155
}
104156
}
105157
}
106158

107-
fn try_decode_hash(data: &[u8]) -> Option<<H as Hasher>::Out> {
108-
if data.len() == H::LENGTH {
109-
let mut r = <H as Hasher>::Out::default();
110-
r.as_mut().copy_from_slice(data);
111-
Some(r)
112-
} else {
113-
None
114-
}
115-
}
116-
117159
fn is_empty_node(data: &[u8]) -> bool {
118-
data == <Self as NodeCodecT<_>>::empty_node()
160+
data == <Self as NodeCodecT>::empty_node()
119161
}
120162

121163
fn empty_node() -> &'static [u8] {

test/utils/runtime/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pallet-timestamp = { path = "../../../frame/timestamp", default-features = false
3535
substrate-client = { path = "../../../client", optional = true }
3636
substrate-trie = { path = "../../../primitives/trie", default-features = false }
3737
transaction-pool-api = { package = "substrate-transaction-pool-runtime-api", path = "../../../primitives/transaction-pool/runtime-api", default-features = false }
38-
trie-db = { version = "0.15.2", default-features = false }
38+
trie-db = { version = "0.16.0", default-features = false }
3939

4040
[dev-dependencies]
4141
substrate-executor = { path = "../../../client/executor" }

0 commit comments

Comments
 (0)