oasis_core_runtime/storage/mkvs/tree/
node.rs

1use std::{cell::RefCell, rc::Rc};
2
3use crate::{
4    common::{crypto::hash::Hash, namespace::Namespace},
5    storage::mkvs::{
6        cache::{CacheExtra, CacheItem},
7        marshal::Marshal,
8    },
9};
10
11/// Common interface for node-like objects in the tree.
12pub trait Node {
13    /// Check whether the node is clean or not.
14    fn is_clean(&self) -> bool;
15    /// Get the node's hash.
16    fn get_hash(&self) -> Hash;
17    /// Recompute the node's hash.
18    fn update_hash(&mut self);
19    /// Duplicate the node but include only hash references.
20    fn extract(&self) -> NodeRef;
21}
22
23/// Storage root type.
24#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)]
25#[repr(u8)]
26pub enum RootType {
27    /// Invalid or uninitialized storage root type.
28    #[default]
29    Invalid = 0,
30    /// Storage root for runtime state.
31    State = 1,
32    /// Storage root for transaction IO.
33    IO = 2,
34}
35
36/// Storage root.
37#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
38pub struct Root {
39    /// Namespace under which the root is stored.
40    #[cbor(rename = "ns")]
41    pub namespace: Namespace,
42    /// Monotonically increasing version number in which the root is stored.
43    pub version: u64,
44    /// The storage type that this root has data for.
45    pub root_type: RootType,
46    /// Merkle root hash.
47    pub hash: Hash,
48}
49
50/// A box type that can contain either internal or leaf nodes.
51#[derive(Debug, Eq, PartialEq)]
52pub enum NodeBox {
53    Internal(InternalNode),
54    Leaf(LeafNode),
55}
56
57impl Default for NodeBox {
58    fn default() -> Self {
59        NodeBox::Internal(Default::default())
60    }
61}
62
63impl Node for NodeBox {
64    fn is_clean(&self) -> bool {
65        match self {
66            NodeBox::Internal(ref n) => n.is_clean(),
67            NodeBox::Leaf(ref n) => n.is_clean(),
68        }
69    }
70
71    fn get_hash(&self) -> Hash {
72        match self {
73            NodeBox::Internal(ref n) => n.get_hash(),
74            NodeBox::Leaf(ref n) => n.get_hash(),
75        }
76    }
77
78    fn update_hash(&mut self) {
79        match self {
80            NodeBox::Internal(ref mut n) => n.update_hash(),
81            NodeBox::Leaf(ref mut n) => n.update_hash(),
82        }
83    }
84
85    fn extract(&self) -> NodeRef {
86        match self {
87            NodeBox::Internal(ref n) => n.extract(),
88            NodeBox::Leaf(ref n) => n.extract(),
89        }
90    }
91}
92
93/// Node types in the tree.
94///
95/// Integer values of the variants here are also used in subtree
96/// serialization and as prefixes in node hash computations.
97#[derive(Copy, Clone, Debug)]
98#[repr(u8)]
99pub enum NodeKind {
100    None = 0x02,
101    Internal = 0x01,
102    Leaf = 0x00,
103}
104
105/// `NodeRef` is a reference-counted pointer to a node box.
106pub type NodeRef = Rc<RefCell<NodeBox>>;
107
108/// A pointer to a node in the tree.
109#[derive(Debug, Default)]
110pub struct NodePointer {
111    pub clean: bool,
112    pub hash: Hash,
113    pub node: Option<NodeRef>,
114
115    pub cache_extra: CacheExtra<NodePointer>,
116}
117
118/// A reference-counted pointer to a pointer.
119pub type NodePtrRef = Rc<RefCell<NodePointer>>;
120
121impl NodePointer {
122    /// Construct a null pointer.
123    pub fn null_ptr() -> NodePtrRef {
124        Rc::new(RefCell::new(NodePointer {
125            node: None,
126            clean: true,
127            hash: Hash::empty_hash(),
128            ..Default::default()
129        }))
130    }
131
132    /// Construct a hash-only pointer.
133    pub fn hash_ptr(hash: Hash) -> NodePtrRef {
134        Rc::new(RefCell::new(NodePointer {
135            node: None,
136            clean: true,
137            hash,
138            ..Default::default()
139        }))
140    }
141
142    /// Construct a node pointer from a full node.
143    pub fn from_node(node: NodeBox) -> NodePtrRef {
144        Rc::new(RefCell::new(NodePointer {
145            hash: node.get_hash(),
146            node: Some(Rc::new(RefCell::new(node))),
147            clean: true,
148            ..Default::default()
149        }))
150    }
151
152    /// Check if the pointer is a null pointer.
153    pub fn is_null(&self) -> bool {
154        self.hash.is_empty()
155    }
156
157    /// Check if the pointer has a resolved reference to a concrete node.
158    pub fn has_node(&self) -> bool {
159        !self.is_null() && self.node.is_some()
160    }
161
162    /// Get a reference to the node the pointer is pointing to.
163    pub fn get_node(&self) -> NodeRef {
164        match &self.node {
165            None => panic!("mkvs: get_node called on pointer without a node"),
166            Some(node) => node.clone(),
167        }
168    }
169
170    /// Return a copy of this pointer containing only hash references.
171    pub fn extract(&self) -> NodePtrRef {
172        assert!(self.clean, "mkvs: extract called on dirty pointer");
173
174        Rc::new(RefCell::new(NodePointer {
175            clean: true,
176            hash: self.hash,
177            ..Default::default()
178        }))
179    }
180
181    // Make deep copy of the Pointer to LeafNode excluding LRU and DBInternal.
182    //
183    // Panics, if it's called on non-leaf node pointer.
184    fn copy_leaf_ptr(&self) -> NodePtrRef {
185        if !self.has_node() {
186            return NodePointer::null_ptr();
187        }
188
189        assert!(self.clean, "mkvs: copy_leaf_ptr called on dirty pointer");
190
191        if let Some(ref some_node) = self.node {
192            let nyoo = noderef_as!(some_node, Leaf).copy();
193            Rc::new(RefCell::new(NodePointer {
194                clean: true,
195                hash: self.hash,
196                node: Some(Rc::new(RefCell::new(NodeBox::Leaf(nyoo)))),
197                ..Default::default()
198            }))
199        } else {
200            panic!("mkvs: copy_leaf_ptr called on a non-leaf pointer");
201        }
202    }
203}
204
205impl CacheItem for NodePointer {
206    fn get_cache_extra(&self) -> CacheExtra<NodePointer> {
207        self.cache_extra
208    }
209
210    fn set_cache_extra(&mut self, new_val: CacheExtra<NodePointer>) {
211        self.cache_extra = new_val;
212    }
213
214    fn get_cached_size(&self) -> usize {
215        1
216    }
217}
218
219impl PartialEq for NodePointer {
220    fn eq(&self, other: &NodePointer) -> bool {
221        if self.clean && other.clean {
222            self.hash == other.hash
223        } else {
224            self.node.is_some() && self.node == other.node
225        }
226    }
227}
228
229impl Eq for NodePointer {}
230
231/// An internal tree node with two children and possibly a leaf.
232#[derive(Debug, Default)]
233pub struct InternalNode {
234    pub clean: bool,
235    pub hash: Hash,
236    pub label: Key,              // label on the incoming edge
237    pub label_bit_length: Depth, // length of the label in bits
238    pub leaf_node: NodePtrRef,   // for the key ending at this depth
239    pub left: NodePtrRef,
240    pub right: NodePtrRef,
241}
242
243impl Node for InternalNode {
244    fn is_clean(&self) -> bool {
245        self.clean
246    }
247
248    fn get_hash(&self) -> Hash {
249        self.hash
250    }
251
252    fn update_hash(&mut self) {
253        let leaf_node_hash = self.leaf_node.borrow().hash;
254        let left_hash = self.left.borrow().hash;
255        let right_hash = self.right.borrow().hash;
256
257        self.hash = Hash::digest_bytes_list(&[
258            &[NodeKind::Internal as u8],
259            &self.label_bit_length.marshal_binary().unwrap(),
260            self.label.as_ref(),
261            leaf_node_hash.as_ref(),
262            left_hash.as_ref(),
263            right_hash.as_ref(),
264        ]);
265    }
266
267    fn extract(&self) -> NodeRef {
268        assert!(self.clean, "mkvs: extract called on dirty node");
269
270        Rc::new(RefCell::new(NodeBox::Internal(InternalNode {
271            clean: true,
272            hash: self.hash,
273            label: self.label.clone(),
274            label_bit_length: self.label_bit_length,
275            leaf_node: self.leaf_node.borrow().copy_leaf_ptr(),
276            left: self.left.borrow().extract(),
277            right: self.right.borrow().extract(),
278        })))
279    }
280}
281
282impl PartialEq for InternalNode {
283    fn eq(&self, other: &InternalNode) -> bool {
284        if self.clean && other.clean {
285            self.hash == other.hash
286        } else {
287            self.leaf_node == other.leaf_node
288                && self.left == other.left
289                && self.right == other.right
290        }
291    }
292}
293
294impl Eq for InternalNode {}
295
296/// A leaf node containing a key/value pair.
297#[derive(Debug, Default)]
298pub struct LeafNode {
299    pub clean: bool,
300    pub hash: Hash,
301    pub key: Key,
302    pub value: Value,
303}
304
305impl LeafNode {
306    pub fn copy(&self) -> LeafNode {
307        LeafNode {
308            clean: self.clean,
309            hash: self.hash,
310            key: self.key.to_owned(),
311            value: self.value.clone(),
312        }
313    }
314}
315
316impl Node for LeafNode {
317    fn is_clean(&self) -> bool {
318        self.clean
319    }
320
321    fn get_hash(&self) -> Hash {
322        self.hash
323    }
324
325    fn update_hash(&mut self) {
326        self.hash = Hash::digest_bytes_list(&[
327            &[NodeKind::Leaf as u8],
328            &(self.key.len() as u32).marshal_binary().unwrap(),
329            self.key.as_ref(),
330            &(self.value.len() as u32).marshal_binary().unwrap(),
331            self.value.as_ref(),
332        ]);
333    }
334
335    fn extract(&self) -> NodeRef {
336        assert!(self.clean, "mkvs: extract called on dirty node");
337        Rc::new(RefCell::new(NodeBox::Leaf(LeafNode {
338            clean: true,
339            hash: self.hash,
340            key: self.key.clone(),
341            value: self.value.clone(),
342        })))
343    }
344}
345
346impl PartialEq for LeafNode {
347    fn eq(&self, other: &LeafNode) -> bool {
348        if self.clean && other.clean {
349            self.hash == other.hash
350        } else {
351            self.key == other.key && self.value == other.value
352        }
353    }
354}
355
356impl Eq for LeafNode {}
357
358// Depth determines the maximum length of the key in bits.
359//
360// max length = 2^size_of(Depth)*8
361pub type Depth = u16;
362
363pub trait DepthTrait {
364    // Returns the number of bytes needed to fit given bits.
365    fn to_bytes(&self) -> usize;
366}
367
368impl DepthTrait for Depth {
369    fn to_bytes(&self) -> usize {
370        let size = self / 8;
371        if self % 8 != 0 {
372            (size + 1) as usize
373        } else {
374            size as usize
375        }
376    }
377}
378
379// Key holds variable-length key.
380pub type Key = Vec<u8>;
381
382pub trait KeyTrait {
383    /// Get a single bit from the given hash.
384    fn get_bit(&self, bit: Depth) -> bool;
385    /// Returns the length of the key in bits.
386    fn bit_length(&self) -> Depth;
387    /// Bit-wise splits of the key.
388    fn split(&self, split_point: Depth, key_len: Depth) -> (Key, Key);
389    /// Bit-wise merges key of given length with another key of given length.
390    fn merge(&self, key_len: Depth, k2: &Key, k2_len: Depth) -> Key;
391    /// Appends the given bit to the key.
392    fn append_bit(&self, key_len: Depth, bit: bool) -> Key;
393    /// Computes length of common prefix of k and k2 with given bit lengths.
394    fn common_prefix_len(&self, key_len: Depth, k2: &Key, k2_len: Depth) -> Depth;
395}
396
397impl KeyTrait for Key {
398    fn get_bit(&self, bit: Depth) -> bool {
399        (self[(bit / 8) as usize] & (1 << (7 - (bit % 8)))) != 0
400    }
401
402    fn bit_length(&self) -> Depth {
403        (self.len() * 8) as Depth
404    }
405
406    fn split(&self, split_point: Depth, key_len: Depth) -> (Key, Key) {
407        assert!(
408            split_point <= key_len,
409            "mkvs: split_point {} greater than key_len {}",
410            split_point,
411            key_len
412        );
413
414        let prefix_len = split_point.to_bytes();
415        let suffix_len = (key_len - split_point).to_bytes();
416        let mut prefix: Key = vec![0; prefix_len];
417        let mut suffix: Key = vec![0; suffix_len];
418
419        prefix.clone_from_slice(&self[0..split_point.to_bytes()]);
420
421        // Clean the remainder of the byte.
422        if split_point % 8 != 0 {
423            prefix[prefix_len - 1] &= 0xff << (8 - split_point % 8)
424        }
425
426        for i in 0..suffix_len {
427            // First set the left chunk of the byte
428            suffix[i] = self[i + split_point as usize / 8] << (split_point % 8);
429            // ...and the right chunk, if we haven't reached the end of k yet.
430            if split_point % 8 != 0 && i + split_point as usize / 8 + 1 != self.len() {
431                suffix[i] |=
432                    self[i + split_point as usize / 8 + 1] >> (8 - split_point as usize % 8);
433            }
434        }
435
436        (prefix, suffix)
437    }
438
439    fn merge(&self, key_len: Depth, k2: &Key, k2_len: Depth) -> Key {
440        let mut key_len_bytes = (key_len as usize) / 8;
441        if key_len % 8 != 0 {
442            key_len_bytes += 1;
443        }
444
445        let mut new_key: Key = vec![0; (key_len + k2_len).to_bytes()];
446        new_key[..key_len_bytes].clone_from_slice(&self[..key_len_bytes]);
447
448        for i in 0..k2.len() {
449            // First set the right chunk of the previous byte
450            if key_len % 8 != 0 && key_len_bytes > 0 {
451                new_key[key_len_bytes + i - 1] |= k2[i] >> (key_len % 8);
452            }
453            // ...and the next left chunk, if we haven't reached the end of newKey
454            // yet.
455            if key_len_bytes + i < new_key.len() {
456                // another mod 8 to prevent bit shifting for 8 bits
457                new_key[key_len_bytes + i] |= k2[i] << ((8 - key_len % 8) % 8);
458            }
459        }
460
461        new_key
462    }
463
464    fn append_bit(&self, key_len: Depth, val: bool) -> Key {
465        let mut new_key: Key = vec![0; (key_len + 1).to_bytes()];
466        new_key[..self.len()].clone_from_slice(self);
467
468        if val {
469            new_key[key_len as usize / 8] |= 0x80 >> (key_len % 8)
470        } else {
471            new_key[key_len as usize / 8] &= !(0x80 >> (key_len % 8))
472        }
473
474        new_key
475    }
476
477    fn common_prefix_len(&self, key_bit_len: Depth, k2: &Key, k2_bit_len: Depth) -> Depth {
478        let min_key_len = if k2.len() < self.len() {
479            k2.len()
480        } else {
481            self.len()
482        };
483
484        // Compute the common prefix byte-wise.
485        let mut i: usize = 0;
486        while i < min_key_len {
487            if self[i] != k2[i] {
488                break;
489            }
490            i += 1;
491        }
492
493        // Prefixes match i bytes and maybe some more bits below.
494        let mut bit_length = (i * 8) as Depth;
495
496        if i != self.len() && i != k2.len() {
497            // We got a mismatch somewhere along the way. We need to compute how
498            // many additional bits in i-th byte match.
499            bit_length += (self[i] ^ k2[i]).leading_zeros() as Depth;
500        }
501
502        // In any case, bit_length should never exceed length of the shorter key.
503        if bit_length > key_bit_len {
504            bit_length = key_bit_len;
505        }
506        if bit_length > k2_bit_len {
507            bit_length = k2_bit_len;
508        };
509        bit_length
510    }
511}
512
513// Value holds the leaf node value.
514pub type Value = Vec<u8>;