1use 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#[cfg_attr(feature = "std", derive(Debug))]
47struct StorageHandle(usize);
48
49#[cfg_attr(feature = "std", derive(Debug))]
51enum NodeHandle<H> {
52 InMemory(StorageHandle),
54 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
71type NibbleFullKey<'key> = NibbleSlice<'key>;
74
75#[derive(Clone, Eq)]
77pub enum Value<L: TrieLayout> {
78 Inline(Bytes),
80 Node(TrieHash<L>),
82 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 _ => 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
210enum Node<L: TrieLayout> {
212 Empty,
214 Leaf(NodeKey, Value<L>),
218 Extension(NodeKey, NodeHandle<TrieHash<L>>),
223 Branch(Box<[Option<NodeHandle<TrieHash<L>>>; nibble_ops::NIBBLE_LENGTH]>, Option<Value<L>>),
225 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 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 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 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 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 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 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 children.iter_mut().map(Option::take).enumerate().map(|(i, maybe_child)| {
492 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 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
516enum Action<L: TrieLayout> {
518 Replace(Node<L>),
520 Restore(Node<L>),
522 Delete,
524}
525
526enum InsertAction<L: TrieLayout> {
528 Replace(Node<L>),
530 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 fn unwrap_node(self) -> Node<L> {
544 match self {
545 InsertAction::Replace(n) | InsertAction::Restore(n) => n,
546 }
547 }
548}
549
550enum Stored<L: TrieLayout> {
552 New(Node<L>),
554 Cached(Node<L>, TrieHash<L>),
556}
557
558#[derive(Clone, Copy)]
560#[cfg_attr(feature = "std", derive(Debug))]
561pub enum ChildReference<HO> {
562 Hash(HO),
564 Inline(HO, usize), }
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
595struct NodeStorage<L: TrieLayout> {
597 nodes: Vec<Stored<L>>,
598 free_indices: VecDeque<usize>,
599}
600
601impl<L: TrieLayout> NodeStorage<L> {
602 fn empty() -> Self {
604 NodeStorage { nodes: Vec::new(), free_indices: VecDeque::new() }
605 }
606
607 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 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
638pub 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 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 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 pub fn with_cache(mut self, cache: &'db mut dyn TrieCache<L::Codec>) -> Self {
669 self.cache = Some(cache);
670 self
671 }
672
673 pub fn with_optional_cache<'cache: 'db>(
675 mut self,
676 cache: Option<&'cache mut dyn TrieCache<L::Codec>>,
677 ) -> Self {
678 self.cache = cache.map(|c| c as _);
680 self
681 }
682
683 pub fn with_recorder(mut self, recorder: &'db mut dyn TrieRecorder<TrieHash<L>>) -> Self {
685 self.recorder = Some(recorder);
686 self
687 }
688
689 pub fn with_optional_recorder<'recorder: 'db>(
691 mut self,
692 recorder: Option<&'recorder mut dyn TrieRecorder<TrieHash<L>>>,
693 ) -> Self {
694 self.recorder = recorder.map(|r| r as _);
696 self
697 }
698
699 pub fn disable_commit_on_drop(mut self) -> Self {
709 self.commit_on_drop = false;
710 self
711 }
712
713 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
733pub 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 cache: Option<&'a mut dyn TrieCache<L::Codec>>,
772 recorder: Option<core::cell::RefCell<&'a mut dyn TrieRecorder<TrieHash<L>>>>,
774 commit_on_drop: bool,
776}
777
778impl<'a, L> TrieDBMut<'a, L>
779where
780 L: TrieLayout,
781{
782 pub fn db(&self) -> &dyn HashDB<L::Hash, DBValue> {
784 self.db
785 }
786
787 pub fn db_mut(&mut self) -> &mut dyn HashDB<L::Hash, DBValue> {
789 self.db
790 }
791
792 fn cache(
794 &mut self,
795 hash: TrieHash<L>,
796 key: Prefix,
797 ) -> Result<StorageHandle, TrieHash<L>, CError<L>> {
798 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 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 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 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 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 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), _)) | 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 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 let (new_child, changed) = self.insert_at(child, key, value, old_val)?;
1048 children[idx] = Some(new_child.into());
1049 if !changed {
1050 return Ok(InsertAction::Restore(Node::Branch(children, stored_value)))
1053 }
1054 } else {
1055 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 #[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 #[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 let (new_child, changed) = self.insert_at(child, key, value, old_val)?;
1134 children[idx] = Some(new_child.into());
1135 if !changed {
1136 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 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 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 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 let mut children = empty_children();
1192 let branch = if L::USE_EXTENSION && existing_key.is_empty() {
1193 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 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 let branch = Node::NibbledBranch(
1220 existing_key.to_stored(),
1221 empty_children(),
1222 Some(stored_value),
1223 );
1224 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 let branch = Node::Branch(empty_children(), Some(stored_value));
1236 key.advance(common);
1238 let branch = self.insert_inspector(branch, key, value, old_val)?.unwrap_node();
1239
1240 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 let low = Node::Leaf(existing_key.mid(common).to_stored(), stored_value);
1258
1259 key.advance(common);
1262 let augmented_low =
1263 self.insert_inspector(low, key, value, old_val)?.unwrap_node();
1264 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 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 Some(child_branch)
1294 } else {
1295 let ext = Node::Extension(existing_key.mid(1).to_stored(), child_branch);
1298 Some(self.storage.alloc(Stored::New(ext)).into())
1299 };
1300
1301 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 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 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 let low = Node::Extension(existing_key.mid(common).to_stored(), child_branch);
1337 key.advance(common);
1340 let augmented_low =
1341 self.insert_inspector(low, key, value, old_val)?.unwrap_node();
1342
1343 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 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 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 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 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 true => Action::Replace(branch),
1417 false => Action::Restore(branch),
1419 }
1420 },
1421 None => {
1422 #[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 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 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 Action::Restore(Node::NibbledBranch(encoded, children, value))
1453 } else {
1454 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 true => Action::Replace(branch),
1473 false => Action::Restore(branch),
1475 }
1476 },
1477 None => {
1478 #[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 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 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 #[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 #[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 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 Action::Delete
1547 },
1548 }
1549 } else {
1550 Action::Restore(Node::Extension(encoded, child_branch))
1552 }
1553 },
1554 })
1555 }
1556
1557 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 #[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 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 #[cfg(feature = "std")]
1610 trace!(target: "trie", "fixing: branch -> leaf");
1611 Ok(Node::Leaf(NibbleSlice::new(&[]).to_stored(), value))
1612 },
1613 (_, value) => {
1614 #[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 #[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 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 #[cfg(feature = "std")]
1706 trace!(target: "trie", "fixing: branch -> leaf");
1707 Ok(Node::Leaf(enc_nibble, value))
1708 },
1709 (_, value) => {
1710 #[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 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 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 if let Some(hash) = maybe_hash {
1768 self.death_row
1770 .insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1771 }
1772 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 if let Some(hash) = maybe_hash {
1787 self.death_row
1789 .insert((hash, (child_prefix.0[..].into(), child_prefix.1)));
1790 }
1791 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 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), }
1819 }
1820
1821 pub fn commit(&mut self) {
1824 #[cfg(feature = "std")]
1825 trace!(target: "trie", "Committing trie changes to db.");
1826
1827 #[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, NodeHandle::InMemory(h) => h,
1844 };
1845
1846 match self.storage.destroy(handle) {
1847 Stored::New(node) => {
1848 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 *self.root = hash;
1883 self.root_handle =
1884 NodeHandle::InMemory(self.storage.alloc(Stored::Cached(node, hash)));
1885 },
1886 }
1887 }
1888
1889 fn cache_node(&mut self, hash: TrieHash<L>, encoded: &[u8], full_key: Option<NibbleVec>) {
1891 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 let node = if let Ok(node) = node { node } else { return };
1902
1903 let mut values_to_cache = Vec::new();
1904
1905 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 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 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 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 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 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 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 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
2134fn 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}