Skip to main content

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