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 fn extract(&self) -> NodeRef;
21}
22
23#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)]
25#[repr(u8)]
26pub enum RootType {
27 #[default]
29 Invalid = 0,
30 State = 1,
32 IO = 2,
34}
35
36#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)]
38pub struct Root {
39 #[cbor(rename = "ns")]
41 pub namespace: Namespace,
42 pub version: u64,
44 pub root_type: RootType,
46 pub hash: Hash,
48}
49
50#[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#[derive(Copy, Clone, Debug)]
98#[repr(u8)]
99pub enum NodeKind {
100 None = 0x02,
101 Internal = 0x01,
102 Leaf = 0x00,
103}
104
105pub type NodeRef = Rc<RefCell<NodeBox>>;
107
108#[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
118pub type NodePtrRef = Rc<RefCell<NodePointer>>;
120
121impl NodePointer {
122 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 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 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 pub fn is_null(&self) -> bool {
154 self.hash.is_empty()
155 }
156
157 pub fn has_node(&self) -> bool {
159 !self.is_null() && self.node.is_some()
160 }
161
162 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 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 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#[derive(Debug, Default)]
233pub struct InternalNode {
234 pub clean: bool,
235 pub hash: Hash,
236 pub label: Key, pub label_bit_length: Depth, pub leaf_node: NodePtrRef, 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#[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
358pub type Depth = u16;
362
363pub trait DepthTrait {
364 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
379pub type Key = Vec<u8>;
381
382pub trait KeyTrait {
383 fn get_bit(&self, bit: Depth) -> bool;
385 fn bit_length(&self) -> Depth;
387 fn split(&self, split_point: Depth, key_len: Depth) -> (Key, Key);
389 fn merge(&self, key_len: Depth, k2: &Key, k2_len: Depth) -> Key;
391 fn append_bit(&self, key_len: Depth, bit: bool) -> Key;
393 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 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 suffix[i] = self[i + split_point as usize / 8] << (split_point % 8);
429 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 if key_len % 8 != 0 && key_len_bytes > 0 {
451 new_key[key_len_bytes + i - 1] |= k2[i] >> (key_len % 8);
452 }
453 if key_len_bytes + i < new_key.len() {
456 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 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 let mut bit_length = (i * 8) as Depth;
495
496 if i != self.len() && i != k2.len() {
497 bit_length += (self[i] ^ k2[i]).leading_zeros() as Depth;
500 }
501
502 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
513pub type Value = Vec<u8>;