oasis_core_runtime/storage/mkvs/tree/
node.rs1use 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
11pub trait Node {
13 fn is_clean(&self) -> bool;
15 fn get_hash(&self) -> Hash;
17 fn update_hash(&mut self);
19 #[allow(dead_code)]
21 fn extract(&self) -> NodeRef;
22}
23
24#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)]
26#[repr(u8)]
27pub enum RootType {
28 #[default]
30 Invalid = 0,
31 State = 1,
33 IO = 2,
35}
36
37#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
39pub struct Root {
40 #[cbor(rename = "ns")]
42 pub namespace: Namespace,
43 pub version: u64,
45 pub root_type: RootType,
47 pub hash: Hash,
49}
50
51#[derive(Debug, Eq, PartialEq)]
53pub enum NodeBox {
54 Internal(InternalNode),
55 Leaf(LeafNode),
56}
57
58impl Default for NodeBox {
59 fn default() -> Self {
60 NodeBox::Internal(Default::default())
61 }
62}
63
64impl Node for NodeBox {
65 fn is_clean(&self) -> bool {
66 match self {
67 NodeBox::Internal(ref n) => n.is_clean(),
68 NodeBox::Leaf(ref n) => n.is_clean(),
69 }
70 }
71
72 fn get_hash(&self) -> Hash {
73 match self {
74 NodeBox::Internal(ref n) => n.get_hash(),
75 NodeBox::Leaf(ref n) => n.get_hash(),
76 }
77 }
78
79 fn update_hash(&mut self) {
80 match self {
81 NodeBox::Internal(ref mut n) => n.update_hash(),
82 NodeBox::Leaf(ref mut n) => n.update_hash(),
83 }
84 }
85
86 fn extract(&self) -> NodeRef {
87 match self {
88 NodeBox::Internal(ref n) => n.extract(),
89 NodeBox::Leaf(ref n) => n.extract(),
90 }
91 }
92}
93
94#[derive(Copy, Clone, Debug)]
99#[repr(u8)]
100pub enum NodeKind {
101 None = 0x02,
102 Internal = 0x01,
103 Leaf = 0x00,
104}
105
106pub type NodeRef = Rc<RefCell<NodeBox>>;
108
109#[derive(Debug, Default)]
111pub struct NodePointer {
112 pub clean: bool,
113 pub hash: Hash,
114 pub node: Option<NodeRef>,
115
116 pub cache_extra: CacheExtra<NodePointer>,
117}
118
119pub type NodePtrRef = Rc<RefCell<NodePointer>>;
121
122impl NodePointer {
123 pub fn null_ptr() -> NodePtrRef {
125 Rc::new(RefCell::new(NodePointer {
126 node: None,
127 clean: true,
128 hash: Hash::empty_hash(),
129 ..Default::default()
130 }))
131 }
132
133 pub fn hash_ptr(hash: Hash) -> NodePtrRef {
135 Rc::new(RefCell::new(NodePointer {
136 node: None,
137 clean: true,
138 hash,
139 ..Default::default()
140 }))
141 }
142
143 pub fn from_node(node: NodeBox) -> NodePtrRef {
145 Rc::new(RefCell::new(NodePointer {
146 hash: node.get_hash(),
147 node: Some(Rc::new(RefCell::new(node))),
148 clean: true,
149 ..Default::default()
150 }))
151 }
152
153 pub fn is_null(&self) -> bool {
155 self.hash.is_empty()
156 }
157
158 pub fn has_node(&self) -> bool {
160 !self.is_null() && self.node.is_some()
161 }
162
163 pub fn get_node(&self) -> NodeRef {
165 match &self.node {
166 None => panic!("mkvs: get_node called on pointer without a node"),
167 Some(node) => node.clone(),
168 }
169 }
170
171 pub fn extract(&self) -> NodePtrRef {
173 assert!(self.clean, "mkvs: extract called on dirty pointer");
174
175 Rc::new(RefCell::new(NodePointer {
176 clean: true,
177 hash: self.hash,
178 ..Default::default()
179 }))
180 }
181
182 #[allow(dead_code)]
186 fn copy_leaf_ptr(&self) -> NodePtrRef {
187 if !self.has_node() {
188 return NodePointer::null_ptr();
189 }
190
191 assert!(self.clean, "mkvs: copy_leaf_ptr called on dirty pointer");
192
193 if let Some(ref some_node) = self.node {
194 let nyoo = noderef_as!(some_node, Leaf).copy();
195 Rc::new(RefCell::new(NodePointer {
196 clean: true,
197 hash: self.hash,
198 node: Some(Rc::new(RefCell::new(NodeBox::Leaf(nyoo)))),
199 ..Default::default()
200 }))
201 } else {
202 panic!("mkvs: copy_leaf_ptr called on a non-leaf pointer");
203 }
204 }
205}
206
207impl CacheItem for NodePointer {
208 fn get_cache_extra(&self) -> CacheExtra<NodePointer> {
209 self.cache_extra
210 }
211
212 fn set_cache_extra(&mut self, new_val: CacheExtra<NodePointer>) {
213 self.cache_extra = new_val;
214 }
215
216 fn get_cached_size(&self) -> usize {
217 1
218 }
219}
220
221impl PartialEq for NodePointer {
222 fn eq(&self, other: &NodePointer) -> bool {
223 if self.clean && other.clean {
224 self.hash == other.hash
225 } else {
226 self.node.is_some() && self.node == other.node
227 }
228 }
229}
230
231impl Eq for NodePointer {}
232
233#[derive(Debug, Default)]
235pub struct InternalNode {
236 pub clean: bool,
237 pub hash: Hash,
238 pub label: Key, pub label_bit_length: Depth, pub leaf_node: NodePtrRef, pub left: NodePtrRef,
242 pub right: NodePtrRef,
243}
244
245impl Node for InternalNode {
246 fn is_clean(&self) -> bool {
247 self.clean
248 }
249
250 fn get_hash(&self) -> Hash {
251 self.hash
252 }
253
254 fn update_hash(&mut self) {
255 let leaf_node_hash = self.leaf_node.borrow().hash;
256 let left_hash = self.left.borrow().hash;
257 let right_hash = self.right.borrow().hash;
258
259 self.hash = Hash::digest_bytes_list(&[
260 &[NodeKind::Internal as u8],
261 &self.label_bit_length.marshal_binary().unwrap(),
262 self.label.as_ref(),
263 leaf_node_hash.as_ref(),
264 left_hash.as_ref(),
265 right_hash.as_ref(),
266 ]);
267 }
268
269 fn extract(&self) -> NodeRef {
270 assert!(self.clean, "mkvs: extract called on dirty node");
271
272 Rc::new(RefCell::new(NodeBox::Internal(InternalNode {
273 clean: true,
274 hash: self.hash,
275 label: self.label.clone(),
276 label_bit_length: self.label_bit_length,
277 leaf_node: self.leaf_node.borrow().copy_leaf_ptr(),
278 left: self.left.borrow().extract(),
279 right: self.right.borrow().extract(),
280 })))
281 }
282}
283
284impl PartialEq for InternalNode {
285 fn eq(&self, other: &InternalNode) -> bool {
286 if self.clean && other.clean {
287 self.hash == other.hash
288 } else {
289 self.leaf_node == other.leaf_node
290 && self.left == other.left
291 && self.right == other.right
292 }
293 }
294}
295
296impl Eq for InternalNode {}
297
298#[derive(Debug, Default)]
300pub struct LeafNode {
301 pub clean: bool,
302 pub hash: Hash,
303 pub key: Key,
304 pub value: Value,
305}
306
307impl LeafNode {
308 pub fn copy(&self) -> LeafNode {
309 LeafNode {
310 clean: self.clean,
311 hash: self.hash,
312 key: self.key.to_owned(),
313 value: self.value.clone(),
314 }
315 }
316}
317
318impl Node for LeafNode {
319 fn is_clean(&self) -> bool {
320 self.clean
321 }
322
323 fn get_hash(&self) -> Hash {
324 self.hash
325 }
326
327 fn update_hash(&mut self) {
328 self.hash = Hash::digest_bytes_list(&[
329 &[NodeKind::Leaf as u8],
330 &(self.key.len() as u32).marshal_binary().unwrap(),
331 self.key.as_ref(),
332 &(self.value.len() as u32).marshal_binary().unwrap(),
333 self.value.as_ref(),
334 ]);
335 }
336
337 fn extract(&self) -> NodeRef {
338 assert!(self.clean, "mkvs: extract called on dirty node");
339 Rc::new(RefCell::new(NodeBox::Leaf(LeafNode {
340 clean: true,
341 hash: self.hash,
342 key: self.key.clone(),
343 value: self.value.clone(),
344 })))
345 }
346}
347
348impl PartialEq for LeafNode {
349 fn eq(&self, other: &LeafNode) -> bool {
350 if self.clean && other.clean {
351 self.hash == other.hash
352 } else {
353 self.key == other.key && self.value == other.value
354 }
355 }
356}
357
358impl Eq for LeafNode {}
359
360pub type Depth = u16;
364
365pub trait DepthTrait {
366 fn to_bytes(&self) -> usize;
368}
369
370impl DepthTrait for Depth {
371 fn to_bytes(&self) -> usize {
372 let size = self / 8;
373 if !self.is_multiple_of(8) {
374 (size + 1) as usize
375 } else {
376 size as usize
377 }
378 }
379}
380
381pub type Key = Vec<u8>;
383
384pub trait KeyTrait {
385 fn get_bit(&self, bit: Depth) -> bool;
387 fn bit_length(&self) -> Depth;
389 fn split(&self, split_point: Depth, key_len: Depth) -> (Key, Key);
391 fn merge(&self, key_len: Depth, k2: &Key, k2_len: Depth) -> Key;
393 fn append_bit(&self, key_len: Depth, bit: bool) -> Key;
395 fn common_prefix_len(&self, key_len: Depth, k2: &Key, k2_len: Depth) -> Depth;
397}
398
399impl KeyTrait for Key {
400 fn get_bit(&self, bit: Depth) -> bool {
401 (self[(bit / 8) as usize] & (1 << (7 - (bit % 8)))) != 0
402 }
403
404 fn bit_length(&self) -> Depth {
405 (self.len() * 8) as Depth
406 }
407
408 fn split(&self, split_point: Depth, key_len: Depth) -> (Key, Key) {
409 assert!(
410 split_point <= key_len,
411 "mkvs: split_point {} greater than key_len {}",
412 split_point,
413 key_len
414 );
415
416 let prefix_len = split_point.to_bytes();
417 let suffix_len = (key_len - split_point).to_bytes();
418 let mut prefix: Key = vec![0; prefix_len];
419 let mut suffix: Key = vec![0; suffix_len];
420
421 prefix.clone_from_slice(&self[0..split_point.to_bytes()]);
422
423 if !split_point.is_multiple_of(8) {
425 prefix[prefix_len - 1] &= 0xff << (8 - split_point % 8)
426 }
427
428 for i in 0..suffix_len {
429 suffix[i] = self[i + split_point as usize / 8] << (split_point % 8);
431 if !split_point.is_multiple_of(8) && i + split_point as usize / 8 + 1 != self.len() {
433 suffix[i] |=
434 self[i + split_point as usize / 8 + 1] >> (8 - split_point as usize % 8);
435 }
436 }
437
438 (prefix, suffix)
439 }
440
441 fn merge(&self, key_len: Depth, k2: &Key, k2_len: Depth) -> Key {
442 let mut key_len_bytes = (key_len as usize) / 8;
443 if !key_len.is_multiple_of(8) {
444 key_len_bytes += 1;
445 }
446
447 let mut new_key: Key = vec![0; (key_len + k2_len).to_bytes()];
448 new_key[..key_len_bytes].clone_from_slice(&self[..key_len_bytes]);
449
450 for i in 0..k2.len() {
451 if !key_len.is_multiple_of(8) && key_len_bytes > 0 {
453 new_key[key_len_bytes + i - 1] |= k2[i] >> (key_len % 8);
454 }
455 if key_len_bytes + i < new_key.len() {
458 new_key[key_len_bytes + i] |= k2[i] << ((8 - key_len % 8) % 8);
460 }
461 }
462
463 new_key
464 }
465
466 fn append_bit(&self, key_len: Depth, val: bool) -> Key {
467 let mut new_key: Key = vec![0; (key_len + 1).to_bytes()];
468 new_key[..self.len()].clone_from_slice(self);
469
470 if val {
471 new_key[key_len as usize / 8] |= 0x80 >> (key_len % 8)
472 } else {
473 new_key[key_len as usize / 8] &= !(0x80 >> (key_len % 8))
474 }
475
476 new_key
477 }
478
479 fn common_prefix_len(&self, key_bit_len: Depth, k2: &Key, k2_bit_len: Depth) -> Depth {
480 let min_key_len = if k2.len() < self.len() {
481 k2.len()
482 } else {
483 self.len()
484 };
485
486 let mut i: usize = 0;
488 while i < min_key_len {
489 if self[i] != k2[i] {
490 break;
491 }
492 i += 1;
493 }
494
495 let mut bit_length = (i * 8) as Depth;
497
498 if i != self.len() && i != k2.len() {
499 bit_length += (self[i] ^ k2[i]).leading_zeros() as Depth;
502 }
503
504 if bit_length > key_bit_len {
506 bit_length = key_bit_len;
507 }
508 if bit_length > k2_bit_len {
509 bit_length = k2_bit_len;
510 };
511 bit_length
512 }
513}
514
515pub type Value = Vec<u8>;