1use std::{
2 collections::{HashMap, HashSet},
3 path::PathBuf,
4 sync::{Arc, Mutex},
5};
6
7use mina_curves::pasta::Fp;
8use mina_signer::CompressedPubKey;
9
10use crate::{
11 account::{Account, AccountId, TokenId},
12 address::Address,
13 base::{next_uuid, AccountIndex, BaseLedger, GetOrCreated, MerklePath, Uuid},
14 database::{Database, DatabaseError},
15 tree_version::V2,
16 HashesMatrix,
17};
18
19use super::mask_impl::{MaskImpl, MaskImplShort};
20
21#[derive(Clone, Debug)]
22pub struct Mask {
23 pub inner: Arc<Mutex<MaskImpl>>,
25}
26
27impl Drop for Mask {
28 fn drop(&mut self) {
29 if Arc::strong_count(&self.inner) > 2 {
30 return;
32 }
33
34 let Ok(inner) = self.inner.try_lock() else {
35 return;
37 };
38
39 if inner.any_child_alive() {
40 return;
42 }
43
44 let Some(parent) = inner.get_parent() else {
45 return;
47 };
48
49 parent.remove_child_uuid(inner.get_uuid());
64 }
65}
66
67#[derive(Debug)]
68pub enum UnregisterBehavior {
69 Check,
70 Recursive,
71 IPromiseIAmReparentingThisMask,
72}
73
74impl Mask {
75 pub(super) fn with<F, R>(&self, fun: F) -> R
76 where
77 F: FnOnce(&mut MaskImpl) -> R,
78 {
79 let mut inner = self.inner.try_lock().expect("lock failed");
80 fun(&mut inner)
81 }
82}
83
84impl Mask {
85 pub fn new_root(db: Database<V2>) -> Self {
86 let uuid = db.get_uuid();
87 let mask = Self {
88 inner: Arc::new(Mutex::new(MaskImpl::Root {
89 database: db,
90 childs: HashMap::with_capacity(2),
91 })),
92 };
93 super::alive_add(&uuid);
94 mask
95 }
96
97 pub fn new_unattached(depth: usize) -> Self {
98 let uuid = next_uuid();
99
100 let mask = Self {
101 inner: Arc::new(Mutex::new(MaskImpl::Unattached {
102 owning_account: Default::default(),
103 token_owners: Default::default(),
104 id_to_addr: Default::default(),
105 last_location: None,
106 depth: depth as u8,
107 childs: HashMap::with_capacity(2),
108 uuid: uuid.clone(),
109 hashes: HashesMatrix::new(depth),
110 })),
111 };
112
113 super::alive_add(&uuid);
114
115 mask
116 }
117
118 pub fn create(depth: usize) -> Self {
119 Self::new_root(Database::create(depth as u8))
120 }
121
122 pub fn create_with_token_owners(depth: usize) -> Self {
123 Self::new_root(Database::create_with_token_owners(depth as u8))
124 }
125
126 pub fn set_token_owners(&mut self) {
127 self.with(|this| this.set_token_owners());
128 }
129
130 pub fn unset_token_owners(&mut self) {
132 self.with(|this| this.unset_token_owners());
133 }
134
135 pub fn make_child(&self) -> Mask {
136 let mut new_mask = Mask::new_unattached(self.depth() as usize);
137
138 if self.has_token_owners() {
139 new_mask.set_token_owners();
140 }
141
142 self.register_mask(new_mask)
143 }
144
145 pub fn set_parent(&self, parent: Mask, parent_last_filled: Option<Option<Address>>) -> Mask {
146 let this = self.clone();
147 self.with(|this| this.set_parent(parent, parent_last_filled));
148 this
149 }
150
151 pub(crate) fn nmasks_to_root(&self) -> usize {
152 self.with(|this| this.nmasks_to_root())
153 }
154
155 pub fn copy(&self) -> Mask {
156 let mask = self.with(|this| this.clone());
157 Self {
158 inner: Arc::new(Mutex::new(mask)),
159 }
160 }
161
162 pub fn register_mask(&self, mask: Mask) -> Mask {
164 let self_mask = self.clone();
167 self.with(|this| this.register_mask(self_mask, mask))
168 }
169
170 pub fn unregister_mask(&self, behavior: UnregisterBehavior) -> Mask {
172 self.unregister_mask_impl(behavior, true)
173 }
174
175 pub(super) fn unregister_mask_impl(
176 &self,
177 behavior: UnregisterBehavior,
178 remove_from_parent: bool,
179 ) -> Mask {
180 let this = self.clone();
181 self.with(|this| this.unregister_mask(behavior, remove_from_parent));
182 this
183 }
184
185 pub(super) fn remove_child_uuid(&self, uuid: Uuid) -> Option<Mask> {
186 self.with(|this| this.remove_child_uuid(uuid))
187 }
188
189 pub fn is_root(&self) -> bool {
190 self.with(|this| this.is_root())
191 }
192
193 pub fn is_attached(&self) -> bool {
194 self.with(|this| this.is_attached())
195 }
196
197 fn uuid(&self) -> Uuid {
198 self.with(|this| this.get_uuid())
199 }
200
201 pub fn get_parent(&self) -> Option<Mask> {
202 self.with(|this| this.get_parent())
203 }
204
205 pub fn unset_parent(&self, trigger_detach_signal: bool) {
206 self.with(|this| this.unset_parent(trigger_detach_signal))
207 }
208
209 pub fn remove_and_reparent(&self) -> Option<Mask> {
222 self.with(|this| this.remove_and_reparent())
223 }
224
225 pub fn get_hash(&self, addr: Address) -> Option<Fp> {
227 self.with(|this| this.get_hash(addr))
228 }
229
230 pub fn commit(&self) {
232 self.with(|this| this.commit())
233 }
234
235 pub fn commit_and_reparent_to_root(&mut self) -> Option<Mask> {
238 self.with(|this| this.commit_and_reparent_to_root())
239 }
240
241 pub fn parent_set_notify(&self, account_index: AccountIndex, account: &Account) {
246 self.with(|this| this.parent_set_notify(account_index, account))
247 }
248
249 pub fn remove_parent(&self) -> Option<Mask> {
250 self.with(|this| this.remove_parent())
251 }
252
253 pub fn depth(&self) -> u8 {
254 self.with(|this| this.depth())
255 }
256
257 pub fn get_cached_hash(&mut self, addr: &Address) -> Option<Fp> {
258 self.with(|this| this.get_cached_hash(addr))
259 }
260
261 pub fn set_cached_hash_unchecked(&mut self, addr: &Address, hash: Fp) {
262 self.with(|this| this.set_cached_hash_unchecked(addr, hash))
263 }
264
265 pub(super) fn set_impl(&mut self, addr: Address, account: Box<Account>, ignore: Option<Uuid>) {
266 self.with(|this| this.set_impl(addr, account, ignore))
267 }
268
269 pub(super) fn transfert_hashes(&mut self, hashes: HashesMatrix) {
270 self.with(|this| this.transfert_hashes(hashes))
271 }
272
273 pub(super) fn remove_accounts_without_notif(&mut self, ids: &[AccountId]) {
274 self.with(|this| this.remove_accounts_without_notif(ids))
275 }
276
277 pub fn short(&self) -> MaskImplShort {
278 self.with(|this| this.short())
279 }
280
281 pub fn validate_inner_hashes(&mut self) -> Result<(), ()> {
286 self.with(|this| this.validate_inner_hashes())
287 }
288
289 pub fn get_raw_inner_hashes(&self) -> Vec<(u64, Fp)> {
292 self.with(|this| this.get_raw_inner_hashes())
293 }
294
295 pub fn set_raw_inner_hashes(&self, hashes: Vec<(u64, Fp)>) {
297 self.with(|this| this.set_raw_inner_hashes(hashes))
298 }
299 pub fn has_token_owners(&self) -> bool {
300 self.with(|this| this.has_token_owners())
301 }
302
303 #[cfg(test)]
305 fn test_is_in_mask(&self, addr: &Address) -> bool {
306 self.with(|this| this.test_is_in_mask(addr))
307 }
308
309 #[cfg(test)]
311 fn test_matrix(&self) -> HashesMatrix {
312 self.with(|this| this.test_matrix())
313 }
314
315 #[cfg(feature = "fuzzing")]
317 pub fn fuzzing_to_root(&self) -> Mask {
318 let accounts = self.to_list();
319 let mut new_root = Self::create(self.depth() as usize);
320
321 for account in accounts {
322 new_root
323 .get_or_create_account(account.id(), account)
324 .unwrap();
325 }
326
327 new_root
328 }
329}
330
331impl BaseLedger for Mask {
332 fn to_list(&self) -> Vec<Account> {
333 self.with(|this| this.to_list())
334 }
335
336 fn iter<F>(&self, fun: F)
337 where
338 F: FnMut(&Account),
339 {
340 self.with(|this| this.iter(fun))
341 }
342
343 fn fold<B, F>(&self, init: B, fun: F) -> B
344 where
345 F: FnMut(B, &Account) -> B,
346 {
347 self.with(|this| this.fold(init, fun))
348 }
349
350 fn fold_with_ignored_accounts<B, F>(&self, ignoreds: HashSet<AccountId>, init: B, fun: F) -> B
351 where
352 F: FnMut(B, &Account) -> B,
353 {
354 self.with(|this| this.fold_with_ignored_accounts(ignoreds, init, fun))
355 }
356
357 fn fold_until<B, F>(&self, init: B, fun: F) -> B
358 where
359 F: FnMut(B, &Account) -> std::ops::ControlFlow<B, B>,
360 {
361 self.with(|this| this.fold_until(init, fun))
362 }
363
364 fn accounts(&self) -> HashSet<AccountId> {
365 self.with(|this| this.accounts())
366 }
367
368 fn token_owner(&self, token_id: TokenId) -> Option<AccountId> {
369 self.with(|this| this.token_owner(token_id))
370 }
371
372 fn tokens(&self, public_key: CompressedPubKey) -> HashSet<TokenId> {
373 self.with(|this| this.tokens(public_key))
374 }
375
376 fn location_of_account(&self, account_id: &AccountId) -> Option<Address> {
377 self.with(|this| this.location_of_account(account_id))
378 }
379
380 fn location_of_account_batch(
381 &self,
382 account_ids: &[AccountId],
383 ) -> Vec<(AccountId, Option<Address>)> {
384 self.with(|this| this.location_of_account_batch(account_ids))
385 }
386
387 fn get_or_create_account(
388 &mut self,
389 account_id: AccountId,
390 account: Account,
391 ) -> Result<GetOrCreated, DatabaseError> {
392 self.with(|this| this.get_or_create_account(account_id, account))
393 }
394
395 fn close(&self) {
396 }
398
399 fn last_filled(&self) -> Option<Address> {
400 self.with(|this| this.last_filled())
401 }
402
403 fn get_uuid(&self) -> Uuid {
404 self.with(|this| this.get_uuid())
405 }
406
407 fn get_directory(&self) -> Option<PathBuf> {
408 self.with(|this| this.get_directory())
409 }
410
411 fn get_account_hash(&mut self, account_index: AccountIndex) -> Option<Fp> {
412 self.with(|this| this.get_account_hash(account_index))
413 }
414
415 fn get(&self, addr: Address) -> Option<Box<Account>> {
416 self.with(|this| this.get(addr))
417 }
418
419 fn get_batch(&self, addr: &[Address]) -> Vec<(Address, Option<Box<Account>>)> {
420 self.with(|this| this.get_batch(addr))
421 }
422
423 fn set(&mut self, addr: Address, account: Box<Account>) {
424 self.with(|this| this.set(addr, account))
425 }
426
427 fn set_batch(&mut self, list: &[(Address, Box<Account>)]) {
428 self.with(|this| this.set_batch(list))
429 }
430
431 fn get_at_index(&self, index: AccountIndex) -> Option<Box<Account>> {
432 self.with(|this| this.get_at_index(index))
433 }
434
435 fn set_at_index(&mut self, index: AccountIndex, account: Box<Account>) -> Result<(), ()> {
436 self.with(|this| this.set_at_index(index, account))
437 }
438
439 fn index_of_account(&self, account_id: AccountId) -> Option<AccountIndex> {
440 self.with(|this| this.index_of_account(account_id))
441 }
442
443 fn merkle_root(&mut self) -> Fp {
444 self.with(|this| this.merkle_root())
445 }
446
447 fn merkle_path(&mut self, addr: Address) -> Vec<MerklePath> {
448 let addr_length = addr.length();
449 let res = self.with(|this| this.merkle_path(addr.clone()));
450 assert_eq!(res.len(), addr_length);
451
452 res
460 }
461
462 fn merkle_path_at_index(&mut self, index: AccountIndex) -> Vec<MerklePath> {
463 self.with(|this| this.merkle_path_at_index(index))
464 }
465
466 fn remove_accounts(&mut self, ids: &[AccountId]) {
467 self.with(|this| this.remove_accounts(ids))
468 }
469
470 fn detached_signal(&mut self) {
471 self.with(|this| this.detached_signal())
472 }
473
474 fn depth(&self) -> u8 {
475 self.with(|this| this.depth())
476 }
477
478 fn num_accounts(&self) -> usize {
479 self.with(|this| this.num_accounts())
480 }
481
482 fn merkle_path_at_addr(&mut self, addr: Address) -> Vec<MerklePath> {
483 self.with(|this| this.merkle_path_at_addr(addr))
484 }
485
486 fn get_inner_hash_at_addr(&mut self, addr: Address) -> Result<Fp, String> {
487 self.with(|this| this.get_inner_hash_at_addr(addr))
488 }
489
490 fn set_inner_hash_at_addr(&mut self, addr: Address, hash: Fp) -> Result<(), ()> {
491 self.with(|this| this.set_inner_hash_at_addr(addr, hash))
492 }
493
494 fn set_all_accounts_rooted_at(
495 &mut self,
496 addr: Address,
497 accounts: &[Box<Account>],
498 ) -> Result<(), ()> {
499 self.with(|this| this.set_all_accounts_rooted_at(addr, accounts))
500 }
501
502 fn get_all_accounts_rooted_at(&self, addr: Address) -> Option<Vec<(Address, Box<Account>)>> {
503 self.with(|this| this.get_all_accounts_rooted_at(addr))
504 }
505
506 fn make_space_for(&mut self, space: usize) {
507 self.with(|this| this.make_space_for(space))
508 }
509
510 fn commit(&mut self) {
511 self.with(|this| this.commit())
512 }
513}
514
515#[cfg(test)]
516mod tests {
517 use super::*;
518 use tests_mask_ocaml::*;
519
520 #[cfg(target_family = "wasm")]
521 use wasm_bindgen_test::wasm_bindgen_test as test;
522
523 #[test]
524 fn test_drop_mask() {
525 let root_uuid;
526 let child1_uuid;
527 let child2_uuid;
528
529 let child = {
530 let child = {
531 println!("A");
532 let root = Mask::new_unattached(25);
533 root_uuid = root.get_uuid();
534 println!("root={:?}", root.get_uuid());
535 println!("B");
537 let child = root.make_child();
538 println!("child={:?}", child.get_uuid());
539 child1_uuid = child.get_uuid();
540 child
541 };
542 println!("C");
543 assert!(child.is_attached());
544
545 let child = child.make_child();
546 child2_uuid = child.get_uuid();
547 child
548 };
549
550 println!("D");
551 println!("child2={:?}", child.get_uuid());
552 assert!(child.is_attached());
553
554 {
555 let parent = child.get_parent().unwrap();
556 let parent = parent.get_parent().unwrap();
557 assert_eq!(parent.get_uuid(), root_uuid);
558 }
559
560 assert!(crate::mask::is_alive(&root_uuid));
562 assert!(crate::mask::is_alive(&child1_uuid));
563 assert!(crate::mask::is_alive(&child2_uuid));
564
565 std::mem::drop(child);
566
567 assert!(!crate::mask::is_alive(&root_uuid));
569 assert!(!crate::mask::is_alive(&child1_uuid));
570 assert!(!crate::mask::is_alive(&child2_uuid));
571 }
572
573 #[test]
574 fn test_merkle_path_one_account() {
575 let (mut root, mask) = new_instances(DEPTH);
576 let mut mask = root.register_mask(mask);
577
578 let account = Account::rand();
579
580 let addr = root
581 .get_or_create_account(account.id(), account)
582 .unwrap()
583 .addr();
584
585 let path = mask.merkle_path(addr);
586 assert_eq!(path.len(), DEPTH);
587 }
588
589 #[test]
590 fn test_masks() {
591 const DEPTH: usize = 20;
592
593 let root = Mask::new_unattached(DEPTH);
594 let mask = Mask::new_unattached(DEPTH);
595
596 let mut mask = root.register_mask(mask);
597
598 let accounts: Vec<_> = (0..18).map(|_| Account::rand()).collect();
599
600 for account in &accounts {
601 mask.get_or_create_account(account.id(), account.clone())
602 .unwrap();
603 }
604
605 let mask_paths: Vec<_> = (0..18)
606 .map(|index| {
607 let index: AccountIndex = index.into();
608 let addr = Address::from_index(index, DEPTH);
609 mask.merkle_path(addr)
610 })
611 .collect();
612
613 let mask_root_hash = mask.merkle_root();
614
615 let mut db = Database::create(DEPTH as u8);
616 for account in &accounts {
617 db.get_or_create_account(account.id(), account.clone())
618 .unwrap();
619 }
620
621 let db_paths: Vec<_> = (0..18)
622 .map(|index| {
623 let index: AccountIndex = index.into();
624 let addr = Address::from_index(index, DEPTH);
625 mask.merkle_path(addr)
626 })
627 .collect();
628
629 let db_root_hash = db.merkle_root();
630
631 assert_eq!(mask_root_hash, db_root_hash);
632 assert_eq!(mask_paths, db_paths);
633 }
634
635 #[test]
636 fn test_masks_unregister_recursive() {
637 let (_root, layer1, layer2) = new_chain(DEPTH);
638
639 let layer3 = layer2.make_child();
640 let layer4 = layer2.make_child();
641
642 for mask in [&layer1, &layer2, &layer3, &layer4] {
643 assert!(mask.get_parent().is_some());
644 }
645
646 layer1.unregister_mask(UnregisterBehavior::Recursive);
648
649 for mask in [&layer1, &layer2, &layer3, &layer4] {
650 assert!(mask.get_parent().is_none());
651 }
652 }
653
654 #[test]
656 fn test_masks_cached_hashes() {
657 for case in 0..2 {
658 let (mut root, mut layer1, mut layer2) = new_chain(DEPTH);
659
660 let acc1 = Account::rand();
661 let acc2 = Account::rand();
662 let acc3 = Account::rand();
663
664 let _loc1 = root.get_or_create_account(acc1.id(), acc1).unwrap().addr();
665 let _loc2 = layer1
666 .get_or_create_account(acc2.id(), acc2.clone())
667 .unwrap()
668 .addr();
669 let _loc3 = layer2
670 .get_or_create_account(acc3.id(), acc3)
671 .unwrap()
672 .addr();
673
674 let root_hash = layer2.merkle_root();
675
676 if case == 0 {
679 layer1.remove_accounts(&[acc2.id()]);
680 } else if case == 1 {
681 let account_index = AccountIndex::from(1);
682 let addr = Address::from_index(account_index, DEPTH);
683 let new_account = Account::rand();
684
685 assert_ne!(*layer1.get(addr.clone()).unwrap(), new_account);
686
687 layer1.set(addr, Box::new(new_account));
688 }
689
690 assert_ne!(root_hash, layer2.merkle_root(), "case {:?}", case);
691 }
692 }
693
694 #[test]
695 fn test_cached_merkle_path() {
696 let (mut root, mask) = new_instances(DEPTH);
697 let mut mask = root.register_mask(mask);
698
699 let account = Account::rand();
700 let addr = Address::first(DEPTH);
701
702 mask.set(addr.clone(), Box::new(account.clone()));
703 mask.merkle_root();
704 let mask_merkle_path = mask.merkle_path(addr.clone());
705
706 root.set(addr.clone(), Box::new(account));
707 root.merkle_root();
708 let root_merkle_path = root.merkle_path(addr);
709
710 assert!(!mask_merkle_path.is_empty());
711 assert_eq!(mask_merkle_path, root_merkle_path);
712 elog!("path={:?}", mask_merkle_path);
713 }
714}
715
716#[cfg(test)]
717mod tests_mask_ocaml {
718 use crate::scan_state::currency::{Balance, Magnitude};
719
720 use super::*;
721
722 use rand::{thread_rng, Rng};
723
724 #[cfg(target_family = "wasm")]
725 use wasm_bindgen_test::wasm_bindgen_test as test;
726
727 pub const DEPTH: usize = 4;
728 pub const FIRST_LOC: Address = Address::first(DEPTH);
729
730 pub fn new_instances(depth: usize) -> (Mask, Mask) {
731 let db = Database::<V2>::create(depth as u8);
732 (Mask::new_root(db), Mask::new_unattached(depth))
733 }
734
735 pub fn new_chain(depth: usize) -> (Mask, Mask, Mask) {
736 let db = Database::<V2>::create(depth as u8);
737 let layer1 = Mask::new_unattached(depth);
738 let layer2 = Mask::new_unattached(depth);
739
740 let root = Mask::new_root(db);
741 let layer1 = root.register_mask(layer1);
742 let layer2 = layer1.register_mask(layer2);
743
744 (root, layer1, layer2)
745 }
746
747 fn make_full_accounts(depth: usize) -> Vec<Account> {
748 (0..2u64.pow(depth as u32))
749 .map(|_| Account::rand())
750 .collect()
751 }
752
753 #[test]
755 fn test_parent_mask_agree_on_set() {
756 let (mut root, mask) = new_instances(DEPTH);
757 let mask = root.register_mask(mask);
758
759 root.set(FIRST_LOC, Box::new(Account::rand()));
760
761 let root_account = root.get(FIRST_LOC).unwrap();
762 let mask_account = mask.get(FIRST_LOC).unwrap();
763
764 assert_eq!(root_account, mask_account);
765 }
766
767 #[test]
769 fn test_parent_mask_agree_on_set2() {
770 let (mut root, mask) = new_instances(DEPTH);
771 let mut mask = root.register_mask(mask);
772
773 let account = Box::new(Account::rand());
774 root.set(FIRST_LOC, account.clone());
775 mask.set(FIRST_LOC, account);
776
777 let root_account = root.get(FIRST_LOC).unwrap();
778 let mask_account = mask.get(FIRST_LOC).unwrap();
779
780 assert_eq!(root_account, mask_account);
781 }
782
783 #[test]
785 fn test_parent_mask_agree_on_hashes() {
786 let (mut root, mask) = new_instances(DEPTH);
787 let mut mask = root.register_mask(mask);
788
789 let account = Box::new(Account::rand());
790 root.set(FIRST_LOC, account.clone());
791 mask.set(FIRST_LOC, account);
792
793 assert_eq!(root.merkle_root(), mask.merkle_root());
794 }
795
796 #[test]
798 fn test_parent_mask_agree_on_hashes_set_parent_only() {
799 let (mut root, mask) = new_instances(DEPTH);
800 let mut mask = root.register_mask(mask);
801
802 let account = Box::new(Account::rand());
803 root.set(FIRST_LOC, account);
804
805 assert_eq!(root.merkle_root(), mask.merkle_root());
806 }
807
808 #[test]
810 fn test_mask_delegate_to_parent() {
811 let (mut root, mask) = new_instances(DEPTH);
812 let mask = root.register_mask(mask);
813
814 let account = Box::new(Account::rand());
815 root.set(FIRST_LOC, account.clone());
816
817 let child_account = mask.get(FIRST_LOC).unwrap();
818
819 assert_eq!(account, child_account);
820 }
821
822 #[test]
824 fn test_mask_prune_after_parent_notif() {
825 let (mut root, mask) = new_instances(DEPTH);
826 let mut mask = root.register_mask(mask);
827
828 let account = Box::new(Account::rand());
830 mask.set(FIRST_LOC, account.clone());
831
832 assert!(mask.test_is_in_mask(&FIRST_LOC));
833
834 root.set(FIRST_LOC, account);
835
836 assert!(!mask.test_is_in_mask(&FIRST_LOC));
838 }
839
840 #[test]
842 fn test_commit_puts_mask_in_parent_and_flush_mask() {
843 let (root, mask) = new_instances(DEPTH);
844 let mut mask = root.register_mask(mask);
845
846 let account = Box::new(Account::rand());
847 mask.set(FIRST_LOC, account);
848
849 assert!(mask.test_is_in_mask(&FIRST_LOC));
850
851 mask.commit();
852
853 assert!(!mask.test_is_in_mask(&FIRST_LOC));
855 assert!(root.get(FIRST_LOC).is_some());
857 }
858
859 #[test]
861 fn test_commit_layer2_dumps_to_layer1_not_in_base() {
862 let (root, layer1, mut layer2) = new_chain(DEPTH);
863
864 let account = Box::new(Account::rand());
865
866 layer2.set(FIRST_LOC, account);
867 assert!(layer2.test_is_in_mask(&FIRST_LOC));
868 assert!(!layer1.test_is_in_mask(&FIRST_LOC));
869
870 layer2.commit();
871 assert!(!layer2.test_is_in_mask(&FIRST_LOC));
872 assert!(layer1.test_is_in_mask(&FIRST_LOC));
873 assert!(!root.test_is_in_mask(&FIRST_LOC));
874 }
875
876 #[test]
878 fn test_commit_layer2_to_root_dumps_to_base_not_in_layer1() {
879 let (root, mut layer1, mut layer2) = new_chain(DEPTH);
880
881 let (addr1, addr2) = (FIRST_LOC, FIRST_LOC.next().unwrap());
882 let (account1, account2) = (Box::new(Account::rand()), Box::new(Account::rand()));
883
884 layer1.set(addr1.clone(), account1);
885 layer2.set(addr2.clone(), account2);
886
887 assert!(layer1.test_is_in_mask(&addr1));
888 assert!(!layer1.test_is_in_mask(&addr2));
889 assert!(layer2.test_is_in_mask(&addr2));
890 assert!(!layer2.test_is_in_mask(&addr1));
891
892 layer2.commit_and_reparent_to_root();
893 assert!(!layer1.test_is_in_mask(&addr1));
894 assert!(!layer1.test_is_in_mask(&addr2));
895 assert!(!layer2.test_is_in_mask(&addr1));
896 assert!(!layer2.test_is_in_mask(&addr2));
897
898 assert!(!layer1.is_attached());
899 assert!(!layer2.is_attached());
900 assert!(root.test_is_in_mask(&addr1));
901 assert!(root.test_is_in_mask(&addr2));
902 }
903
904 #[test]
906 fn test_register_unregister_mask() {
907 let (root, mask) = new_instances(DEPTH);
908 let mask = root.register_mask(mask);
909 mask.unregister_mask(UnregisterBehavior::Recursive);
910 }
911
912 #[test]
914 fn test_mask_and_parent_agree_on_merkle_path() {
915 let (mut root, mask) = new_instances(DEPTH);
916 let mut mask = root.register_mask(mask);
917
918 let account = Box::new(Account::rand());
919 let addr = Address::first(DEPTH);
920
921 mask.set(addr.clone(), account.clone());
922 let mask_merkle_path = mask.merkle_path(addr.clone());
923
924 root.set(addr.clone(), account);
925 let root_merkle_path = root.merkle_path(addr);
926
927 assert!(!mask_merkle_path.is_empty());
928 assert_eq!(mask_merkle_path, root_merkle_path);
929 elog!("path={:?}", mask_merkle_path);
930 }
931
932 #[test]
934 fn test_agree_on_root_hash_before_set() {
935 let (mut root, mask) = new_instances(DEPTH);
936 let mut mask = root.register_mask(mask);
937
938 assert_eq!(root.merkle_root(), mask.merkle_root());
939 }
940
941 #[test]
943 fn test_agree_on_root_hash_after_set() {
944 let (mut root, mask) = new_instances(DEPTH);
945 let mut mask = root.register_mask(mask);
946
947 let account = Box::new(Account::rand());
948
949 root.set(FIRST_LOC, account.clone());
954 mask.set(FIRST_LOC, account);
955
956 assert!(root.test_is_in_mask(&FIRST_LOC));
957 assert!(mask.test_is_in_mask(&FIRST_LOC));
958 assert_eq!(root.merkle_root(), mask.merkle_root());
959 }
960
961 #[test]
963 fn test_add_retrieve_block_of_accounts() {
964 let (root, mask) = new_instances(DEPTH);
965 let mut mask = root.register_mask(mask);
966
967 let accounts = make_full_accounts(DEPTH);
968
969 for account in &accounts {
970 let account_id = account.id();
971 let res = mask
972 .get_or_create_account(account_id, account.clone())
973 .unwrap();
974 assert!(matches!(res, GetOrCreated::Added(_)));
975 }
976
977 let retrieved_accounts = mask
978 .get_all_accounts_rooted_at(Address::root())
979 .unwrap()
980 .into_iter()
981 .map(|(_, acc)| acc)
982 .collect::<Vec<_>>();
983
984 assert_eq!(
985 accounts.into_iter().map(Box::new).collect::<Vec<_>>(),
986 retrieved_accounts
987 );
988 }
989
990 #[test]
992 fn test_removing_accounts_from_mask_restore_root_hash() {
993 let (root, mask) = new_instances(DEPTH);
994 let mut mask = root.register_mask(mask);
995
996 let accounts = (0..5).map(|_| Account::rand()).collect::<Vec<_>>();
997 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
998 let root_hash0 = mask.merkle_root();
999
1000 for account in accounts {
1001 mask.get_or_create_account(account.id(), account).unwrap();
1002 }
1003 assert_ne!(root_hash0, mask.merkle_root());
1004
1005 mask.remove_accounts(&accounts_ids);
1006 assert_eq!(root_hash0, mask.merkle_root());
1007 }
1008
1009 #[test]
1011 fn test_removing_accounts_from_parent_restore_root_hash() {
1012 let (mut root, mask) = new_instances(DEPTH);
1013 let mut mask = root.register_mask(mask);
1014
1015 let accounts = (0..5).map(|_| Account::rand()).collect::<Vec<_>>();
1016 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
1017 let root_hash0 = mask.merkle_root();
1018
1019 for account in accounts {
1020 root.get_or_create_account(account.id(), account).unwrap();
1021 }
1022 assert_ne!(root_hash0, mask.merkle_root());
1023
1024 mask.remove_accounts(&accounts_ids);
1025 assert_eq!(root_hash0, mask.merkle_root());
1026 }
1027
1028 #[test]
1030 fn test_removing_accounts_from_parent_and_mask_restore_root_hash() {
1031 let (mut root, mask) = new_instances(DEPTH);
1032 let mut mask = root.register_mask(mask);
1033
1034 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1035 let (accounts_parent, accounts_mask) = accounts.split_at(5);
1036 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
1037
1038 let root_hash0 = mask.merkle_root();
1039
1040 for account in accounts_parent {
1041 root.get_or_create_account(account.id(), account.clone())
1042 .unwrap();
1043 }
1044 for account in accounts_mask {
1045 mask.get_or_create_account(account.id(), account.clone())
1046 .unwrap();
1047 }
1048 assert_ne!(root_hash0, mask.merkle_root());
1049
1050 mask.remove_accounts(&accounts_ids);
1051 assert_eq!(root_hash0, mask.merkle_root());
1052 }
1053
1054 #[test]
1056 fn test_fold_of_addition_over_account_balance_in_parent_and_mask() {
1057 let (mut root, mask) = new_instances(DEPTH);
1058 let mut mask = root.register_mask(mask);
1059
1060 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1061 let balance = accounts
1062 .iter()
1063 .fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1064
1065 let (accounts_parent, accounts_mask) = accounts.split_at(5);
1066
1067 for account in accounts_parent {
1068 root.get_or_create_account(account.id(), account.clone())
1069 .unwrap();
1070 }
1071 for account in accounts_mask {
1072 mask.get_or_create_account(account.id(), account.clone())
1073 .unwrap();
1074 }
1075
1076 let retrieved_balance =
1077 mask.fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1078 assert_eq!(balance, retrieved_balance);
1079 }
1080
1081 fn create_existing_account(mask: &mut Mask, account: Account) {
1082 match mask
1083 .get_or_create_account(account.id(), account.clone())
1084 .unwrap()
1085 {
1086 GetOrCreated::Added(_) => panic!("Should add an existing account"),
1087 GetOrCreated::Existed(addr) => {
1088 mask.set(addr, Box::new(account));
1089 }
1090 }
1091 }
1092
1093 #[test]
1095 fn test_masking_in_to_list() {
1096 let (mut root, mask) = new_instances(DEPTH);
1097 let mut mask = root.register_mask(mask);
1098
1099 let mut accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1100 let one = Balance::from_u64(1);
1102 accounts
1103 .iter_mut()
1104 .for_each(|account| account.balance = account.balance.checked_add(&one).unwrap_or(one));
1105
1106 for account in &accounts {
1107 root.get_or_create_account(account.id(), account.clone())
1108 .unwrap();
1109 }
1110
1111 let parent_list = root.to_list();
1112
1113 accounts
1115 .iter_mut()
1116 .for_each(|account| account.balance = Balance::zero());
1117
1118 for account in accounts {
1119 create_existing_account(&mut mask, account);
1120 }
1121
1122 let mask_list = mask.to_list();
1123
1124 assert_eq!(parent_list.len(), mask_list.len());
1125 assert_eq!(
1127 parent_list.iter().map(Account::id).collect::<Vec<_>>(),
1128 mask_list.iter().map(Account::id).collect::<Vec<_>>(),
1129 );
1130 assert_eq!(
1132 mask_list
1133 .iter()
1134 .fold(0u128, |acc, account| acc + account.balance.as_u64() as u128),
1135 0
1136 );
1137 }
1138
1139 #[test]
1141 fn test_masking_in_to_foldi() {
1142 let (mut root, mask) = new_instances(DEPTH);
1143 let mut mask = root.register_mask(mask);
1144
1145 let mut accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1146 let one = Balance::from_u64(1);
1148 accounts
1149 .iter_mut()
1150 .for_each(|account| account.balance = account.balance.checked_add(&one).unwrap_or(one));
1151
1152 for account in &accounts {
1153 root.get_or_create_account(account.id(), account.clone())
1154 .unwrap();
1155 }
1156
1157 let parent_sum_balance =
1158 root.fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1159 assert_ne!(parent_sum_balance, 0);
1160
1161 accounts
1163 .iter_mut()
1164 .for_each(|account| account.balance = Balance::zero());
1165
1166 for account in accounts {
1167 create_existing_account(&mut mask, account);
1168 }
1169
1170 let mask_sum_balance =
1171 mask.fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1172 assert_eq!(mask_sum_balance, 0);
1173 }
1174
1175 #[test]
1177 fn test_create_empty_doesnt_modify_the_hash() {
1178 let (root, mask) = new_instances(DEPTH);
1179 let mut mask = root.register_mask(mask);
1180
1181 let start_hash = mask.merkle_root();
1182
1183 let account = Account::empty();
1184 mask.get_or_create_account(account.id(), account).unwrap();
1185
1186 assert_eq!(mask.num_accounts(), 1);
1187 assert_eq!(start_hash, mask.merkle_root());
1188 }
1189
1190 #[test]
1192 fn test_reuse_of_locations_for_removed_accounts() {
1193 let (root, mask) = new_instances(DEPTH);
1194 let mut mask = root.register_mask(mask);
1195
1196 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1197 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
1198
1199 assert!(mask.last_filled().is_none());
1200 for account in accounts {
1201 mask.get_or_create_account(account.id(), account.clone())
1202 .unwrap();
1203 }
1204 assert!(mask.last_filled().is_some());
1205
1206 mask.remove_accounts(&accounts_ids);
1207 assert!(mask.last_filled().is_none());
1208 }
1209
1210 #[test]
1212 fn test_num_accounts_for_unique_keys_in_mask_and_parent() {
1213 let (mut root, mask) = new_instances(DEPTH);
1214 let mut mask = root.register_mask(mask);
1215
1216 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1217
1218 for account in &accounts {
1219 mask.get_or_create_account(account.id(), account.clone())
1220 .unwrap();
1221 }
1222
1223 let mask_num_accounts_before = mask.num_accounts();
1224
1225 for account in &accounts {
1227 root.get_or_create_account(account.id(), account.clone())
1228 .unwrap();
1229 }
1230
1231 let parent_num_accounts = root.num_accounts();
1232 let mask_num_accounts_after = mask.num_accounts();
1233
1234 assert_eq!(accounts.len(), parent_num_accounts);
1235 assert_eq!(parent_num_accounts, mask_num_accounts_before);
1236 assert_eq!(parent_num_accounts, mask_num_accounts_after);
1237 }
1238
1239 #[test]
1241 fn test_mask_reparenting_works() {
1242 let (mut root, mut layer1, mut layer2) = new_chain(DEPTH);
1243
1244 let acc1 = Account::rand();
1245 let acc2 = Account::rand();
1246 let acc3 = Account::rand();
1247
1248 let loc1 = root.get_or_create_account(acc1.id(), acc1).unwrap().addr();
1249 let loc2 = layer1
1250 .get_or_create_account(acc2.id(), acc2)
1251 .unwrap()
1252 .addr();
1253 let loc3 = layer2
1254 .get_or_create_account(acc3.id(), acc3)
1255 .unwrap()
1256 .addr();
1257
1258 assert!(layer2.get(loc1.clone()).is_some());
1260 assert!(layer2.get(loc2.clone()).is_some());
1261 assert!(layer2.get(loc3.clone()).is_some());
1262
1263 assert!(root.get(loc1.clone()).is_some());
1265
1266 layer1.commit();
1267
1268 assert!(root.get(loc2.clone()).is_some());
1270
1271 layer1.remove_and_reparent();
1272
1273 assert!(root.get(loc1.clone()).is_some());
1275 assert!(root.get(loc2.clone()).is_some());
1276
1277 assert!(root.get(loc3.clone()).is_none());
1279
1280 assert!(layer2.get(loc1).is_some());
1282 assert!(layer2.get(loc2).is_some());
1283 assert!(layer2.get(loc3).is_some());
1284 }
1285
1286 #[test]
1289 fn test_set_account_in_parent_doesnt_remove_if_mask_is_dirty() {
1290 let (mut root, mask) = new_instances(DEPTH);
1291 let mut mask = root.register_mask(mask);
1292
1293 let mut account = Box::new(Account::rand());
1294 let mut account2 = account.clone();
1295
1296 account.balance = Balance::from_u64(10);
1297 account2.balance = Balance::from_u64(5);
1298
1299 let loc = mask
1300 .get_or_create_account(account.id(), *account.clone())
1301 .unwrap()
1302 .addr();
1303
1304 root.set(loc.clone(), account2);
1305
1306 assert_eq!(mask.get(loc).unwrap(), account);
1307 }
1308
1309 #[test]
1312 fn test_get_all_accounts_should_preserve_ordering() {
1313 let (_root, mut layer1, mut layer2) = new_chain(DEPTH);
1314
1315 let accounts = make_full_accounts(DEPTH);
1316
1317 for account in &accounts {
1318 layer1
1319 .get_or_create_account(account.id(), account.clone())
1320 .unwrap();
1321 }
1322
1323 let mut updated_accounts = accounts.clone();
1324 let mut rng = thread_rng();
1325 let mut nmodified = 0;
1326
1327 for account in updated_accounts.iter_mut() {
1328 if rng.gen::<u8>() >= 150 {
1329 continue;
1330 }
1331 account.balance = rng.gen();
1332
1333 create_existing_account(&mut layer2, account.clone());
1334 nmodified += 1;
1335 }
1336
1337 assert!(nmodified > 0);
1338 assert_eq!(
1339 updated_accounts
1340 .into_iter()
1341 .map(Box::new)
1342 .collect::<Vec<_>>(),
1343 layer2
1344 .get_all_accounts_rooted_at(Address::root())
1345 .unwrap()
1346 .into_iter()
1347 .map(|(_, account)| account)
1348 .collect::<Vec<_>>()
1349 );
1350 assert_eq!(
1351 accounts.into_iter().map(Box::new).collect::<Vec<_>>(),
1352 layer1
1353 .get_all_accounts_rooted_at(Address::root())
1354 .unwrap()
1355 .into_iter()
1356 .map(|(_, account)| account)
1357 .collect::<Vec<_>>()
1358 );
1359 }
1360
1361 #[test]
1362 fn test_validate_inner_hashes() {
1363 let l = Address::first(1);
1364 assert_eq!(l.parent().unwrap(), Address::root());
1365 assert_eq!(l.parent(), l.next().unwrap().parent());
1366 let (root, layer1, layer2) = new_chain(DEPTH);
1367
1368 let accounts = make_full_accounts(DEPTH);
1369
1370 for (i, mut mask) in [root, layer1, layer2].into_iter().enumerate() {
1371 for account in accounts.iter().skip(i) {
1372 mask.get_or_create_account(account.id(), account.clone())
1373 .unwrap();
1374 }
1375 dbg!(mask.merkle_root());
1376 mask.validate_inner_hashes().unwrap();
1377 }
1378 }
1379
1380 #[test]
1381 fn test_nmasks_to_root() {
1382 let (root, layer1, layer2) = new_chain(DEPTH);
1383 assert_eq!(root.nmasks_to_root(), 0);
1384 assert_eq!(layer1.nmasks_to_root(), 1);
1385 assert_eq!(layer2.nmasks_to_root(), 2);
1386
1387 let mut mask = layer2;
1388 for index in 0..300 {
1389 assert_eq!(mask.nmasks_to_root(), 2 + index);
1390 mask = mask.make_child();
1391 }
1392 }
1393}