trie_db_fun/
node.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
15use crate::{
16	nibble::{self, nibble_ops, NibbleSlice, NibbleVec},
17	node_codec::NodeCodec,
18	Bytes, CError, ChildReference, Result, TrieError, TrieHash, TrieLayout,
19};
20#[cfg(not(feature = "std"))]
21use alloc::{boxed::Box, vec::Vec};
22use hash_db::Hasher;
23
24use crate::rstd::{borrow::Borrow, mem, ops::Range};
25
26/// Partial node key type: offset and owned value of a nibbleslice.
27/// Offset is applied on first byte of array (bytes are right aligned).
28pub type NodeKey = (usize, nibble::BackingByteVec);
29
30/// A reference to a trie node which may be stored within another trie node.
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum NodeHandle<'a> {
33	Hash(&'a [u8]),
34	Inline(&'a [u8]),
35}
36
37impl NodeHandle<'_> {
38	/// Converts this node handle into a [`NodeHandleOwned`].
39	pub fn to_owned_handle<L: TrieLayout>(
40		&self,
41	) -> Result<NodeHandleOwned<TrieHash<L>>, TrieHash<L>, CError<L>> {
42		match self {
43			Self::Hash(h) => decode_hash::<L::Hash>(h)
44				.ok_or_else(|| Box::new(TrieError::InvalidHash(Default::default(), h.to_vec())))
45				.map(NodeHandleOwned::Hash),
46			Self::Inline(i) => match L::Codec::decode(i) {
47				Ok(node) => Ok(NodeHandleOwned::Inline(Box::new(node.to_owned_node::<L>()?))),
48				Err(e) => Err(Box::new(TrieError::DecoderError(Default::default(), e))),
49			},
50		}
51	}
52}
53
54/// Owned version of [`NodeHandleOwned`].
55#[derive(Clone, PartialEq, Eq)]
56#[cfg_attr(feature = "std", derive(Debug))]
57pub enum NodeHandleOwned<H> {
58	Hash(H),
59	Inline(Box<NodeOwned<H>>),
60}
61
62impl<H> NodeHandleOwned<H>
63where
64	H: Default + AsRef<[u8]> + AsMut<[u8]> + Copy,
65{
66	/// Returns `self` as a [`ChildReference`].
67	///
68	/// # Panic
69	///
70	/// This function panics if `self == Self::Inline(_)` and the inline node encoded length is
71	/// greater then the length of the hash.
72	fn as_child_reference<C: NodeCodec<HashOut = H>>(&self) -> ChildReference<H> {
73		match self {
74			NodeHandleOwned::Hash(h) => ChildReference::Hash(*h),
75			NodeHandleOwned::Inline(n) => {
76				let encoded = n.to_encoded::<C>();
77				let mut store = H::default();
78				assert!(store.as_ref().len() > encoded.len(), "Invalid inline node handle");
79
80				store.as_mut()[..encoded.len()].copy_from_slice(&encoded);
81				ChildReference::Inline(store, encoded.len())
82			},
83		}
84	}
85}
86
87impl<H> NodeHandleOwned<H> {
88	/// Returns `self` as inline node.
89	pub fn as_inline(&self) -> Option<&NodeOwned<H>> {
90		match self {
91			Self::Hash(_) => None,
92			Self::Inline(node) => Some(&*node),
93		}
94	}
95}
96
97/// Read a hash from a slice into a Hasher output. Returns None if the slice is the wrong length.
98pub fn decode_hash<H: Hasher>(data: &[u8]) -> Option<H::Out> {
99	if data.len() != H::LENGTH {
100		return None
101	}
102	let mut hash = H::Out::default();
103	hash.as_mut().copy_from_slice(data);
104	Some(hash)
105}
106
107/// Value representation in `Node`.
108#[derive(Eq, PartialEq, Clone)]
109#[cfg_attr(feature = "std", derive(Debug))]
110pub enum Value<'a> {
111	/// Value byte slice as stored in a trie node.
112	Inline(&'a [u8]),
113	/// Hash byte slice as stored in a trie node.
114	Node(&'a [u8]),
115}
116
117impl<'a> Value<'a> {
118	pub(crate) fn new_inline(value: &'a [u8], threshold: Option<u32>) -> Option<Self> {
119		if let Some(threshold) = threshold {
120			if value.len() >= threshold as usize {
121				return None
122			} else {
123				Some(Value::Inline(value))
124			}
125		} else {
126			Some(Value::Inline(value))
127		}
128	}
129
130	pub fn to_owned_value<L: TrieLayout>(&self) -> ValueOwned<TrieHash<L>> {
131		match self {
132			Self::Inline(data) => ValueOwned::Inline(Bytes::from(*data), L::Hash::hash(data)),
133			Self::Node(hash) => {
134				let mut res = TrieHash::<L>::default();
135				res.as_mut().copy_from_slice(hash);
136
137				ValueOwned::Node(res)
138			},
139		}
140	}
141}
142
143/// Owned value representation in `Node`.
144#[derive(Eq, PartialEq, Clone)]
145#[cfg_attr(feature = "std", derive(Debug))]
146pub enum ValueOwned<H> {
147	/// Value bytes as stored in a trie node and its hash.
148	Inline(Bytes, H),
149	/// Hash byte slice as stored in a trie node.
150	Node(H),
151}
152
153impl<H: AsRef<[u8]> + Copy> ValueOwned<H> {
154	/// Returns self as [`Value`].
155	pub fn as_value(&self) -> Value {
156		match self {
157			Self::Inline(data, _) => Value::Inline(&data),
158			Self::Node(hash) => Value::Node(hash.as_ref()),
159		}
160	}
161
162	/// Returns the hash of the data stored in self.
163	pub fn data_hash(&self) -> Option<H> {
164		match self {
165			Self::Inline(_, hash) => Some(*hash),
166			Self::Node(hash) => Some(*hash),
167		}
168	}
169}
170
171impl<H> ValueOwned<H> {
172	/// Returns the data stored in self.
173	pub fn data(&self) -> Option<&Bytes> {
174		match self {
175			Self::Inline(data, _) => Some(data),
176			Self::Node(_) => None,
177		}
178	}
179}
180
181/// Type of node in the trie and essential information thereof.
182#[derive(Eq, PartialEq, Clone)]
183#[cfg_attr(feature = "std", derive(Debug))]
184pub enum Node<'a> {
185	/// Null trie node; could be an empty root or an empty branch entry.
186	Empty,
187	/// Leaf node; has key slice and value. Value may not be empty.
188	Leaf(NibbleSlice<'a>, Value<'a>),
189	/// Extension node; has key slice and node data. Data may not be null.
190	Extension(NibbleSlice<'a>, NodeHandle<'a>),
191	/// Branch node; has slice of child nodes (each possibly null)
192	/// and an optional immediate node data.
193	Branch([Option<NodeHandle<'a>>; nibble_ops::NIBBLE_LENGTH], Option<Value<'a>>),
194	/// Branch node with support for a nibble (when extension nodes are not used).
195	NibbledBranch(
196		NibbleSlice<'a>,
197		[Option<NodeHandle<'a>>; nibble_ops::NIBBLE_LENGTH],
198		Option<Value<'a>>,
199	),
200}
201
202impl Node<'_> {
203	/// Converts this node into a [`NodeOwned`].
204	pub fn to_owned_node<L: TrieLayout>(
205		&self,
206	) -> Result<NodeOwned<TrieHash<L>>, TrieHash<L>, CError<L>> {
207		match self {
208			Self::Empty => Ok(NodeOwned::Empty),
209			Self::Leaf(n, d) => Ok(NodeOwned::Leaf((*n).into(), d.to_owned_value::<L>())),
210			Self::Extension(n, h) =>
211				Ok(NodeOwned::Extension((*n).into(), h.to_owned_handle::<L>()?)),
212			Self::Branch(childs, data) => {
213				let mut childs_owned = [(); nibble_ops::NIBBLE_LENGTH].map(|_| None);
214				childs
215					.iter()
216					.enumerate()
217					.map(|(i, c)| {
218						childs_owned[i] =
219							c.as_ref().map(|c| c.to_owned_handle::<L>()).transpose()?;
220						Ok(())
221					})
222					.collect::<Result<_, _, _>>()?;
223
224				Ok(NodeOwned::Branch(childs_owned, data.as_ref().map(|d| d.to_owned_value::<L>())))
225			},
226			Self::NibbledBranch(n, childs, data) => {
227				let mut childs_owned = [(); nibble_ops::NIBBLE_LENGTH].map(|_| None);
228				childs
229					.iter()
230					.enumerate()
231					.map(|(i, c)| {
232						childs_owned[i] =
233							c.as_ref().map(|c| c.to_owned_handle::<L>()).transpose()?;
234						Ok(())
235					})
236					.collect::<Result<_, _, _>>()?;
237
238				Ok(NodeOwned::NibbledBranch(
239					(*n).into(),
240					childs_owned,
241					data.as_ref().map(|d| d.to_owned_value::<L>()),
242				))
243			},
244		}
245	}
246}
247
248/// Owned version of [`Node`].
249#[derive(Eq, PartialEq, Clone)]
250#[cfg_attr(feature = "std", derive(Debug))]
251pub enum NodeOwned<H> {
252	/// Null trie node; could be an empty root or an empty branch entry.
253	Empty,
254	/// Leaf node; has key slice and value. Value may not be empty.
255	Leaf(NibbleVec, ValueOwned<H>),
256	/// Extension node; has key slice and node data. Data may not be null.
257	Extension(NibbleVec, NodeHandleOwned<H>),
258	/// Branch node; has slice of child nodes (each possibly null)
259	/// and an optional immediate node data.
260	Branch([Option<NodeHandleOwned<H>>; nibble_ops::NIBBLE_LENGTH], Option<ValueOwned<H>>),
261	/// Branch node with support for a nibble (when extension nodes are not used).
262	NibbledBranch(
263		NibbleVec,
264		[Option<NodeHandleOwned<H>>; nibble_ops::NIBBLE_LENGTH],
265		Option<ValueOwned<H>>,
266	),
267	/// Node that represents a value.
268	///
269	/// This variant is only constructed when working with a [`crate::TrieCache`]. It is only
270	/// used to cache a raw value.
271	Value(Bytes, H),
272}
273
274impl<H> NodeOwned<H>
275where
276	H: Default + AsRef<[u8]> + AsMut<[u8]> + Copy,
277{
278	/// Convert to its encoded format.
279	pub fn to_encoded<C>(&self) -> Vec<u8>
280	where
281		C: NodeCodec<HashOut = H>,
282	{
283		match self {
284			Self::Empty => C::empty_node().to_vec(),
285			Self::Leaf(partial, value) =>
286				C::leaf_node(partial.right_iter(), partial.len(), value.as_value()),
287			Self::Extension(partial, child) => C::extension_node(
288				partial.right_iter(),
289				partial.len(),
290				child.as_child_reference::<C>(),
291			),
292			Self::Branch(children, value) => C::branch_node(
293				children.iter().map(|child| child.as_ref().map(|c| c.as_child_reference::<C>())),
294				value.as_ref().map(|v| v.as_value()),
295			),
296			Self::NibbledBranch(partial, children, value) => C::branch_node_nibbled(
297				partial.right_iter(),
298				partial.len(),
299				children.iter().map(|child| child.as_ref().map(|c| c.as_child_reference::<C>())),
300				value.as_ref().map(|v| v.as_value()),
301			),
302			Self::Value(data, _) => data.to_vec(),
303		}
304	}
305
306	/// Returns an iterator over all existing children with their optional nibble.
307	pub fn child_iter(&self) -> impl Iterator<Item = (Option<u8>, &NodeHandleOwned<H>)> {
308		enum ChildIter<'a, H> {
309			Empty,
310			Single(&'a NodeHandleOwned<H>, bool),
311			Array(&'a [Option<NodeHandleOwned<H>>; nibble_ops::NIBBLE_LENGTH], usize),
312		}
313
314		impl<'a, H> Iterator for ChildIter<'a, H> {
315			type Item = (Option<u8>, &'a NodeHandleOwned<H>);
316
317			fn next(&mut self) -> Option<Self::Item> {
318				loop {
319					match self {
320						Self::Empty => break None,
321						Self::Single(child, returned) =>
322							break if *returned {
323								None
324							} else {
325								*returned = true;
326								Some((None, child))
327							},
328						Self::Array(childs, index) =>
329							if *index >= childs.len() {
330								break None
331							} else {
332								*index += 1;
333
334								// Ignore non-existing childs.
335								if let Some(ref child) = childs[*index - 1] {
336									break Some((Some(*index as u8 - 1), child))
337								}
338							},
339					}
340				}
341			}
342		}
343
344		match self {
345			Self::Leaf(_, _) | Self::Empty | Self::Value(_, _) => ChildIter::Empty,
346			Self::Extension(_, child) => ChildIter::Single(child, false),
347			Self::Branch(children, _) | Self::NibbledBranch(_, children, _) =>
348				ChildIter::Array(children, 0),
349		}
350	}
351
352	/// Returns the hash of the data attached to this node.
353	pub fn data_hash(&self) -> Option<H> {
354		match &self {
355			Self::Empty => None,
356			Self::Leaf(_, value) => value.data_hash(),
357			Self::Extension(_, _) => None,
358			Self::Branch(_, value) => value.as_ref().and_then(|v| v.data_hash()),
359			Self::NibbledBranch(_, _, value) => value.as_ref().and_then(|v| v.data_hash()),
360			Self::Value(_, hash) => Some(*hash),
361		}
362	}
363}
364
365impl<H> NodeOwned<H> {
366	/// Returns the data attached to this node.
367	pub fn data(&self) -> Option<&Bytes> {
368		match &self {
369			Self::Empty => None,
370			Self::Leaf(_, value) => value.data(),
371			Self::Extension(_, _) => None,
372			Self::Branch(_, value) => value.as_ref().and_then(|v| v.data()),
373			Self::NibbledBranch(_, _, value) => value.as_ref().and_then(|v| v.data()),
374			Self::Value(data, _) => Some(data),
375		}
376	}
377
378	/// Returns the partial key of this node.
379	pub fn partial_key(&self) -> Option<&NibbleVec> {
380		match self {
381			Self::Branch(_, _) | Self::Value(_, _) | Self::Empty => None,
382			Self::Extension(partial, _) |
383			Self::Leaf(partial, _) |
384			Self::NibbledBranch(partial, _, _) => Some(partial),
385		}
386	}
387
388	/// Returns the size in bytes of this node in memory.
389	///
390	/// This also includes the size of any inline child nodes.
391	pub fn size_in_bytes(&self) -> usize {
392		let self_size = mem::size_of::<Self>();
393
394		fn childs_size<'a, H: 'a>(
395			childs: impl Iterator<Item = &'a Option<NodeHandleOwned<H>>>,
396		) -> usize {
397			// If a `child` isn't an inline node, its size is already taken account for by
398			// `self_size`.
399			childs
400				.filter_map(|c| c.as_ref())
401				.map(|c| c.as_inline().map_or(0, |n| n.size_in_bytes()))
402				.sum()
403		}
404
405		// As `self_size` only represents the static size of `Self`, we also need
406		// to add the size of any dynamically allocated data.
407		let dynamic_size = match self {
408			Self::Empty => 0,
409			Self::Leaf(nibbles, value) =>
410				nibbles.inner().len() + value.data().map_or(0, |b| b.len()),
411			Self::Value(bytes, _) => bytes.len(),
412			Self::Extension(nibbles, child) => {
413				// If the `child` isn't an inline node, its size is already taken account for by
414				// `self_size`.
415				nibbles.inner().len() + child.as_inline().map_or(0, |n| n.size_in_bytes())
416			},
417			Self::Branch(childs, value) =>
418				childs_size(childs.iter()) +
419					value.as_ref().and_then(|v| v.data()).map_or(0, |b| b.len()),
420			Self::NibbledBranch(nibbles, childs, value) =>
421				nibbles.inner().len() +
422					childs_size(childs.iter()) +
423					value.as_ref().and_then(|v| v.data()).map_or(0, |b| b.len()),
424		};
425
426		self_size + dynamic_size
427	}
428}
429
430/// A `NodeHandlePlan` is a decoding plan for constructing a `NodeHandle` from an encoded trie
431/// node. This is used as a substructure of `NodePlan`. See `NodePlan` for details.
432#[derive(Debug, Clone, PartialEq, Eq)]
433pub enum NodeHandlePlan {
434	Hash(Range<usize>),
435	Inline(Range<usize>),
436}
437
438impl NodeHandlePlan {
439	/// Build a node handle by decoding a byte slice according to the node handle plan. It is the
440	/// responsibility of the caller to ensure that the node plan was created for the argument
441	/// data, otherwise the call may decode incorrectly or panic.
442	pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> NodeHandle<'b> {
443		match self {
444			NodeHandlePlan::Hash(range) => NodeHandle::Hash(&data[range.clone()]),
445			NodeHandlePlan::Inline(range) => NodeHandle::Inline(&data[range.clone()]),
446		}
447	}
448}
449
450/// A `NibbleSlicePlan` is a blueprint for decoding a nibble slice from a byte slice. The
451/// `NibbleSlicePlan` is created by parsing a byte slice and can be reused multiple times.
452#[derive(Eq, PartialEq, Clone)]
453#[cfg_attr(feature = "std", derive(Debug))]
454pub struct NibbleSlicePlan {
455	bytes: Range<usize>,
456	offset: usize,
457}
458
459impl NibbleSlicePlan {
460	/// Construct a nibble slice decode plan.
461	pub fn new(bytes: Range<usize>, offset: usize) -> Self {
462		NibbleSlicePlan { bytes, offset }
463	}
464
465	/// Returns the nibble length of the slice.
466	pub fn len(&self) -> usize {
467		(self.bytes.end - self.bytes.start) * nibble_ops::NIBBLE_PER_BYTE - self.offset
468	}
469
470	/// Build a nibble slice by decoding a byte slice according to the plan. It is the
471	/// responsibility of the caller to ensure that the node plan was created for the argument
472	/// data, otherwise the call may decode incorrectly or panic.
473	pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> NibbleSlice<'b> {
474		NibbleSlice::new_offset(&data[self.bytes.clone()], self.offset)
475	}
476}
477
478/// Plan for value representation in `NodePlan`.
479#[derive(Eq, PartialEq, Clone)]
480#[cfg_attr(feature = "std", derive(Debug))]
481pub enum ValuePlan {
482	/// Range for byte representation in encoded node.
483	Inline(Range<usize>),
484	/// Range for hash in encoded node and original
485	/// value size.
486	Node(Range<usize>),
487}
488
489impl ValuePlan {
490	/// Build a value slice by decoding a byte slice according to the plan.
491	pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> Value<'b> {
492		match self {
493			ValuePlan::Inline(range) => Value::Inline(&data[range.clone()]),
494			ValuePlan::Node(range) => Value::Node(&data[range.clone()]),
495		}
496	}
497}
498
499/// A `NodePlan` is a blueprint for decoding a node from a byte slice. The `NodePlan` is created
500/// by parsing an encoded node and can be reused multiple times. This is useful as a `Node` borrows
501/// from a byte slice and this struct does not.
502///
503/// The enum values mirror those of `Node` except that instead of byte slices, this struct stores
504/// ranges that can be used to index into a large byte slice.
505#[derive(Eq, PartialEq, Clone)]
506#[cfg_attr(feature = "std", derive(Debug))]
507pub enum NodePlan {
508	/// Null trie node; could be an empty root or an empty branch entry.
509	Empty,
510	/// Leaf node; has a partial key plan and value.
511	Leaf { partial: NibbleSlicePlan, value: ValuePlan },
512	/// Extension node; has a partial key plan and child data.
513	Extension { partial: NibbleSlicePlan, child: NodeHandlePlan },
514	/// Branch node; has slice of child nodes (each possibly null)
515	/// and an optional immediate node data.
516	Branch {
517		value: Option<ValuePlan>,
518		children: [Option<NodeHandlePlan>; nibble_ops::NIBBLE_LENGTH],
519	},
520	/// Branch node with support for a nibble (when extension nodes are not used).
521	NibbledBranch {
522		partial: NibbleSlicePlan,
523		value: Option<ValuePlan>,
524		children: [Option<NodeHandlePlan>; nibble_ops::NIBBLE_LENGTH],
525	},
526}
527
528impl NodePlan {
529	/// Build a node by decoding a byte slice according to the node plan. It is the responsibility
530	/// of the caller to ensure that the node plan was created for the argument data, otherwise the
531	/// call may decode incorrectly or panic.
532	pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> Node<'b> {
533		match self {
534			NodePlan::Empty => Node::Empty,
535			NodePlan::Leaf { partial, value } => Node::Leaf(partial.build(data), value.build(data)),
536			NodePlan::Extension { partial, child } =>
537				Node::Extension(partial.build(data), child.build(data)),
538			NodePlan::Branch { value, children } => {
539				let mut child_slices = [None; nibble_ops::NIBBLE_LENGTH];
540				for i in 0..nibble_ops::NIBBLE_LENGTH {
541					child_slices[i] = children[i].as_ref().map(|child| child.build(data));
542				}
543				Node::Branch(child_slices, value.as_ref().map(|v| v.build(data)))
544			},
545			NodePlan::NibbledBranch { partial, value, children } => {
546				let mut child_slices = [None; nibble_ops::NIBBLE_LENGTH];
547				for i in 0..nibble_ops::NIBBLE_LENGTH {
548					child_slices[i] = children[i].as_ref().map(|child| child.build(data));
549				}
550				Node::NibbledBranch(
551					partial.build(data),
552					child_slices,
553					value.as_ref().map(|v| v.build(data)),
554				)
555			},
556		}
557	}
558
559	/// Access value plan from node plan, return `None` for
560	/// node that cannot contain a `ValuePlan`.
561	pub fn value_plan(&self) -> Option<&ValuePlan> {
562		match self {
563			NodePlan::Extension { .. } | NodePlan::Empty => None,
564			NodePlan::Leaf { value, .. } => Some(value),
565			NodePlan::Branch { value, .. } | NodePlan::NibbledBranch { value, .. } =>
566				value.as_ref(),
567		}
568	}
569
570	/// Mutable ccess value plan from node plan, return `None` for
571	/// node that cannot contain a `ValuePlan`.
572	pub fn value_plan_mut(&mut self) -> Option<&mut ValuePlan> {
573		match self {
574			NodePlan::Extension { .. } | NodePlan::Empty => None,
575			NodePlan::Leaf { value, .. } => Some(value),
576			NodePlan::Branch { value, .. } | NodePlan::NibbledBranch { value, .. } =>
577				value.as_mut(),
578		}
579	}
580}
581
582/// An `OwnedNode` is an owned type from which a `Node` can be constructed which borrows data from
583/// the `OwnedNode`. This is useful for trie iterators.
584#[cfg_attr(feature = "std", derive(Debug))]
585#[derive(PartialEq, Eq)]
586pub struct OwnedNode<D: Borrow<[u8]>> {
587	data: D,
588	plan: NodePlan,
589}
590
591impl<D: Borrow<[u8]>> OwnedNode<D> {
592	/// Construct an `OwnedNode` by decoding an owned data source according to some codec.
593	pub fn new<C: NodeCodec>(data: D) -> core::result::Result<Self, C::Error> {
594		let plan = C::decode_plan(data.borrow())?;
595		Ok(OwnedNode { data, plan })
596	}
597
598	/// Returns a reference to the backing data.
599	pub fn data(&self) -> &[u8] {
600		self.data.borrow()
601	}
602
603	/// Returns a reference to the node decode plan.
604	pub fn node_plan(&self) -> &NodePlan {
605		&self.plan
606	}
607
608	/// Returns a mutable reference to the node decode plan.
609	pub fn node_plan_mut(&mut self) -> &mut NodePlan {
610		&mut self.plan
611	}
612
613	/// Construct a `Node` by borrowing data from this struct.
614	pub fn node(&self) -> Node {
615		self.plan.build(self.data.borrow())
616	}
617}