1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

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

            
18
//! Utility functions to interact with Substrate's Base-16 Modified Merkle Patricia tree ("trie").
19

            
20
#![cfg_attr(not(feature = "std"), no_std)]
21

            
22
extern crate alloc;
23

            
24
pub mod accessed_nodes_tracker;
25
#[cfg(feature = "std")]
26
pub mod cache;
27
mod error;
28
mod node_codec;
29
mod node_header;
30
#[cfg(feature = "std")]
31
pub mod recorder;
32
pub mod recorder_ext;
33
mod storage_proof;
34
mod trie_codec;
35
mod trie_stream;
36

            
37
#[cfg(feature = "std")]
38
pub mod proof_size_extension;
39

            
40
use alloc::{borrow::Borrow, boxed::Box, vec, vec::Vec};
41
use core::marker::PhantomData;
42
/// Our `NodeCodec`-specific error.
43
pub use error::Error;
44
/// Various re-exports from the `hash-db` crate.
45
pub use hash_db::{HashDB as HashDBT, EMPTY_PREFIX};
46
use hash_db::{Hasher, Prefix};
47
/// Various re-exports from the `memory-db` crate.
48
pub use memory_db::{prefixed_key, HashKey, KeyFunction, PrefixedKey};
49
/// The Substrate format implementation of `NodeCodec`.
50
pub use node_codec::NodeCodec;
51
pub use storage_proof::{CompactProof, StorageProof, StorageProofError};
52
/// Trie codec reexport, mainly child trie support
53
/// for trie compact proof.
54
pub use trie_codec::{decode_compact, encode_compact, Error as CompactProofError};
55
use trie_db::proof::{generate_proof, verify_proof};
56
/// Various re-exports from the `trie-db` crate.
57
pub use trie_db::{
58
	nibble_ops,
59
	node::{NodePlan, ValuePlan},
60
	triedb::{TrieDBDoubleEndedIterator, TrieDBKeyDoubleEndedIterator},
61
	CError, DBValue, Query, Recorder, Trie, TrieCache, TrieConfiguration, TrieDBIterator,
62
	TrieDBKeyIterator, TrieDBNodeDoubleEndedIterator, TrieDBRawIterator, TrieLayout, TrieMut,
63
	TrieRecorder,
64
};
65
pub use trie_db::{proof::VerifyError, MerkleValue};
66
/// The Substrate format implementation of `TrieStream`.
67
pub use trie_stream::TrieStream;
68

            
69
/// Raw storage proof type (just raw trie nodes).
70
pub type RawStorageProof = Vec<Vec<u8>>;
71

            
72
/// substrate trie layout
73
pub struct LayoutV0<H>(PhantomData<H>);
74

            
75
/// substrate trie layout, with external value nodes.
76
pub struct LayoutV1<H>(PhantomData<H>);
77

            
78
impl<H> TrieLayout for LayoutV0<H>
79
where
80
	H: Hasher,
81
{
82
	const USE_EXTENSION: bool = false;
83
	const ALLOW_EMPTY: bool = true;
84
	const MAX_INLINE_VALUE: Option<u32> = None;
85

            
86
	type Hash = H;
87
	type Codec = NodeCodec<Self::Hash>;
88
}
89

            
90
impl<H> TrieConfiguration for LayoutV0<H>
91
where
92
	H: Hasher,
93
{
94
129842
	fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out
95
129842
	where
96
129842
		I: IntoIterator<Item = (A, B)>,
97
129842
		A: AsRef<[u8]> + Ord,
98
129842
		B: AsRef<[u8]>,
99
129842
	{
100
129842
		trie_root::trie_root_no_extension::<H, TrieStream, _, _, _>(input, Self::MAX_INLINE_VALUE)
101
129842
	}
102

            
103
	fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8>
104
	where
105
		I: IntoIterator<Item = (A, B)>,
106
		A: AsRef<[u8]> + Ord,
107
		B: AsRef<[u8]>,
108
	{
109
		trie_root::unhashed_trie_no_extension::<H, TrieStream, _, _, _>(
110
			input,
111
			Self::MAX_INLINE_VALUE,
112
		)
113
	}
114

            
115
129842
	fn encode_index(input: u32) -> Vec<u8> {
116
129842
		codec::Encode::encode(&codec::Compact(input))
117
129842
	}
118
}
119

            
120
impl<H> TrieLayout for LayoutV1<H>
121
where
122
	H: Hasher,
123
{
124
	const USE_EXTENSION: bool = false;
125
	const ALLOW_EMPTY: bool = true;
126
	const MAX_INLINE_VALUE: Option<u32> = Some(sp_core::storage::TRIE_VALUE_NODE_THRESHOLD);
127

            
128
	type Hash = H;
129
	type Codec = NodeCodec<Self::Hash>;
130
}
131

            
132
impl<H> TrieConfiguration for LayoutV1<H>
133
where
134
	H: Hasher,
135
{
136
7339768
	fn trie_root<I, A, B>(input: I) -> <Self::Hash as Hasher>::Out
137
7339768
	where
138
7339768
		I: IntoIterator<Item = (A, B)>,
139
7339768
		A: AsRef<[u8]> + Ord,
140
7339768
		B: AsRef<[u8]>,
141
7339768
	{
142
7339768
		trie_root::trie_root_no_extension::<H, TrieStream, _, _, _>(input, Self::MAX_INLINE_VALUE)
143
7339768
	}
144

            
145
	fn trie_root_unhashed<I, A, B>(input: I) -> Vec<u8>
146
	where
147
		I: IntoIterator<Item = (A, B)>,
148
		A: AsRef<[u8]> + Ord,
149
		B: AsRef<[u8]>,
150
	{
151
		trie_root::unhashed_trie_no_extension::<H, TrieStream, _, _, _>(
152
			input,
153
			Self::MAX_INLINE_VALUE,
154
		)
155
	}
156

            
157
	fn encode_index(input: u32) -> Vec<u8> {
158
		codec::Encode::encode(&codec::Compact(input))
159
	}
160
}
161

            
162
/// Type that is able to provide a [`trie_db::TrieRecorder`].
163
///
164
/// Types implementing this trait can be used to maintain recorded state
165
/// across operations on different [`trie_db::TrieDB`] instances.
166
pub trait TrieRecorderProvider<H: Hasher> {
167
	/// Recorder type that is going to be returned by implementors of this trait.
168
	type Recorder<'a>: trie_db::TrieRecorder<H::Out> + 'a
169
	where
170
		Self: 'a;
171

            
172
	/// Create a [`StorageProof`] derived from the internal state.
173
	fn drain_storage_proof(self) -> Option<StorageProof>;
174

            
175
	/// Provide a recorder implementing [`trie_db::TrieRecorder`].
176
	fn as_trie_recorder(&self, storage_root: H::Out) -> Self::Recorder<'_>;
177
}
178

            
179
/// Type that is able to provide a proof size estimation.
180
pub trait ProofSizeProvider {
181
	/// Returns the storage proof size.
182
	fn estimate_encoded_size(&self) -> usize;
183
}
184

            
185
/// TrieDB error over `TrieConfiguration` trait.
186
pub type TrieError<L> = trie_db::TrieError<TrieHash<L>, CError<L>>;
187
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
188
pub trait AsHashDB<H: Hasher>: hash_db::AsHashDB<H, trie_db::DBValue> {}
189
impl<H: Hasher, T: hash_db::AsHashDB<H, trie_db::DBValue>> AsHashDB<H> for T {}
190
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
191
pub type HashDB<'a, H> = dyn hash_db::HashDB<H, trie_db::DBValue> + 'a;
192
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
193
/// This uses a `KeyFunction` for prefixing keys internally (avoiding
194
/// key conflict for non random keys).
195
pub type PrefixedMemoryDB<H> = memory_db::MemoryDB<H, memory_db::PrefixedKey<H>, trie_db::DBValue>;
196
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
197
/// This uses a noops `KeyFunction` (key addressing must be hashed or using
198
/// an encoding scheme that avoid key conflict).
199
pub type MemoryDB<H> = memory_db::MemoryDB<H, memory_db::HashKey<H>, trie_db::DBValue>;
200
/// Reexport from `hash_db`, with genericity set for `Hasher` trait.
201
pub type GenericMemoryDB<H, KF> = memory_db::MemoryDB<H, KF, trie_db::DBValue>;
202

            
203
/// Persistent trie database read-access interface for a given hasher.
204
pub type TrieDB<'a, 'cache, L> = trie_db::TrieDB<'a, 'cache, L>;
205
/// Builder for creating a [`TrieDB`].
206
pub type TrieDBBuilder<'a, 'cache, L> = trie_db::TrieDBBuilder<'a, 'cache, L>;
207
/// Persistent trie database write-access interface for a given hasher.
208
pub type TrieDBMut<'a, L> = trie_db::TrieDBMut<'a, L>;
209
/// Builder for creating a [`TrieDBMut`].
210
pub type TrieDBMutBuilder<'a, L> = trie_db::TrieDBMutBuilder<'a, L>;
211
/// Querying interface, as in `trie_db` but less generic.
212
pub type Lookup<'a, 'cache, L, Q> = trie_db::Lookup<'a, 'cache, L, Q>;
213
/// Hash type for a trie layout.
214
pub type TrieHash<L> = <<L as TrieLayout>::Hash as Hasher>::Out;
215
/// This module is for non generic definition of trie type.
216
/// Only the `Hasher` trait is generic in this case.
217
pub mod trie_types {
218
	use super::*;
219

            
220
	/// Persistent trie database read-access interface for a given hasher.
221
	///
222
	/// Read only V1 and V0 are compatible, thus we always use V1.
223
	pub type TrieDB<'a, 'cache, H> = super::TrieDB<'a, 'cache, LayoutV1<H>>;
224
	/// Builder for creating a [`TrieDB`].
225
	pub type TrieDBBuilder<'a, 'cache, H> = super::TrieDBBuilder<'a, 'cache, LayoutV1<H>>;
226
	/// Persistent trie database write-access interface for a given hasher.
227
	pub type TrieDBMutV0<'a, H> = super::TrieDBMut<'a, LayoutV0<H>>;
228
	/// Builder for creating a [`TrieDBMutV0`].
229
	pub type TrieDBMutBuilderV0<'a, H> = super::TrieDBMutBuilder<'a, LayoutV0<H>>;
230
	/// Persistent trie database write-access interface for a given hasher.
231
	pub type TrieDBMutV1<'a, H> = super::TrieDBMut<'a, LayoutV1<H>>;
232
	/// Builder for creating a [`TrieDBMutV1`].
233
	pub type TrieDBMutBuilderV1<'a, H> = super::TrieDBMutBuilder<'a, LayoutV1<H>>;
234
	/// Querying interface, as in `trie_db` but less generic.
235
	pub type Lookup<'a, 'cache, H, Q> = trie_db::Lookup<'a, 'cache, LayoutV1<H>, Q>;
236
	/// As in `trie_db`, but less generic, error type for the crate.
237
	pub type TrieError<H> = trie_db::TrieError<H, super::Error<H>>;
238
}
239

            
240
/// Create a proof for a subset of keys in a trie.
241
///
242
/// The `keys` may contain any set of keys regardless of each one of them is included
243
/// in the `db`.
244
///
245
/// For a key `K` that is included in the `db` a proof of inclusion is generated.
246
/// For a key `K` that is not included in the `db` a proof of non-inclusion is generated.
247
/// These can be later checked in `verify_trie_proof`.
248
pub fn generate_trie_proof<'a, L, I, K, DB>(
249
	db: &DB,
250
	root: TrieHash<L>,
251
	keys: I,
252
) -> Result<Vec<Vec<u8>>, Box<TrieError<L>>>
253
where
254
	L: TrieConfiguration,
255
	I: IntoIterator<Item = &'a K>,
256
	K: 'a + AsRef<[u8]>,
257
	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
258
{
259
	generate_proof::<_, L, _, _>(db, &root, keys)
260
}
261

            
262
/// Verify a set of key-value pairs against a trie root and a proof.
263
///
264
/// Checks a set of keys with optional values for inclusion in the proof that was generated by
265
/// `generate_trie_proof`.
266
/// If the value in the pair is supplied (`(key, Some(value))`), this key-value pair will be
267
/// checked for inclusion in the proof.
268
/// If the value is omitted (`(key, None)`), this key will be checked for non-inclusion in the
269
/// proof.
270
pub fn verify_trie_proof<'a, L, I, K, V>(
271
	root: &TrieHash<L>,
272
	proof: &[Vec<u8>],
273
	items: I,
274
) -> Result<(), VerifyError<TrieHash<L>, CError<L>>>
275
where
276
	L: TrieConfiguration,
277
	I: IntoIterator<Item = &'a (K, Option<V>)>,
278
	K: 'a + AsRef<[u8]>,
279
	V: 'a + AsRef<[u8]>,
280
{
281
	verify_proof::<L, _, _, _>(root, proof, items)
282
}
283

            
284
/// Determine a trie root given a hash DB and delta values.
285
3540042
pub fn delta_trie_root<L: TrieConfiguration, I, A, B, DB, V>(
286
3540042
	db: &mut DB,
287
3540042
	mut root: TrieHash<L>,
288
3540042
	delta: I,
289
3540042
	recorder: Option<&mut dyn trie_db::TrieRecorder<TrieHash<L>>>,
290
3540042
	cache: Option<&mut dyn TrieCache<L::Codec>>,
291
3540042
) -> Result<TrieHash<L>, Box<TrieError<L>>>
292
3540042
where
293
3540042
	I: IntoIterator<Item = (A, B)>,
294
3540042
	A: Borrow<[u8]>,
295
3540042
	B: Borrow<Option<V>>,
296
3540042
	V: Borrow<[u8]>,
297
3540042
	DB: hash_db::HashDB<L::Hash, trie_db::DBValue>,
298
3540042
{
299
3540042
	{
300
3540042
		let mut trie = TrieDBMutBuilder::<L>::from_existing(db, &mut root)
301
3540042
			.with_optional_cache(cache)
302
3540042
			.with_optional_recorder(recorder)
303
3540042
			.build();
304
3540042

            
305
3540042
		let mut delta = delta.into_iter().collect::<Vec<_>>();
306
3540042
		delta.sort_by(|l, r| l.0.borrow().cmp(r.0.borrow()));
307

            
308
7080084
		for (key, change) in delta {
309
3540042
			match change.borrow() {
310
3540042
				Some(val) => trie.insert(key.borrow(), val.borrow())?,
311
				None => trie.remove(key.borrow())?,
312
			};
313
		}
314
	}
315

            
316
3540042
	Ok(root)
317
3540042
}
318

            
319
/// Read a value from the trie.
320
53637
pub fn read_trie_value<L: TrieLayout, DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>>(
321
53637
	db: &DB,
322
53637
	root: &TrieHash<L>,
323
53637
	key: &[u8],
324
53637
	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
325
53637
	cache: Option<&mut dyn TrieCache<L::Codec>>,
326
53637
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
327
53637
	TrieDBBuilder::<L>::new(db, root)
328
53637
		.with_optional_cache(cache)
329
53637
		.with_optional_recorder(recorder)
330
53637
		.build()
331
53637
		.get(key)
332
53637
}
333

            
334
/// Read the [`trie_db::MerkleValue`] of the node that is the closest descendant for
335
/// the provided key.
336
pub fn read_trie_first_descendant_value<L: TrieLayout, DB>(
337
	db: &DB,
338
	root: &TrieHash<L>,
339
	key: &[u8],
340
	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
341
	cache: Option<&mut dyn TrieCache<L::Codec>>,
342
) -> Result<Option<MerkleValue<TrieHash<L>>>, Box<TrieError<L>>>
343
where
344
	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
345
{
346
	TrieDBBuilder::<L>::new(db, root)
347
		.with_optional_cache(cache)
348
		.with_optional_recorder(recorder)
349
		.build()
350
		.lookup_first_descendant(key)
351
}
352

            
353
/// Read a value from the trie with given Query.
354
pub fn read_trie_value_with<
355
	L: TrieLayout,
356
	Q: Query<L::Hash, Item = Vec<u8>>,
357
	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
358
>(
359
	db: &DB,
360
	root: &TrieHash<L>,
361
	key: &[u8],
362
	query: Q,
363
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>> {
364
	TrieDBBuilder::<L>::new(db, root).build().get_with(key, query)
365
}
366

            
367
/// Determine the empty trie root.
368
7080084
pub fn empty_trie_root<L: TrieConfiguration>() -> <L::Hash as Hasher>::Out {
369
7080084
	L::trie_root::<_, Vec<u8>, Vec<u8>>(core::iter::empty())
370
7080084
}
371

            
372
/// Determine the empty child trie root.
373
129842
pub fn empty_child_trie_root<L: TrieConfiguration>() -> <L::Hash as Hasher>::Out {
374
129842
	L::trie_root::<_, Vec<u8>, Vec<u8>>(core::iter::empty())
375
129842
}
376

            
377
/// Determine a child trie root given its ordered contents, closed form. H is the default hasher,
378
/// but a generic implementation may ignore this type parameter and use other hashers.
379
pub fn child_trie_root<L: TrieConfiguration, I, A, B>(input: I) -> <L::Hash as Hasher>::Out
380
where
381
	I: IntoIterator<Item = (A, B)>,
382
	A: AsRef<[u8]> + Ord,
383
	B: AsRef<[u8]>,
384
{
385
	L::trie_root(input)
386
}
387

            
388
/// Determine a child trie root given a hash DB and delta values. H is the default hasher,
389
/// but a generic implementation may ignore this type parameter and use other hashers.
390
pub fn child_delta_trie_root<L: TrieConfiguration, I, A, B, DB, RD, V>(
391
	keyspace: &[u8],
392
	db: &mut DB,
393
	root_data: RD,
394
	delta: I,
395
	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
396
	cache: Option<&mut dyn TrieCache<L::Codec>>,
397
) -> Result<<L::Hash as Hasher>::Out, Box<TrieError<L>>>
398
where
399
	I: IntoIterator<Item = (A, B)>,
400
	A: Borrow<[u8]>,
401
	B: Borrow<Option<V>>,
402
	V: Borrow<[u8]>,
403
	RD: AsRef<[u8]>,
404
	DB: hash_db::HashDB<L::Hash, trie_db::DBValue>,
405
{
406
	let mut root = TrieHash::<L>::default();
407
	// root is fetched from DB, not writable by runtime, so it's always valid.
408
	root.as_mut().copy_from_slice(root_data.as_ref());
409

            
410
	let mut db = KeySpacedDBMut::new(db, keyspace);
411
	delta_trie_root::<L, _, _, _, _, _>(&mut db, root, delta, recorder, cache)
412
}
413

            
414
/// Read a value from the child trie.
415
pub fn read_child_trie_value<L: TrieConfiguration, DB>(
416
	keyspace: &[u8],
417
	db: &DB,
418
	root: &TrieHash<L>,
419
	key: &[u8],
420
	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
421
	cache: Option<&mut dyn TrieCache<L::Codec>>,
422
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
423
where
424
	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
425
{
426
	let db = KeySpacedDB::new(db, keyspace);
427
	TrieDBBuilder::<L>::new(&db, &root)
428
		.with_optional_recorder(recorder)
429
		.with_optional_cache(cache)
430
		.build()
431
		.get(key)
432
		.map(|x| x.map(|val| val.to_vec()))
433
}
434

            
435
/// Read a hash from the child trie.
436
pub fn read_child_trie_hash<L: TrieConfiguration, DB>(
437
	keyspace: &[u8],
438
	db: &DB,
439
	root: &TrieHash<L>,
440
	key: &[u8],
441
	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
442
	cache: Option<&mut dyn TrieCache<L::Codec>>,
443
) -> Result<Option<TrieHash<L>>, Box<TrieError<L>>>
444
where
445
	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
446
{
447
	let db = KeySpacedDB::new(db, keyspace);
448
	TrieDBBuilder::<L>::new(&db, &root)
449
		.with_optional_recorder(recorder)
450
		.with_optional_cache(cache)
451
		.build()
452
		.get_hash(key)
453
}
454

            
455
/// Read the [`trie_db::MerkleValue`] of the node that is the closest descendant for
456
/// the provided child key.
457
pub fn read_child_trie_first_descendant_value<L: TrieConfiguration, DB>(
458
	keyspace: &[u8],
459
	db: &DB,
460
	root: &TrieHash<L>,
461
	key: &[u8],
462
	recorder: Option<&mut dyn TrieRecorder<TrieHash<L>>>,
463
	cache: Option<&mut dyn TrieCache<L::Codec>>,
464
) -> Result<Option<MerkleValue<TrieHash<L>>>, Box<TrieError<L>>>
465
where
466
	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
467
{
468
	let db = KeySpacedDB::new(db, keyspace);
469
	TrieDBBuilder::<L>::new(&db, &root)
470
		.with_optional_recorder(recorder)
471
		.with_optional_cache(cache)
472
		.build()
473
		.lookup_first_descendant(key)
474
}
475

            
476
/// Read a value from the child trie with given query.
477
pub fn read_child_trie_value_with<L, Q, DB>(
478
	keyspace: &[u8],
479
	db: &DB,
480
	root_slice: &[u8],
481
	key: &[u8],
482
	query: Q,
483
) -> Result<Option<Vec<u8>>, Box<TrieError<L>>>
484
where
485
	L: TrieConfiguration,
486
	Q: Query<L::Hash, Item = DBValue>,
487
	DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
488
{
489
	let mut root = TrieHash::<L>::default();
490
	// root is fetched from DB, not writable by runtime, so it's always valid.
491
	root.as_mut().copy_from_slice(root_slice);
492

            
493
	let db = KeySpacedDB::new(db, keyspace);
494
	TrieDBBuilder::<L>::new(&db, &root)
495
		.build()
496
		.get_with(key, query)
497
		.map(|x| x.map(|val| val.to_vec()))
498
}
499

            
500
/// `HashDB` implementation that append a encoded prefix (unique id bytes) in addition to the
501
/// prefix of every key value.
502
pub struct KeySpacedDB<'a, DB: ?Sized, H>(&'a DB, &'a [u8], PhantomData<H>);
503

            
504
/// `HashDBMut` implementation that append a encoded prefix (unique id bytes) in addition to the
505
/// prefix of every key value.
506
///
507
/// Mutable variant of `KeySpacedDB`, see [`KeySpacedDB`].
508
pub struct KeySpacedDBMut<'a, DB: ?Sized, H>(&'a mut DB, &'a [u8], PhantomData<H>);
509

            
510
/// Utility function used to merge some byte data (keyspace) and `prefix` data
511
/// before calling key value database primitives.
512
fn keyspace_as_prefix_alloc(ks: &[u8], prefix: Prefix) -> (Vec<u8>, Option<u8>) {
513
	let mut result = vec![0; ks.len() + prefix.0.len()];
514
	result[..ks.len()].copy_from_slice(ks);
515
	result[ks.len()..].copy_from_slice(prefix.0);
516
	(result, prefix.1)
517
}
518

            
519
impl<'a, DB: ?Sized, H> KeySpacedDB<'a, DB, H> {
520
	/// instantiate new keyspaced db
521
	#[inline]
522
	pub fn new(db: &'a DB, ks: &'a [u8]) -> Self {
523
		KeySpacedDB(db, ks, PhantomData)
524
	}
525
}
526

            
527
impl<'a, DB: ?Sized, H> KeySpacedDBMut<'a, DB, H> {
528
	/// instantiate new keyspaced db
529
	pub fn new(db: &'a mut DB, ks: &'a [u8]) -> Self {
530
		KeySpacedDBMut(db, ks, PhantomData)
531
	}
532
}
533

            
534
impl<'a, DB, H, T> hash_db::HashDBRef<H, T> for KeySpacedDB<'a, DB, H>
535
where
536
	DB: hash_db::HashDBRef<H, T> + ?Sized,
537
	H: Hasher,
538
	T: From<&'static [u8]>,
539
{
540
	fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
541
		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
542
		self.0.get(key, (&derived_prefix.0, derived_prefix.1))
543
	}
544

            
545
	fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
546
		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
547
		self.0.contains(key, (&derived_prefix.0, derived_prefix.1))
548
	}
549
}
550

            
551
impl<'a, DB, H, T> hash_db::HashDB<H, T> for KeySpacedDBMut<'a, DB, H>
552
where
553
	DB: hash_db::HashDB<H, T>,
554
	H: Hasher,
555
	T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
556
{
557
	fn get(&self, key: &H::Out, prefix: Prefix) -> Option<T> {
558
		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
559
		self.0.get(key, (&derived_prefix.0, derived_prefix.1))
560
	}
561

            
562
	fn contains(&self, key: &H::Out, prefix: Prefix) -> bool {
563
		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
564
		self.0.contains(key, (&derived_prefix.0, derived_prefix.1))
565
	}
566

            
567
	fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H::Out {
568
		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
569
		self.0.insert((&derived_prefix.0, derived_prefix.1), value)
570
	}
571

            
572
	fn emplace(&mut self, key: H::Out, prefix: Prefix, value: T) {
573
		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
574
		self.0.emplace(key, (&derived_prefix.0, derived_prefix.1), value)
575
	}
576

            
577
	fn remove(&mut self, key: &H::Out, prefix: Prefix) {
578
		let derived_prefix = keyspace_as_prefix_alloc(self.1, prefix);
579
		self.0.remove(key, (&derived_prefix.0, derived_prefix.1))
580
	}
581
}
582

            
583
impl<'a, DB, H, T> hash_db::AsHashDB<H, T> for KeySpacedDBMut<'a, DB, H>
584
where
585
	DB: hash_db::HashDB<H, T>,
586
	H: Hasher,
587
	T: Default + PartialEq<T> + for<'b> From<&'b [u8]> + Clone + Send + Sync,
588
{
589
	fn as_hash_db(&self) -> &dyn hash_db::HashDB<H, T> {
590
		self
591
	}
592

            
593
	fn as_hash_db_mut<'b>(&'b mut self) -> &'b mut (dyn hash_db::HashDB<H, T> + 'b) {
594
		&mut *self
595
	}
596
}
597

            
598
/// Constants used into trie simplification codec.
599
mod trie_constants {
600
	const FIRST_PREFIX: u8 = 0b_00 << 6;
601
	pub const LEAF_PREFIX_MASK: u8 = 0b_01 << 6;
602
	pub const BRANCH_WITHOUT_MASK: u8 = 0b_10 << 6;
603
	pub const BRANCH_WITH_MASK: u8 = 0b_11 << 6;
604
	pub const EMPTY_TRIE: u8 = FIRST_PREFIX | (0b_00 << 4);
605
	pub const ALT_HASHING_LEAF_PREFIX_MASK: u8 = FIRST_PREFIX | (0b_1 << 5);
606
	pub const ALT_HASHING_BRANCH_WITH_MASK: u8 = FIRST_PREFIX | (0b_01 << 4);
607
	pub const ESCAPE_COMPACT_HEADER: u8 = EMPTY_TRIE | 0b_00_01;
608
}
609

            
610
#[cfg(test)]
611
mod tests {
612
	use super::*;
613
	use codec::{Compact, Decode, Encode};
614
	use hash_db::{HashDB, Hasher};
615
	use sp_core::Blake2Hasher;
616
	use trie_db::{DBValue, NodeCodec as NodeCodecT, Trie, TrieMut};
617
	use trie_standardmap::{Alphabet, StandardMap, ValueMode};
618

            
619
	type LayoutV0 = super::LayoutV0<Blake2Hasher>;
620
	type LayoutV1 = super::LayoutV1<Blake2Hasher>;
621

            
622
	type MemoryDBMeta<H> = memory_db::MemoryDB<H, memory_db::HashKey<H>, trie_db::DBValue>;
623

            
624
	pub fn create_trie<L: TrieLayout>(
625
		data: &[(&[u8], &[u8])],
626
	) -> (MemoryDB<L::Hash>, trie_db::TrieHash<L>) {
627
		let mut db = MemoryDB::default();
628
		let mut root = Default::default();
629

            
630
		{
631
			let mut trie = trie_db::TrieDBMutBuilder::<L>::new(&mut db, &mut root).build();
632
			for (k, v) in data {
633
				trie.insert(k, v).expect("Inserts data");
634
			}
635
		}
636

            
637
		let mut recorder = Recorder::<L>::new();
638
		{
639
			let trie = trie_db::TrieDBBuilder::<L>::new(&mut db, &mut root)
640
				.with_recorder(&mut recorder)
641
				.build();
642
			for (k, _v) in data {
643
				trie.get(k).unwrap();
644
			}
645
		}
646

            
647
		(db, root)
648
	}
649

            
650
	pub fn create_storage_proof<L: TrieLayout>(
651
		data: &[(&[u8], &[u8])],
652
	) -> (RawStorageProof, trie_db::TrieHash<L>) {
653
		let (db, root) = create_trie::<L>(data);
654

            
655
		let mut recorder = Recorder::<L>::new();
656
		{
657
			let trie = trie_db::TrieDBBuilder::<L>::new(&db, &root)
658
				.with_recorder(&mut recorder)
659
				.build();
660
			for (k, _v) in data {
661
				trie.get(k).unwrap();
662
			}
663
		}
664

            
665
		(recorder.drain().into_iter().map(|record| record.data).collect(), root)
666
	}
667

            
668
	fn hashed_null_node<T: TrieConfiguration>() -> TrieHash<T> {
669
		<T::Codec as NodeCodecT>::hashed_null_node()
670
	}
671

            
672
	fn check_equivalent<T: TrieConfiguration>(input: &Vec<(&[u8], &[u8])>) {
673
		{
674
			let closed_form = T::trie_root(input.clone());
675
			let d = T::trie_root_unhashed(input.clone());
676
			println!("Data: {:#x?}, {:#x?}", d, Blake2Hasher::hash(&d[..]));
677
			let persistent = {
678
				let mut memdb = MemoryDBMeta::default();
679
				let mut root = Default::default();
680
				let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
681
				for (x, y) in input.iter().rev() {
682
					t.insert(x, y).unwrap();
683
				}
684
				*t.root()
685
			};
686
			assert_eq!(closed_form, persistent);
687
		}
688
	}
689

            
690
	fn check_iteration<T: TrieConfiguration>(input: &Vec<(&[u8], &[u8])>) {
691
		let mut memdb = MemoryDBMeta::default();
692
		let mut root = Default::default();
693
		{
694
			let mut t = TrieDBMutBuilder::<T>::new(&mut memdb, &mut root).build();
695
			for (x, y) in input.clone() {
696
				t.insert(x, y).unwrap();
697
			}
698
		}
699
		{
700
			let t = TrieDBBuilder::<T>::new(&memdb, &root).build();
701
			assert_eq!(
702
				input.iter().map(|(i, j)| (i.to_vec(), j.to_vec())).collect::<Vec<_>>(),
703
				t.iter()
704
					.unwrap()
705
					.map(|x| x.map(|y| (y.0, y.1.to_vec())).unwrap())
706
					.collect::<Vec<_>>()
707
			);
708
		}
709
	}
710

            
711
	fn check_input(input: &Vec<(&[u8], &[u8])>) {
712
		check_equivalent::<LayoutV0>(input);
713
		check_iteration::<LayoutV0>(input);
714
		check_equivalent::<LayoutV1>(input);
715
		check_iteration::<LayoutV1>(input);
716
	}
717

            
718
	#[test]
719
	fn default_trie_root() {
720
		let mut db = MemoryDB::default();
721
		let mut root = TrieHash::<LayoutV1>::default();
722
		let mut empty = TrieDBMutBuilder::<LayoutV1>::new(&mut db, &mut root).build();
723
		empty.commit();
724
		let root1 = empty.root().as_ref().to_vec();
725
		let root2: Vec<u8> = LayoutV1::trie_root::<_, Vec<u8>, Vec<u8>>(std::iter::empty())
726
			.as_ref()
727
			.iter()
728
			.cloned()
729
			.collect();
730

            
731
		assert_eq!(root1, root2);
732
	}
733

            
734
	#[test]
735
	fn empty_is_equivalent() {
736
		let input: Vec<(&[u8], &[u8])> = vec![];
737
		check_input(&input);
738
	}
739

            
740
	#[test]
741
	fn leaf_is_equivalent() {
742
		let input: Vec<(&[u8], &[u8])> = vec![(&[0xaa][..], &[0xbb][..])];
743
		check_input(&input);
744
	}
745

            
746
	#[test]
747
	fn branch_is_equivalent() {
748
		let input: Vec<(&[u8], &[u8])> =
749
			vec![(&[0xaa][..], &[0x10][..]), (&[0xba][..], &[0x11][..])];
750
		check_input(&input);
751
	}
752

            
753
	#[test]
754
	fn extension_and_branch_is_equivalent() {
755
		let input: Vec<(&[u8], &[u8])> =
756
			vec![(&[0xaa][..], &[0x10][..]), (&[0xab][..], &[0x11][..])];
757
		check_input(&input);
758
	}
759

            
760
	#[test]
761
	fn standard_is_equivalent() {
762
		let st = StandardMap {
763
			alphabet: Alphabet::All,
764
			min_key: 32,
765
			journal_key: 0,
766
			value_mode: ValueMode::Random,
767
			count: 1000,
768
		};
769
		let mut d = st.make();
770
		d.sort_by(|(a, _), (b, _)| a.cmp(b));
771
		let dr = d.iter().map(|v| (&v.0[..], &v.1[..])).collect();
772
		check_input(&dr);
773
	}
774

            
775
	#[test]
776
	fn extension_and_branch_with_value_is_equivalent() {
777
		let input: Vec<(&[u8], &[u8])> = vec![
778
			(&[0xaa][..], &[0xa0][..]),
779
			(&[0xaa, 0xaa][..], &[0xaa][..]),
780
			(&[0xaa, 0xbb][..], &[0xab][..]),
781
		];
782
		check_input(&input);
783
	}
784

            
785
	#[test]
786
	fn bigger_extension_and_branch_with_value_is_equivalent() {
787
		let input: Vec<(&[u8], &[u8])> = vec![
788
			(&[0xaa][..], &[0xa0][..]),
789
			(&[0xaa, 0xaa][..], &[0xaa][..]),
790
			(&[0xaa, 0xbb][..], &[0xab][..]),
791
			(&[0xbb][..], &[0xb0][..]),
792
			(&[0xbb, 0xbb][..], &[0xbb][..]),
793
			(&[0xbb, 0xcc][..], &[0xbc][..]),
794
		];
795
		check_input(&input);
796
	}
797

            
798
	#[test]
799
	fn single_long_leaf_is_equivalent() {
800
		let input: Vec<(&[u8], &[u8])> = vec![
801
			(
802
				&[0xaa][..],
803
				&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
804
			),
805
			(&[0xba][..], &[0x11][..]),
806
		];
807
		check_input(&input);
808
	}
809

            
810
	#[test]
811
	fn two_long_leaves_is_equivalent() {
812
		let input: Vec<(&[u8], &[u8])> = vec![
813
			(
814
				&[0xaa][..],
815
				&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
816
			),
817
			(
818
				&[0xba][..],
819
				&b"ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC"[..],
820
			),
821
		];
822
		check_input(&input);
823
	}
824

            
825
	fn populate_trie<'db, T: TrieConfiguration>(
826
		db: &'db mut dyn HashDB<T::Hash, DBValue>,
827
		root: &'db mut TrieHash<T>,
828
		v: &[(Vec<u8>, Vec<u8>)],
829
	) -> TrieDBMut<'db, T> {
830
		let mut t = TrieDBMutBuilder::<T>::new(db, root).build();
831
		for i in 0..v.len() {
832
			let key: &[u8] = &v[i].0;
833
			let val: &[u8] = &v[i].1;
834
			t.insert(key, val).unwrap();
835
		}
836
		t
837
	}
838

            
839
	fn unpopulate_trie<T: TrieConfiguration>(t: &mut TrieDBMut<'_, T>, v: &[(Vec<u8>, Vec<u8>)]) {
840
		for i in v {
841
			let key: &[u8] = &i.0;
842
			t.remove(key).unwrap();
843
		}
844
	}
845

            
846
	#[test]
847
	fn random_should_work() {
848
		random_should_work_inner::<LayoutV1>();
849
		random_should_work_inner::<LayoutV0>();
850
	}
851
	fn random_should_work_inner<L: TrieConfiguration>() {
852
		let mut seed = <Blake2Hasher as Hasher>::Out::zero();
853
		for test_i in 0..10_000 {
854
			if test_i % 50 == 0 {
855
				println!("{:?} of 10000 stress tests done", test_i);
856
			}
857
			let x = StandardMap {
858
				alphabet: Alphabet::Custom(b"@QWERTYUIOPASDFGHJKLZXCVBNM[/]^_".to_vec()),
859
				min_key: 5,
860
				journal_key: 0,
861
				value_mode: ValueMode::Index,
862
				count: 100,
863
			}
864
			.make_with(seed.as_fixed_bytes_mut());
865

            
866
			let real = L::trie_root(x.clone());
867
			let mut memdb = MemoryDB::default();
868
			let mut root = Default::default();
869

            
870
			let mut memtrie = populate_trie::<L>(&mut memdb, &mut root, &x);
871

            
872
			memtrie.commit();
873
			if *memtrie.root() != real {
874
				println!("TRIE MISMATCH");
875
				println!();
876
				println!("{:?} vs {:?}", memtrie.root(), real);
877
				for i in &x {
878
					println!("{:#x?} -> {:#x?}", i.0, i.1);
879
				}
880
			}
881
			assert_eq!(*memtrie.root(), real);
882
			unpopulate_trie::<L>(&mut memtrie, &x);
883
			memtrie.commit();
884
			let hashed_null_node = hashed_null_node::<L>();
885
			if *memtrie.root() != hashed_null_node {
886
				println!("- TRIE MISMATCH");
887
				println!();
888
				println!("{:?} vs {:?}", memtrie.root(), hashed_null_node);
889
				for i in &x {
890
					println!("{:#x?} -> {:#x?}", i.0, i.1);
891
				}
892
			}
893
			assert_eq!(*memtrie.root(), hashed_null_node);
894
		}
895
	}
896

            
897
	fn to_compact(n: u8) -> u8 {
898
		Compact(n).encode()[0]
899
	}
900

            
901
	#[test]
902
	fn codec_trie_empty() {
903
		let input: Vec<(&[u8], &[u8])> = vec![];
904
		let trie = LayoutV1::trie_root_unhashed(input);
905
		println!("trie: {:#x?}", trie);
906
		assert_eq!(trie, vec![0x0]);
907
	}
908

            
909
	#[test]
910
	fn codec_trie_single_tuple() {
911
		let input = vec![(vec![0xaa], vec![0xbb])];
912
		let trie = LayoutV1::trie_root_unhashed(input);
913
		println!("trie: {:#x?}", trie);
914
		assert_eq!(
915
			trie,
916
			vec![
917
				0x42,          // leaf 0x40 (2^6) with (+) key of 2 nibbles (0x02)
918
				0xaa,          // key data
919
				to_compact(1), // length of value in bytes as Compact
920
				0xbb           // value data
921
			]
922
		);
923
	}
924

            
925
	#[test]
926
	fn codec_trie_two_tuples_disjoint_keys() {
927
		let input = vec![(&[0x48, 0x19], &[0xfe]), (&[0x13, 0x14], &[0xff])];
928
		let trie = LayoutV1::trie_root_unhashed(input);
929
		println!("trie: {:#x?}", trie);
930
		let mut ex = Vec::<u8>::new();
931
		ex.push(0x80); // branch, no value (0b_10..) no nibble
932
		ex.push(0x12); // slots 1 & 4 are taken from 0-7
933
		ex.push(0x00); // no slots from 8-15
934
		ex.push(to_compact(0x05)); // first slot: LEAF, 5 bytes long.
935
		ex.push(0x43); // leaf 0x40 with 3 nibbles
936
		ex.push(0x03); // first nibble
937
		ex.push(0x14); // second & third nibble
938
		ex.push(to_compact(0x01)); // 1 byte data
939
		ex.push(0xff); // value data
940
		ex.push(to_compact(0x05)); // second slot: LEAF, 5 bytes long.
941
		ex.push(0x43); // leaf with 3 nibbles
942
		ex.push(0x08); // first nibble
943
		ex.push(0x19); // second & third nibble
944
		ex.push(to_compact(0x01)); // 1 byte data
945
		ex.push(0xfe); // value data
946

            
947
		assert_eq!(trie, ex);
948
	}
949

            
950
	#[test]
951
	fn iterator_works() {
952
		iterator_works_inner::<LayoutV1>();
953
		iterator_works_inner::<LayoutV0>();
954
	}
955
	fn iterator_works_inner<Layout: TrieConfiguration>() {
956
		let pairs = vec![
957
			(
958
				array_bytes::hex2bytes_unchecked("0103000000000000000464"),
959
				array_bytes::hex2bytes_unchecked("0400000000"),
960
			),
961
			(
962
				array_bytes::hex2bytes_unchecked("0103000000000000000469"),
963
				array_bytes::hex2bytes_unchecked("0401000000"),
964
			),
965
		];
966

            
967
		let mut mdb = MemoryDB::default();
968
		let mut root = Default::default();
969
		let _ = populate_trie::<Layout>(&mut mdb, &mut root, &pairs);
970

            
971
		let trie = TrieDBBuilder::<Layout>::new(&mdb, &root).build();
972

            
973
		let iter = trie.iter().unwrap();
974
		let mut iter_pairs = Vec::new();
975
		for pair in iter {
976
			let (key, value) = pair.unwrap();
977
			iter_pairs.push((key, value));
978
		}
979

            
980
		assert_eq!(pairs, iter_pairs);
981
	}
982

            
983
	#[test]
984
	fn proof_non_inclusion_works() {
985
		let pairs = vec![
986
			(array_bytes::hex2bytes_unchecked("0102"), array_bytes::hex2bytes_unchecked("01")),
987
			(array_bytes::hex2bytes_unchecked("0203"), array_bytes::hex2bytes_unchecked("0405")),
988
		];
989

            
990
		let mut memdb = MemoryDB::default();
991
		let mut root = Default::default();
992
		populate_trie::<LayoutV1>(&mut memdb, &mut root, &pairs);
993

            
994
		let non_included_key: Vec<u8> = array_bytes::hex2bytes_unchecked("0909");
995
		let proof =
996
			generate_trie_proof::<LayoutV1, _, _, _>(&memdb, root, &[non_included_key.clone()])
997
				.unwrap();
998

            
999
		// Verifying that the K was not included into the trie should work.
		assert!(verify_trie_proof::<LayoutV1, _, _, Vec<u8>>(
			&root,
			&proof,
			&[(non_included_key.clone(), None)],
		)
		.is_ok());
		// Verifying that the K was included into the trie should fail.
		assert!(verify_trie_proof::<LayoutV1, _, _, Vec<u8>>(
			&root,
			&proof,
			&[(non_included_key, Some(array_bytes::hex2bytes_unchecked("1010")))],
		)
		.is_err());
	}
	#[test]
	fn proof_inclusion_works() {
		let pairs = vec![
			(array_bytes::hex2bytes_unchecked("0102"), array_bytes::hex2bytes_unchecked("01")),
			(array_bytes::hex2bytes_unchecked("0203"), array_bytes::hex2bytes_unchecked("0405")),
		];
		let mut memdb = MemoryDB::default();
		let mut root = Default::default();
		populate_trie::<LayoutV1>(&mut memdb, &mut root, &pairs);
		let proof =
			generate_trie_proof::<LayoutV1, _, _, _>(&memdb, root, &[pairs[0].0.clone()]).unwrap();
		// Check that a K, V included into the proof are verified.
		assert!(verify_trie_proof::<LayoutV1, _, _, _>(
			&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::<LayoutV1, _, _, Vec<u8>>(
			&root,
			&proof,
			&[(pairs[0].0.clone(), None)]
		)
		.is_err());
		// K not included into the trie is not verified.
		assert!(verify_trie_proof::<LayoutV1, _, _, _>(
			&root,
			&proof,
			&[(array_bytes::hex2bytes_unchecked("4242"), 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::<LayoutV1, _, _, _>(
			&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();
		// 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();
		// Delta order that is "valid"
		let valid_delta = Vec::<(Vec<u8>, Option<Vec<u8>>)>::decode(
			&mut &include_bytes!("../test-res/valid-delta-order")[..],
		)
		.unwrap();
		let proof_db = proof.into_memory_db::<Blake2Hasher>();
		let first_storage_root = delta_trie_root::<LayoutV0, _, _, _, _, _>(
			&mut proof_db.clone(),
			storage_root,
			valid_delta,
			None,
			None,
		)
		.unwrap();
		let second_storage_root = delta_trie_root::<LayoutV0, _, _, _, _, _>(
			&mut proof_db.clone(),
			storage_root,
			invalid_delta,
			None,
			None,
		)
		.unwrap();
		assert_eq!(first_storage_root, second_storage_root);
	}
	#[test]
	fn big_key() {
		let check = |keysize: usize| {
			let mut memdb = PrefixedMemoryDB::<Blake2Hasher>::default();
			let mut root = Default::default();
			let mut t = TrieDBMutBuilder::<LayoutV1>::new(&mut memdb, &mut root).build();
			t.insert(&vec![0x01u8; keysize][..], &[0x01u8, 0x23]).unwrap();
			std::mem::drop(t);
			let t = TrieDBBuilder::<LayoutV1>::new(&memdb, &root).build();
			assert_eq!(t.get(&vec![0x01u8; keysize][..]).unwrap(), Some(vec![0x01u8, 0x23]));
		};
		check(u16::MAX as usize / 2); // old limit
		check(u16::MAX as usize / 2 + 1); // value over old limit still works
	}
	#[test]
	fn node_with_no_children_fail_decoding() {
		let branch = NodeCodec::<Blake2Hasher>::branch_node_nibbled(
			b"some_partial".iter().copied(),
			24,
			vec![None; 16].into_iter(),
			Some(trie_db::node::Value::Inline(b"value"[..].into())),
		);
		assert!(NodeCodec::<Blake2Hasher>::decode(branch.as_slice()).is_err());
	}
}