mina_tree/mask/
mask.rs

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    // Using a mutex for now but this can be replaced with a RefCell
24    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            // Don't drop because of counter
31            return;
32        }
33
34        let Ok(inner) = self.inner.try_lock() else {
35            // The Mask is used somewhere else
36            return;
37        };
38
39        if inner.any_child_alive() {
40            // Still got childs, don't do anything
41            return;
42        }
43
44        let Some(parent) = inner.get_parent() else {
45            // No parent, we don't need to do anything
46            return;
47        };
48
49        // We reached a point where we don't have childs, and it remains at most 2
50        // pointers of our mask:
51        // - 1 pointer from the parent (having us in its `MaskImpl::childs` )
52        // - 1 currently dropping pointer
53        //
54        // Unregister our mask from the parent (remove us from its `MaskImpl::childs`)
55        // It will recursively drop/deallocate any parent with the same conditions
56
57        // Note:
58        // There is a case where the parent does not have any pointer of us:
59        // During transaction application, we don't call `register_mask`
60        // In that case, the `remove_child_uuid` below has no effect
61        // <https://github.com/MinaProtocol/mina/blob/f6756507ff7380a691516ce02a3cf7d9d32915ae/src/lib/mina_ledger/ledger.ml#L204>
62
63        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    // Note: This should be only called on startup
131    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    /// Make `mask` a child of `self`
163    pub fn register_mask(&self, mask: Mask) -> Mask {
164        // elog!("self={:p} mask={:p}", &self.inner, &mask.inner);
165
166        let self_mask = self.clone();
167        self.with(|this| this.register_mask(self_mask, mask))
168    }
169
170    /// Detach this mask from its parent
171    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    /// //             o
210    /// //            /
211    /// //           /
212    /// //  o --- o -
213    /// //  ^     ^  \
214    /// // parent |   \
215    /// //       mask  o
216    /// //           children
217    ///
218    /// Removes the attached mask from its parent and attaches the children to the
219    /// parent instead. Raises an exception if the merkle roots of the mask and the
220    /// parent are not the same.
221    pub fn remove_and_reparent(&self) -> Option<Mask> {
222        self.with(|this| this.remove_and_reparent())
223    }
224
225    /// get hash from mask, if present, else from its parent
226    pub fn get_hash(&self, addr: Address) -> Option<Fp> {
227        self.with(|this| this.get_hash(addr))
228    }
229
230    /// commit all state to the parent, flush state locally
231    pub fn commit(&self) {
232        self.with(|this| this.commit())
233    }
234
235    /// commit all the masks from this mask all the way upto the root
236    /// and return root mask while also detaching all intermediary masks.
237    pub fn commit_and_reparent_to_root(&mut self) -> Option<Mask> {
238        self.with(|this| this.commit_and_reparent_to_root())
239    }
240
241    /// called when parent sets an account; update local state
242    ///
243    /// if the mask's parent sets an account, we can prune an entry in the mask
244    /// if the account in the parent is the same in the mask *)
245    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    /// Validate inner hashes by rehashing everything.
282    /// Returns `Ok(())` if recalculated hashes matched the existing ones.
283    ///
284    /// Warning: Heavy operation.
285    pub fn validate_inner_hashes(&mut self) -> Result<(), ()> {
286        self.with(|this| this.validate_inner_hashes())
287    }
288
289    /// Returns a vector of tuples of (index, hash) of all the hashes contained
290    /// in this mask.
291    pub fn get_raw_inner_hashes(&self) -> Vec<(u64, Fp)> {
292        self.with(|this| this.get_raw_inner_hashes())
293    }
294
295    /// Sets the contents of this mask's hash matrix using raw data.
296    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    /// For tests only, check if the address is in the mask, without checking parent
304    #[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    /// For tests only
310    #[cfg(test)]
311    fn test_matrix(&self) -> HashesMatrix {
312        self.with(|this| this.test_matrix())
313    }
314
315    /// Use for fuzzing only
316    #[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        // Drop self
397    }
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        // elog!(
453        //     "merkle_path addr={:?} path_len={:?} path={:?}",
454        //     addr,
455        //     res.len(),
456        //     res
457        // );
458
459        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                // let root = Mask::new_root(crate::Database::create(35.try_into().unwrap()));
536                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        // The 3 masks should still be alive
561        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        // Now they are all drop/deallocated
568        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        // This should not panic
647        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    // Make sure hashes are correctly invalided in masks (parents/childs)
655    #[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            // Different cases where is should result in a different hash for the childs
677
678            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    // "parent, mask agree on set"
754    #[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    // "parent, mask agree on set"
768    #[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    // "parent, mask agree on hashes; set in both mask and parent"
784    #[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    // "parent, mask agree on hashes; set only in parent"
797    #[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    // "mask delegates to parent"
809    #[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    // "mask prune after parent notification"
823    #[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        // Set in mask
829        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        // The address is no more in the mask
837        assert!(!mask.test_is_in_mask(&FIRST_LOC));
838    }
839
840    // "commit puts mask contents in parent, flushes mask"
841    #[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        // No more in mask
854        assert!(!mask.test_is_in_mask(&FIRST_LOC));
855        // The parent get the account
856        assert!(root.get(FIRST_LOC).is_some());
857    }
858
859    // "commit at layer2, dumps to layer1, not in base"
860    #[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    // "commit at layer2, dumps to layer1, not in base"
877    #[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    // "register and unregister mask"
905    #[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    // "mask and parent agree on Merkle path"
913    #[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    // "mask and parent agree on Merkle root before set"
933    #[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    // "mask and parent agree on Merkle root after set"
942    #[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        // the order of sets matters here; if we set in the mask first,
950        // the set in the maskable notifies the mask, which then removes
951        // the account, changing the Merkle root to what it was before the set
952
953        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    // "add and retrieve a block of accounts"
962    #[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    // "removing accounts from mask restores Merkle root"
991    #[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    // "removing accounts from parent restores Merkle root"
1010    #[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    // "removing accounts from parent and mask restores Merkle root"
1029    #[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    // "fold of addition over account balances in parent and mask"
1055    #[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    // "masking in to_list"
1094    #[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        // Make balances non-zero
1101        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        // Make balances to zero for those same account
1114        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        // Same accounts and order
1126        assert_eq!(
1127            parent_list.iter().map(Account::id).collect::<Vec<_>>(),
1128            mask_list.iter().map(Account::id).collect::<Vec<_>>(),
1129        );
1130        // Balances of mask are zero
1131        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    // "masking in foldi"
1140    #[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        // Make balances non-zero
1147        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        // Make balances to zero for those same account
1162        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    // "create_empty doesn't modify the hash"
1176    #[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    // "reuse of locations for removed accounts"
1191    #[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    // "num_accounts for unique keys in mask and parent"
1211    #[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        // Add same accounts to parent
1226        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    // "Mask reparenting works"
1240    #[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        // All accounts are accessible from layer2
1259        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        // acc1 is in root
1264        assert!(root.get(loc1.clone()).is_some());
1265
1266        layer1.commit();
1267
1268        // acc2 is in root
1269        assert!(root.get(loc2.clone()).is_some());
1270
1271        layer1.remove_and_reparent();
1272
1273        // acc1, acc2 are in root
1274        assert!(root.get(loc1.clone()).is_some());
1275        assert!(root.get(loc2.clone()).is_some());
1276
1277        // acc3 not in root
1278        assert!(root.get(loc3.clone()).is_none());
1279
1280        // All accounts are accessible from layer2
1281        assert!(layer2.get(loc1).is_some());
1282        assert!(layer2.get(loc2).is_some());
1283        assert!(layer2.get(loc3).is_some());
1284    }
1285
1286    // "setting an account in the parent doesn't remove the masked
1287    // copy if the mask is still dirty for that account"
1288    #[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    // "get_all_accounts should preserve the ordering of accounts by
1310    // location with noncontiguous updates of accounts on the mask"
1311    #[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}