mina_tree/database/
database_impl.rs

1use std::{
2    collections::{HashMap, HashSet},
3    ops::ControlFlow,
4    path::PathBuf,
5};
6
7use mina_curves::pasta::Fp;
8use mina_signer::CompressedPubKey;
9
10use crate::{
11    next_uuid, Account, AccountId, AccountIndex, AccountLegacy, Address, AddressIterator,
12    BaseLedger, Direction, GetOrCreated, HashesMatrix, MerklePath, TokenId, TreeVersion, Uuid, V1,
13    V2,
14};
15
16use super::DatabaseError;
17
18#[derive(Clone)]
19pub struct DatabaseImpl<T: TreeVersion> {
20    accounts: Vec<Option<T::Account>>,
21    pub hashes_matrix: HashesMatrix,
22    id_to_addr: HashMap<AccountId, Address>,
23    token_owners: Option<HashMap<T::TokenId, AccountId>>,
24    depth: u8,
25    last_location: Option<Address>,
26    naccounts: usize,
27    uuid: Uuid,
28    directory: PathBuf,
29}
30
31impl<T: TreeVersion> std::fmt::Debug for DatabaseImpl<T> {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        f.debug_struct("Database")
34            // .field("accounts", &self.accounts)
35            .field("hashes_matrix", &self.hashes_matrix)
36            // .field("id_to_addr", &self.id_to_addr)
37            // .field("token_owners", &self.token_owners)
38            // .field("depth", &self.depth)
39            // .field("last_location", &self.last_location)
40            .field("naccounts", &self.naccounts)
41            .field("uuid", &self.uuid)
42            .field("directory", &self.directory)
43            .finish()
44    }
45}
46
47// #[derive(Debug, PartialEq, Eq)]
48// pub enum DatabaseError {
49//     OutOfLeaves,
50// }
51
52impl DatabaseImpl<V2> {
53    pub fn clone_db(&self, new_directory: PathBuf) -> Self {
54        Self {
55            // root: self.root.clone(),
56            accounts: self.accounts.clone(),
57            id_to_addr: self.id_to_addr.clone(),
58            token_owners: self.token_owners.clone(),
59            depth: self.depth,
60            last_location: self.last_location.clone(),
61            naccounts: self.naccounts,
62            uuid: next_uuid(),
63            directory: new_directory,
64            hashes_matrix: self.hashes_matrix.clone(),
65            // root_hash: RefCell::new(*self.root_hash.borrow()),
66        }
67    }
68
69    fn remove(&mut self, addr: Address) -> Option<Account> {
70        let index = addr.to_index();
71        let index: usize = index.0 as usize;
72
73        if let Some(account) = self.accounts.get_mut(index) {
74            return account.take();
75        }
76
77        None
78    }
79
80    fn create_account(
81        &mut self,
82        account_id: AccountId,
83        account: Account,
84    ) -> Result<GetOrCreated, DatabaseError> {
85        // if self.root.is_none() {
86        //     self.root = Some(NodeOrLeaf::Node(Node::default()));
87        // }
88
89        if let Some(addr) = self.id_to_addr.get(&account_id).cloned() {
90            return Ok(GetOrCreated::Existed(addr));
91        }
92
93        let token_id = account.token_id.clone();
94        let location = match self.last_location.as_ref() {
95            Some(last) => last.next().ok_or(DatabaseError::OutOfLeaves)?,
96            None => Address::first(self.depth as usize),
97        };
98
99        assert_eq!(location.to_index(), self.accounts.len());
100        self.accounts.push(Some(account));
101
102        // let root = self.root.as_mut().unwrap();
103        // root.add_account_on_path(account, location.iter());
104
105        self.last_location = Some(location.clone());
106        self.naccounts += 1;
107
108        if !token_id.is_default() {
109            if let Some(token_owners) = self.token_owners.as_mut() {
110                token_owners.insert(account_id.derive_token_id(), account_id.clone());
111            }
112        }
113        self.id_to_addr.insert(account_id, location.clone());
114
115        // self.root_hash.borrow_mut().take();
116
117        Ok(GetOrCreated::Added(location))
118    }
119
120    pub fn iter_with_addr<F>(&self, mut fun: F)
121    where
122        F: FnMut(Address, &Account),
123    {
124        let depth = self.depth as usize;
125
126        for (index, account) in self.accounts.iter().enumerate() {
127            let account = match account {
128                Some(account) => account,
129                None => continue,
130            };
131
132            let addr = Address::from_index(index.into(), depth);
133            fun(addr, account);
134        }
135    }
136
137    fn emulate_tree_to_get_hash_at(&mut self, addr: Address) -> Fp {
138        if let Some(hash) = self.hashes_matrix.get(&addr) {
139            return *hash;
140        };
141
142        // let tree_depth = self.depth() as usize;
143        // let mut children = addr.iter_children(tree_depth);
144
145        // // First child
146        // let first_account_index = children.next().unwrap().to_index().0 as u64;
147        // let mut nremaining = self
148        //     .naccounts()
149        //     .saturating_sub(first_account_index as usize);
150
151        let last_account = self
152            .last_filled()
153            .unwrap_or_else(|| Address::first(self.depth as usize));
154
155        self.emulate_tree_recursive(addr, &last_account)
156    }
157
158    // fn emulate_recursive(&mut self, addr: Address, nremaining: &mut usize) -> Fp {
159    pub fn emulate_tree_recursive(&mut self, addr: Address, last_account: &Address) -> Fp {
160        let tree_depth = self.depth as usize;
161        let current_depth = tree_depth - addr.length();
162
163        if current_depth == 0 {
164            return self
165                .get_account_hash(addr.to_index())
166                .unwrap_or_else(|| self.hashes_matrix.empty_hash_at_height(0));
167        }
168
169        let mut get_child_hash = |addr: Address| {
170            if let Some(hash) = self.hashes_matrix.get(&addr) {
171                *hash
172            } else if addr.is_before(last_account) {
173                self.emulate_tree_recursive(addr, last_account)
174            } else {
175                self.hashes_matrix.empty_hash_at_height(current_depth - 1)
176            }
177        };
178
179        let left_hash = get_child_hash(addr.child_left());
180        let right_hash = get_child_hash(addr.child_right());
181
182        match self.hashes_matrix.get(&addr) {
183            Some(hash) => *hash,
184            None => {
185                let hash = V2::hash_node(current_depth - 1, left_hash, right_hash);
186                self.hashes_matrix.set(&addr, hash);
187                hash
188            }
189        }
190    }
191
192    pub fn emulate_tree_to_get_path(
193        &mut self,
194        addr: Address,
195        last_account: &Address,
196        path: &mut AddressIterator,
197        merkle_path: &mut Vec<MerklePath>,
198    ) -> Fp {
199        let tree_depth = self.depth as usize;
200
201        if addr.length() == self.depth as usize {
202            return self
203                .get_account_hash(addr.to_index())
204                .unwrap_or_else(|| self.hashes_matrix.empty_hash_at_height(0));
205        }
206
207        let next_direction = path.next();
208
209        // We go until the end of the path
210        if let Some(direction) = next_direction.as_ref() {
211            let child = match direction {
212                Direction::Left => addr.child_left(),
213                Direction::Right => addr.child_right(),
214            };
215            self.emulate_tree_to_get_path(child, last_account, path, merkle_path);
216        };
217
218        let depth_in_tree = tree_depth - addr.length();
219
220        let mut get_child_hash = |addr: Address| match self.hashes_matrix.get(&addr) {
221            Some(hash) => *hash,
222            None => {
223                if let Some(hash) = self.hashes_matrix.get(&addr) {
224                    *hash
225                } else if addr.is_before(last_account) {
226                    self.emulate_tree_to_get_path(addr, last_account, path, merkle_path)
227                } else {
228                    self.hashes_matrix.empty_hash_at_height(depth_in_tree - 1)
229                }
230            }
231        };
232
233        let left = get_child_hash(addr.child_left());
234        let right = get_child_hash(addr.child_right());
235
236        if let Some(direction) = next_direction {
237            let hash = match direction {
238                Direction::Left => MerklePath::Left(right),
239                Direction::Right => MerklePath::Right(left),
240            };
241            merkle_path.push(hash);
242        };
243
244        match self.hashes_matrix.get(&addr) {
245            Some(hash) => *hash,
246            None => {
247                let hash = V2::hash_node(depth_in_tree - 1, left, right);
248                self.hashes_matrix.set(&addr, hash);
249                hash
250            }
251        }
252    }
253
254    pub fn create_checkpoint(&self, directory_name: String) {
255        elog!("create_checkpoint {}", directory_name);
256    }
257
258    pub fn make_checkpoint(&self, directory_name: String) {
259        elog!("make_checkpoint {}", directory_name);
260    }
261
262    pub fn get_cached_hash(&self, addr: &Address) -> Option<Fp> {
263        self.hashes_matrix.get(addr).copied()
264    }
265
266    pub fn set_cached_hash(&mut self, addr: &Address, hash: Fp) {
267        self.hashes_matrix.set(addr, hash);
268    }
269
270    pub fn empty_hash_at_height(&mut self, height: usize) -> Fp {
271        self.hashes_matrix.empty_hash_at_height(height)
272    }
273
274    pub fn invalidate_hashes(&mut self, account_index: AccountIndex) {
275        self.hashes_matrix.invalidate_hashes(account_index)
276    }
277
278    pub fn transfert_hashes(&mut self, hashes: HashesMatrix) {
279        self.hashes_matrix.transfert_hashes(hashes)
280    }
281
282    pub fn has_token_owners(&self) -> bool {
283        self.token_owners.is_some()
284    }
285}
286
287impl DatabaseImpl<V1> {
288    pub fn create_account(
289        &mut self,
290        _account_id: (),
291        account: AccountLegacy,
292    ) -> Result<Address, DatabaseError> {
293        // if self.root.is_none() {
294        //     self.root = Some(NodeOrLeaf::Node(Node::default()));
295        // }
296
297        let location = match self.last_location.as_ref() {
298            Some(last) => last.next().ok_or(DatabaseError::OutOfLeaves)?,
299            None => Address::first(self.depth as usize),
300        };
301
302        assert_eq!(location.to_index(), self.accounts.len());
303        self.accounts.push(Some(account));
304
305        // let root = self.root.as_mut().unwrap();
306        // let path_iter = location.clone().into_iter();
307        // root.add_account_on_path(account, path_iter);
308
309        self.last_location = Some(location.clone());
310        self.naccounts += 1;
311
312        Ok(location)
313    }
314}
315
316impl DatabaseImpl<V2> {
317    const NACCOUNTS: usize = 10_000;
318    const NTOKENS: usize = 10;
319
320    pub fn create_with_dir(depth: u8, dir_name: Option<PathBuf>) -> Self {
321        assert!((1..0xfe).contains(&depth));
322
323        let uuid = next_uuid();
324
325        let path = match dir_name {
326            Some(dir_name) => dir_name,
327            None => {
328                let directory = format!("minadb-{uuid}");
329
330                let mut path = PathBuf::from("/tmp");
331                path.push(&directory);
332                path
333            }
334        };
335
336        // elog!(
337        //     "DB depth={:?} uuid={:?} pid={:?} path={:?}",
338        //     depth,
339        //     uuid,
340        //     crate::util::pid(),
341        //     path
342        // );
343
344        // std::fs::create_dir_all(&path).ok();
345
346        Self {
347            depth,
348            accounts: Vec::with_capacity(Self::NACCOUNTS),
349            last_location: None,
350            naccounts: 0,
351            id_to_addr: HashMap::with_capacity(Self::NACCOUNTS),
352            token_owners: None,
353            uuid,
354            directory: path,
355            hashes_matrix: HashesMatrix::new(depth as usize),
356            // root_hash: Default::default(),
357        }
358    }
359
360    pub fn create(depth: u8) -> Self {
361        Self::create_with_dir(depth, None)
362    }
363
364    pub fn create_with_token_owners(depth: u8) -> Self {
365        let mut db = Self::create_with_dir(depth, None);
366        db.set_token_owners();
367        db
368    }
369
370    pub fn set_token_owners(&mut self) {
371        if self.token_owners.is_none() {
372            self.token_owners = Some(HashMap::with_capacity(Self::NTOKENS));
373        }
374    }
375
376    pub fn unset_token_owners(&mut self) {
377        self.token_owners = None;
378    }
379
380    pub fn root_hash(&mut self) -> Fp {
381        self.emulate_tree_to_get_hash_at(Address::root())
382    }
383
384    // Do not use
385    pub fn naccounts(&self) -> usize {
386        self.accounts.iter().filter_map(Option::as_ref).count()
387    }
388
389    // fn naccounts_recursive(&self, elem: &NodeOrLeaf<T>, naccounts: &mut usize) {
390    //     match elem {
391    //         NodeOrLeaf::Leaf(_) => *naccounts += 1,
392    //         NodeOrLeaf::Node(node) => {
393    //             if let Some(left) = node.left.as_ref() {
394    //                 self.naccounts_recursive(left, naccounts);
395    //             };
396    //             if let Some(right) = node.right.as_ref() {
397    //                 self.naccounts_recursive(right, naccounts);
398    //             };
399    //         }
400    //     }
401    // }
402
403    fn get_account_ref(&self, addr: Address) -> Option<&Account> {
404        let index = addr.to_index();
405        let index: usize = index.0 as usize;
406
407        self.accounts.get(index)?.as_ref()
408    }
409}
410
411impl BaseLedger for DatabaseImpl<V2> {
412    fn to_list(&self) -> Vec<Account> {
413        self.accounts
414            .iter()
415            .filter_map(Option::as_ref)
416            .cloned()
417            .collect()
418        // let root = match self.root.as_ref() {
419        //     Some(root) => root,
420        //     None => return Vec::new(),
421        // };
422
423        // let mut accounts = Vec::with_capacity(100);
424
425        // root.iter_recursive(&mut |account| {
426        //     accounts.push(account.clone());
427        //     ControlFlow::Continue(())
428        // });
429
430        // accounts
431    }
432
433    fn iter<F>(&self, fun: F)
434    where
435        F: FnMut(&Account),
436    {
437        self.accounts
438            .iter()
439            .filter_map(Option::as_ref)
440            .for_each(fun);
441
442        // let root = match self.root.as_ref() {
443        //     Some(root) => root,
444        //     None => return,
445        // };
446
447        // root.iter_recursive(&mut |account| {
448        //     fun(account);
449        //     ControlFlow::Continue(())
450        // });
451    }
452
453    fn fold<B, F>(&self, init: B, mut fun: F) -> B
454    where
455        F: FnMut(B, &Account) -> B,
456    {
457        let mut accum = init;
458        for account in self.accounts.iter().filter_map(Option::as_ref) {
459            accum = fun(accum, account);
460        }
461        accum
462
463        // let root = match self.root.as_ref() {
464        //     Some(root) => root,
465        //     None => return init,
466        // };
467
468        // let mut accum = Some(init);
469        // root.iter_recursive(&mut |account| {
470        //     let res = fun(accum.take().unwrap(), account);
471        //     accum = Some(res);
472        //     ControlFlow::Continue(())
473        // });
474
475        // accum.unwrap()
476    }
477
478    fn fold_with_ignored_accounts<B, F>(
479        &self,
480        ignoreds: HashSet<AccountId>,
481        init: B,
482        mut fun: F,
483    ) -> B
484    where
485        F: FnMut(B, &Account) -> B,
486    {
487        let mut accum = init;
488        for account in self.accounts.iter().filter_map(Option::as_ref) {
489            let account_id = account.id();
490
491            if !ignoreds.contains(&account_id) {
492                accum = fun(accum, account);
493            }
494        }
495        accum
496        // self.fold(init, |accum, account| {
497        //     let account_id = account.id();
498
499        //     if !ignoreds.contains(&account_id) {
500        //         fun(accum, account)
501        //     } else {
502        //         accum
503        //     }
504        // })
505    }
506
507    fn fold_until<B, F>(&self, init: B, mut fun: F) -> B
508    where
509        F: FnMut(B, &Account) -> ControlFlow<B, B>,
510    {
511        let mut accum = init;
512        for account in self.accounts.iter().filter_map(Option::as_ref) {
513            match fun(accum, account) {
514                ControlFlow::Continue(v) => {
515                    accum = v;
516                }
517                ControlFlow::Break(v) => {
518                    accum = v;
519                    break;
520                }
521            }
522        }
523        accum
524
525        // let root = match self.root.as_ref() {
526        //     Some(root) => root,
527        //     None => return init,
528        // };
529
530        // let mut accum = Some(init);
531        // root.iter_recursive(&mut |account| match fun(accum.take().unwrap(), account) {
532        //     ControlFlow::Continue(account) => {
533        //         accum = Some(account);
534        //         ControlFlow::Continue(())
535        //     }
536        //     ControlFlow::Break(account) => {
537        //         accum = Some(account);
538        //         ControlFlow::Break(())
539        //     }
540        // });
541
542        // accum.unwrap()
543    }
544
545    fn accounts(&self) -> HashSet<AccountId> {
546        self.id_to_addr.keys().cloned().collect()
547    }
548
549    fn token_owner(&self, token_id: TokenId) -> Option<AccountId> {
550        self.token_owners
551            .as_ref()
552            .and_then(|token_owners| token_owners.get(&token_id).cloned())
553    }
554
555    fn tokens(&self, public_key: CompressedPubKey) -> HashSet<TokenId> {
556        let mut set = HashSet::with_capacity(100);
557
558        for account in self.accounts.iter().filter_map(Option::as_ref) {
559            if account.public_key == public_key {
560                set.insert(account.token_id.clone());
561            }
562        }
563
564        // let root = match self.root.as_ref() {
565        //     Some(root) => root,
566        //     None => return HashSet::default(),
567        // };
568
569        // let mut set = HashSet::with_capacity(self.naccounts);
570
571        // root.iter_recursive(&mut |account| {
572        //     if account.public_key == public_key {
573        //         set.insert(account.token_id.clone());
574        //     }
575
576        //     ControlFlow::Continue(())
577        // });
578
579        set
580    }
581
582    fn location_of_account(&self, account_id: &AccountId) -> Option<Address> {
583        let res = self.id_to_addr.get(account_id).cloned();
584
585        // elog!("location_of_account id={:?}\n{:?}", account_id, res);
586
587        res
588    }
589
590    fn location_of_account_batch(
591        &self,
592        account_ids: &[AccountId],
593    ) -> Vec<(AccountId, Option<Address>)> {
594        let res: Vec<_> = account_ids
595            .iter()
596            .map(|account_id| {
597                let addr = self.id_to_addr.get(account_id).cloned();
598                (account_id.clone(), addr)
599            })
600            .collect();
601
602        elog!(
603            "location_of_account_batch ids={:?}\nres={:?}={:?}",
604            account_ids,
605            res.len(),
606            res
607        );
608
609        res
610    }
611
612    fn get_or_create_account(
613        &mut self,
614        account_id: AccountId,
615        account: Account,
616    ) -> Result<GetOrCreated, DatabaseError> {
617        let result = self.create_account(account_id, account);
618
619        if let Ok(GetOrCreated::Added(addr)) = result.as_ref() {
620            let account_index = addr.to_index();
621            self.hashes_matrix.invalidate_hashes(account_index);
622        };
623
624        result
625    }
626
627    fn close(&self) {
628        elog!(
629            "close pid={:?} uuid={:?} path={:?}",
630            crate::util::pid(),
631            self.uuid,
632            self.directory
633        );
634        // Drop
635    }
636
637    fn last_filled(&self) -> Option<Address> {
638        self.last_location.clone()
639    }
640
641    fn get_uuid(&self) -> crate::base::Uuid {
642        self.uuid.clone()
643    }
644
645    fn get_directory(&self) -> Option<PathBuf> {
646        Some(self.directory.clone())
647    }
648
649    fn get_account_hash(&mut self, account_index: AccountIndex) -> Option<Fp> {
650        let addr = Address::from_index(account_index, self.depth as usize);
651
652        if let Some(hash) = self.hashes_matrix.get(&addr) {
653            return Some(*hash);
654        }
655
656        let account = self.get_account_ref(addr.clone())?;
657        let hash = account.hash();
658
659        self.hashes_matrix.set(&addr, hash);
660
661        Some(hash)
662    }
663
664    #[inline(never)]
665    fn get(&self, addr: Address) -> Option<Box<Account>> {
666        self.get_account_ref(addr).cloned().map(Box::new)
667    }
668
669    fn get_batch(&self, addr: &[Address]) -> Vec<(Address, Option<Box<Account>>)> {
670        let res: Vec<_> = addr
671            .iter()
672            .map(|addr| (addr.clone(), self.get(addr.clone())))
673            .collect();
674
675        // let root = match self.root.as_ref() {
676        //     Some(root) => Cow::Borrowed(root),
677        //     None => Cow::Owned(NodeOrLeaf::Node(Node::default())),
678        // };
679
680        // let res: Vec<_> = addr
681        //     .iter()
682        //     .map(|addr| (addr.clone(), root.get_on_path(addr.iter()).cloned()))
683        //     .collect();
684
685        elog!("get_batch addrs={:?}\nres={:?}={:?}", addr, res.len(), res);
686
687        res
688    }
689
690    fn set(&mut self, addr: Address, account: Box<Account>) {
691        let index = addr.to_index();
692
693        self.hashes_matrix.invalidate_hashes(index);
694
695        let index: usize = index.0 as usize;
696
697        if self.accounts.len() <= index {
698            self.accounts.resize(index + 1, None);
699        }
700
701        // if self.root.is_none() {
702        //     self.root = Some(NodeOrLeaf::Node(Node::default()));
703        // }
704
705        let id = account.id();
706        // let root = self.root.as_mut().unwrap();
707
708        // Remove account at the address and it's index
709        if let Some(account) = self.get(addr.clone()) {
710            let id = account.id();
711            self.id_to_addr.remove(&id);
712            if !id.token_id.is_default() {
713                if let Some(token_owners) = self.token_owners.as_mut() {
714                    token_owners.remove(&id.derive_token_id());
715                }
716            }
717        } else {
718            self.naccounts += 1;
719        }
720
721        if !account.token_id.is_default() {
722            if let Some(token_owners) = self.token_owners.as_mut() {
723                token_owners.insert(account.id().derive_token_id(), id.clone());
724            }
725        }
726        self.id_to_addr.insert(id, addr.clone());
727        self.accounts[index] = Some(*account);
728        // root.add_account_on_path(account, addr.iter());
729
730        if self
731            .last_location
732            .as_ref()
733            .map(|l| l.to_index() < addr.to_index())
734            .unwrap_or(true)
735        {
736            self.last_location = Some(addr);
737        }
738
739        // self.root_hash.borrow_mut().take();
740    }
741
742    fn set_batch(&mut self, list: &[(Address, Box<Account>)]) {
743        elog!("SET_BATCH {:?}", list.len());
744        // elog!("SET_BATCH {:?} {:?}", list.len(), list);
745        for (addr, account) in list {
746            assert_eq!(addr.length(), self.depth as usize, "addr={:?}", addr);
747            self.set(addr.clone(), account.clone());
748        }
749    }
750
751    fn get_at_index(&self, index: AccountIndex) -> Option<Box<Account>> {
752        let addr = Address::from_index(index, self.depth as usize);
753        self.get(addr)
754    }
755
756    fn set_at_index(&mut self, index: AccountIndex, account: Box<Account>) -> Result<(), ()> {
757        let addr = Address::from_index(index, self.depth as usize);
758        self.set(addr, account);
759
760        // self.root_hash.borrow_mut().take();
761
762        Ok(())
763    }
764
765    fn index_of_account(&self, account_id: AccountId) -> Option<AccountIndex> {
766        self.id_to_addr.get(&account_id).map(Address::to_index)
767    }
768
769    fn merkle_root(&mut self) -> Fp {
770        // let now = crate::util::Instant::now();
771
772        self.root_hash()
773
774        // let root = match *self.root_hash.borrow() {
775        //     Some(root) => root,
776        //     None => self.root_hash(),
777        // };
778
779        // elog!(
780        //     "uuid={:?} ROOT={} num_account={:?} elapsed={:?}",
781        //     self.get_uuid(),
782        //     root,
783        //     self.num_accounts(),
784        //     now.elapsed(),
785        // );
786
787        // self.root_hash.borrow_mut().replace(root);
788
789        // elog!("PATH={:#?}", self.merkle_path(Address::first(self.depth as usize)));
790
791        // self.merkle_path(Address::first(self.depth as usize));
792
793        // root
794    }
795
796    fn merkle_path(&mut self, addr: Address) -> Vec<MerklePath> {
797        elog!("merkle_path called depth={:?} addr={:?}", self.depth, addr);
798
799        let mut merkle_path = Vec::with_capacity(addr.length());
800        let mut path = addr.into_iter();
801        let addr = Address::root();
802
803        let last_account = self
804            .last_filled()
805            .unwrap_or_else(|| Address::first(self.depth as usize));
806
807        // let tree_index = TreeIndex::root(self.depth() as usize);
808
809        self.emulate_tree_to_get_path(addr, &last_account, &mut path, &mut merkle_path);
810
811        merkle_path
812    }
813
814    fn merkle_path_at_index(&mut self, index: AccountIndex) -> Vec<MerklePath> {
815        let addr = Address::from_index(index, self.depth as usize);
816        self.merkle_path(addr)
817    }
818
819    fn remove_accounts(&mut self, ids: &[AccountId]) {
820        // let root = match self.root.as_mut() {
821        //     Some(root) => root,
822        //     None => return,
823        // };
824
825        let mut addrs = ids
826            .iter()
827            .map(|accound_id| self.id_to_addr.remove(accound_id).unwrap())
828            .collect::<Vec<_>>();
829        addrs.sort_by_key(Address::to_index);
830
831        for addr in addrs.iter().rev() {
832            // let leaf = match root.get_mut_leaf_on_path(addr.iter()) {
833            //     Some(leaf) => leaf,
834            //     None => continue,
835            // };
836
837            // let account = match leaf.account.take() {
838            //     Some(account) => account,
839            //     None => continue,
840            // };
841
842            let account_index = addr.to_index();
843            self.hashes_matrix.invalidate_hashes(account_index);
844
845            let account = match self.remove(addr.clone()) {
846                Some(account) => account,
847                None => continue,
848            };
849
850            // let index = addr.to_index();
851            // let account = std::mem::take()
852
853            let id = account.id();
854            self.id_to_addr.remove(&id);
855            if !id.token_id.is_default() {
856                if let Some(token_owners) = self.token_owners.as_mut() {
857                    token_owners.remove(&id.derive_token_id());
858                }
859            }
860
861            self.naccounts = self
862                .naccounts
863                .checked_sub(1)
864                .expect("invalid naccounts counter");
865
866            if self
867                .last_location
868                .as_ref()
869                .map(|last| last == addr)
870                .unwrap_or(false)
871            {
872                self.last_location = addr.prev();
873            }
874        }
875
876        // self.root_hash.borrow_mut().take();
877    }
878
879    fn detached_signal(&mut self) {
880        todo!()
881    }
882
883    fn depth(&self) -> u8 {
884        self.depth
885    }
886
887    fn num_accounts(&self) -> usize {
888        self.naccounts
889    }
890
891    fn merkle_path_at_addr(&mut self, addr: Address) -> Vec<MerklePath> {
892        self.merkle_path(addr)
893    }
894
895    fn get_inner_hash_at_addr(&mut self, addr: Address) -> Result<Fp, String> {
896        let res = self.emulate_tree_to_get_hash_at(addr.clone());
897
898        elog!("get_inner_hash_at_addr addr={:?} hash={}", addr, res);
899
900        Ok(res)
901    }
902
903    fn set_inner_hash_at_addr(&mut self, _addr: Address, _hash: Fp) -> Result<(), ()> {
904        // No-op for now, because we don't store the hashes anywhere
905        Ok(())
906    }
907
908    fn set_all_accounts_rooted_at(
909        &mut self,
910        addr: Address,
911        accounts: &[Box<Account>],
912    ) -> Result<(), ()> {
913        if addr.length() > self.depth as usize {
914            return Err(());
915        }
916
917        for (child_addr, account) in addr.iter_children(self.depth as usize).zip(accounts) {
918            self.set(child_addr, account.clone());
919        }
920
921        Ok(())
922    }
923
924    fn get_all_accounts_rooted_at(&self, addr: Address) -> Option<Vec<(Address, Box<Account>)>> {
925        if addr.length() > self.depth as usize {
926            return None;
927        }
928
929        // let root = match self.root.as_ref() {
930        //     Some(root) => root,
931        //     None => return None,
932        // };
933
934        let children = addr.iter_children(self.depth as usize);
935        let mut accounts = Vec::with_capacity(children.len());
936
937        for child_addr in children {
938            let account = match self.get(child_addr.clone()) {
939                Some(account) => account,
940                None => continue,
941            };
942            accounts.push((child_addr, account));
943        }
944
945        if accounts.is_empty() {
946            None
947        } else {
948            Some(accounts)
949        }
950    }
951
952    fn make_space_for(&mut self, _space: usize) {
953        // No op, we're in memory
954    }
955
956    fn commit(&mut self) {
957        // no-op
958    }
959}