trie_db/
triedbmut.rs

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