1use std::{fmt::Debug, sync::Arc};
2
3use serde::{Deserialize, Serialize};
4
5use crate::prelude::*;
6
7#[derive(Clone, Derivative, Serialize, Deserialize)]
9#[serde(bound(serialize = "Child: Serialize, Child::Complete: Serialize"))]
10#[serde(bound(deserialize = "Child: Deserialize<'de>, Child::Complete: Deserialize<'de>"))]
11#[derivative(Debug(bound = "Child: Debug, Child::Complete: Debug"))]
12pub struct Node<Child: Focus> {
13 #[derivative(PartialEq = "ignore", Debug)]
14 #[serde(skip)]
15 hash: CachedHash,
16 #[serde(skip)]
17 forgotten: [Forgotten; 4],
18 siblings: Three<Arc<Insert<Child::Complete>>>,
19 focus: Arc<Child>,
20}
21
22impl<Child: Focus> Node<Child> {
23 pub(crate) fn from_parts(
25 forgotten: [Forgotten; 4],
26 siblings: Three<Arc<Insert<Child::Complete>>>,
27 focus: Child,
28 ) -> Self
29 where
30 Child: Frontier + GetHash,
31 {
32 Self {
33 hash: Default::default(),
34 forgotten,
35 siblings,
36 focus: Arc::new(focus),
37 }
38 }
39
40 #[inline]
42 pub(crate) fn forgotten(&self) -> &[Forgotten; 4] {
43 &self.forgotten
44 }
45}
46
47impl<Child: Focus> Height for Node<Child> {
48 type Height = Succ<Child::Height>;
49}
50
51impl<Child: Focus> GetHash for Node<Child> {
52 fn hash(&self) -> Hash {
53 fn hashes_of_all<T: GetHash, const N: usize>(full: [&Arc<Insert<T>>; N]) -> [Hash; N] {
55 full.map(|hash_or_t| match &**hash_or_t {
56 Insert::Hash(hash) => *hash,
57 Insert::Keep(t) => t.hash(),
58 })
59 }
60
61 self.hash.set_if_empty(|| {
62 let zero = Hash::zero();
65 let focus = self.focus.hash();
66
67 let (a, b, c, d) = match self.siblings.elems() {
68 Elems::_0([]) => (focus, zero, zero, zero),
69 Elems::_1(full) => {
70 let [a] = hashes_of_all(full);
71 (a, focus, zero, zero)
72 }
73 Elems::_2(full) => {
74 let [a, b] = hashes_of_all(full);
75 (a, b, focus, zero)
76 }
77 Elems::_3(full) => {
78 let [a, b, c] = hashes_of_all(full);
79 (a, b, c, focus)
80 }
81 };
82
83 Hash::node(<Self as Height>::Height::HEIGHT, a, b, c, d)
86 })
87 }
88
89 #[inline]
90 fn cached_hash(&self) -> Option<Hash> {
91 self.hash.get()
92 }
93
94 #[inline]
95 fn clear_cached_hash(&self) {
96 self.hash.clear();
97 }
98}
99
100impl<Child: Focus + Clone> Focus for Node<Child>
101where
102 Child::Complete: Clone,
103{
104 type Complete = complete::Node<Child::Complete>;
105
106 #[inline]
107 fn finalize_owned(self) -> Insert<Self::Complete> {
108 let one = || Insert::Hash(Hash::one());
109
110 fn get<T: Clone>(arc: Arc<T>) -> T {
112 Arc::try_unwrap(arc).unwrap_or_else(|arc| (*arc).clone())
113 }
114
115 let Self {
116 hash: _, forgotten,
118 siblings,
119 focus,
120 } = self;
121
122 let focus = Arc::try_unwrap(focus).unwrap_or_else(|arc| (*arc).clone());
124
125 complete::Node::from_children_or_else_hash(
129 forgotten,
130 match siblings.push(Arc::new(focus.finalize_owned())) {
131 Err([a, b, c, d]) => [get(a), get(b), get(c), get(d)],
132 Ok(siblings) => match siblings.into_elems() {
133 IntoElems::_3([a, b, c]) => [get(a), get(b), get(c), one()],
134 IntoElems::_2([a, b]) => [get(a), get(b), one(), one()],
135 IntoElems::_1([a]) => [get(a), one(), one(), one()],
136 IntoElems::_0([]) => [one(), one(), one(), one()],
137 },
138 },
139 )
140 }
141}
142
143impl<Child: Clone> Frontier for Node<Child>
144where
145 Child: Focus + Frontier + GetHash,
146 Child::Complete: Clone,
147{
148 type Item = Child::Item;
149
150 #[inline]
151 fn new(item: Self::Item) -> Self {
152 let focus = Child::new(item);
153 let siblings = Three::new();
154 Self::from_parts(Default::default(), siblings, focus)
155 }
156
157 #[inline]
158 fn update<T>(&mut self, f: impl FnOnce(&mut Self::Item) -> T) -> Option<T> {
159 let before_hash = self.focus.cached_hash();
160 let output = Arc::make_mut(&mut self.focus).update(f);
161 let after_hash = self.focus.cached_hash();
162
163 if before_hash != after_hash {
166 self.hash = CachedHash::default();
167 }
168
169 output
170 }
171
172 #[inline]
173 fn focus(&self) -> Option<&Self::Item> {
174 self.focus.focus()
175 }
176
177 #[inline]
178 fn insert_owned(self, item: Self::Item) -> Result<Self, Full<Self>> {
179 let Self {
180 hash: _, forgotten,
182 siblings,
183 focus,
184 } = self;
185
186 let focus = Arc::try_unwrap(focus).unwrap_or_else(|arc| (*arc).clone());
188
189 match focus.insert_owned(item) {
190 Ok(focus) => Ok(Self::from_parts(forgotten, siblings, focus)),
192
193 Err(Full {
196 item,
197 complete: sibling,
198 }) => match siblings.push(Arc::new(sibling)) {
199 Ok(siblings) => Ok(Self::from_parts(forgotten, siblings, Child::new(item))),
202
203 Err(children) => Err(Full {
207 item,
208 complete: complete::Node::from_children_or_else_hash(
209 forgotten,
210 children
211 .map(|arc| Arc::try_unwrap(arc).unwrap_or_else(|arc| (*arc).clone())),
213 ),
214 }),
215 },
216 }
217 }
218
219 #[inline]
220 fn is_full(&self) -> bool {
221 self.siblings.is_full() && self.focus.is_full()
222 }
223}
224
225impl<Child: Focus + GetPosition> GetPosition for Node<Child> {
226 #[inline]
227 fn position(&self) -> Option<u64> {
228 let child_capacity: u64 = 4u64.pow(Child::Height::HEIGHT.into());
229 let siblings = self.siblings.len() as u64;
230
231 if let Some(focus_position) = self.focus.position() {
232 Some(siblings * child_capacity + focus_position)
235 } else if siblings + 1 < 4
236 {
238 Some((siblings + 1) * child_capacity)
241 } else {
242 None
243 }
244 }
245}
246
247impl<Child: Focus + Witness> Witness for Node<Child>
248where
249 Child::Complete: Witness,
250{
251 fn witness(&self, index: impl Into<u64>) -> Option<(AuthPath<Self>, Hash)> {
252 use Elems::*;
253 use WhichWay::*;
254
255 let index = index.into();
256
257 let zero = Hash::zero();
259
260 let (which_way, index) = WhichWay::at(Self::Height::HEIGHT, index);
262
263 let (siblings, (child, leaf)) = match (self.siblings.elems(), &self.focus) {
264 (_0([]), a) => match which_way {
266 Leftmost => (
267 [zero; 3],
269 a.witness(index)?,
271 ),
272 Left | Right | Rightmost => return None,
273 },
274
275 (_1([a]), b) => match which_way {
277 Leftmost => (
278 [b.hash(), zero, zero],
280 (**a).as_ref().keep()?.witness(index)?,
282 ),
283 Left => (
284 [a.hash(), zero, zero],
286 b.witness(index)?,
288 ),
289 Right | Rightmost => return None,
290 },
291
292 (_2([a, b]), c) => match which_way {
294 Leftmost => (
295 [b.hash(), c.hash(), zero],
297 (**a).as_ref().keep()?.witness(index)?,
299 ),
300 Left => (
301 [a.hash(), c.hash(), zero],
303 (**b).as_ref().keep()?.witness(index)?,
305 ),
306 Right => (
307 [a.hash(), b.hash(), zero],
309 c.witness(index)?,
311 ),
312 Rightmost => return None,
313 },
314
315 (_3([a, b, c]), d) => match which_way {
317 Leftmost => (
318 [b.hash(), c.hash(), d.hash()],
320 (**a).as_ref().keep()?.witness(index)?,
322 ),
323 Left => (
324 [a.hash(), c.hash(), d.hash()],
326 (**b).as_ref().keep()?.witness(index)?,
328 ),
329 Right => (
330 [a.hash(), b.hash(), d.hash()],
332 (**c).as_ref().keep()?.witness(index)?,
334 ),
335 Rightmost => (
336 [a.hash(), b.hash(), c.hash()],
338 d.witness(index)?,
340 ),
341 },
342 };
343
344 Some((path::Node { siblings, child }, leaf))
345 }
346}
347
348impl<Child: Focus + Forget + Clone> Forget for Node<Child>
349where
350 Child::Complete: ForgetOwned + Clone,
351{
352 fn forget(&mut self, forgotten: Option<Forgotten>, index: impl Into<u64>) -> bool {
353 use ElemsMut::*;
354 use WhichWay::*;
355
356 let index = index.into();
357
358 let (which_way, index) = WhichWay::at(Self::Height::HEIGHT, index);
360
361 let was_forgotten = match (self.siblings.elems_mut(), &mut self.focus) {
362 (_0([]), a) => match which_way {
363 Leftmost => Arc::make_mut(a).forget(forgotten, index),
364 Left | Right | Rightmost => false,
365 },
366 (_1([a]), b) => match which_way {
367 Leftmost => Arc::make_mut(a).forget(forgotten, index),
368 Left => Arc::make_mut(b).forget(forgotten, index),
369 Right | Rightmost => false,
370 },
371 (_2([a, b]), c) => match which_way {
372 Leftmost => Arc::make_mut(a).forget(forgotten, index),
373 Left => Arc::make_mut(b).forget(forgotten, index),
374 Right => Arc::make_mut(c).forget(forgotten, index),
375 Rightmost => false,
376 },
377 (_3([a, b, c]), d) => match which_way {
378 Leftmost => Arc::make_mut(a).forget(forgotten, index),
379 Left => Arc::make_mut(b).forget(forgotten, index),
380 Right => Arc::make_mut(c).forget(forgotten, index),
381 Rightmost => Arc::make_mut(d).forget(forgotten, index),
382 },
383 };
384
385 if was_forgotten {
387 if let Some(forgotten) = forgotten {
388 self.forgotten[which_way] = forgotten.next();
389 }
390 }
391
392 was_forgotten
393 }
394}
395
396impl<'tree, Child: Focus + GetPosition + Height + structure::Any<'tree>> structure::Any<'tree>
397 for Node<Child>
398where
399 Child::Complete: structure::Any<'tree>,
400{
401 fn kind(&self) -> Kind {
402 Kind::Internal {
403 height: <Self as Height>::Height::HEIGHT,
404 }
405 }
406
407 fn forgotten(&self) -> Forgotten {
408 self.forgotten().iter().copied().max().unwrap_or_default()
409 }
410
411 fn children(&'tree self) -> Vec<HashOrNode<'tree>> {
412 let children = self
413 .siblings
414 .iter()
415 .map(|child| (**child).as_ref().map(|child| child as &dyn structure::Any))
416 .chain(std::iter::once(Insert::Keep(
417 &*self.focus as &dyn structure::Any,
418 )));
419
420 self.forgotten
421 .iter()
422 .copied()
423 .zip(children)
424 .map(|(forgotten, child)| match child {
425 Insert::Keep(node) => HashOrNode::Node(node),
426 Insert::Hash(hash) => HashOrNode::Hash(HashedNode {
427 hash,
428 forgotten,
429 height: <Child as Height>::Height::HEIGHT,
430 }),
431 })
432 .collect()
433 }
434}
435
436impl<Child: Height + Focus + OutOfOrder + Clone> OutOfOrder for Node<Child>
437where
438 Child::Complete: OutOfOrderOwned + Clone,
439{
440 fn uninitialized(position: Option<u64>, forgotten: Forgotten) -> Self {
441 let siblings_len = if let Some(position) = position {
443 debug_assert!(position > 0, "position for frontier node is never zero");
448 let path_bits = position - 1;
449 (path_bits >> (Child::Height::HEIGHT * 2)) & 0b11
450 } else {
451 0b11
453 };
454
455 let mut siblings = Three::new();
456 for _ in 0..siblings_len {
457 siblings =
458 if let Ok(siblings) = siblings.push(Arc::new(Insert::Hash(Hash::uninitialized()))) {
459 siblings
460 } else {
461 unreachable!("for all x, 0b11 & x < 4, so siblings can't overflow")
462 }
463 }
464
465 let focus = Arc::new(Child::uninitialized(position, forgotten));
466 let hash = CachedHash::default();
467 let forgotten = [forgotten; 4];
468
469 Node {
470 siblings,
471 focus,
472 hash,
473 forgotten,
474 }
475 }
476
477 fn uninitialized_out_of_order_insert_commitment(
478 &mut self,
479 index: u64,
480 commitment: StateCommitment,
481 ) {
482 use ElemsMut::*;
483 use WhichWay::*;
484
485 let (which_way, index) = WhichWay::at(<Self as Height>::Height::HEIGHT, index);
486
487 fn recur_sibling<Sibling>(
491 sibling: &mut Arc<Insert<Sibling>>,
492 index: u64,
493 commitment: StateCommitment,
494 ) where
495 Sibling: OutOfOrderOwned + Clone,
496 {
497 let sibling = Arc::make_mut(sibling);
498
499 *sibling = Insert::Keep(Sibling::uninitialized_out_of_order_insert_commitment_owned(
500 std::mem::replace(sibling, Insert::Hash(Hash::uninitialized())),
504 index,
505 commitment,
506 ));
507 }
508
509 match (self.siblings.elems_mut(), &mut self.focus) {
510 (_0([]), a) => match which_way {
511 Leftmost => {
512 Arc::make_mut(a).uninitialized_out_of_order_insert_commitment(index, commitment)
513 }
514 Left | Right | Rightmost => {}
515 },
516 (_1([a]), b) => match which_way {
517 Leftmost => recur_sibling(a, index, commitment),
518 Left => {
519 Arc::make_mut(b).uninitialized_out_of_order_insert_commitment(index, commitment)
520 }
521 Right | Rightmost => {}
522 },
523 (_2([a, b]), c) => match which_way {
524 Leftmost => recur_sibling(a, index, commitment),
525 Left => recur_sibling(b, index, commitment),
526 Right => {
527 Arc::make_mut(c).uninitialized_out_of_order_insert_commitment(index, commitment)
528 }
529 Rightmost => {}
530 },
531 (_3([a, b, c]), d) => match which_way {
532 Leftmost => recur_sibling(a, index, commitment),
533 Left => recur_sibling(b, index, commitment),
534 Right => recur_sibling(c, index, commitment),
535 Rightmost => {
536 Arc::make_mut(d).uninitialized_out_of_order_insert_commitment(index, commitment)
537 }
538 },
539 }
540 }
541}
542
543impl<Child: Focus + UncheckedSetHash + Clone> UncheckedSetHash for Node<Child>
544where
545 Child::Complete: UncheckedSetHash + Clone,
546{
547 fn unchecked_set_hash(&mut self, index: u64, height: u8, hash: Hash) {
548 use std::cmp::Ordering::*;
549 use ElemsMut::*;
550 use WhichWay::*;
551
552 fn recur_sibling<T: Height + UncheckedSetHash + Clone>(
555 insert: &mut Arc<Insert<T>>,
556 index: u64,
557 height: u8,
558 hash: Hash,
559 ) {
560 match Arc::make_mut(insert) {
561 Insert::Keep(item) => item.unchecked_set_hash(index, height, hash),
563 Insert::Hash(this_hash) => {
565 if height == <T as Height>::Height::HEIGHT {
566 *this_hash = hash;
567 }
568 }
569 };
570 }
571
572 match height.cmp(&Self::Height::HEIGHT) {
573 Greater => panic!("height too large when setting hash: {height}"),
574 Equal => self.hash = hash.into(),
576 Less => {
578 let (which_way, index) = WhichWay::at(Self::Height::HEIGHT, index);
579
580 match (self.siblings.elems_mut(), &mut self.focus) {
581 (_0([]), a) => match which_way {
582 Leftmost => Arc::make_mut(a).unchecked_set_hash(index, height, hash),
583 Left | Right | Rightmost => {}
584 },
585 (_1([a]), b) => match which_way {
586 Leftmost => recur_sibling(a, index, height, hash),
587 Left => Arc::make_mut(b).unchecked_set_hash(index, height, hash),
588 Right | Rightmost => {}
589 },
590 (_2([a, b]), c) => match which_way {
591 Leftmost => recur_sibling(a, index, height, hash),
592 Left => recur_sibling(b, index, height, hash),
593 Right => Arc::make_mut(c).unchecked_set_hash(index, height, hash),
594 Rightmost => {}
595 },
596 (_3([a, b, c]), d) => match which_way {
597 Leftmost => recur_sibling(a, index, height, hash),
598 Left => recur_sibling(b, index, height, hash),
599 Right => recur_sibling(c, index, height, hash),
600 Rightmost => Arc::make_mut(d).unchecked_set_hash(index, height, hash),
601 },
602 }
603 }
604 }
605 }
606
607 fn finish_initialize(&mut self) {
608 Arc::make_mut(&mut self.focus).finish_initialize();
610
611 for sibling in self.siblings.iter_mut() {
613 match Arc::make_mut(sibling) {
614 Insert::Keep(item) => item.finish_initialize(),
615 Insert::Hash(hash) => {
616 if hash.is_uninitialized() {
617 *hash = Hash::one();
619 }
620 }
621 }
622 }
623
624 }
628}