trie_db/
triedbmut.rs

1// Copyright 2017, 2021 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! In-memory trie representation.
16
17use crate::{
18	lookup::Lookup,
19	nibble::{nibble_ops, BackingByteVec, NibbleSlice, NibbleVec},
20	node::{
21		decode_hash, Node as EncodedNode, NodeHandle as EncodedNodeHandle, NodeHandleOwned,
22		NodeKey, NodeOwned, Value as EncodedValue, ValueOwned,
23	},
24	node_codec::NodeCodec,
25	rstd::{boxed::Box, convert::TryFrom, mem, ops::Index, result, vec::Vec, VecDeque},
26	Bytes, CError, CachedValue, DBValue, Result, TrieAccess, TrieCache, TrieError, TrieHash,
27	TrieLayout, TrieMut, TrieRecorder,
28};
29
30use hash_db::{HashDB, Hasher, Prefix, EMPTY_PREFIX};
31
32#[cfg(feature = "std")]
33use std::collections::HashSet as Set;
34
35#[cfg(not(feature = "std"))]
36use alloc::collections::btree_set::BTreeSet as Set;
37
38#[cfg(feature = "std")]
39use log::trace;
40
41#[cfg(feature = "std")]
42use crate::rstd::fmt::{self, Debug};
43
44// For lookups into the Node storage buffer.
45// This is deliberately non-copyable.
46#[cfg_attr(feature = "std", derive(Debug))]
47struct StorageHandle(usize);
48
49// Handles to nodes in the trie.
50#[cfg_attr(feature = "std", derive(Debug))]
51enum NodeHandle<H> {
52	/// Loaded into memory.
53	InMemory(StorageHandle),
54	/// Either a hash or an inline node
55	Hash(H),
56}
57
58impl<H> From<StorageHandle> for NodeHandle<H> {
59	fn from(handle: StorageHandle) -> Self {
60		NodeHandle::InMemory(handle)
61	}
62}
63
64fn empty_children<H>() -> Box<[Option<NodeHandle<H>>; nibble_ops::NIBBLE_LENGTH]> {
65	Box::new([
66		None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
67		None,
68	])
69}
70
71/// Type alias to indicate the nible covers a full key,
72/// therefore its left side is a full prefix.
73type NibbleFullKey<'key> = NibbleSlice<'key>;
74
75/// Value representation for Node.
76#[derive(Clone, Eq)]
77pub enum Value<L: TrieLayout> {
78	/// Value bytes inlined in a trie node.
79	Inline(Bytes),
80	/// Hash of the value.
81	Node(TrieHash<L>),
82	/// Hash of value bytes if calculated and value bytes.
83	/// The hash may be undefined until it node is added
84	/// to the db.
85	NewNode(Option<TrieHash<L>>, Bytes),
86}
87
88impl<L: TrieLayout> PartialEq<Self> for Value<L> {
89	fn eq(&self, other: &Self) -> bool {
90		match (self, other) {
91			(Value::Inline(v), Value::Inline(ov)) => v == ov,
92			(Value::Node(h), Value::Node(oh)) => h == oh,
93			(Value::NewNode(Some(h), _), Value::NewNode(Some(oh), _)) => h == oh,
94			(Value::NewNode(_, v), Value::NewNode(_, ov)) => v == ov,
95			// Note that for uncalculated hash we do not calculate it and default to true.
96			// This is rather similar to default Eq implementation.
97			_ => false,
98		}
99	}
100}
101
102impl<'a, L: TrieLayout> From<EncodedValue<'a>> for Value<L> {
103	fn from(v: EncodedValue<'a>) -> Self {
104		match v {
105			EncodedValue::Inline(value) => Value::Inline(value.into()),
106			EncodedValue::Node(hash) => {
107				let mut h = TrieHash::<L>::default();
108				h.as_mut().copy_from_slice(hash);
109				Value::Node(h)
110			},
111		}
112	}
113}
114
115impl<L: TrieLayout> From<&ValueOwned<TrieHash<L>>> for Value<L> {
116	fn from(val: &ValueOwned<TrieHash<L>>) -> Self {
117		match val {
118			ValueOwned::Inline(data, _) => Self::Inline(data.clone()),
119			ValueOwned::Node(hash) => Self::Node(*hash),
120		}
121	}
122}
123
124impl<L: TrieLayout> From<(Bytes, Option<u32>)> for Value<L> {
125	fn from((v, threshold): (Bytes, Option<u32>)) -> Self {
126		match v {
127			value =>
128				if threshold.map_or(false, |threshold| value.len() >= threshold as usize) {
129					Value::NewNode(None, value)
130				} else {
131					Value::Inline(value)
132				},
133		}
134	}
135}
136
137enum NodeToEncode<'a, H> {
138	Node(&'a [u8]),
139	TrieNode(NodeHandle<H>),
140}
141
142impl<L: TrieLayout> Value<L> {
143	fn new(value: Bytes, new_threshold: Option<u32>) -> Self {
144		(value, new_threshold).into()
145	}
146
147	fn into_encoded<'a, F>(
148		&'a mut self,
149		partial: Option<&NibbleSlice>,
150		f: &mut F,
151	) -> EncodedValue<'a>
152	where
153		F: FnMut(
154			NodeToEncode<TrieHash<L>>,
155			Option<&NibbleSlice>,
156			Option<u8>,
157		) -> ChildReference<TrieHash<L>>,
158	{
159		if let Value::NewNode(hash, value) = self {
160			let new_hash =
161				if let ChildReference::Hash(hash) = f(NodeToEncode::Node(&value), partial, None) {
162					hash
163				} else {
164					unreachable!("Value node can never be inlined; qed")
165				};
166			if let Some(h) = hash.as_ref() {
167				debug_assert!(h == &new_hash);
168			} else {
169				*hash = Some(new_hash);
170			}
171		}
172		let value = match &*self {
173			Value::Inline(value) => EncodedValue::Inline(&value),
174			Value::Node(hash) => EncodedValue::Node(hash.as_ref()),
175			Value::NewNode(Some(hash), _value) => EncodedValue::Node(hash.as_ref()),
176			Value::NewNode(None, _value) =>
177				unreachable!("New external value are always added before encoding anode"),
178		};
179		value
180	}
181
182	fn in_memory_fetched_value(
183		&self,
184		prefix: Prefix,
185		db: &dyn HashDB<L::Hash, DBValue>,
186		recorder: &Option<core::cell::RefCell<&mut dyn TrieRecorder<TrieHash<L>>>>,
187		full_key: &[u8],
188	) -> Result<Option<DBValue>, TrieHash<L>, CError<L>> {
189		Ok(Some(match self {
190			Value::Inline(value) => value.to_vec(),
191			Value::NewNode(_, value) => value.to_vec(),
192			Value::Node(hash) =>
193				if let Some(value) = db.get(hash, prefix) {
194					recorder.as_ref().map(|r| {
195						r.borrow_mut().record(TrieAccess::Value {
196							hash: *hash,
197							value: value.as_slice().into(),
198							full_key,
199						})
200					});
201
202					value
203				} else {
204					return Err(Box::new(TrieError::IncompleteDatabase(hash.clone())))
205				},
206		}))
207	}
208}
209
210/// Node types in the Trie.
211enum Node<L: TrieLayout> {
212	/// Empty node.
213	Empty,
214	/// A leaf node contains the end of a key and a value.
215	/// This key is encoded from a `NibbleSlice`, meaning it contains
216	/// a flag indicating it is a leaf.
217	Leaf(NodeKey, Value<L>),
218	/// An extension contains a shared portion of a key and a child node.
219	/// The shared portion is encoded from a `NibbleSlice` meaning it contains
220	/// a flag indicating it is an extension.
221	/// The child node is always a branch.
222	Extension(NodeKey, NodeHandle<TrieHash<L>>),
223	/// A branch has up to 16 children and an optional value.
224	Branch(Box<[Option<NodeHandle<TrieHash<L>>>; nibble_ops::NIBBLE_LENGTH]>, Option<Value<L>>),
225	/// Branch node with support for a nibble (to avoid extension node).
226	NibbledBranch(
227		NodeKey,
228		Box<[Option<NodeHandle<TrieHash<L>>>; nibble_ops::NIBBLE_LENGTH]>,
229		Option<Value<L>>,
230	),
231}
232
233#[cfg(feature = "std")]
234struct ToHex<'a>(&'a [u8]);
235#[cfg(feature = "std")]
236impl<'a> Debug for ToHex<'a> {
237	fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
238		let hex = rustc_hex::ToHexIter::new(self.0.iter());
239		for b in hex {
240			write!(fmt, "{}", b)?;
241		}
242		Ok(())
243	}
244}
245
246#[cfg(feature = "std")]
247impl<L: TrieLayout> Debug for Value<L> {
248	fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
249		match self {
250			Self::Inline(value) => write!(fmt, "Some({:?})", ToHex(value)),
251			Self::Node(hash) => write!(fmt, "Hash({:?})", ToHex(hash.as_ref())),
252			Self::NewNode(Some(hash), _) => write!(fmt, "Hash({:?})", ToHex(hash.as_ref())),
253			Self::NewNode(_hash, value) => write!(fmt, "Some({:?})", ToHex(value)),
254		}
255	}
256}
257
258#[cfg(feature = "std")]
259impl<L: TrieLayout> Debug for Node<L>
260where
261	L::Hash: Debug,
262{
263	fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
264		match *self {
265			Self::Empty => write!(fmt, "Empty"),
266			Self::Leaf((ref a, ref b), ref c) =>
267				write!(fmt, "Leaf({:?}, {:?})", (a, ToHex(&*b)), c),
268			Self::Extension((ref a, ref b), ref c) =>
269				write!(fmt, "Extension({:?}, {:?})", (a, ToHex(&*b)), c),
270			Self::Branch(ref a, ref b) => write!(fmt, "Branch({:?}, {:?}", a, b),
271			Self::NibbledBranch((ref a, ref b), ref c, ref d) =>
272				write!(fmt, "NibbledBranch({:?}, {:?}, {:?})", (a, ToHex(&*b)), c, d),
273		}
274	}
275}
276
277impl<L: TrieLayout> Node<L> {
278	// load an inline node into memory or get the hash to do the lookup later.
279	fn inline_or_hash(
280		parent_hash: TrieHash<L>,
281		child: EncodedNodeHandle,
282		storage: &mut NodeStorage<L>,
283	) -> Result<NodeHandle<TrieHash<L>>, TrieHash<L>, CError<L>> {
284		let handle = match child {
285			EncodedNodeHandle::Hash(data) => {
286				let hash = decode_hash::<L::Hash>(data)
287					.ok_or_else(|| Box::new(TrieError::InvalidHash(parent_hash, data.to_vec())))?;
288				NodeHandle::Hash(hash)
289			},
290			EncodedNodeHandle::Inline(data) => {
291				let child = Node::from_encoded(parent_hash, data, storage)?;
292				NodeHandle::InMemory(storage.alloc(Stored::New(child)))
293			},
294		};
295		Ok(handle)
296	}
297
298	// load an inline node into memory or get the hash to do the lookup later.
299	fn inline_or_hash_owned(
300		child: &NodeHandleOwned<TrieHash<L>>,
301		storage: &mut NodeStorage<L>,
302	) -> NodeHandle<TrieHash<L>> {
303		match child {
304			NodeHandleOwned::Hash(hash) => NodeHandle::Hash(*hash),
305			NodeHandleOwned::Inline(node) => {
306				let child = Node::from_node_owned(&**node, storage);
307				NodeHandle::InMemory(storage.alloc(Stored::New(child)))
308			},
309		}
310	}
311
312	// Decode a node from encoded bytes.
313	fn from_encoded<'a, 'b>(
314		node_hash: TrieHash<L>,
315		data: &'a [u8],
316		storage: &'b mut NodeStorage<L>,
317	) -> Result<Self, TrieHash<L>, CError<L>> {
318		let encoded_node =
319			L::Codec::decode(data).map_err(|e| Box::new(TrieError::DecoderError(node_hash, e)))?;
320		let node = match encoded_node {
321			EncodedNode::Empty => Node::Empty,
322			EncodedNode::Leaf(k, v) => Node::Leaf(k.into(), v.into()),
323			EncodedNode::Extension(key, cb) =>
324				Node::Extension(key.into(), Self::inline_or_hash(node_hash, cb, storage)?),
325			EncodedNode::Branch(encoded_children, val) => {
326				let mut child = |i: usize| match encoded_children[i] {
327					Some(child) => Self::inline_or_hash(node_hash, child, storage).map(Some),
328					None => Ok(None),
329				};
330
331				let children = Box::new([
332					child(0)?,
333					child(1)?,
334					child(2)?,
335					child(3)?,
336					child(4)?,
337					child(5)?,
338					child(6)?,
339					child(7)?,
340					child(8)?,
341					child(9)?,
342					child(10)?,
343					child(11)?,
344					child(12)?,
345					child(13)?,
346					child(14)?,
347					child(15)?,
348				]);
349
350				Node::Branch(children, val.map(Into::into))
351			},
352			EncodedNode::NibbledBranch(k, encoded_children, val) => {
353				let mut child = |i: usize| match encoded_children[i] {
354					Some(child) => Self::inline_or_hash(node_hash, child, storage).map(Some),
355					None => Ok(None),
356				};
357
358				let children = Box::new([
359					child(0)?,
360					child(1)?,
361					child(2)?,
362					child(3)?,
363					child(4)?,
364					child(5)?,
365					child(6)?,
366					child(7)?,
367					child(8)?,
368					child(9)?,
369					child(10)?,
370					child(11)?,
371					child(12)?,
372					child(13)?,
373					child(14)?,
374					child(15)?,
375				]);
376
377				Node::NibbledBranch(k.into(), children, val.map(Into::into))
378			},
379		};
380		Ok(node)
381	}
382
383	/// Decode a node from a [`NodeOwned`].
384	fn from_node_owned(node_owned: &NodeOwned<TrieHash<L>>, storage: &mut NodeStorage<L>) -> Self {
385		match node_owned {
386			NodeOwned::Empty => Node::Empty,
387			NodeOwned::Leaf(k, v) => Node::Leaf(k.into(), v.into()),
388			NodeOwned::Extension(key, cb) =>
389				Node::Extension(key.into(), Self::inline_or_hash_owned(cb, storage)),
390			NodeOwned::Branch(encoded_children, val) => {
391				let mut child = |i: usize| {
392					encoded_children.get(i).map(|child| Self::inline_or_hash_owned(child, storage))
393				};
394
395				let children = Box::new([
396					child(0),
397					child(1),
398					child(2),
399					child(3),
400					child(4),
401					child(5),
402					child(6),
403					child(7),
404					child(8),
405					child(9),
406					child(10),
407					child(11),
408					child(12),
409					child(13),
410					child(14),
411					child(15),
412				]);
413
414				Node::Branch(children, val.as_ref().map(Into::into))
415			},
416			NodeOwned::NibbledBranch(k, encoded_children, val) => {
417				let mut child = |i: usize| {
418					encoded_children.get(i).map(|child| Self::inline_or_hash_owned(child, storage))
419				};
420
421				let children = Box::new([
422					child(0),
423					child(1),
424					child(2),
425					child(3),
426					child(4),
427					child(5),
428					child(6),
429					child(7),
430					child(8),
431					child(9),
432					child(10),
433					child(11),
434					child(12),
435					child(13),
436					child(14),
437					child(15),
438				]);
439
440				Node::NibbledBranch(k.into(), children, val.as_ref().map(Into::into))
441			},
442			NodeOwned::Value(_, _) =>
443				unreachable!("`NodeOwned::Value` can only be returned for the hash of a value."),
444		}
445	}
446
447	// TODO: parallelize
448	/// Here `child_cb` should process the first parameter to either insert an external
449	/// node value or to encode and add a new branch child node.
450	fn into_encoded<F>(self, mut child_cb: F) -> Vec<u8>
451	where
452		F: FnMut(
453			NodeToEncode<TrieHash<L>>,
454			Option<&NibbleSlice>,
455			Option<u8>,
456		) -> ChildReference<TrieHash<L>>,
457	{
458		match self {
459			Node::Empty => L::Codec::empty_node().to_vec(),
460			Node::Leaf(partial, mut value) => {
461				let pr = NibbleSlice::new_offset(&partial.1[..], partial.0);
462				let value = value.into_encoded::<F>(Some(&pr), &mut child_cb);
463				L::Codec::leaf_node(pr.right_iter(), pr.len(), value)
464			},
465			Node::Extension(partial, child) => {
466				let pr = NibbleSlice::new_offset(&partial.1[..], partial.0);
467				let it = pr.right_iter();
468				let c = child_cb(NodeToEncode::TrieNode(child), Some(&pr), None);
469				L::Codec::extension_node(it, pr.len(), c)
470			},
471			Node::Branch(mut children, mut value) => {
472				let value = value.as_mut().map(|v| v.into_encoded::<F>(None, &mut child_cb));
473				L::Codec::branch_node(
474					// map the `NodeHandle`s from the Branch to `ChildReferences`
475					children.iter_mut().map(Option::take).enumerate().map(|(i, maybe_child)| {
476						maybe_child.map(|child| {
477							child_cb(NodeToEncode::TrieNode(child), None, Some(i as u8))
478						})
479					}),
480					value,
481				)
482			},
483			Node::NibbledBranch(partial, mut children, mut value) => {
484				let pr = NibbleSlice::new_offset(&partial.1[..], partial.0);
485				let value = value.as_mut().map(|v| v.into_encoded::<F>(Some(&pr), &mut child_cb));
486				let it = pr.right_iter();
487				L::Codec::branch_node_nibbled(
488					it,
489					pr.len(),
490					// map the `NodeHandle`s from the Branch to `ChildReferences`
491					children.iter_mut().map(Option::take).enumerate().map(|(i, maybe_child)| {
492						//let branch_index = [i as u8];
493						maybe_child.map(|child| {
494							let pr = NibbleSlice::new_offset(&partial.1[..], partial.0);
495							child_cb(NodeToEncode::TrieNode(child), Some(&pr), Some(i as u8))
496						})
497					}),
498					value,
499				)
500			},
501		}
502	}
503
504	/// Returns the key partial key of this node.
505	fn partial_key(&self) -> Option<&NodeKey> {
506		match &self {
507			Self::Empty => None,
508			Self::Leaf(key, _) => Some(key),
509			Self::Branch(_, _) => None,
510			Self::NibbledBranch(key, _, _) => Some(key),
511			Self::Extension(key, _) => Some(key),
512		}
513	}
514}
515
516// post-inspect action.
517enum Action<L: TrieLayout> {
518	// Replace a node with a new one.
519	Replace(Node<L>),
520	// Restore the original node. This trusts that the node is actually the original.
521	Restore(Node<L>),
522	// if it is a new node, just clears the storage.
523	Delete,
524}
525
526// post-insert action. Same as action without delete
527enum InsertAction<L: TrieLayout> {
528	// Replace a node with a new one.
529	Replace(Node<L>),
530	// Restore the original node.
531	Restore(Node<L>),
532}
533
534impl<L: TrieLayout> InsertAction<L> {
535	fn into_action(self) -> Action<L> {
536		match self {
537			InsertAction::Replace(n) => Action::Replace(n),
538			InsertAction::Restore(n) => Action::Restore(n),
539		}
540	}
541
542	// unwrap the node, disregarding replace or restore state.
543	fn unwrap_node(self) -> Node<L> {
544		match self {
545			InsertAction::Replace(n) | InsertAction::Restore(n) => n,
546		}
547	}
548}
549
550// What kind of node is stored here.
551enum Stored<L: TrieLayout> {
552	// A new node.
553	New(Node<L>),
554	// A cached node, loaded from the DB.
555	Cached(Node<L>, TrieHash<L>),
556}
557
558/// Used to build a collection of child nodes from a collection of `NodeHandle`s
559#[derive(Clone, Copy)]
560#[cfg_attr(feature = "std", derive(Debug))]
561pub enum ChildReference<HO> {
562	// `HO` is e.g. `H256`, i.e. the output of a `Hasher`
563	Hash(HO),
564	Inline(HO, usize), // usize is the length of the node data we store in the `H::Out`
565}
566
567impl<'a, HO> TryFrom<EncodedNodeHandle<'a>> for ChildReference<HO>
568where
569	HO: AsRef<[u8]> + AsMut<[u8]> + Default + Clone + Copy,
570{
571	type Error = Vec<u8>;
572
573	fn try_from(handle: EncodedNodeHandle<'a>) -> result::Result<Self, Vec<u8>> {
574		match handle {
575			EncodedNodeHandle::Hash(data) => {
576				let mut hash = HO::default();
577				if data.len() != hash.as_ref().len() {
578					return Err(data.to_vec())
579				}
580				hash.as_mut().copy_from_slice(data);
581				Ok(ChildReference::Hash(hash))
582			},
583			EncodedNodeHandle::Inline(data) => {
584				let mut hash = HO::default();
585				if data.len() > hash.as_ref().len() {
586					return Err(data.to_vec())
587				}
588				hash.as_mut()[..data.len()].copy_from_slice(data);
589				Ok(ChildReference::Inline(hash, data.len()))
590			},
591		}
592	}
593}
594
595/// Compact and cache-friendly storage for Trie nodes.
596struct NodeStorage<L: TrieLayout> {
597	nodes: Vec<Stored<L>>,
598	free_indices: VecDeque<usize>,
599}
600
601impl<L: TrieLayout> NodeStorage<L> {
602	/// Create a new storage.
603	fn empty() -> Self {
604		NodeStorage { nodes: Vec::new(), free_indices: VecDeque::new() }
605	}
606
607	/// Allocate a new node in the storage.
608	fn alloc(&mut self, stored: Stored<L>) -> StorageHandle {
609		if let Some(idx) = self.free_indices.pop_front() {
610			self.nodes[idx] = stored;
611			StorageHandle(idx)
612		} else {
613			self.nodes.push(stored);
614			StorageHandle(self.nodes.len() - 1)
615		}
616	}
617
618	/// Remove a node from the storage, consuming the handle and returning the node.
619	fn destroy(&mut self, handle: StorageHandle) -> Stored<L> {
620		let idx = handle.0;
621
622		self.free_indices.push_back(idx);
623		mem::replace(&mut self.nodes[idx], Stored::New(Node::Empty))
624	}
625}
626
627impl<'a, L: TrieLayout> Index<&'a StorageHandle> for NodeStorage<L> {
628	type Output = Node<L>;
629
630	fn index(&self, handle: &'a StorageHandle) -> &Node<L> {
631		match self.nodes[handle.0] {
632			Stored::New(ref node) => node,
633			Stored::Cached(ref node, _) => node,
634		}
635	}
636}
637
638/// A builder for creating a [`TrieDBMut`].
639pub struct TrieDBMutBuilder<'db, L: TrieLayout> {
640	db: &'db mut dyn HashDB<L::Hash, DBValue>,
641	root: &'db mut TrieHash<L>,
642	cache: Option<&'db mut dyn TrieCache<L::Codec>>,
643	recorder: Option<&'db mut dyn TrieRecorder<TrieHash<L>>>,
644}
645
646impl<'db, L: TrieLayout> TrieDBMutBuilder<'db, L> {
647	/// Create a builder for constructing a new trie with the backing database `db` and empty
648	/// `root`.
649	pub fn new(db: &'db mut dyn HashDB<L::Hash, DBValue>, root: &'db mut TrieHash<L>) -> Self {
650		*root = L::Codec::hashed_null_node();
651
652		Self { root, db, cache: None, recorder: None }
653	}
654
655	/// Create a builder for constructing a new trie with the backing database `db` and `root`.
656	///
657	/// This doesn't check if `root` exists in the given `db`. If `root` doesn't exist it will fail
658	/// when trying to lookup any key.
659	pub fn from_existing(
660		db: &'db mut dyn HashDB<L::Hash, DBValue>,
661		root: &'db mut TrieHash<L>,
662	) -> Self {
663		Self { db, root, cache: None, recorder: None }
664	}
665
666	/// Use the given `cache` for the db.
667	pub fn with_cache(mut self, cache: &'db mut dyn TrieCache<L::Codec>) -> Self {
668		self.cache = Some(cache);
669		self
670	}
671
672	/// Use the given optional `cache` for the db.
673	pub fn with_optional_cache<'cache: 'db>(
674		mut self,
675		cache: Option<&'cache mut dyn TrieCache<L::Codec>>,
676	) -> Self {
677		// Make the compiler happy by "converting" the lifetime
678		self.cache = cache.map(|c| c as _);
679		self
680	}
681
682	/// Use the given `recorder` to record trie accesses.
683	pub fn with_recorder(mut self, recorder: &'db mut dyn TrieRecorder<TrieHash<L>>) -> Self {
684		self.recorder = Some(recorder);
685		self
686	}
687
688	/// Use the given optional `recorder` to record trie accesses.
689	pub fn with_optional_recorder<'recorder: 'db>(
690		mut self,
691		recorder: Option<&'recorder mut dyn TrieRecorder<TrieHash<L>>>,
692	) -> Self {
693		// Make the compiler happy by "converting" the lifetime
694		self.recorder = recorder.map(|r| r as _);
695		self
696	}
697
698	/// Build the [`TrieDBMut`].
699	pub fn build(self) -> TrieDBMut<'db, L> {
700		let root_handle = NodeHandle::Hash(*self.root);
701
702		TrieDBMut {
703			db: self.db,
704			root: self.root,
705			cache: self.cache,
706			recorder: self.recorder.map(core::cell::RefCell::new),
707			storage: NodeStorage::empty(),
708			death_row: Default::default(),
709			root_handle,
710		}
711	}
712}
713
714/// A `Trie` implementation using a generic `HashDB` backing database.
715///
716/// Use it as a `TrieMut` trait object. You can use `db()` to get the backing database object.
717/// Note that changes are not committed to the database until `commit` is called.
718///
719/// Querying the root or dropping the trie will commit automatically.
720///
721///
722/// # Example
723/// ```ignore
724/// use hash_db::Hasher;
725/// use reference_trie::{RefTrieDBMut, TrieMut};
726/// use trie_db::DBValue;
727/// use keccak_hasher::KeccakHasher;
728/// use memory_db::*;
729///
730/// let mut memdb = MemoryDB::<KeccakHasher, HashKey<_>, DBValue>::default();
731/// let mut root = Default::default();
732/// let mut t = RefTrieDBMut::new(&mut memdb, &mut root);
733/// assert!(t.is_empty());
734/// assert_eq!(*t.root(), KeccakHasher::hash(&[0u8][..]));
735/// t.insert(b"foo", b"bar").unwrap();
736/// assert!(t.contains(b"foo").unwrap());
737/// assert_eq!(t.get(b"foo").unwrap().unwrap(), b"bar".to_vec());
738/// t.remove(b"foo").unwrap();
739/// assert!(!t.contains(b"foo").unwrap());
740/// ```
741pub struct TrieDBMut<'a, L>
742where
743	L: TrieLayout,
744{
745	storage: NodeStorage<L>,
746	db: &'a mut dyn HashDB<L::Hash, DBValue>,
747	root: &'a mut TrieHash<L>,
748	root_handle: NodeHandle<TrieHash<L>>,
749	death_row: Set<(TrieHash<L>, (BackingByteVec, Option<u8>))>,
750	/// Optional cache for speeding up the lookup of nodes.
751	cache: Option<&'a mut dyn TrieCache<L::Codec>>,
752	/// Optional trie recorder for recording trie accesses.
753	recorder: Option<core::cell::RefCell<&'a mut dyn TrieRecorder<TrieHash<L>>>>,
754}
755
756impl<'a, L> TrieDBMut<'a, L>
757where
758	L: TrieLayout,
759{
760	/// Get the backing database.
761	pub fn db(&self) -> &dyn HashDB<L::Hash, DBValue> {
762		self.db
763	}
764
765	/// Get the backing database mutably.
766	pub fn db_mut(&mut self) -> &mut dyn HashDB<L::Hash, DBValue> {
767		self.db
768	}
769
770	// Cache a node by hash.
771	fn cache(
772		&mut self,
773		hash: TrieHash<L>,
774		key: Prefix,
775	) -> Result<StorageHandle, TrieHash<L>, CError<L>> {
776		// We only check the `cache` for a node with `get_node` and don't insert
777		// the node if it wasn't there, because in substrate we only access the node while computing
778		// a new trie (aka some branch). We assume that this node isn't that important
779		// to have it being cached.
780		let node = match self.cache.as_mut().and_then(|c| c.get_node(&hash)) {
781			Some(node) => {
782				if let Some(recorder) = self.recorder.as_mut() {
783					recorder.borrow_mut().record(TrieAccess::NodeOwned { hash, node_owned: &node });
784				}
785
786				Node::from_node_owned(&node, &mut self.storage)
787			},
788			None => {
789				let node_encoded = self
790					.db
791					.get(&hash, key)
792					.ok_or_else(|| Box::new(TrieError::IncompleteDatabase(hash)))?;
793
794				if let Some(recorder) = self.recorder.as_mut() {
795					recorder.borrow_mut().record(TrieAccess::EncodedNode {
796						hash,
797						encoded_node: node_encoded.as_slice().into(),
798					});
799				}
800
801				Node::from_encoded(hash, &node_encoded, &mut self.storage)?
802			},
803		};
804
805		Ok(self.storage.alloc(Stored::Cached(node, hash)))
806	}
807
808	// Inspect a node, choosing either to replace, restore, or delete it.
809	// If restored or replaced, returns the new node along with a flag of whether it was changed.
810	fn inspect<F>(
811		&mut self,
812		stored: Stored<L>,
813		key: &mut NibbleFullKey,
814		inspector: F,
815	) -> Result<Option<(Stored<L>, bool)>, TrieHash<L>, CError<L>>
816	where
817		F: FnOnce(
818			&mut Self,
819			Node<L>,
820			&mut NibbleFullKey,
821		) -> Result<Action<L>, TrieHash<L>, CError<L>>,
822	{
823		let current_key = *key;
824		Ok(match stored {
825			Stored::New(node) => match inspector(self, node, key)? {
826				Action::Restore(node) => Some((Stored::New(node), false)),
827				Action::Replace(node) => Some((Stored::New(node), true)),
828				Action::Delete => None,
829			},
830			Stored::Cached(node, hash) => match inspector(self, node, key)? {
831				Action::Restore(node) => Some((Stored::Cached(node, hash), false)),
832				Action::Replace(node) => {
833					self.death_row.insert((hash, current_key.left_owned()));
834					Some((Stored::New(node), true))
835				},
836				Action::Delete => {
837					self.death_row.insert((hash, current_key.left_owned()));
838					None
839				},
840			},
841		})
842	}
843
844	// Walk the trie, attempting to find the key's node.
845	fn lookup(
846		&self,
847		full_key: &[u8],
848		mut partial: NibbleSlice,
849		handle: &NodeHandle<TrieHash<L>>,
850	) -> Result<Option<DBValue>, TrieHash<L>, CError<L>> {
851		let mut handle = handle;
852		// prefix only use for value node access, so this is always correct.
853		let prefix = (full_key, None);
854		loop {
855			let (mid, child) = match handle {
856				NodeHandle::Hash(hash) => {
857					let mut recorder = self.recorder.as_ref().map(|r| r.borrow_mut());
858
859					return Lookup::<L, _> {
860						db: &self.db,
861						query: |v: &[u8]| v.to_vec(),
862						hash: *hash,
863						cache: None,
864						recorder: recorder
865							.as_mut()
866							.map(|r| &mut ***r as &mut dyn TrieRecorder<TrieHash<L>>),
867					}
868					.look_up(full_key, partial)
869				},
870				NodeHandle::InMemory(handle) => match &self.storage[handle] {
871					Node::Empty => return Ok(None),
872					Node::Leaf(slice, value) =>
873						if NibbleSlice::from_stored(slice) == partial {
874							return Ok(value.in_memory_fetched_value(
875								prefix,
876								self.db,
877								&self.recorder,
878								full_key,
879							)?)
880						} else {
881							return Ok(None)
882						},
883					Node::Extension(slice, child) => {
884						let slice = NibbleSlice::from_stored(slice);
885						if partial.starts_with(&slice) {
886							(slice.len(), child)
887						} else {
888							return Ok(None)
889						}
890					},
891					Node::Branch(children, value) =>
892						if partial.is_empty() {
893							return Ok(if let Some(v) = value.as_ref() {
894								v.in_memory_fetched_value(
895									prefix,
896									self.db,
897									&self.recorder,
898									full_key,
899								)?
900							} else {
901								None
902							})
903						} else {
904							let idx = partial.at(0);
905							match children[idx as usize].as_ref() {
906								Some(child) => (1, child),
907								None => return Ok(None),
908							}
909						},
910					Node::NibbledBranch(slice, children, value) => {
911						let slice = NibbleSlice::from_stored(slice);
912						if slice == partial {
913							return Ok(if let Some(v) = value.as_ref() {
914								v.in_memory_fetched_value(
915									prefix,
916									self.db,
917									&self.recorder,
918									full_key,
919								)?
920							} else {
921								None
922							})
923						} else if partial.starts_with(&slice) {
924							let idx = partial.at(slice.len());
925							match children[idx as usize].as_ref() {
926								Some(child) => (1 + slice.len(), child),
927								None => return Ok(None),
928							}
929						} else {
930							return Ok(None)
931						}
932					},
933				},
934			};
935
936			partial = partial.mid(mid);
937			handle = child;
938		}
939	}
940
941	/// Insert a key-value pair into the trie, creating new nodes if necessary.
942	fn insert_at(
943		&mut self,
944		handle: NodeHandle<TrieHash<L>>,
945		key: &mut NibbleFullKey,
946		value: Bytes,
947		old_val: &mut Option<Value<L>>,
948	) -> Result<(StorageHandle, bool), TrieHash<L>, CError<L>> {
949		let h = match handle {
950			NodeHandle::InMemory(h) => h,
951			NodeHandle::Hash(h) => self.cache(h, key.left())?,
952		};
953		// cache then destroy for hash handle (handle being root in most case)
954		let stored = self.storage.destroy(h);
955		let (new_stored, changed) = self
956			.inspect(stored, key, move |trie, stored, key| {
957				trie.insert_inspector(stored, key, value, old_val).map(|a| a.into_action())
958			})?
959			.expect("Insertion never deletes.");
960
961		Ok((self.storage.alloc(new_stored), changed))
962	}
963
964	fn replace_old_value(
965		&mut self,
966		old_value: &mut Option<Value<L>>,
967		stored_value: Option<Value<L>>,
968		prefix: Prefix,
969	) {
970		match &stored_value {
971			Some(Value::NewNode(Some(hash), _)) // also removing new node in case commit is called multiple times
972			| Some(Value::Node(hash)) => {
973				self.death_row.insert((
974					hash.clone(),
975					(prefix.0.into(), prefix.1),
976				));
977			},
978			_ => (),
979		}
980		*old_value = stored_value;
981	}
982
983	/// The insertion inspector.
984	fn insert_inspector(
985		&mut self,
986		node: Node<L>,
987		key: &mut NibbleFullKey,
988		value: Bytes,
989		old_val: &mut Option<Value<L>>,
990	) -> Result<InsertAction<L>, TrieHash<L>, CError<L>> {
991		let partial = *key;
992
993		#[cfg(feature = "std")]
994		trace!(target: "trie", "augmented (partial: {:?}, value: {:?})", partial, ToHex(&value));
995
996		Ok(match node {
997			Node::Empty => {
998				#[cfg(feature = "std")]
999				trace!(target: "trie", "empty: COMPOSE");
1000				let value = Value::new(value, L::MAX_INLINE_VALUE);
1001				InsertAction::Replace(Node::Leaf(partial.to_stored(), value))
1002			},
1003			Node::Branch(mut children, stored_value) => {
1004				debug_assert!(L::USE_EXTENSION);
1005				#[cfg(feature = "std")]
1006				trace!(target: "trie", "branch: ROUTE,AUGMENT");
1007
1008				if partial.is_empty() {
1009					let value = Some(Value::new(value, L::MAX_INLINE_VALUE));
1010					let unchanged = stored_value == value;
1011					let branch = Node::Branch(children, value);
1012
1013					self.replace_old_value(old_val, stored_value, key.left());
1014
1015					if unchanged {
1016						InsertAction::Restore(branch)
1017					} else {
1018						InsertAction::Replace(branch)
1019					}
1020				} else {
1021					let idx = partial.at(0) as usize;
1022					key.advance(1);
1023					if let Some(child) = children[idx].take() {
1024						// Original had something there. recurse down into it.
1025						let (new_child, changed) = self.insert_at(child, key, value, old_val)?;
1026						children[idx] = Some(new_child.into());
1027						if !changed {
1028							// The new node we composed didn't change.
1029							// It means our branch is untouched too.
1030							return Ok(InsertAction::Restore(Node::Branch(children, stored_value)))
1031						}
1032					} else {
1033						// Original had nothing there. compose a leaf.
1034						let value = Value::new(value, L::MAX_INLINE_VALUE);
1035						let leaf =
1036							self.storage.alloc(Stored::New(Node::Leaf(key.to_stored(), value)));
1037						children[idx] = Some(leaf.into());
1038					}
1039
1040					InsertAction::Replace(Node::Branch(children, stored_value))
1041				}
1042			},
1043			Node::NibbledBranch(encoded, mut children, stored_value) => {
1044				debug_assert!(!L::USE_EXTENSION);
1045				#[cfg(feature = "std")]
1046				trace!(target: "trie", "branch: ROUTE,AUGMENT");
1047				let existing_key = NibbleSlice::from_stored(&encoded);
1048
1049				let common = partial.common_prefix(&existing_key);
1050				if common == existing_key.len() && common == partial.len() {
1051					let value = Some(Value::new(value, L::MAX_INLINE_VALUE));
1052					let unchanged = stored_value == value;
1053					let branch = Node::NibbledBranch(existing_key.to_stored(), children, value);
1054
1055					let mut key_val = key.clone();
1056					key_val.advance(existing_key.len());
1057					self.replace_old_value(old_val, stored_value, key_val.left());
1058
1059					if unchanged {
1060						InsertAction::Restore(branch)
1061					} else {
1062						InsertAction::Replace(branch)
1063					}
1064				} else if common < existing_key.len() {
1065					// insert a branch value in between
1066					#[cfg(feature = "std")]
1067					trace!(
1068						target: "trie",
1069						"partially-shared-prefix (exist={:?}; new={:?}; common={:?}):\
1070							 AUGMENT-AT-END",
1071						existing_key.len(),
1072						partial.len(),
1073						common,
1074					);
1075					let nbranch_partial = existing_key.mid(common + 1).to_stored();
1076					let low = Node::NibbledBranch(nbranch_partial, children, stored_value);
1077					let ix = existing_key.at(common);
1078					let mut children = empty_children();
1079					let alloc_storage = self.storage.alloc(Stored::New(low));
1080
1081					children[ix as usize] = Some(alloc_storage.into());
1082
1083					let value = Value::new(value, L::MAX_INLINE_VALUE);
1084					if partial.len() - common == 0 {
1085						InsertAction::Replace(Node::NibbledBranch(
1086							existing_key.to_stored_range(common),
1087							children,
1088							Some(value),
1089						))
1090					} else {
1091						let ix = partial.at(common);
1092						let stored_leaf = Node::Leaf(partial.mid(common + 1).to_stored(), value);
1093
1094						let leaf = self.storage.alloc(Stored::New(stored_leaf));
1095
1096						children[ix as usize] = Some(leaf.into());
1097						InsertAction::Replace(Node::NibbledBranch(
1098							existing_key.to_stored_range(common),
1099							children,
1100							None,
1101						))
1102					}
1103				} else {
1104					// Append after common == existing_key and partial > common
1105					#[cfg(feature = "std")]
1106					trace!(target: "trie", "branch: ROUTE,AUGMENT");
1107					let idx = partial.at(common) as usize;
1108					key.advance(common + 1);
1109					if let Some(child) = children[idx].take() {
1110						// Original had something there. recurse down into it.
1111						let (new_child, changed) = self.insert_at(child, key, value, old_val)?;
1112						children[idx] = Some(new_child.into());
1113						if !changed {
1114							// The new node we composed didn't change.
1115							// It means our branch is untouched too.
1116							let n_branch = Node::NibbledBranch(
1117								existing_key.to_stored(),
1118								children,
1119								stored_value,
1120							);
1121							return Ok(InsertAction::Restore(n_branch))
1122						}
1123					} else {
1124						// Original had nothing there. compose a leaf.
1125						let value = Value::new(value, L::MAX_INLINE_VALUE);
1126						let leaf =
1127							self.storage.alloc(Stored::New(Node::Leaf(key.to_stored(), value)));
1128
1129						children[idx] = Some(leaf.into());
1130					}
1131					InsertAction::Replace(Node::NibbledBranch(
1132						existing_key.to_stored(),
1133						children,
1134						stored_value,
1135					))
1136				}
1137			},
1138			Node::Leaf(encoded, stored_value) => {
1139				let existing_key = NibbleSlice::from_stored(&encoded);
1140				let common = partial.common_prefix(&existing_key);
1141				if common == existing_key.len() && common == partial.len() {
1142					#[cfg(feature = "std")]
1143					trace!(target: "trie", "equivalent-leaf: REPLACE");
1144					// equivalent leaf.
1145					let value = Value::new(value, L::MAX_INLINE_VALUE);
1146					let unchanged = stored_value == value;
1147					let mut key_val = key.clone();
1148					key_val.advance(existing_key.len());
1149					self.replace_old_value(old_val, Some(stored_value), key_val.left());
1150					if unchanged {
1151						// unchanged. restore
1152						InsertAction::Restore(Node::Leaf(encoded.clone(), value))
1153					} else {
1154						InsertAction::Replace(Node::Leaf(encoded.clone(), value))
1155					}
1156				} else if (L::USE_EXTENSION && common == 0) ||
1157					(!L::USE_EXTENSION && common < existing_key.len())
1158				{
1159					#[cfg(feature = "std")]
1160					trace!(
1161						target: "trie",
1162						"lesser-common-prefix, not-both-empty (exist={:?}; new={:?}):\
1163							TRANSMUTE,AUGMENT",
1164						existing_key.len(),
1165						partial.len(),
1166					);
1167
1168					// one of us isn't empty: transmute to branch here
1169					let mut children = empty_children();
1170					let branch = if L::USE_EXTENSION && existing_key.is_empty() {
1171						// always replace since branch isn't leaf.
1172						Node::Branch(children, Some(stored_value))
1173					} else {
1174						let idx = existing_key.at(common) as usize;
1175						let new_leaf =
1176							Node::Leaf(existing_key.mid(common + 1).to_stored(), stored_value);
1177						children[idx] = Some(self.storage.alloc(Stored::New(new_leaf)).into());
1178
1179						if L::USE_EXTENSION {
1180							Node::Branch(children, None)
1181						} else {
1182							Node::NibbledBranch(partial.to_stored_range(common), children, None)
1183						}
1184					};
1185
1186					// always replace because whatever we get out here
1187					// is not the branch we started with.
1188					let branch_action =
1189						self.insert_inspector(branch, key, value, old_val)?.unwrap_node();
1190					InsertAction::Replace(branch_action)
1191				} else if !L::USE_EXTENSION {
1192					#[cfg(feature = "std")]
1193					trace!(target: "trie", "complete-prefix (common={:?}): AUGMENT-AT-END", common);
1194
1195					// fully-shared prefix for an extension.
1196					// make a stub branch
1197					let branch = Node::NibbledBranch(
1198						existing_key.to_stored(),
1199						empty_children(),
1200						Some(stored_value),
1201					);
1202					// augment the new branch.
1203					let branch = self.insert_inspector(branch, key, value, old_val)?.unwrap_node();
1204
1205					InsertAction::Replace(branch)
1206				} else if common == existing_key.len() {
1207					debug_assert!(L::USE_EXTENSION);
1208					#[cfg(feature = "std")]
1209					trace!(target: "trie", "complete-prefix (common={:?}): AUGMENT-AT-END", common);
1210
1211					// fully-shared prefix for an extension.
1212					// make a stub branch and an extension.
1213					let branch = Node::Branch(empty_children(), Some(stored_value));
1214					// augment the new branch.
1215					key.advance(common);
1216					let branch = self.insert_inspector(branch, key, value, old_val)?.unwrap_node();
1217
1218					// always replace since we took a leaf and made an extension.
1219					let leaf = self.storage.alloc(Stored::New(branch));
1220					InsertAction::Replace(Node::Extension(existing_key.to_stored(), leaf.into()))
1221				} else {
1222					debug_assert!(L::USE_EXTENSION);
1223					#[cfg(feature = "std")]
1224					trace!(
1225						target: "trie",
1226						"partially-shared-prefix (exist={:?}; new={:?}; common={:?}):\
1227							 AUGMENT-AT-END",
1228						existing_key.len(),
1229						partial.len(),
1230						common,
1231					);
1232
1233					// partially-shared prefix for an extension.
1234					// start by making a leaf.
1235					let low = Node::Leaf(existing_key.mid(common).to_stored(), stored_value);
1236
1237					// augment it. this will result in the Leaf -> common == 0 routine,
1238					// which creates a branch.
1239					key.advance(common);
1240					let augmented_low =
1241						self.insert_inspector(low, key, value, old_val)?.unwrap_node();
1242					// make an extension using it. this is a replacement.
1243					InsertAction::Replace(Node::Extension(
1244						existing_key.to_stored_range(common),
1245						self.storage.alloc(Stored::New(augmented_low)).into(),
1246					))
1247				}
1248			},
1249			Node::Extension(encoded, child_branch) => {
1250				debug_assert!(L::USE_EXTENSION);
1251				let existing_key = NibbleSlice::from_stored(&encoded);
1252				let common = partial.common_prefix(&existing_key);
1253				if common == 0 {
1254					#[cfg(feature = "std")]
1255					trace!(
1256						target: "trie",
1257						"no-common-prefix, not-both-empty (exist={:?}; new={:?}):\
1258							 TRANSMUTE,AUGMENT",
1259						existing_key.len(),
1260						partial.len(),
1261					);
1262
1263					// partial isn't empty: make a branch here
1264					// extensions may not have empty partial keys.
1265					assert!(!existing_key.is_empty());
1266					let idx = existing_key.at(0) as usize;
1267
1268					let mut children = empty_children();
1269					children[idx] = if existing_key.len() == 1 {
1270						// direct extension, just replace.
1271						Some(child_branch)
1272					} else {
1273						// No need to register set branch (was here before).
1274						// Note putting a branch in extension requires fix.
1275						let ext = Node::Extension(existing_key.mid(1).to_stored(), child_branch);
1276						Some(self.storage.alloc(Stored::New(ext)).into())
1277					};
1278
1279					// continue inserting.
1280					let branch_action = self
1281						.insert_inspector(Node::Branch(children, None), key, value, old_val)?
1282						.unwrap_node();
1283					InsertAction::Replace(branch_action)
1284				} else if common == existing_key.len() {
1285					#[cfg(feature = "std")]
1286					trace!(target: "trie", "complete-prefix (common={:?}): AUGMENT-AT-END", common);
1287
1288					// fully-shared prefix.
1289
1290					// insert into the child node.
1291					key.advance(common);
1292					let (new_child, changed) = self.insert_at(child_branch, key, value, old_val)?;
1293
1294					let new_ext = Node::Extension(existing_key.to_stored(), new_child.into());
1295
1296					// if the child branch wasn't changed, meaning this extension remains the same.
1297					if changed {
1298						InsertAction::Replace(new_ext)
1299					} else {
1300						InsertAction::Restore(new_ext)
1301					}
1302				} else {
1303					#[cfg(feature = "std")]
1304					trace!(
1305						target: "trie",
1306						"partially-shared-prefix (exist={:?}; new={:?}; common={:?}):\
1307							 AUGMENT-AT-END",
1308						existing_key.len(),
1309						partial.len(),
1310						common,
1311					);
1312
1313					// partially-shared.
1314					let low = Node::Extension(existing_key.mid(common).to_stored(), child_branch);
1315					// augment the extension. this will take the common == 0 path,
1316					// creating a branch.
1317					key.advance(common);
1318					let augmented_low =
1319						self.insert_inspector(low, key, value, old_val)?.unwrap_node();
1320
1321					// always replace, since this extension is not the one we started with.
1322					// this is known because the partial key is only the common prefix.
1323					InsertAction::Replace(Node::Extension(
1324						existing_key.to_stored_range(common),
1325						self.storage.alloc(Stored::New(augmented_low)).into(),
1326					))
1327				}
1328			},
1329		})
1330	}
1331
1332	/// Removes a node from the trie based on key.
1333	fn remove_at(
1334		&mut self,
1335		handle: NodeHandle<TrieHash<L>>,
1336		key: &mut NibbleFullKey,
1337		old_val: &mut Option<Value<L>>,
1338	) -> Result<Option<(StorageHandle, bool)>, TrieHash<L>, CError<L>> {
1339		let stored = match handle {
1340			NodeHandle::InMemory(h) => self.storage.destroy(h),
1341			NodeHandle::Hash(h) => {
1342				let handle = self.cache(h, key.left())?;
1343				self.storage.destroy(handle)
1344			},
1345		};
1346
1347		let opt = self.inspect(stored, key, move |trie, node, key| {
1348			trie.remove_inspector(node, key, old_val)
1349		})?;
1350
1351		Ok(opt.map(|(new, changed)| (self.storage.alloc(new), changed)))
1352	}
1353
1354	/// The removal inspector.
1355	fn remove_inspector(
1356		&mut self,
1357		node: Node<L>,
1358		key: &mut NibbleFullKey,
1359		old_val: &mut Option<Value<L>>,
1360	) -> Result<Action<L>, TrieHash<L>, CError<L>> {
1361		let partial = *key;
1362		Ok(match (node, partial.is_empty()) {
1363			(Node::Empty, _) => Action::Delete,
1364			(Node::Branch(c, None), true) => Action::Restore(Node::Branch(c, None)),
1365			(Node::NibbledBranch(n, c, None), true) =>
1366				Action::Restore(Node::NibbledBranch(n, c, None)),
1367			(Node::Branch(children, val), true) => {
1368				self.replace_old_value(old_val, val, key.left());
1369				// always replace since we took the value out.
1370				Action::Replace(self.fix(Node::Branch(children, None), *key)?)
1371			},
1372			(Node::NibbledBranch(n, children, val), true) => {
1373				self.replace_old_value(old_val, val, key.left());
1374				// always replace since we took the value out.
1375				Action::Replace(self.fix(Node::NibbledBranch(n, children, None), *key)?)
1376			},
1377			(Node::Branch(mut children, value), false) => {
1378				let idx = partial.at(0) as usize;
1379				if let Some(child) = children[idx].take() {
1380					#[cfg(feature = "std")]
1381					trace!(
1382						target: "trie",
1383						"removing value out of branch child, partial={:?}",
1384						partial,
1385					);
1386					let prefix = *key;
1387					key.advance(1);
1388					match self.remove_at(child, key, old_val)? {
1389						Some((new, changed)) => {
1390							children[idx] = Some(new.into());
1391							let branch = Node::Branch(children, value);
1392							match changed {
1393								// child was changed, so we were too.
1394								true => Action::Replace(branch),
1395								// unchanged, so we are too.
1396								false => Action::Restore(branch),
1397							}
1398						},
1399						None => {
1400							// the child we took was deleted.
1401							// the node may need fixing.
1402							#[cfg(feature = "std")]
1403							trace!(target: "trie", "branch child deleted, partial={:?}", partial);
1404							Action::Replace(self.fix(Node::Branch(children, value), prefix)?)
1405						},
1406					}
1407				} else {
1408					// no change needed.
1409					Action::Restore(Node::Branch(children, value))
1410				}
1411			},
1412			(Node::NibbledBranch(encoded, mut children, value), false) => {
1413				let (common, existing_length) = {
1414					let existing_key = NibbleSlice::from_stored(&encoded);
1415					(existing_key.common_prefix(&partial), existing_key.len())
1416				};
1417				if common == existing_length && common == partial.len() {
1418					// replace val
1419					if let Some(value) = value {
1420						let mut key_val = key.clone();
1421						key_val.advance(existing_length);
1422						self.replace_old_value(old_val, Some(value), key_val.left());
1423						let f = self.fix(Node::NibbledBranch(encoded, children, None), *key);
1424						Action::Replace(f?)
1425					} else {
1426						Action::Restore(Node::NibbledBranch(encoded, children, None))
1427					}
1428				} else if common < existing_length {
1429					// partway through an extension -- nothing to do here.
1430					Action::Restore(Node::NibbledBranch(encoded, children, value))
1431				} else {
1432					// common == existing_length && common < partial.len() : check children
1433					let idx = partial.at(common) as usize;
1434
1435					if let Some(child) = children[idx].take() {
1436						#[cfg(feature = "std")]
1437						trace!(
1438							target: "trie",
1439							"removing value out of branch child, partial={:?}",
1440							partial,
1441						);
1442						let prefix = *key;
1443						key.advance(common + 1);
1444						match self.remove_at(child, key, old_val)? {
1445							Some((new, changed)) => {
1446								children[idx] = Some(new.into());
1447								let branch = Node::NibbledBranch(encoded, children, value);
1448								match changed {
1449									// child was changed, so we were too.
1450									true => Action::Replace(branch),
1451									// unchanged, so we are too.
1452									false => Action::Restore(branch),
1453								}
1454							},
1455							None => {
1456								// the child we took was deleted.
1457								// the node may need fixing.
1458								#[cfg(feature = "std")]
1459								trace!(
1460									target: "trie",
1461									"branch child deleted, partial={:?}",
1462									partial,
1463								);
1464								Action::Replace(
1465									self.fix(
1466										Node::NibbledBranch(encoded, children, value),
1467										prefix,
1468									)?,
1469								)
1470							},
1471						}
1472					} else {
1473						// no change needed.
1474						Action::Restore(Node::NibbledBranch(encoded, children, value))
1475					}
1476				}
1477			},
1478			(Node::Leaf(encoded, value), _) => {
1479				let existing_key = NibbleSlice::from_stored(&encoded);
1480				if existing_key == partial {
1481					// this is the node we were looking for. Let's delete it.
1482					let mut key_val = key.clone();
1483					key_val.advance(existing_key.len());
1484					self.replace_old_value(old_val, Some(value), key_val.left());
1485					Action::Delete
1486				} else {
1487					// leaf the node alone.
1488					#[cfg(feature = "std")]
1489					trace!(
1490						target: "trie",
1491						"restoring leaf wrong partial, partial={:?}, existing={:?}",
1492						partial,
1493						NibbleSlice::from_stored(&encoded),
1494					);
1495					Action::Restore(Node::Leaf(encoded, value))
1496				}
1497			},
1498			(Node::Extension(encoded, child_branch), _) => {
1499				let (common, existing_length) = {
1500					let existing_key = NibbleSlice::from_stored(&encoded);
1501					(existing_key.common_prefix(&partial), existing_key.len())
1502				};
1503				if common == existing_length {
1504					// try to remove from the child branch.
1505					#[cfg(feature = "std")]
1506					trace!(target: "trie", "removing from extension child, partial={:?}", partial);
1507					let prefix = *key;
1508					key.advance(common);
1509					match self.remove_at(child_branch, key, old_val)? {
1510						Some((new_child, changed)) => {
1511							// if the child branch was unchanged, then the extension is too.
1512							// otherwise, this extension may need fixing.
1513							match changed {
1514								true => Action::Replace(
1515									self.fix(Node::Extension(encoded, new_child.into()), prefix)?,
1516								),
1517								false =>
1518									Action::Restore(Node::Extension(encoded, new_child.into())),
1519							}
1520						},
1521						None => {
1522							// the whole branch got deleted.
1523							// that means that this extension is useless.
1524							Action::Delete
1525						},
1526					}
1527				} else {
1528					// partway through an extension -- nothing to do here.
1529					Action::Restore(Node::Extension(encoded, child_branch))
1530				}
1531			},
1532		})
1533	}
1534
1535	/// Given a node which may be in an _invalid state_, fix it such that it is then in a valid
1536	/// state.
1537	///
1538	/// _invalid state_ means:
1539	/// - Branch node where there is only a single entry;
1540	/// - Extension node followed by anything other than a Branch node.
1541	fn fix(&mut self, node: Node<L>, key: NibbleSlice) -> Result<Node<L>, TrieHash<L>, CError<L>> {
1542		self.fix_inner(node, key, false)
1543	}
1544	fn fix_inner(
1545		&mut self,
1546		node: Node<L>,
1547		key: NibbleSlice,
1548		recurse_extension: bool,
1549	) -> Result<Node<L>, TrieHash<L>, CError<L>> {
1550		match node {
1551			Node::Branch(mut children, value) => {
1552				// if only a single value, transmute to leaf/extension and feed through fixed.
1553				#[cfg_attr(feature = "std", derive(Debug))]
1554				enum UsedIndex {
1555					None,
1556					One(u8),
1557					Many,
1558				}
1559				let mut used_index = UsedIndex::None;
1560				for i in 0..16 {
1561					match (children[i].is_none(), &used_index) {
1562						(false, &UsedIndex::None) => used_index = UsedIndex::One(i as u8),
1563						(false, &UsedIndex::One(_)) => {
1564							used_index = UsedIndex::Many;
1565							break
1566						},
1567						_ => continue,
1568					}
1569				}
1570
1571				match (used_index, value) {
1572					(UsedIndex::None, None) => {
1573						panic!("Branch with no subvalues. Something went wrong.")
1574					},
1575					(UsedIndex::One(a), None) => {
1576						// only one onward node. make an extension.
1577
1578						let new_partial = NibbleSlice::new_offset(&[a], 1).to_stored();
1579						let child = children[a as usize]
1580							.take()
1581							.expect("used_index only set if occupied; qed");
1582						let new_node = Node::Extension(new_partial, child);
1583						self.fix(new_node, key)
1584					},
1585					(UsedIndex::None, Some(value)) => {
1586						// make a leaf.
1587						#[cfg(feature = "std")]
1588						trace!(target: "trie", "fixing: branch -> leaf");
1589						Ok(Node::Leaf(NibbleSlice::new(&[]).to_stored(), value))
1590					},
1591					(_, value) => {
1592						// all is well.
1593						#[cfg(feature = "std")]
1594						trace!(target: "trie", "fixing: restoring branch");
1595						Ok(Node::Branch(children, value))
1596					},
1597				}
1598			},
1599			Node::NibbledBranch(enc_nibble, mut children, value) => {
1600				// if only a single value, transmute to leaf/extension and feed through fixed.
1601				#[cfg_attr(feature = "std", derive(Debug))]
1602				enum UsedIndex {
1603					None,
1604					One(u8),
1605					Many,
1606				}
1607				let mut used_index = UsedIndex::None;
1608				for i in 0..16 {
1609					match (children[i].is_none(), &used_index) {
1610						(false, &UsedIndex::None) => used_index = UsedIndex::One(i as u8),
1611						(false, &UsedIndex::One(_)) => {
1612							used_index = UsedIndex::Many;
1613							break
1614						},
1615						_ => continue,
1616					}
1617				}
1618
1619				match (used_index, value) {
1620					(UsedIndex::None, None) => {
1621						panic!("Branch with no subvalues. Something went wrong.")
1622					},
1623					(UsedIndex::One(a), None) => {
1624						// only one onward node. use child instead
1625						let child = children[a as usize]
1626							.take()
1627							.expect("used_index only set if occupied; qed");
1628						let mut key2 = key.clone();
1629						key2.advance(
1630							(enc_nibble.1.len() * nibble_ops::NIBBLE_PER_BYTE) - enc_nibble.0,
1631						);
1632						let (start, alloc_start, prefix_end) = match key2.left() {
1633							(start, None) => (start, None, Some(nibble_ops::push_at_left(0, a, 0))),
1634							(start, Some(v)) => {
1635								let mut so: BackingByteVec = start.into();
1636								so.push(nibble_ops::pad_left(v) | a);
1637								(start, Some(so), None)
1638							},
1639						};
1640						let child_prefix = (
1641							alloc_start.as_ref().map(|start| &start[..]).unwrap_or(start),
1642							prefix_end,
1643						);
1644						let stored = match child {
1645							NodeHandle::InMemory(h) => self.storage.destroy(h),
1646							NodeHandle::Hash(h) => {
1647								let handle = self.cache(h, child_prefix)?;
1648								self.storage.destroy(handle)
1649							},
1650						};
1651						let child_node = match stored {
1652							Stored::New(node) => node,
1653							Stored::Cached(node, hash) => {
1654								self.death_row
1655									.insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1656								node
1657							},
1658						};
1659						match child_node {
1660							Node::Leaf(sub_partial, value) => {
1661								let mut enc_nibble = enc_nibble;
1662								combine_key(
1663									&mut enc_nibble,
1664									(nibble_ops::NIBBLE_PER_BYTE - 1, &[a][..]),
1665								);
1666								combine_key(&mut enc_nibble, (sub_partial.0, &sub_partial.1[..]));
1667								Ok(Node::Leaf(enc_nibble, value))
1668							},
1669							Node::NibbledBranch(sub_partial, ch_children, ch_value) => {
1670								let mut enc_nibble = enc_nibble;
1671								combine_key(
1672									&mut enc_nibble,
1673									(nibble_ops::NIBBLE_PER_BYTE - 1, &[a][..]),
1674								);
1675								combine_key(&mut enc_nibble, (sub_partial.0, &sub_partial.1[..]));
1676								Ok(Node::NibbledBranch(enc_nibble, ch_children, ch_value))
1677							},
1678							_ => unreachable!(),
1679						}
1680					},
1681					(UsedIndex::None, Some(value)) => {
1682						// make a leaf.
1683						#[cfg(feature = "std")]
1684						trace!(target: "trie", "fixing: branch -> leaf");
1685						Ok(Node::Leaf(enc_nibble, value))
1686					},
1687					(_, value) => {
1688						// all is well.
1689						#[cfg(feature = "std")]
1690						trace!(target: "trie", "fixing: restoring branch");
1691						Ok(Node::NibbledBranch(enc_nibble, children, value))
1692					},
1693				}
1694			},
1695			Node::Extension(partial, child) => {
1696				let mut key2 = key.clone();
1697				let (start, alloc_start, prefix_end) = if !recurse_extension {
1698					// We could advance key, but this code can also be called
1699					// recursively, so there might be some prefix from branch.
1700					let last = partial.1[partial.1.len() - 1] & (255 >> 4);
1701					key2.advance((partial.1.len() * nibble_ops::NIBBLE_PER_BYTE) - partial.0 - 1);
1702					match key2.left() {
1703						(start, None) => (start, None, Some(nibble_ops::push_at_left(0, last, 0))),
1704						(start, Some(v)) => {
1705							let mut so: BackingByteVec = start.into();
1706							// Complete last byte with `last`.
1707							so.push(nibble_ops::pad_left(v) | last);
1708							(start, Some(so), None)
1709						},
1710					}
1711				} else {
1712					let k2 = key2.left();
1713
1714					let mut so: NibbleVec = Default::default();
1715					so.append_optional_slice_and_nibble(Some(&NibbleSlice::new(k2.0)), None);
1716					if let Some(n) = k2.1 {
1717						so.push(n >> nibble_ops::BIT_PER_NIBBLE);
1718					}
1719					so.append_optional_slice_and_nibble(
1720						Some(&NibbleSlice::from_stored(&partial)),
1721						None,
1722					);
1723					let so = so.as_prefix();
1724					(k2.0, Some(so.0.into()), so.1)
1725				};
1726				let child_prefix =
1727					(alloc_start.as_ref().map(|start| &start[..]).unwrap_or(start), prefix_end);
1728
1729				let stored = match child {
1730					NodeHandle::InMemory(h) => self.storage.destroy(h),
1731					NodeHandle::Hash(h) => {
1732						let handle = self.cache(h, child_prefix)?;
1733						self.storage.destroy(handle)
1734					},
1735				};
1736
1737				let (child_node, maybe_hash) = match stored {
1738					Stored::New(node) => (node, None),
1739					Stored::Cached(node, hash) => (node, Some(hash)),
1740				};
1741
1742				match child_node {
1743					Node::Extension(sub_partial, sub_child) => {
1744						// combine with node below.
1745						if let Some(hash) = maybe_hash {
1746							// delete the cached child since we are going to replace it.
1747							self.death_row
1748								.insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1749						}
1750						// subpartial
1751						let mut partial = partial;
1752						combine_key(&mut partial, (sub_partial.0, &sub_partial.1[..]));
1753						#[cfg(feature = "std")]
1754						trace!(
1755							target: "trie",
1756							"fixing: extension combination. new_partial={:?}",
1757							partial,
1758						);
1759
1760						self.fix_inner(Node::Extension(partial, sub_child), key.into(), true)
1761					},
1762					Node::Leaf(sub_partial, value) => {
1763						// combine with node below.
1764						if let Some(hash) = maybe_hash {
1765							// delete the cached child since we are going to replace it.
1766							self.death_row
1767								.insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1768						}
1769						// subpartial oly
1770						let mut partial = partial;
1771						combine_key(&mut partial, (sub_partial.0, &sub_partial.1[..]));
1772						#[cfg(feature = "std")]
1773						trace!(
1774							target: "trie",
1775							"fixing: extension -> leaf. new_partial={:?}",
1776							partial,
1777						);
1778						Ok(Node::Leaf(partial, value))
1779					},
1780					child_node => {
1781						#[cfg(feature = "std")]
1782						trace!(target: "trie", "fixing: restoring extension");
1783
1784						// reallocate the child node.
1785						let stored = if let Some(hash) = maybe_hash {
1786							Stored::Cached(child_node, hash)
1787						} else {
1788							Stored::New(child_node)
1789						};
1790
1791						Ok(Node::Extension(partial, self.storage.alloc(stored).into()))
1792					},
1793				}
1794			},
1795			other => Ok(other), // only ext and branch need fixing.
1796		}
1797	}
1798
1799	/// Commit the in-memory changes to disk, freeing their storage and
1800	/// updating the state root.
1801	pub fn commit(&mut self) {
1802		#[cfg(feature = "std")]
1803		trace!(target: "trie", "Committing trie changes to db.");
1804
1805		// always kill all the nodes on death row.
1806		#[cfg(feature = "std")]
1807		trace!(target: "trie", "{:?} nodes to remove from db", self.death_row.len());
1808
1809		#[cfg(feature = "std")]
1810		for (hash, prefix) in self.death_row.drain() {
1811			self.db.remove(&hash, (&prefix.0[..], prefix.1));
1812		}
1813
1814		#[cfg(not(feature = "std"))]
1815		for (hash, prefix) in core::mem::take(&mut self.death_row).into_iter() {
1816			self.db.remove(&hash, (&prefix.0[..], prefix.1));
1817		}
1818
1819		let handle = match self.root_handle() {
1820			NodeHandle::Hash(_) => return, // no changes necessary.
1821			NodeHandle::InMemory(h) => h,
1822		};
1823
1824		match self.storage.destroy(handle) {
1825			Stored::New(node) => {
1826				// Reconstructs the full key for root node.
1827				let full_key = self.cache.as_ref().and_then(|_| {
1828					node.partial_key().and_then(|k| Some(NibbleSlice::from_stored(k).into()))
1829				});
1830
1831				let mut k = NibbleVec::new();
1832
1833				let encoded_root = node.into_encoded(|node, o_slice, o_index| {
1834					let mov = k.append_optional_slice_and_nibble(o_slice, o_index);
1835					match node {
1836						NodeToEncode::Node(value) => {
1837							let value_hash = self.db.insert(k.as_prefix(), value);
1838							self.cache_value(k.inner(), value, value_hash);
1839							k.drop_lasts(mov);
1840							ChildReference::Hash(value_hash)
1841						},
1842						NodeToEncode::TrieNode(child) => {
1843							let result = self.commit_child(child, &mut k);
1844							k.drop_lasts(mov);
1845							result
1846						},
1847					}
1848				});
1849				#[cfg(feature = "std")]
1850				trace!(target: "trie", "encoded root node: {:?}", ToHex(&encoded_root[..]));
1851
1852				*self.root = self.db.insert(EMPTY_PREFIX, &encoded_root);
1853
1854				self.cache_node(*self.root, &encoded_root, full_key);
1855
1856				self.root_handle = NodeHandle::Hash(*self.root);
1857			},
1858			Stored::Cached(node, hash) => {
1859				// probably won't happen, but update the root and move on.
1860				*self.root = hash;
1861				self.root_handle =
1862					NodeHandle::InMemory(self.storage.alloc(Stored::Cached(node, hash)));
1863			},
1864		}
1865	}
1866
1867	/// Cache the given `encoded` node.
1868	fn cache_node(&mut self, hash: TrieHash<L>, encoded: &[u8], full_key: Option<NibbleVec>) {
1869		// If we have a cache, cache our node directly.
1870		if let Some(cache) = self.cache.as_mut() {
1871			let node = cache.get_or_insert_node(hash, &mut || {
1872				Ok(L::Codec::decode(&encoded)
1873					.ok()
1874					.and_then(|n| n.to_owned_node::<L>().ok())
1875					.expect("Just encoded the node, so it should decode without any errors; qed"))
1876			});
1877
1878			// `node` should always be `OK`, but let's play it safe.
1879			let node = if let Ok(node) = node { node } else { return };
1880
1881			let mut values_to_cache = Vec::new();
1882
1883			// If the given node has data attached, the `full_key` is the full key to this node.
1884			if let Some(full_key) = full_key {
1885				node.data().and_then(|v| node.data_hash().map(|h| (&full_key, v, h))).map(
1886					|(k, v, h)| {
1887						values_to_cache.push((k.inner().to_vec(), (v.clone(), h).into()));
1888					},
1889				);
1890
1891				fn cache_child_values<L: TrieLayout>(
1892					node: &NodeOwned<TrieHash<L>>,
1893					values_to_cache: &mut Vec<(Vec<u8>, CachedValue<TrieHash<L>>)>,
1894					full_key: NibbleVec,
1895				) {
1896					node.child_iter().flat_map(|(n, c)| c.as_inline().map(|c| (n, c))).for_each(
1897						|(n, c)| {
1898							let mut key = full_key.clone();
1899							n.map(|n| key.push(n));
1900							c.partial_key().map(|p| key.append(p));
1901
1902							if let Some((hash, data)) =
1903								c.data().and_then(|d| c.data_hash().map(|h| (h, d)))
1904							{
1905								values_to_cache
1906									.push((key.inner().to_vec(), (data.clone(), hash).into()));
1907							}
1908
1909							cache_child_values::<L>(c, values_to_cache, key);
1910						},
1911					);
1912				}
1913
1914				// Also cache values of inline nodes.
1915				cache_child_values::<L>(&node, &mut values_to_cache, full_key.clone());
1916			}
1917
1918			values_to_cache.into_iter().for_each(|(k, v)| cache.cache_value_for_key(&k, v));
1919		}
1920	}
1921
1922	/// Cache the given `value`.
1923	///
1924	/// `hash` is the hash of `value`.
1925	fn cache_value(&mut self, full_key: &[u8], value: impl Into<Bytes>, hash: TrieHash<L>) {
1926		if let Some(cache) = self.cache.as_mut() {
1927			let value = value.into();
1928
1929			// `get_or_insert` should always return `Ok`, but be safe.
1930			let value = if let Ok(value) = cache
1931				.get_or_insert_node(hash, &mut || Ok(NodeOwned::Value(value.clone(), hash)))
1932				.map(|n| n.data().cloned())
1933			{
1934				value
1935			} else {
1936				None
1937			};
1938
1939			if let Some(value) = value {
1940				cache.cache_value_for_key(full_key, (value, hash).into())
1941			}
1942		}
1943	}
1944
1945	/// Commit a node by hashing it and writing it to the db. Returns a
1946	/// `ChildReference` which in most cases carries a normal hash but for the
1947	/// case where we can fit the actual data in the `Hasher`s output type, we
1948	/// store the data inline. This function is used as the callback to the
1949	/// `into_encoded` method of `Node`.
1950	fn commit_child(
1951		&mut self,
1952		handle: NodeHandle<TrieHash<L>>,
1953		prefix: &mut NibbleVec,
1954	) -> ChildReference<TrieHash<L>> {
1955		match handle {
1956			NodeHandle::Hash(hash) => ChildReference::Hash(hash),
1957			NodeHandle::InMemory(storage_handle) => {
1958				match self.storage.destroy(storage_handle) {
1959					Stored::Cached(_, hash) => ChildReference::Hash(hash),
1960					Stored::New(node) => {
1961						// Reconstructs the full key
1962						let full_key = self.cache.as_ref().and_then(|_| {
1963							let mut prefix = prefix.clone();
1964							if let Some(partial) = node.partial_key() {
1965								prefix.append_partial(NibbleSlice::from_stored(partial).right());
1966							}
1967							Some(prefix)
1968						});
1969
1970						let encoded = {
1971							let commit_child = |node: NodeToEncode<TrieHash<L>>,
1972							                    o_slice: Option<&NibbleSlice>,
1973							                    o_index: Option<u8>| {
1974								let mov = prefix.append_optional_slice_and_nibble(o_slice, o_index);
1975								match node {
1976									NodeToEncode::Node(value) => {
1977										let value_hash = self.db.insert(prefix.as_prefix(), value);
1978
1979										self.cache_value(prefix.inner(), value, value_hash);
1980
1981										prefix.drop_lasts(mov);
1982										ChildReference::Hash(value_hash)
1983									},
1984									NodeToEncode::TrieNode(node_handle) => {
1985										let result = self.commit_child(node_handle, prefix);
1986										prefix.drop_lasts(mov);
1987										result
1988									},
1989								}
1990							};
1991							node.into_encoded(commit_child)
1992						};
1993						if encoded.len() >= L::Hash::LENGTH {
1994							let hash = self.db.insert(prefix.as_prefix(), &encoded);
1995
1996							self.cache_node(hash, &encoded, full_key);
1997
1998							ChildReference::Hash(hash)
1999						} else {
2000							// it's a small value, so we cram it into a `TrieHash<L>`
2001							// and tag with length
2002							let mut h = <TrieHash<L>>::default();
2003							let len = encoded.len();
2004							h.as_mut()[..len].copy_from_slice(&encoded[..len]);
2005
2006							ChildReference::Inline(h, len)
2007						}
2008					},
2009				}
2010			},
2011		}
2012	}
2013
2014	// a hack to get the root node's handle
2015	fn root_handle(&self) -> NodeHandle<TrieHash<L>> {
2016		match self.root_handle {
2017			NodeHandle::Hash(h) => NodeHandle::Hash(h),
2018			NodeHandle::InMemory(StorageHandle(x)) => NodeHandle::InMemory(StorageHandle(x)),
2019		}
2020	}
2021}
2022
2023impl<'a, L> TrieMut<L> for TrieDBMut<'a, L>
2024where
2025	L: TrieLayout,
2026{
2027	fn root(&mut self) -> &TrieHash<L> {
2028		self.commit();
2029		self.root
2030	}
2031
2032	fn is_empty(&self) -> bool {
2033		match self.root_handle {
2034			NodeHandle::Hash(h) => h == L::Codec::hashed_null_node(),
2035			NodeHandle::InMemory(ref h) => match self.storage[h] {
2036				Node::Empty => true,
2037				_ => false,
2038			},
2039		}
2040	}
2041
2042	fn get<'x, 'key>(&'x self, key: &'key [u8]) -> Result<Option<DBValue>, TrieHash<L>, CError<L>>
2043	where
2044		'x: 'key,
2045	{
2046		self.lookup(key, NibbleSlice::new(key), &self.root_handle)
2047	}
2048
2049	fn insert(
2050		&mut self,
2051		key: &[u8],
2052		value: &[u8],
2053	) -> Result<Option<Value<L>>, TrieHash<L>, CError<L>> {
2054		if !L::ALLOW_EMPTY && value.is_empty() {
2055			return self.remove(key)
2056		}
2057
2058		let mut old_val = None;
2059
2060		#[cfg(feature = "std")]
2061		trace!(target: "trie", "insert: key={:?}, value={:?}", ToHex(key), ToHex(&value));
2062
2063		let value = Bytes::from(value);
2064		let root_handle = self.root_handle();
2065		let (new_handle, _changed) =
2066			self.insert_at(root_handle, &mut NibbleSlice::new(key), value, &mut old_val)?;
2067
2068		#[cfg(feature = "std")]
2069		trace!(target: "trie", "insert: altered trie={}", _changed);
2070		self.root_handle = NodeHandle::InMemory(new_handle);
2071
2072		Ok(old_val)
2073	}
2074
2075	fn remove(&mut self, key: &[u8]) -> Result<Option<Value<L>>, TrieHash<L>, CError<L>> {
2076		#[cfg(feature = "std")]
2077		trace!(target: "trie", "remove: key={:?}", ToHex(key));
2078
2079		let root_handle = self.root_handle();
2080		let mut key_slice = NibbleSlice::new(key);
2081		let mut old_val = None;
2082
2083		match self.remove_at(root_handle, &mut key_slice, &mut old_val)? {
2084			Some((handle, _changed)) => {
2085				#[cfg(feature = "std")]
2086				trace!(target: "trie", "remove: altered trie={}", _changed);
2087				self.root_handle = NodeHandle::InMemory(handle);
2088			},
2089			None => {
2090				#[cfg(feature = "std")]
2091				trace!(target: "trie", "remove: obliterated trie");
2092				self.root_handle = NodeHandle::Hash(L::Codec::hashed_null_node());
2093				*self.root = L::Codec::hashed_null_node();
2094			},
2095		}
2096
2097		Ok(old_val)
2098	}
2099}
2100
2101impl<'a, L> Drop for TrieDBMut<'a, L>
2102where
2103	L: TrieLayout,
2104{
2105	fn drop(&mut self) {
2106		self.commit();
2107	}
2108}
2109
2110/// combine two NodeKeys
2111fn combine_key(start: &mut NodeKey, end: (usize, &[u8])) {
2112	debug_assert!(start.0 < nibble_ops::NIBBLE_PER_BYTE);
2113	debug_assert!(end.0 < nibble_ops::NIBBLE_PER_BYTE);
2114	let final_offset = (start.0 + end.0) % nibble_ops::NIBBLE_PER_BYTE;
2115	let _shifted = nibble_ops::shift_key(start, final_offset);
2116	let st = if end.0 > 0 {
2117		let sl = start.1.len();
2118		start.1[sl - 1] |= nibble_ops::pad_right(end.1[0]);
2119		1
2120	} else {
2121		0
2122	};
2123	(st..end.1.len()).for_each(|i| start.1.push(end.1[i]));
2124}
2125
2126#[cfg(test)]
2127mod tests {
2128	use crate::nibble::BackingByteVec;
2129
2130	#[test]
2131	fn combine_test() {
2132		let a: BackingByteVec = [0x12, 0x34][..].into();
2133		let b: &[u8] = [0x56, 0x78][..].into();
2134		let test_comb = |a: (_, &BackingByteVec), b, c| {
2135			let mut a = (a.0, a.1.clone());
2136			super::combine_key(&mut a, b);
2137			assert_eq!((a.0, &a.1[..]), c);
2138		};
2139		test_comb((0, &a), (0, &b), (0, &[0x12, 0x34, 0x56, 0x78][..]));
2140		test_comb((1, &a), (0, &b), (1, &[0x12, 0x34, 0x56, 0x78][..]));
2141		test_comb((0, &a), (1, &b), (1, &[0x01, 0x23, 0x46, 0x78][..]));
2142		test_comb((1, &a), (1, &b), (0, &[0x23, 0x46, 0x78][..]));
2143	}
2144}