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 res
452 }
453
454 fn merkle_path_at_index(&mut self, index: AccountIndex) -> Vec<MerklePath> {
455 self.with(|this| this.merkle_path_at_index(index))
456 }
457
458 fn remove_accounts(&mut self, ids: &[AccountId]) {
459 self.with(|this| this.remove_accounts(ids))
460 }
461
462 fn detached_signal(&mut self) {
463 self.with(|this| this.detached_signal())
464 }
465
466 fn depth(&self) -> u8 {
467 self.with(|this| this.depth())
468 }
469
470 fn num_accounts(&self) -> usize {
471 self.with(|this| this.num_accounts())
472 }
473
474 fn merkle_path_at_addr(&mut self, addr: Address) -> Vec<MerklePath> {
475 self.with(|this| this.merkle_path_at_addr(addr))
476 }
477
478 fn get_inner_hash_at_addr(&mut self, addr: Address) -> Result<Fp, String> {
479 self.with(|this| this.get_inner_hash_at_addr(addr))
480 }
481
482 fn set_inner_hash_at_addr(&mut self, addr: Address, hash: Fp) -> Result<(), ()> {
483 self.with(|this| this.set_inner_hash_at_addr(addr, hash))
484 }
485
486 fn set_all_accounts_rooted_at(
487 &mut self,
488 addr: Address,
489 accounts: &[Box<Account>],
490 ) -> Result<(), ()> {
491 self.with(|this| this.set_all_accounts_rooted_at(addr, accounts))
492 }
493
494 fn get_all_accounts_rooted_at(&self, addr: Address) -> Option<Vec<(Address, Box<Account>)>> {
495 self.with(|this| this.get_all_accounts_rooted_at(addr))
496 }
497
498 fn make_space_for(&mut self, space: usize) {
499 self.with(|this| this.make_space_for(space))
500 }
501
502 fn commit(&mut self) {
503 self.with(|this| this.commit())
504 }
505}
506
507#[cfg(test)]
508mod tests {
509 use super::*;
510 use tests_mask_ocaml::*;
511
512 #[cfg(target_family = "wasm")]
513 use wasm_bindgen_test::wasm_bindgen_test as test;
514
515 #[test]
516 fn test_drop_mask() {
517 let root_uuid;
518 let child1_uuid;
519 let child2_uuid;
520
521 let child = {
522 let child = {
523 println!("A");
524 let root = Mask::new_unattached(25);
525 root_uuid = root.get_uuid();
526 println!("root={:?}", root.get_uuid());
527 println!("B");
529 let child = root.make_child();
530 println!("child={:?}", child.get_uuid());
531 child1_uuid = child.get_uuid();
532 child
533 };
534 println!("C");
535 assert!(child.is_attached());
536
537 let child = child.make_child();
538 child2_uuid = child.get_uuid();
539 child
540 };
541
542 println!("D");
543 println!("child2={:?}", child.get_uuid());
544 assert!(child.is_attached());
545
546 {
547 let parent = child.get_parent().unwrap();
548 let parent = parent.get_parent().unwrap();
549 assert_eq!(parent.get_uuid(), root_uuid);
550 }
551
552 assert!(crate::mask::is_alive(&root_uuid));
554 assert!(crate::mask::is_alive(&child1_uuid));
555 assert!(crate::mask::is_alive(&child2_uuid));
556
557 std::mem::drop(child);
558
559 assert!(!crate::mask::is_alive(&root_uuid));
561 assert!(!crate::mask::is_alive(&child1_uuid));
562 assert!(!crate::mask::is_alive(&child2_uuid));
563 }
564
565 #[test]
566 fn test_merkle_path_one_account() {
567 let (mut root, mask) = new_instances(DEPTH);
568 let mut mask = root.register_mask(mask);
569
570 let account = Account::rand();
571
572 let addr = root
573 .get_or_create_account(account.id(), account)
574 .unwrap()
575 .addr();
576
577 let path = mask.merkle_path(addr);
578 assert_eq!(path.len(), DEPTH);
579 }
580
581 #[test]
582 fn test_masks() {
583 const DEPTH: usize = 20;
584
585 let root = Mask::new_unattached(DEPTH);
586 let mask = Mask::new_unattached(DEPTH);
587
588 let mut mask = root.register_mask(mask);
589
590 let accounts: Vec<_> = (0..18).map(|_| Account::rand()).collect();
591
592 for account in &accounts {
593 mask.get_or_create_account(account.id(), account.clone())
594 .unwrap();
595 }
596
597 let mask_paths: Vec<_> = (0..18)
598 .map(|index| {
599 let index: AccountIndex = index.into();
600 let addr = Address::from_index(index, DEPTH);
601 mask.merkle_path(addr)
602 })
603 .collect();
604
605 let mask_root_hash = mask.merkle_root();
606
607 let mut db = Database::create(DEPTH as u8);
608 for account in &accounts {
609 db.get_or_create_account(account.id(), account.clone())
610 .unwrap();
611 }
612
613 let db_paths: Vec<_> = (0..18)
614 .map(|index| {
615 let index: AccountIndex = index.into();
616 let addr = Address::from_index(index, DEPTH);
617 mask.merkle_path(addr)
618 })
619 .collect();
620
621 let db_root_hash = db.merkle_root();
622
623 assert_eq!(mask_root_hash, db_root_hash);
624 assert_eq!(mask_paths, db_paths);
625 }
626
627 #[test]
628 fn test_masks_unregister_recursive() {
629 let (_root, layer1, layer2) = new_chain(DEPTH);
630
631 let layer3 = layer2.make_child();
632 let layer4 = layer2.make_child();
633
634 for mask in [&layer1, &layer2, &layer3, &layer4] {
635 assert!(mask.get_parent().is_some());
636 }
637
638 layer1.unregister_mask(UnregisterBehavior::Recursive);
640
641 for mask in [&layer1, &layer2, &layer3, &layer4] {
642 assert!(mask.get_parent().is_none());
643 }
644 }
645
646 #[test]
648 fn test_masks_cached_hashes() {
649 for case in 0..2 {
650 let (mut root, mut layer1, mut layer2) = new_chain(DEPTH);
651
652 let acc1 = Account::rand();
653 let acc2 = Account::rand();
654 let acc3 = Account::rand();
655
656 let _loc1 = root.get_or_create_account(acc1.id(), acc1).unwrap().addr();
657 let _loc2 = layer1
658 .get_or_create_account(acc2.id(), acc2.clone())
659 .unwrap()
660 .addr();
661 let _loc3 = layer2
662 .get_or_create_account(acc3.id(), acc3)
663 .unwrap()
664 .addr();
665
666 let root_hash = layer2.merkle_root();
667
668 if case == 0 {
671 layer1.remove_accounts(&[acc2.id()]);
672 } else if case == 1 {
673 let account_index = AccountIndex::from(1);
674 let addr = Address::from_index(account_index, DEPTH);
675 let new_account = Account::rand();
676
677 assert_ne!(*layer1.get(addr.clone()).unwrap(), new_account);
678
679 layer1.set(addr, Box::new(new_account));
680 }
681
682 assert_ne!(root_hash, layer2.merkle_root(), "case {:?}", case);
683 }
684 }
685
686 #[test]
687 fn test_cached_merkle_path() {
688 let (mut root, mask) = new_instances(DEPTH);
689 let mut mask = root.register_mask(mask);
690
691 let account = Account::rand();
692 let addr = Address::first(DEPTH);
693
694 mask.set(addr.clone(), Box::new(account.clone()));
695 mask.merkle_root();
696 let mask_merkle_path = mask.merkle_path(addr.clone());
697
698 root.set(addr.clone(), Box::new(account));
699 root.merkle_root();
700 let root_merkle_path = root.merkle_path(addr);
701
702 assert!(!mask_merkle_path.is_empty());
703 assert_eq!(mask_merkle_path, root_merkle_path);
704 elog!("path={:?}", mask_merkle_path);
705 }
706}
707
708#[cfg(test)]
709mod tests_mask_ocaml {
710 use crate::scan_state::currency::{Balance, Magnitude};
711
712 use super::*;
713
714 use rand::{thread_rng, Rng};
715
716 #[cfg(target_family = "wasm")]
717 use wasm_bindgen_test::wasm_bindgen_test as test;
718
719 pub const DEPTH: usize = 4;
720 pub const FIRST_LOC: Address = Address::first(DEPTH);
721
722 pub fn new_instances(depth: usize) -> (Mask, Mask) {
723 let db = Database::<V2>::create(depth as u8);
724 (Mask::new_root(db), Mask::new_unattached(depth))
725 }
726
727 pub fn new_chain(depth: usize) -> (Mask, Mask, Mask) {
728 let db = Database::<V2>::create(depth as u8);
729 let layer1 = Mask::new_unattached(depth);
730 let layer2 = Mask::new_unattached(depth);
731
732 let root = Mask::new_root(db);
733 let layer1 = root.register_mask(layer1);
734 let layer2 = layer1.register_mask(layer2);
735
736 (root, layer1, layer2)
737 }
738
739 fn make_full_accounts(depth: usize) -> Vec<Account> {
740 (0..2u64.pow(depth as u32))
741 .map(|_| Account::rand())
742 .collect()
743 }
744
745 #[test]
747 fn test_parent_mask_agree_on_set() {
748 let (mut root, mask) = new_instances(DEPTH);
749 let mask = root.register_mask(mask);
750
751 root.set(FIRST_LOC, Box::new(Account::rand()));
752
753 let root_account = root.get(FIRST_LOC).unwrap();
754 let mask_account = mask.get(FIRST_LOC).unwrap();
755
756 assert_eq!(root_account, mask_account);
757 }
758
759 #[test]
761 fn test_parent_mask_agree_on_set2() {
762 let (mut root, mask) = new_instances(DEPTH);
763 let mut mask = root.register_mask(mask);
764
765 let account = Box::new(Account::rand());
766 root.set(FIRST_LOC, account.clone());
767 mask.set(FIRST_LOC, account);
768
769 let root_account = root.get(FIRST_LOC).unwrap();
770 let mask_account = mask.get(FIRST_LOC).unwrap();
771
772 assert_eq!(root_account, mask_account);
773 }
774
775 #[test]
777 fn test_parent_mask_agree_on_hashes() {
778 let (mut root, mask) = new_instances(DEPTH);
779 let mut mask = root.register_mask(mask);
780
781 let account = Box::new(Account::rand());
782 root.set(FIRST_LOC, account.clone());
783 mask.set(FIRST_LOC, account);
784
785 assert_eq!(root.merkle_root(), mask.merkle_root());
786 }
787
788 #[test]
790 fn test_parent_mask_agree_on_hashes_set_parent_only() {
791 let (mut root, mask) = new_instances(DEPTH);
792 let mut mask = root.register_mask(mask);
793
794 let account = Box::new(Account::rand());
795 root.set(FIRST_LOC, account);
796
797 assert_eq!(root.merkle_root(), mask.merkle_root());
798 }
799
800 #[test]
802 fn test_mask_delegate_to_parent() {
803 let (mut root, mask) = new_instances(DEPTH);
804 let mask = root.register_mask(mask);
805
806 let account = Box::new(Account::rand());
807 root.set(FIRST_LOC, account.clone());
808
809 let child_account = mask.get(FIRST_LOC).unwrap();
810
811 assert_eq!(account, child_account);
812 }
813
814 #[test]
816 fn test_mask_prune_after_parent_notif() {
817 let (mut root, mask) = new_instances(DEPTH);
818 let mut mask = root.register_mask(mask);
819
820 let account = Box::new(Account::rand());
822 mask.set(FIRST_LOC, account.clone());
823
824 assert!(mask.test_is_in_mask(&FIRST_LOC));
825
826 root.set(FIRST_LOC, account);
827
828 assert!(!mask.test_is_in_mask(&FIRST_LOC));
830 }
831
832 #[test]
834 fn test_commit_puts_mask_in_parent_and_flush_mask() {
835 let (root, mask) = new_instances(DEPTH);
836 let mut mask = root.register_mask(mask);
837
838 let account = Box::new(Account::rand());
839 mask.set(FIRST_LOC, account);
840
841 assert!(mask.test_is_in_mask(&FIRST_LOC));
842
843 mask.commit();
844
845 assert!(!mask.test_is_in_mask(&FIRST_LOC));
847 assert!(root.get(FIRST_LOC).is_some());
849 }
850
851 #[test]
853 fn test_commit_layer2_dumps_to_layer1_not_in_base() {
854 let (root, layer1, mut layer2) = new_chain(DEPTH);
855
856 let account = Box::new(Account::rand());
857
858 layer2.set(FIRST_LOC, account);
859 assert!(layer2.test_is_in_mask(&FIRST_LOC));
860 assert!(!layer1.test_is_in_mask(&FIRST_LOC));
861
862 layer2.commit();
863 assert!(!layer2.test_is_in_mask(&FIRST_LOC));
864 assert!(layer1.test_is_in_mask(&FIRST_LOC));
865 assert!(!root.test_is_in_mask(&FIRST_LOC));
866 }
867
868 #[test]
870 fn test_commit_layer2_to_root_dumps_to_base_not_in_layer1() {
871 let (root, mut layer1, mut layer2) = new_chain(DEPTH);
872
873 let (addr1, addr2) = (FIRST_LOC, FIRST_LOC.next().unwrap());
874 let (account1, account2) = (Box::new(Account::rand()), Box::new(Account::rand()));
875
876 layer1.set(addr1.clone(), account1);
877 layer2.set(addr2.clone(), account2);
878
879 assert!(layer1.test_is_in_mask(&addr1));
880 assert!(!layer1.test_is_in_mask(&addr2));
881 assert!(layer2.test_is_in_mask(&addr2));
882 assert!(!layer2.test_is_in_mask(&addr1));
883
884 layer2.commit_and_reparent_to_root();
885 assert!(!layer1.test_is_in_mask(&addr1));
886 assert!(!layer1.test_is_in_mask(&addr2));
887 assert!(!layer2.test_is_in_mask(&addr1));
888 assert!(!layer2.test_is_in_mask(&addr2));
889
890 assert!(!layer1.is_attached());
891 assert!(!layer2.is_attached());
892 assert!(root.test_is_in_mask(&addr1));
893 assert!(root.test_is_in_mask(&addr2));
894 }
895
896 #[test]
898 fn test_register_unregister_mask() {
899 let (root, mask) = new_instances(DEPTH);
900 let mask = root.register_mask(mask);
901 mask.unregister_mask(UnregisterBehavior::Recursive);
902 }
903
904 #[test]
906 fn test_mask_and_parent_agree_on_merkle_path() {
907 let (mut root, mask) = new_instances(DEPTH);
908 let mut mask = root.register_mask(mask);
909
910 let account = Box::new(Account::rand());
911 let addr = Address::first(DEPTH);
912
913 mask.set(addr.clone(), account.clone());
914 let mask_merkle_path = mask.merkle_path(addr.clone());
915
916 root.set(addr.clone(), account);
917 let root_merkle_path = root.merkle_path(addr);
918
919 assert!(!mask_merkle_path.is_empty());
920 assert_eq!(mask_merkle_path, root_merkle_path);
921 elog!("path={:?}", mask_merkle_path);
922 }
923
924 #[test]
926 fn test_agree_on_root_hash_before_set() {
927 let (mut root, mask) = new_instances(DEPTH);
928 let mut mask = root.register_mask(mask);
929
930 assert_eq!(root.merkle_root(), mask.merkle_root());
931 }
932
933 #[test]
935 fn test_agree_on_root_hash_after_set() {
936 let (mut root, mask) = new_instances(DEPTH);
937 let mut mask = root.register_mask(mask);
938
939 let account = Box::new(Account::rand());
940
941 root.set(FIRST_LOC, account.clone());
946 mask.set(FIRST_LOC, account);
947
948 assert!(root.test_is_in_mask(&FIRST_LOC));
949 assert!(mask.test_is_in_mask(&FIRST_LOC));
950 assert_eq!(root.merkle_root(), mask.merkle_root());
951 }
952
953 #[test]
955 fn test_add_retrieve_block_of_accounts() {
956 let (root, mask) = new_instances(DEPTH);
957 let mut mask = root.register_mask(mask);
958
959 let accounts = make_full_accounts(DEPTH);
960
961 for account in &accounts {
962 let account_id = account.id();
963 let res = mask
964 .get_or_create_account(account_id, account.clone())
965 .unwrap();
966 assert!(matches!(res, GetOrCreated::Added(_)));
967 }
968
969 let retrieved_accounts = mask
970 .get_all_accounts_rooted_at(Address::root())
971 .unwrap()
972 .into_iter()
973 .map(|(_, acc)| acc)
974 .collect::<Vec<_>>();
975
976 assert_eq!(
977 accounts.into_iter().map(Box::new).collect::<Vec<_>>(),
978 retrieved_accounts
979 );
980 }
981
982 #[test]
984 fn test_removing_accounts_from_mask_restore_root_hash() {
985 let (root, mask) = new_instances(DEPTH);
986 let mut mask = root.register_mask(mask);
987
988 let accounts = (0..5).map(|_| Account::rand()).collect::<Vec<_>>();
989 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
990 let root_hash0 = mask.merkle_root();
991
992 for account in accounts {
993 mask.get_or_create_account(account.id(), account).unwrap();
994 }
995 assert_ne!(root_hash0, mask.merkle_root());
996
997 mask.remove_accounts(&accounts_ids);
998 assert_eq!(root_hash0, mask.merkle_root());
999 }
1000
1001 #[test]
1003 fn test_removing_accounts_from_parent_restore_root_hash() {
1004 let (mut root, mask) = new_instances(DEPTH);
1005 let mut mask = root.register_mask(mask);
1006
1007 let accounts = (0..5).map(|_| Account::rand()).collect::<Vec<_>>();
1008 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
1009 let root_hash0 = mask.merkle_root();
1010
1011 for account in accounts {
1012 root.get_or_create_account(account.id(), account).unwrap();
1013 }
1014 assert_ne!(root_hash0, mask.merkle_root());
1015
1016 mask.remove_accounts(&accounts_ids);
1017 assert_eq!(root_hash0, mask.merkle_root());
1018 }
1019
1020 #[test]
1022 fn test_removing_accounts_from_parent_and_mask_restore_root_hash() {
1023 let (mut root, mask) = new_instances(DEPTH);
1024 let mut mask = root.register_mask(mask);
1025
1026 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1027 let (accounts_parent, accounts_mask) = accounts.split_at(5);
1028 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
1029
1030 let root_hash0 = mask.merkle_root();
1031
1032 for account in accounts_parent {
1033 root.get_or_create_account(account.id(), account.clone())
1034 .unwrap();
1035 }
1036 for account in accounts_mask {
1037 mask.get_or_create_account(account.id(), account.clone())
1038 .unwrap();
1039 }
1040 assert_ne!(root_hash0, mask.merkle_root());
1041
1042 mask.remove_accounts(&accounts_ids);
1043 assert_eq!(root_hash0, mask.merkle_root());
1044 }
1045
1046 #[test]
1048 fn test_fold_of_addition_over_account_balance_in_parent_and_mask() {
1049 let (mut root, mask) = new_instances(DEPTH);
1050 let mut mask = root.register_mask(mask);
1051
1052 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1053 let balance = accounts
1054 .iter()
1055 .fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1056
1057 let (accounts_parent, accounts_mask) = accounts.split_at(5);
1058
1059 for account in accounts_parent {
1060 root.get_or_create_account(account.id(), account.clone())
1061 .unwrap();
1062 }
1063 for account in accounts_mask {
1064 mask.get_or_create_account(account.id(), account.clone())
1065 .unwrap();
1066 }
1067
1068 let retrieved_balance =
1069 mask.fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1070 assert_eq!(balance, retrieved_balance);
1071 }
1072
1073 fn create_existing_account(mask: &mut Mask, account: Account) {
1074 match mask
1075 .get_or_create_account(account.id(), account.clone())
1076 .unwrap()
1077 {
1078 GetOrCreated::Added(_) => panic!("Should add an existing account"),
1079 GetOrCreated::Existed(addr) => {
1080 mask.set(addr, Box::new(account));
1081 }
1082 }
1083 }
1084
1085 #[test]
1087 fn test_masking_in_to_list() {
1088 let (mut root, mask) = new_instances(DEPTH);
1089 let mut mask = root.register_mask(mask);
1090
1091 let mut accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1092 let one = Balance::from_u64(1);
1094 accounts
1095 .iter_mut()
1096 .for_each(|account| account.balance = account.balance.checked_add(&one).unwrap_or(one));
1097
1098 for account in &accounts {
1099 root.get_or_create_account(account.id(), account.clone())
1100 .unwrap();
1101 }
1102
1103 let parent_list = root.to_list();
1104
1105 accounts
1107 .iter_mut()
1108 .for_each(|account| account.balance = Balance::zero());
1109
1110 for account in accounts {
1111 create_existing_account(&mut mask, account);
1112 }
1113
1114 let mask_list = mask.to_list();
1115
1116 assert_eq!(parent_list.len(), mask_list.len());
1117 assert_eq!(
1119 parent_list.iter().map(Account::id).collect::<Vec<_>>(),
1120 mask_list.iter().map(Account::id).collect::<Vec<_>>(),
1121 );
1122 assert_eq!(
1124 mask_list
1125 .iter()
1126 .fold(0u128, |acc, account| acc + account.balance.as_u64() as u128),
1127 0
1128 );
1129 }
1130
1131 #[test]
1133 fn test_masking_in_to_foldi() {
1134 let (mut root, mask) = new_instances(DEPTH);
1135 let mut mask = root.register_mask(mask);
1136
1137 let mut accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1138 let one = Balance::from_u64(1);
1140 accounts
1141 .iter_mut()
1142 .for_each(|account| account.balance = account.balance.checked_add(&one).unwrap_or(one));
1143
1144 for account in &accounts {
1145 root.get_or_create_account(account.id(), account.clone())
1146 .unwrap();
1147 }
1148
1149 let parent_sum_balance =
1150 root.fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1151 assert_ne!(parent_sum_balance, 0);
1152
1153 accounts
1155 .iter_mut()
1156 .for_each(|account| account.balance = Balance::zero());
1157
1158 for account in accounts {
1159 create_existing_account(&mut mask, account);
1160 }
1161
1162 let mask_sum_balance =
1163 mask.fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1164 assert_eq!(mask_sum_balance, 0);
1165 }
1166
1167 #[test]
1169 fn test_create_empty_doesnt_modify_the_hash() {
1170 let (root, mask) = new_instances(DEPTH);
1171 let mut mask = root.register_mask(mask);
1172
1173 let start_hash = mask.merkle_root();
1174
1175 let account = Account::empty();
1176 mask.get_or_create_account(account.id(), account).unwrap();
1177
1178 assert_eq!(mask.num_accounts(), 1);
1179 assert_eq!(start_hash, mask.merkle_root());
1180 }
1181
1182 #[test]
1184 fn test_reuse_of_locations_for_removed_accounts() {
1185 let (root, mask) = new_instances(DEPTH);
1186 let mut mask = root.register_mask(mask);
1187
1188 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1189 let accounts_ids = accounts.iter().map(Account::id).collect::<Vec<_>>();
1190
1191 assert!(mask.last_filled().is_none());
1192 for account in accounts {
1193 mask.get_or_create_account(account.id(), account.clone())
1194 .unwrap();
1195 }
1196 assert!(mask.last_filled().is_some());
1197
1198 mask.remove_accounts(&accounts_ids);
1199 assert!(mask.last_filled().is_none());
1200 }
1201
1202 #[test]
1204 fn test_num_accounts_for_unique_keys_in_mask_and_parent() {
1205 let (mut root, mask) = new_instances(DEPTH);
1206 let mut mask = root.register_mask(mask);
1207
1208 let accounts = (0..10).map(|_| Account::rand()).collect::<Vec<_>>();
1209
1210 for account in &accounts {
1211 mask.get_or_create_account(account.id(), account.clone())
1212 .unwrap();
1213 }
1214
1215 let mask_num_accounts_before = mask.num_accounts();
1216
1217 for account in &accounts {
1219 root.get_or_create_account(account.id(), account.clone())
1220 .unwrap();
1221 }
1222
1223 let parent_num_accounts = root.num_accounts();
1224 let mask_num_accounts_after = mask.num_accounts();
1225
1226 assert_eq!(accounts.len(), parent_num_accounts);
1227 assert_eq!(parent_num_accounts, mask_num_accounts_before);
1228 assert_eq!(parent_num_accounts, mask_num_accounts_after);
1229 }
1230
1231 #[test]
1233 fn test_mask_reparenting_works() {
1234 let (mut root, mut layer1, mut layer2) = new_chain(DEPTH);
1235
1236 let acc1 = Account::rand();
1237 let acc2 = Account::rand();
1238 let acc3 = Account::rand();
1239
1240 let loc1 = root.get_or_create_account(acc1.id(), acc1).unwrap().addr();
1241 let loc2 = layer1
1242 .get_or_create_account(acc2.id(), acc2)
1243 .unwrap()
1244 .addr();
1245 let loc3 = layer2
1246 .get_or_create_account(acc3.id(), acc3)
1247 .unwrap()
1248 .addr();
1249
1250 assert!(layer2.get(loc1.clone()).is_some());
1252 assert!(layer2.get(loc2.clone()).is_some());
1253 assert!(layer2.get(loc3.clone()).is_some());
1254
1255 assert!(root.get(loc1.clone()).is_some());
1257
1258 layer1.commit();
1259
1260 assert!(root.get(loc2.clone()).is_some());
1262
1263 layer1.remove_and_reparent();
1264
1265 assert!(root.get(loc1.clone()).is_some());
1267 assert!(root.get(loc2.clone()).is_some());
1268
1269 assert!(root.get(loc3.clone()).is_none());
1271
1272 assert!(layer2.get(loc1).is_some());
1274 assert!(layer2.get(loc2).is_some());
1275 assert!(layer2.get(loc3).is_some());
1276 }
1277
1278 #[test]
1281 fn test_set_account_in_parent_doesnt_remove_if_mask_is_dirty() {
1282 let (mut root, mask) = new_instances(DEPTH);
1283 let mut mask = root.register_mask(mask);
1284
1285 let mut account = Box::new(Account::rand());
1286 let mut account2 = account.clone();
1287
1288 account.balance = Balance::from_u64(10);
1289 account2.balance = Balance::from_u64(5);
1290
1291 let loc = mask
1292 .get_or_create_account(account.id(), *account.clone())
1293 .unwrap()
1294 .addr();
1295
1296 root.set(loc.clone(), account2);
1297
1298 assert_eq!(mask.get(loc).unwrap(), account);
1299 }
1300
1301 #[test]
1304 fn test_get_all_accounts_should_preserve_ordering() {
1305 let (_root, mut layer1, mut layer2) = new_chain(DEPTH);
1306
1307 let accounts = make_full_accounts(DEPTH);
1308
1309 for account in &accounts {
1310 layer1
1311 .get_or_create_account(account.id(), account.clone())
1312 .unwrap();
1313 }
1314
1315 let mut updated_accounts = accounts.clone();
1316 let mut rng = thread_rng();
1317 let mut nmodified = 0;
1318
1319 for account in updated_accounts.iter_mut() {
1320 if rng.gen::<u8>() >= 150 {
1321 continue;
1322 }
1323 account.balance = rng.gen();
1324
1325 create_existing_account(&mut layer2, account.clone());
1326 nmodified += 1;
1327 }
1328
1329 assert!(nmodified > 0);
1330 assert_eq!(
1331 updated_accounts
1332 .into_iter()
1333 .map(Box::new)
1334 .collect::<Vec<_>>(),
1335 layer2
1336 .get_all_accounts_rooted_at(Address::root())
1337 .unwrap()
1338 .into_iter()
1339 .map(|(_, account)| account)
1340 .collect::<Vec<_>>()
1341 );
1342 assert_eq!(
1343 accounts.into_iter().map(Box::new).collect::<Vec<_>>(),
1344 layer1
1345 .get_all_accounts_rooted_at(Address::root())
1346 .unwrap()
1347 .into_iter()
1348 .map(|(_, account)| account)
1349 .collect::<Vec<_>>()
1350 );
1351 }
1352
1353 #[test]
1354 fn test_validate_inner_hashes() {
1355 let l = Address::first(1);
1356 assert_eq!(l.parent().unwrap(), Address::root());
1357 assert_eq!(l.parent(), l.next().unwrap().parent());
1358 let (root, layer1, layer2) = new_chain(DEPTH);
1359
1360 let accounts = make_full_accounts(DEPTH);
1361
1362 for (i, mut mask) in [root, layer1, layer2].into_iter().enumerate() {
1363 for account in accounts.iter().skip(i) {
1364 mask.get_or_create_account(account.id(), account.clone())
1365 .unwrap();
1366 }
1367 dbg!(mask.merkle_root());
1368 mask.validate_inner_hashes().unwrap();
1369 }
1370 }
1371
1372 #[test]
1373 fn test_nmasks_to_root() {
1374 let (root, layer1, layer2) = new_chain(DEPTH);
1375 assert_eq!(root.nmasks_to_root(), 0);
1376 assert_eq!(layer1.nmasks_to_root(), 1);
1377 assert_eq!(layer2.nmasks_to_root(), 2);
1378
1379 let mut mask = layer2;
1380 for index in 0..300 {
1381 assert_eq!(mask.nmasks_to_root(), 2 + index);
1382 mask = mask.make_child();
1383 }
1384 }
1385}