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_or(false, |threshold| value.len() >= threshold as usize) {
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		// prefix only use for value node access, so this is always correct.
856		let prefix = (full_key, None);
857		loop {
858			let (mid, child) = match handle {
859				NodeHandle::Hash(hash) => {
860					let mut recorder = self.recorder.as_ref().map(|r| r.borrow_mut());
861
862					return Lookup::<L, _> {
863						db: &self.db,
864						query: |v: &[u8]| v.to_vec(),
865						hash: *hash,
866						cache: None,
867						recorder: recorder
868							.as_mut()
869							.map(|r| &mut ***r as &mut dyn TrieRecorder<TrieHash<L>>),
870					}
871					.look_up(full_key, partial)
872				},
873				NodeHandle::InMemory(handle) => match &self.storage[handle] {
874					Node::Empty => return Ok(None),
875					Node::Leaf(slice, value) =>
876						if NibbleSlice::from_stored(slice) == partial {
877							return Ok(value.in_memory_fetched_value(
878								prefix,
879								self.db,
880								&self.recorder,
881								full_key,
882							)?)
883						} else {
884							return Ok(None)
885						},
886					Node::Extension(slice, child) => {
887						let slice = NibbleSlice::from_stored(slice);
888						if partial.starts_with(&slice) {
889							(slice.len(), child)
890						} else {
891							return Ok(None)
892						}
893					},
894					Node::Branch(children, value) =>
895						if partial.is_empty() {
896							return Ok(if let Some(v) = value.as_ref() {
897								v.in_memory_fetched_value(
898									prefix,
899									self.db,
900									&self.recorder,
901									full_key,
902								)?
903							} else {
904								None
905							})
906						} else {
907							let idx = partial.at(0);
908							match children[idx as usize].as_ref() {
909								Some(child) => (1, child),
910								None => return Ok(None),
911							}
912						},
913					Node::NibbledBranch(slice, children, value) => {
914						let slice = NibbleSlice::from_stored(slice);
915						if slice == partial {
916							return Ok(if let Some(v) = value.as_ref() {
917								v.in_memory_fetched_value(
918									prefix,
919									self.db,
920									&self.recorder,
921									full_key,
922								)?
923							} else {
924								None
925							})
926						} else if partial.starts_with(&slice) {
927							let idx = partial.at(slice.len());
928							match children[idx as usize].as_ref() {
929								Some(child) => (1 + slice.len(), child),
930								None => return Ok(None),
931							}
932						} else {
933							return Ok(None)
934						}
935					},
936				},
937			};
938
939			partial = partial.mid(mid);
940			handle = child;
941		}
942	}
943
944	/// Insert a key-value pair into the trie, creating new nodes if necessary.
945	fn insert_at(
946		&mut self,
947		handle: NodeHandle<TrieHash<L>>,
948		key: &mut NibbleFullKey,
949		value: Bytes,
950		old_val: &mut Option<Value<L>>,
951	) -> Result<(StorageHandle, bool), TrieHash<L>, CError<L>> {
952		let h = match handle {
953			NodeHandle::InMemory(h) => h,
954			NodeHandle::Hash(h) => self.cache(h, key.left())?,
955		};
956		// cache then destroy for hash handle (handle being root in most case)
957		let stored = self.storage.destroy(h);
958		let (new_stored, changed) = self
959			.inspect(stored, key, move |trie, stored, key| {
960				trie.insert_inspector(stored, key, value, old_val).map(|a| a.into_action())
961			})?
962			.expect("Insertion never deletes.");
963
964		Ok((self.storage.alloc(new_stored), changed))
965	}
966
967	fn replace_old_value(
968		&mut self,
969		old_value: &mut Option<Value<L>>,
970		stored_value: Option<Value<L>>,
971		prefix: Prefix,
972	) {
973		match &stored_value {
974			Some(Value::NewNode(Some(hash), _)) // also removing new node in case commit is called multiple times
975			| Some(Value::Node(hash)) => {
976				self.death_row.insert((
977					hash.clone(),
978					(prefix.0.into(), prefix.1),
979				));
980			},
981			_ => (),
982		}
983		*old_value = stored_value;
984	}
985
986	/// The insertion inspector.
987	fn insert_inspector(
988		&mut self,
989		node: Node<L>,
990		key: &mut NibbleFullKey,
991		value: Bytes,
992		old_val: &mut Option<Value<L>>,
993	) -> Result<InsertAction<L>, TrieHash<L>, CError<L>> {
994		let partial = *key;
995
996		#[cfg(feature = "std")]
997		trace!(target: "trie", "augmented (partial: {:?}, value: {:?})", partial, ToHex(&value));
998
999		Ok(match node {
1000			Node::Empty => {
1001				#[cfg(feature = "std")]
1002				trace!(target: "trie", "empty: COMPOSE");
1003				let value = Value::new(value, L::MAX_INLINE_VALUE);
1004				InsertAction::Replace(Node::Leaf(partial.to_stored(), value))
1005			},
1006			Node::Branch(mut children, stored_value) => {
1007				debug_assert!(L::USE_EXTENSION);
1008				#[cfg(feature = "std")]
1009				trace!(target: "trie", "branch: ROUTE,AUGMENT");
1010
1011				if partial.is_empty() {
1012					let value = Some(Value::new(value, L::MAX_INLINE_VALUE));
1013					let unchanged = stored_value == value;
1014					let branch = Node::Branch(children, value);
1015
1016					self.replace_old_value(old_val, stored_value, key.left());
1017
1018					if unchanged {
1019						InsertAction::Restore(branch)
1020					} else {
1021						InsertAction::Replace(branch)
1022					}
1023				} else {
1024					let idx = partial.at(0) as usize;
1025					key.advance(1);
1026					if let Some(child) = children[idx].take() {
1027						// Original had something there. recurse down into it.
1028						let (new_child, changed) = self.insert_at(child, key, value, old_val)?;
1029						children[idx] = Some(new_child.into());
1030						if !changed {
1031							// The new node we composed didn't change.
1032							// It means our branch is untouched too.
1033							return Ok(InsertAction::Restore(Node::Branch(children, stored_value)))
1034						}
1035					} else {
1036						// Original had nothing there. compose a leaf.
1037						let value = Value::new(value, L::MAX_INLINE_VALUE);
1038						let leaf =
1039							self.storage.alloc(Stored::New(Node::Leaf(key.to_stored(), value)));
1040						children[idx] = Some(leaf.into());
1041					}
1042
1043					InsertAction::Replace(Node::Branch(children, stored_value))
1044				}
1045			},
1046			Node::NibbledBranch(encoded, mut children, stored_value) => {
1047				debug_assert!(!L::USE_EXTENSION);
1048				#[cfg(feature = "std")]
1049				trace!(target: "trie", "branch: ROUTE,AUGMENT");
1050				let existing_key = NibbleSlice::from_stored(&encoded);
1051
1052				let common = partial.common_prefix(&existing_key);
1053				if common == existing_key.len() && common == partial.len() {
1054					let value = Some(Value::new(value, L::MAX_INLINE_VALUE));
1055					let unchanged = stored_value == value;
1056					let branch = Node::NibbledBranch(existing_key.to_stored(), children, value);
1057
1058					let mut key_val = key.clone();
1059					key_val.advance(existing_key.len());
1060					self.replace_old_value(old_val, stored_value, key_val.left());
1061
1062					if unchanged {
1063						InsertAction::Restore(branch)
1064					} else {
1065						InsertAction::Replace(branch)
1066					}
1067				} else if common < existing_key.len() {
1068					// insert a branch value in between
1069					#[cfg(feature = "std")]
1070					trace!(
1071						target: "trie",
1072						"partially-shared-prefix (exist={:?}; new={:?}; common={:?}):\
1073							 AUGMENT-AT-END",
1074						existing_key.len(),
1075						partial.len(),
1076						common,
1077					);
1078					let nbranch_partial = existing_key.mid(common + 1).to_stored();
1079					let low = Node::NibbledBranch(nbranch_partial, children, stored_value);
1080					let ix = existing_key.at(common);
1081					let mut children = empty_children();
1082					let alloc_storage = self.storage.alloc(Stored::New(low));
1083
1084					children[ix as usize] = Some(alloc_storage.into());
1085
1086					let value = Value::new(value, L::MAX_INLINE_VALUE);
1087					if partial.len() - common == 0 {
1088						InsertAction::Replace(Node::NibbledBranch(
1089							existing_key.to_stored_range(common),
1090							children,
1091							Some(value),
1092						))
1093					} else {
1094						let ix = partial.at(common);
1095						let stored_leaf = Node::Leaf(partial.mid(common + 1).to_stored(), value);
1096
1097						let leaf = self.storage.alloc(Stored::New(stored_leaf));
1098
1099						children[ix as usize] = Some(leaf.into());
1100						InsertAction::Replace(Node::NibbledBranch(
1101							existing_key.to_stored_range(common),
1102							children,
1103							None,
1104						))
1105					}
1106				} else {
1107					// Append after common == existing_key and partial > common
1108					#[cfg(feature = "std")]
1109					trace!(target: "trie", "branch: ROUTE,AUGMENT");
1110					let idx = partial.at(common) as usize;
1111					key.advance(common + 1);
1112					if let Some(child) = children[idx].take() {
1113						// Original had something there. recurse down into it.
1114						let (new_child, changed) = self.insert_at(child, key, value, old_val)?;
1115						children[idx] = Some(new_child.into());
1116						if !changed {
1117							// The new node we composed didn't change.
1118							// It means our branch is untouched too.
1119							let n_branch = Node::NibbledBranch(
1120								existing_key.to_stored(),
1121								children,
1122								stored_value,
1123							);
1124							return Ok(InsertAction::Restore(n_branch))
1125						}
1126					} else {
1127						// Original had nothing there. compose a leaf.
1128						let value = Value::new(value, L::MAX_INLINE_VALUE);
1129						let leaf =
1130							self.storage.alloc(Stored::New(Node::Leaf(key.to_stored(), value)));
1131
1132						children[idx] = Some(leaf.into());
1133					}
1134					InsertAction::Replace(Node::NibbledBranch(
1135						existing_key.to_stored(),
1136						children,
1137						stored_value,
1138					))
1139				}
1140			},
1141			Node::Leaf(encoded, stored_value) => {
1142				let existing_key = NibbleSlice::from_stored(&encoded);
1143				let common = partial.common_prefix(&existing_key);
1144				if common == existing_key.len() && common == partial.len() {
1145					#[cfg(feature = "std")]
1146					trace!(target: "trie", "equivalent-leaf: REPLACE");
1147					// equivalent leaf.
1148					let value = Value::new(value, L::MAX_INLINE_VALUE);
1149					let unchanged = stored_value == value;
1150					let mut key_val = key.clone();
1151					key_val.advance(existing_key.len());
1152					self.replace_old_value(old_val, Some(stored_value), key_val.left());
1153					if unchanged {
1154						// unchanged. restore
1155						InsertAction::Restore(Node::Leaf(encoded.clone(), value))
1156					} else {
1157						InsertAction::Replace(Node::Leaf(encoded.clone(), value))
1158					}
1159				} else if (L::USE_EXTENSION && common == 0) ||
1160					(!L::USE_EXTENSION && common < existing_key.len())
1161				{
1162					#[cfg(feature = "std")]
1163					trace!(
1164						target: "trie",
1165						"lesser-common-prefix, not-both-empty (exist={:?}; new={:?}):\
1166							TRANSMUTE,AUGMENT",
1167						existing_key.len(),
1168						partial.len(),
1169					);
1170
1171					// one of us isn't empty: transmute to branch here
1172					let mut children = empty_children();
1173					let branch = if L::USE_EXTENSION && existing_key.is_empty() {
1174						// always replace since branch isn't leaf.
1175						Node::Branch(children, Some(stored_value))
1176					} else {
1177						let idx = existing_key.at(common) as usize;
1178						let new_leaf =
1179							Node::Leaf(existing_key.mid(common + 1).to_stored(), stored_value);
1180						children[idx] = Some(self.storage.alloc(Stored::New(new_leaf)).into());
1181
1182						if L::USE_EXTENSION {
1183							Node::Branch(children, None)
1184						} else {
1185							Node::NibbledBranch(partial.to_stored_range(common), children, None)
1186						}
1187					};
1188
1189					// always replace because whatever we get out here
1190					// is not the branch we started with.
1191					let branch_action =
1192						self.insert_inspector(branch, key, value, old_val)?.unwrap_node();
1193					InsertAction::Replace(branch_action)
1194				} else if !L::USE_EXTENSION {
1195					#[cfg(feature = "std")]
1196					trace!(target: "trie", "complete-prefix (common={:?}): AUGMENT-AT-END", common);
1197
1198					// fully-shared prefix for an extension.
1199					// make a stub branch
1200					let branch = Node::NibbledBranch(
1201						existing_key.to_stored(),
1202						empty_children(),
1203						Some(stored_value),
1204					);
1205					// augment the new branch.
1206					let branch = self.insert_inspector(branch, key, value, old_val)?.unwrap_node();
1207
1208					InsertAction::Replace(branch)
1209				} else if common == existing_key.len() {
1210					debug_assert!(L::USE_EXTENSION);
1211					#[cfg(feature = "std")]
1212					trace!(target: "trie", "complete-prefix (common={:?}): AUGMENT-AT-END", common);
1213
1214					// fully-shared prefix for an extension.
1215					// make a stub branch and an extension.
1216					let branch = Node::Branch(empty_children(), Some(stored_value));
1217					// augment the new branch.
1218					key.advance(common);
1219					let branch = self.insert_inspector(branch, key, value, old_val)?.unwrap_node();
1220
1221					// always replace since we took a leaf and made an extension.
1222					let leaf = self.storage.alloc(Stored::New(branch));
1223					InsertAction::Replace(Node::Extension(existing_key.to_stored(), leaf.into()))
1224				} else {
1225					debug_assert!(L::USE_EXTENSION);
1226					#[cfg(feature = "std")]
1227					trace!(
1228						target: "trie",
1229						"partially-shared-prefix (exist={:?}; new={:?}; common={:?}):\
1230							 AUGMENT-AT-END",
1231						existing_key.len(),
1232						partial.len(),
1233						common,
1234					);
1235
1236					// partially-shared prefix for an extension.
1237					// start by making a leaf.
1238					let low = Node::Leaf(existing_key.mid(common).to_stored(), stored_value);
1239
1240					// augment it. this will result in the Leaf -> common == 0 routine,
1241					// which creates a branch.
1242					key.advance(common);
1243					let augmented_low =
1244						self.insert_inspector(low, key, value, old_val)?.unwrap_node();
1245					// make an extension using it. this is a replacement.
1246					InsertAction::Replace(Node::Extension(
1247						existing_key.to_stored_range(common),
1248						self.storage.alloc(Stored::New(augmented_low)).into(),
1249					))
1250				}
1251			},
1252			Node::Extension(encoded, child_branch) => {
1253				debug_assert!(L::USE_EXTENSION);
1254				let existing_key = NibbleSlice::from_stored(&encoded);
1255				let common = partial.common_prefix(&existing_key);
1256				if common == 0 {
1257					#[cfg(feature = "std")]
1258					trace!(
1259						target: "trie",
1260						"no-common-prefix, not-both-empty (exist={:?}; new={:?}):\
1261							 TRANSMUTE,AUGMENT",
1262						existing_key.len(),
1263						partial.len(),
1264					);
1265
1266					// partial isn't empty: make a branch here
1267					// extensions may not have empty partial keys.
1268					assert!(!existing_key.is_empty());
1269					let idx = existing_key.at(0) as usize;
1270
1271					let mut children = empty_children();
1272					children[idx] = if existing_key.len() == 1 {
1273						// direct extension, just replace.
1274						Some(child_branch)
1275					} else {
1276						// No need to register set branch (was here before).
1277						// Note putting a branch in extension requires fix.
1278						let ext = Node::Extension(existing_key.mid(1).to_stored(), child_branch);
1279						Some(self.storage.alloc(Stored::New(ext)).into())
1280					};
1281
1282					// continue inserting.
1283					let branch_action = self
1284						.insert_inspector(Node::Branch(children, None), key, value, old_val)?
1285						.unwrap_node();
1286					InsertAction::Replace(branch_action)
1287				} else if common == existing_key.len() {
1288					#[cfg(feature = "std")]
1289					trace!(target: "trie", "complete-prefix (common={:?}): AUGMENT-AT-END", common);
1290
1291					// fully-shared prefix.
1292
1293					// insert into the child node.
1294					key.advance(common);
1295					let (new_child, changed) = self.insert_at(child_branch, key, value, old_val)?;
1296
1297					let new_ext = Node::Extension(existing_key.to_stored(), new_child.into());
1298
1299					// if the child branch wasn't changed, meaning this extension remains the same.
1300					if changed {
1301						InsertAction::Replace(new_ext)
1302					} else {
1303						InsertAction::Restore(new_ext)
1304					}
1305				} else {
1306					#[cfg(feature = "std")]
1307					trace!(
1308						target: "trie",
1309						"partially-shared-prefix (exist={:?}; new={:?}; common={:?}):\
1310							 AUGMENT-AT-END",
1311						existing_key.len(),
1312						partial.len(),
1313						common,
1314					);
1315
1316					// partially-shared.
1317					let low = Node::Extension(existing_key.mid(common).to_stored(), child_branch);
1318					// augment the extension. this will take the common == 0 path,
1319					// creating a branch.
1320					key.advance(common);
1321					let augmented_low =
1322						self.insert_inspector(low, key, value, old_val)?.unwrap_node();
1323
1324					// always replace, since this extension is not the one we started with.
1325					// this is known because the partial key is only the common prefix.
1326					InsertAction::Replace(Node::Extension(
1327						existing_key.to_stored_range(common),
1328						self.storage.alloc(Stored::New(augmented_low)).into(),
1329					))
1330				}
1331			},
1332		})
1333	}
1334
1335	/// Removes a node from the trie based on key.
1336	fn remove_at(
1337		&mut self,
1338		handle: NodeHandle<TrieHash<L>>,
1339		key: &mut NibbleFullKey,
1340		old_val: &mut Option<Value<L>>,
1341	) -> Result<Option<(StorageHandle, bool)>, TrieHash<L>, CError<L>> {
1342		let stored = match handle {
1343			NodeHandle::InMemory(h) => self.storage.destroy(h),
1344			NodeHandle::Hash(h) => {
1345				let handle = self.cache(h, key.left())?;
1346				self.storage.destroy(handle)
1347			},
1348		};
1349
1350		let opt = self.inspect(stored, key, move |trie, node, key| {
1351			trie.remove_inspector(node, key, old_val)
1352		})?;
1353
1354		Ok(opt.map(|(new, changed)| (self.storage.alloc(new), changed)))
1355	}
1356
1357	/// The removal inspector.
1358	fn remove_inspector(
1359		&mut self,
1360		node: Node<L>,
1361		key: &mut NibbleFullKey,
1362		old_val: &mut Option<Value<L>>,
1363	) -> Result<Action<L>, TrieHash<L>, CError<L>> {
1364		let partial = *key;
1365		Ok(match (node, partial.is_empty()) {
1366			(Node::Empty, _) => Action::Delete,
1367			(Node::Branch(c, None), true) => Action::Restore(Node::Branch(c, None)),
1368			(Node::NibbledBranch(n, c, None), true) =>
1369				Action::Restore(Node::NibbledBranch(n, c, None)),
1370			(Node::Branch(children, val), true) => {
1371				self.replace_old_value(old_val, val, key.left());
1372				// always replace since we took the value out.
1373				Action::Replace(self.fix(Node::Branch(children, None), *key)?)
1374			},
1375			(Node::NibbledBranch(n, children, val), true) => {
1376				self.replace_old_value(old_val, val, key.left());
1377				// always replace since we took the value out.
1378				Action::Replace(self.fix(Node::NibbledBranch(n, children, None), *key)?)
1379			},
1380			(Node::Branch(mut children, value), false) => {
1381				let idx = partial.at(0) as usize;
1382				if let Some(child) = children[idx].take() {
1383					#[cfg(feature = "std")]
1384					trace!(
1385						target: "trie",
1386						"removing value out of branch child, partial={:?}",
1387						partial,
1388					);
1389					let prefix = *key;
1390					key.advance(1);
1391					match self.remove_at(child, key, old_val)? {
1392						Some((new, changed)) => {
1393							children[idx] = Some(new.into());
1394							let branch = Node::Branch(children, value);
1395							match changed {
1396								// child was changed, so we were too.
1397								true => Action::Replace(branch),
1398								// unchanged, so we are too.
1399								false => Action::Restore(branch),
1400							}
1401						},
1402						None => {
1403							// the child we took was deleted.
1404							// the node may need fixing.
1405							#[cfg(feature = "std")]
1406							trace!(target: "trie", "branch child deleted, partial={:?}", partial);
1407							Action::Replace(self.fix(Node::Branch(children, value), prefix)?)
1408						},
1409					}
1410				} else {
1411					// no change needed.
1412					Action::Restore(Node::Branch(children, value))
1413				}
1414			},
1415			(Node::NibbledBranch(encoded, mut children, value), false) => {
1416				let (common, existing_length) = {
1417					let existing_key = NibbleSlice::from_stored(&encoded);
1418					(existing_key.common_prefix(&partial), existing_key.len())
1419				};
1420				if common == existing_length && common == partial.len() {
1421					// replace val
1422					if let Some(value) = value {
1423						let mut key_val = key.clone();
1424						key_val.advance(existing_length);
1425						self.replace_old_value(old_val, Some(value), key_val.left());
1426						let f = self.fix(Node::NibbledBranch(encoded, children, None), *key);
1427						Action::Replace(f?)
1428					} else {
1429						Action::Restore(Node::NibbledBranch(encoded, children, None))
1430					}
1431				} else if common < existing_length {
1432					// partway through an extension -- nothing to do here.
1433					Action::Restore(Node::NibbledBranch(encoded, children, value))
1434				} else {
1435					// common == existing_length && common < partial.len() : check children
1436					let idx = partial.at(common) as usize;
1437
1438					if let Some(child) = children[idx].take() {
1439						#[cfg(feature = "std")]
1440						trace!(
1441							target: "trie",
1442							"removing value out of branch child, partial={:?}",
1443							partial,
1444						);
1445						let prefix = *key;
1446						key.advance(common + 1);
1447						match self.remove_at(child, key, old_val)? {
1448							Some((new, changed)) => {
1449								children[idx] = Some(new.into());
1450								let branch = Node::NibbledBranch(encoded, children, value);
1451								match changed {
1452									// child was changed, so we were too.
1453									true => Action::Replace(branch),
1454									// unchanged, so we are too.
1455									false => Action::Restore(branch),
1456								}
1457							},
1458							None => {
1459								// the child we took was deleted.
1460								// the node may need fixing.
1461								#[cfg(feature = "std")]
1462								trace!(
1463									target: "trie",
1464									"branch child deleted, partial={:?}",
1465									partial,
1466								);
1467								Action::Replace(
1468									self.fix(
1469										Node::NibbledBranch(encoded, children, value),
1470										prefix,
1471									)?,
1472								)
1473							},
1474						}
1475					} else {
1476						// no change needed.
1477						Action::Restore(Node::NibbledBranch(encoded, children, value))
1478					}
1479				}
1480			},
1481			(Node::Leaf(encoded, value), _) => {
1482				let existing_key = NibbleSlice::from_stored(&encoded);
1483				if existing_key == partial {
1484					// this is the node we were looking for. Let's delete it.
1485					let mut key_val = key.clone();
1486					key_val.advance(existing_key.len());
1487					self.replace_old_value(old_val, Some(value), key_val.left());
1488					Action::Delete
1489				} else {
1490					// leaf the node alone.
1491					#[cfg(feature = "std")]
1492					trace!(
1493						target: "trie",
1494						"restoring leaf wrong partial, partial={:?}, existing={:?}",
1495						partial,
1496						NibbleSlice::from_stored(&encoded),
1497					);
1498					Action::Restore(Node::Leaf(encoded, value))
1499				}
1500			},
1501			(Node::Extension(encoded, child_branch), _) => {
1502				let (common, existing_length) = {
1503					let existing_key = NibbleSlice::from_stored(&encoded);
1504					(existing_key.common_prefix(&partial), existing_key.len())
1505				};
1506				if common == existing_length {
1507					// try to remove from the child branch.
1508					#[cfg(feature = "std")]
1509					trace!(target: "trie", "removing from extension child, partial={:?}", partial);
1510					let prefix = *key;
1511					key.advance(common);
1512					match self.remove_at(child_branch, key, old_val)? {
1513						Some((new_child, changed)) => {
1514							// if the child branch was unchanged, then the extension is too.
1515							// otherwise, this extension may need fixing.
1516							match changed {
1517								true => Action::Replace(
1518									self.fix(Node::Extension(encoded, new_child.into()), prefix)?,
1519								),
1520								false =>
1521									Action::Restore(Node::Extension(encoded, new_child.into())),
1522							}
1523						},
1524						None => {
1525							// the whole branch got deleted.
1526							// that means that this extension is useless.
1527							Action::Delete
1528						},
1529					}
1530				} else {
1531					// partway through an extension -- nothing to do here.
1532					Action::Restore(Node::Extension(encoded, child_branch))
1533				}
1534			},
1535		})
1536	}
1537
1538	/// Given a node which may be in an _invalid state_, fix it such that it is then in a valid
1539	/// state.
1540	///
1541	/// _invalid state_ means:
1542	/// - Branch node where there is only a single entry;
1543	/// - Extension node followed by anything other than a Branch node.
1544	fn fix(&mut self, node: Node<L>, key: NibbleSlice) -> Result<Node<L>, TrieHash<L>, CError<L>> {
1545		self.fix_inner(node, key, false)
1546	}
1547	fn fix_inner(
1548		&mut self,
1549		node: Node<L>,
1550		key: NibbleSlice,
1551		recurse_extension: bool,
1552	) -> Result<Node<L>, TrieHash<L>, CError<L>> {
1553		match node {
1554			Node::Branch(mut children, value) => {
1555				// if only a single value, transmute to leaf/extension and feed through fixed.
1556				#[cfg_attr(feature = "std", derive(Debug))]
1557				enum UsedIndex {
1558					None,
1559					One(u8),
1560					Many,
1561				}
1562				let mut used_index = UsedIndex::None;
1563				for i in 0..16 {
1564					match (children[i].is_none(), &used_index) {
1565						(false, &UsedIndex::None) => used_index = UsedIndex::One(i as u8),
1566						(false, &UsedIndex::One(_)) => {
1567							used_index = UsedIndex::Many;
1568							break
1569						},
1570						_ => continue,
1571					}
1572				}
1573
1574				match (used_index, value) {
1575					(UsedIndex::None, None) => {
1576						panic!("Branch with no subvalues. Something went wrong.")
1577					},
1578					(UsedIndex::One(a), None) => {
1579						// only one onward node. make an extension.
1580
1581						let new_partial = NibbleSlice::new_offset(&[a], 1).to_stored();
1582						let child = children[a as usize]
1583							.take()
1584							.expect("used_index only set if occupied; qed");
1585						let new_node = Node::Extension(new_partial, child);
1586						self.fix(new_node, key)
1587					},
1588					(UsedIndex::None, Some(value)) => {
1589						// make a leaf.
1590						#[cfg(feature = "std")]
1591						trace!(target: "trie", "fixing: branch -> leaf");
1592						Ok(Node::Leaf(NibbleSlice::new(&[]).to_stored(), value))
1593					},
1594					(_, value) => {
1595						// all is well.
1596						#[cfg(feature = "std")]
1597						trace!(target: "trie", "fixing: restoring branch");
1598						Ok(Node::Branch(children, value))
1599					},
1600				}
1601			},
1602			Node::NibbledBranch(enc_nibble, mut children, value) => {
1603				// if only a single value, transmute to leaf/extension and feed through fixed.
1604				#[cfg_attr(feature = "std", derive(Debug))]
1605				enum UsedIndex {
1606					None,
1607					One(u8),
1608					Many,
1609				}
1610				let mut used_index = UsedIndex::None;
1611				for i in 0..16 {
1612					match (children[i].is_none(), &used_index) {
1613						(false, &UsedIndex::None) => used_index = UsedIndex::One(i as u8),
1614						(false, &UsedIndex::One(_)) => {
1615							used_index = UsedIndex::Many;
1616							break
1617						},
1618						_ => continue,
1619					}
1620				}
1621
1622				match (used_index, value) {
1623					(UsedIndex::None, None) => {
1624						panic!("Branch with no subvalues. Something went wrong.")
1625					},
1626					(UsedIndex::One(a), None) => {
1627						// only one onward node. use child instead
1628						let child = children[a as usize]
1629							.take()
1630							.expect("used_index only set if occupied; qed");
1631						let mut key2 = key.clone();
1632						key2.advance(
1633							(enc_nibble.1.len() * nibble_ops::NIBBLE_PER_BYTE) - enc_nibble.0,
1634						);
1635						let (start, alloc_start, prefix_end) = match key2.left() {
1636							(start, None) => (start, None, Some(nibble_ops::push_at_left(0, a, 0))),
1637							(start, Some(v)) => {
1638								let mut so: BackingByteVec = start.into();
1639								so.push(nibble_ops::pad_left(v) | a);
1640								(start, Some(so), None)
1641							},
1642						};
1643						let child_prefix = (
1644							alloc_start.as_ref().map(|start| &start[..]).unwrap_or(start),
1645							prefix_end,
1646						);
1647						let stored = match child {
1648							NodeHandle::InMemory(h) => self.storage.destroy(h),
1649							NodeHandle::Hash(h) => {
1650								let handle = self.cache(h, child_prefix)?;
1651								self.storage.destroy(handle)
1652							},
1653						};
1654						let child_node = match stored {
1655							Stored::New(node) => node,
1656							Stored::Cached(node, hash) => {
1657								self.death_row
1658									.insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1659								node
1660							},
1661						};
1662						match child_node {
1663							Node::Leaf(sub_partial, value) => {
1664								let mut enc_nibble = enc_nibble;
1665								combine_key(
1666									&mut enc_nibble,
1667									(nibble_ops::NIBBLE_PER_BYTE - 1, &[a][..]),
1668								);
1669								combine_key(&mut enc_nibble, (sub_partial.0, &sub_partial.1[..]));
1670								Ok(Node::Leaf(enc_nibble, value))
1671							},
1672							Node::NibbledBranch(sub_partial, ch_children, ch_value) => {
1673								let mut enc_nibble = enc_nibble;
1674								combine_key(
1675									&mut enc_nibble,
1676									(nibble_ops::NIBBLE_PER_BYTE - 1, &[a][..]),
1677								);
1678								combine_key(&mut enc_nibble, (sub_partial.0, &sub_partial.1[..]));
1679								Ok(Node::NibbledBranch(enc_nibble, ch_children, ch_value))
1680							},
1681							_ => unreachable!(),
1682						}
1683					},
1684					(UsedIndex::None, Some(value)) => {
1685						// make a leaf.
1686						#[cfg(feature = "std")]
1687						trace!(target: "trie", "fixing: branch -> leaf");
1688						Ok(Node::Leaf(enc_nibble, value))
1689					},
1690					(_, value) => {
1691						// all is well.
1692						#[cfg(feature = "std")]
1693						trace!(target: "trie", "fixing: restoring branch");
1694						Ok(Node::NibbledBranch(enc_nibble, children, value))
1695					},
1696				}
1697			},
1698			Node::Extension(partial, child) => {
1699				let mut key2 = key.clone();
1700				let (start, alloc_start, prefix_end) = if !recurse_extension {
1701					// We could advance key, but this code can also be called
1702					// recursively, so there might be some prefix from branch.
1703					let last = partial.1[partial.1.len() - 1] & (255 >> 4);
1704					key2.advance((partial.1.len() * nibble_ops::NIBBLE_PER_BYTE) - partial.0 - 1);
1705					match key2.left() {
1706						(start, None) => (start, None, Some(nibble_ops::push_at_left(0, last, 0))),
1707						(start, Some(v)) => {
1708							let mut so: BackingByteVec = start.into();
1709							// Complete last byte with `last`.
1710							so.push(nibble_ops::pad_left(v) | last);
1711							(start, Some(so), None)
1712						},
1713					}
1714				} else {
1715					let k2 = key2.left();
1716
1717					let mut so: NibbleVec = Default::default();
1718					so.append_optional_slice_and_nibble(Some(&NibbleSlice::new(k2.0)), None);
1719					if let Some(n) = k2.1 {
1720						so.push(n >> nibble_ops::BIT_PER_NIBBLE);
1721					}
1722					so.append_optional_slice_and_nibble(
1723						Some(&NibbleSlice::from_stored(&partial)),
1724						None,
1725					);
1726					let so = so.as_prefix();
1727					(k2.0, Some(so.0.into()), so.1)
1728				};
1729				let child_prefix =
1730					(alloc_start.as_ref().map(|start| &start[..]).unwrap_or(start), prefix_end);
1731
1732				let stored = match child {
1733					NodeHandle::InMemory(h) => self.storage.destroy(h),
1734					NodeHandle::Hash(h) => {
1735						let handle = self.cache(h, child_prefix)?;
1736						self.storage.destroy(handle)
1737					},
1738				};
1739
1740				let (child_node, maybe_hash) = match stored {
1741					Stored::New(node) => (node, None),
1742					Stored::Cached(node, hash) => (node, Some(hash)),
1743				};
1744
1745				match child_node {
1746					Node::Extension(sub_partial, sub_child) => {
1747						// combine with node below.
1748						if let Some(hash) = maybe_hash {
1749							// delete the cached child since we are going to replace it.
1750							self.death_row
1751								.insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1752						}
1753						// subpartial
1754						let mut partial = partial;
1755						combine_key(&mut partial, (sub_partial.0, &sub_partial.1[..]));
1756						#[cfg(feature = "std")]
1757						trace!(
1758							target: "trie",
1759							"fixing: extension combination. new_partial={:?}",
1760							partial,
1761						);
1762
1763						self.fix_inner(Node::Extension(partial, sub_child), key.into(), true)
1764					},
1765					Node::Leaf(sub_partial, value) => {
1766						// combine with node below.
1767						if let Some(hash) = maybe_hash {
1768							// delete the cached child since we are going to replace it.
1769							self.death_row
1770								.insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1771						}
1772						// subpartial oly
1773						let mut partial = partial;
1774						combine_key(&mut partial, (sub_partial.0, &sub_partial.1[..]));
1775						#[cfg(feature = "std")]
1776						trace!(
1777							target: "trie",
1778							"fixing: extension -> leaf. new_partial={:?}",
1779							partial,
1780						);
1781						Ok(Node::Leaf(partial, value))
1782					},
1783					child_node => {
1784						#[cfg(feature = "std")]
1785						trace!(target: "trie", "fixing: restoring extension");
1786
1787						// reallocate the child node.
1788						let stored = if let Some(hash) = maybe_hash {
1789							Stored::Cached(child_node, hash)
1790						} else {
1791							Stored::New(child_node)
1792						};
1793
1794						Ok(Node::Extension(partial, self.storage.alloc(stored).into()))
1795					},
1796				}
1797			},
1798			other => Ok(other), // only ext and branch need fixing.
1799		}
1800	}
1801
1802	/// Commit the in-memory changes to disk, freeing their storage and
1803	/// updating the state root.
1804	pub fn commit(&mut self) {
1805		#[cfg(feature = "std")]
1806		trace!(target: "trie", "Committing trie changes to db.");
1807
1808		// always kill all the nodes on death row.
1809		#[cfg(feature = "std")]
1810		trace!(target: "trie", "{:?} nodes to remove from db", self.death_row.len());
1811		for (hash, prefix) in self.death_row.drain() {
1812			self.db.remove(&hash, (&prefix.0[..], prefix.1));
1813		}
1814
1815		let handle = match self.root_handle() {
1816			NodeHandle::Hash(_) => return, // no changes necessary.
1817			NodeHandle::InMemory(h) => h,
1818		};
1819
1820		match self.storage.destroy(handle) {
1821			Stored::New(node) => {
1822				// Reconstructs the full key for root node.
1823				let full_key = self.cache.as_ref().and_then(|_| {
1824					node.partial_key().and_then(|k| Some(NibbleSlice::from_stored(k).into()))
1825				});
1826
1827				let mut k = NibbleVec::new();
1828
1829				let encoded_root = node.into_encoded(|node, o_slice, o_index| {
1830					let mov = k.append_optional_slice_and_nibble(o_slice, o_index);
1831					match node {
1832						NodeToEncode::Node(value) => {
1833							let value_hash = self.db.insert(k.as_prefix(), value);
1834							self.cache_value(k.inner(), value, value_hash);
1835							k.drop_lasts(mov);
1836							ChildReference::Hash(value_hash)
1837						},
1838						NodeToEncode::TrieNode(child) => {
1839							let result = self.commit_child(child, &mut k);
1840							k.drop_lasts(mov);
1841							result
1842						},
1843					}
1844				});
1845				#[cfg(feature = "std")]
1846				trace!(target: "trie", "encoded root node: {:?}", ToHex(&encoded_root[..]));
1847
1848				*self.root = self.db.insert(EMPTY_PREFIX, &encoded_root);
1849				self.hash_count += 1;
1850
1851				self.cache_node(*self.root, &encoded_root, full_key);
1852
1853				self.root_handle = NodeHandle::Hash(*self.root);
1854			},
1855			Stored::Cached(node, hash) => {
1856				// probably won't happen, but update the root and move on.
1857				*self.root = hash;
1858				self.root_handle =
1859					NodeHandle::InMemory(self.storage.alloc(Stored::Cached(node, hash)));
1860			},
1861		}
1862	}
1863
1864	/// Cache the given `encoded` node.
1865	fn cache_node(&mut self, hash: TrieHash<L>, encoded: &[u8], full_key: Option<NibbleVec>) {
1866		// If we have a cache, cache our node directly.
1867		if let Some(cache) = self.cache.as_mut() {
1868			let node = cache.get_or_insert_node(hash, &mut || {
1869				Ok(L::Codec::decode(&encoded)
1870					.ok()
1871					.and_then(|n| n.to_owned_node::<L>().ok())
1872					.expect("Just encoded the node, so it should decode without any errors; qed"))
1873			});
1874
1875			// `node` should always be `OK`, but let's play it safe.
1876			let node = if let Ok(node) = node { node } else { return };
1877
1878			let mut values_to_cache = Vec::new();
1879
1880			// If the given node has data attached, the `full_key` is the full key to this node.
1881			if let Some(full_key) = full_key {
1882				node.data().and_then(|v| node.data_hash().map(|h| (&full_key, v, h))).map(
1883					|(k, v, h)| {
1884						values_to_cache.push((k.inner().to_vec(), (v.clone(), h).into()));
1885					},
1886				);
1887
1888				fn cache_child_values<L: TrieLayout>(
1889					node: &NodeOwned<TrieHash<L>>,
1890					values_to_cache: &mut Vec<(Vec<u8>, CachedValue<TrieHash<L>>)>,
1891					full_key: NibbleVec,
1892				) {
1893					node.child_iter().flat_map(|(n, c)| c.as_inline().map(|c| (n, c))).for_each(
1894						|(n, c)| {
1895							let mut key = full_key.clone();
1896							n.map(|n| key.push(n));
1897							c.partial_key().map(|p| key.append(p));
1898
1899							if let Some((hash, data)) =
1900								c.data().and_then(|d| c.data_hash().map(|h| (h, d)))
1901							{
1902								values_to_cache
1903									.push((key.inner().to_vec(), (data.clone(), hash).into()));
1904							}
1905
1906							cache_child_values::<L>(c, values_to_cache, key);
1907						},
1908					);
1909				}
1910
1911				// Also cache values of inline nodes.
1912				cache_child_values::<L>(&node, &mut values_to_cache, full_key.clone());
1913			}
1914
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}