mina_tree/database/
database.rs

1use std::{
2    collections::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::{AccountIndex, BaseLedger, GetOrCreated, MerklePath, Uuid},
14    // tree::{Database, DatabaseError},
15    tree_version::V2,
16    TreeVersion,
17};
18
19use crate::HashesMatrix;
20
21use super::database_impl::DatabaseImpl;
22
23#[derive(Debug, PartialEq, Eq)]
24pub enum DatabaseError {
25    OutOfLeaves,
26}
27
28#[derive(Clone, Debug)]
29pub struct Database<T: TreeVersion> {
30    // Using a mutex for now but this can be replaced with a RefCell
31    pub inner: Arc<Mutex<DatabaseImpl<T>>>,
32}
33
34// #[derive(Debug)]
35// pub enum UnregisterBehavior {
36//     Check,
37//     Recursive,
38//     IPromiseIAmReparentingThisDatabase,
39// }
40
41impl Database<V2> {
42    pub fn with<F, R>(&self, fun: F) -> R
43    where
44        F: FnOnce(&mut DatabaseImpl<V2>) -> R,
45    {
46        let mut inner = self.inner.try_lock().expect("lock failed");
47        fun(&mut inner)
48    }
49}
50
51impl Database<V2> {
52    pub fn create_with_dir(depth: u8, dir_name: Option<PathBuf>) -> Self {
53        let db = DatabaseImpl::<V2>::create_with_dir(depth, dir_name);
54
55        Self {
56            inner: Arc::new(Mutex::new(db)),
57        }
58    }
59
60    pub fn create(depth: u8) -> Self {
61        Self::create_with_dir(depth, None)
62    }
63
64    pub fn create_with_token_owners(depth: u8) -> Self {
65        let mut db = Self::create_with_dir(depth, None);
66        db.set_token_owners();
67        db
68    }
69
70    pub fn set_token_owners(&mut self) {
71        self.with(|this| this.set_token_owners());
72    }
73
74    pub fn unset_token_owners(&mut self) {
75        self.with(|this| this.unset_token_owners());
76    }
77
78    pub fn root_hash(&mut self) -> Fp {
79        self.with(|this| this.root_hash())
80    }
81
82    // Do not use
83    pub fn naccounts(&self) -> usize {
84        self.with(|this| this.naccounts())
85    }
86
87    pub fn create_checkpoint(&self, directory_name: String) {
88        self.with(|this| this.create_checkpoint(directory_name))
89    }
90
91    pub fn make_checkpoint(&self, directory_name: String) {
92        self.with(|this| this.make_checkpoint(directory_name))
93    }
94
95    pub fn clone_db(&self, directory_name: PathBuf) -> Self {
96        let db = self.with(|this| this.clone_db(directory_name));
97        Self {
98            inner: Arc::new(Mutex::new(db)),
99        }
100    }
101
102    pub fn get_cached_hash(&self, addr: &Address) -> Option<Fp> {
103        self.with(|this| this.get_cached_hash(addr))
104    }
105
106    pub fn set_cached_hash(&mut self, addr: &Address, hash: Fp) {
107        self.with(|this| this.set_cached_hash(addr, hash))
108    }
109
110    pub fn empty_hash_at_height(&mut self, height: usize) -> Fp {
111        self.with(|this| this.empty_hash_at_height(height))
112    }
113
114    pub fn invalidate_hashes(&mut self, account_index: AccountIndex) {
115        self.with(|this| this.invalidate_hashes(account_index))
116    }
117
118    pub fn transfert_hashes(&mut self, hashes: HashesMatrix) {
119        self.with(|this| this.transfert_hashes(hashes))
120    }
121
122    pub fn has_token_owners(&self) -> bool {
123        self.with(|this| this.has_token_owners())
124    }
125
126    #[cfg(test)]
127    pub fn test_matrix(&self) -> HashesMatrix {
128        self.with(|this| this.hashes_matrix.clone())
129        // match self {
130        //     Root { database, .. } => database,
131        //     Unattached { hashes, .. } | Attached { hashes, .. } => hashes.clone(),
132        // }
133    }
134}
135
136impl BaseLedger for Database<V2> {
137    fn to_list(&self) -> Vec<Account> {
138        self.with(|this| this.to_list())
139    }
140
141    fn iter<F>(&self, fun: F)
142    where
143        F: FnMut(&Account),
144    {
145        self.with(|this| this.iter(fun))
146    }
147
148    fn fold<B, F>(&self, init: B, fun: F) -> B
149    where
150        F: FnMut(B, &Account) -> B,
151    {
152        self.with(|this| this.fold(init, fun))
153    }
154
155    fn fold_with_ignored_accounts<B, F>(&self, ignoreds: HashSet<AccountId>, init: B, fun: F) -> B
156    where
157        F: FnMut(B, &Account) -> B,
158    {
159        self.with(|this| this.fold_with_ignored_accounts(ignoreds, init, fun))
160    }
161
162    fn fold_until<B, F>(&self, init: B, fun: F) -> B
163    where
164        F: FnMut(B, &Account) -> std::ops::ControlFlow<B, B>,
165    {
166        self.with(|this| this.fold_until(init, fun))
167    }
168
169    fn accounts(&self) -> HashSet<AccountId> {
170        self.with(|this| this.accounts())
171    }
172
173    fn token_owner(&self, token_id: TokenId) -> Option<AccountId> {
174        self.with(|this| this.token_owner(token_id))
175    }
176
177    fn tokens(&self, public_key: CompressedPubKey) -> HashSet<TokenId> {
178        self.with(|this| this.tokens(public_key))
179    }
180
181    fn location_of_account(&self, account_id: &AccountId) -> Option<Address> {
182        self.with(|this| this.location_of_account(account_id))
183    }
184
185    fn location_of_account_batch(
186        &self,
187        account_ids: &[AccountId],
188    ) -> Vec<(AccountId, Option<Address>)> {
189        self.with(|this| this.location_of_account_batch(account_ids))
190    }
191
192    fn get_or_create_account(
193        &mut self,
194        account_id: AccountId,
195        account: Account,
196    ) -> Result<GetOrCreated, DatabaseError> {
197        self.with(|this| this.get_or_create_account(account_id, account))
198    }
199
200    fn close(&self) {
201        // Drop self
202    }
203
204    fn last_filled(&self) -> Option<Address> {
205        self.with(|this| this.last_filled())
206    }
207
208    fn get_uuid(&self) -> Uuid {
209        self.with(|this| this.get_uuid())
210    }
211
212    fn get_directory(&self) -> Option<PathBuf> {
213        self.with(|this| this.get_directory())
214    }
215
216    fn get_account_hash(&mut self, account_index: AccountIndex) -> Option<Fp> {
217        self.with(|this| this.get_account_hash(account_index))
218    }
219
220    fn get(&self, addr: Address) -> Option<Box<Account>> {
221        self.with(|this| this.get(addr))
222    }
223
224    fn get_batch(&self, addr: &[Address]) -> Vec<(Address, Option<Box<Account>>)> {
225        self.with(|this| this.get_batch(addr))
226    }
227
228    fn set(&mut self, addr: Address, account: Box<Account>) {
229        self.with(|this| this.set(addr, account))
230    }
231
232    fn set_batch(&mut self, list: &[(Address, Box<Account>)]) {
233        self.with(|this| this.set_batch(list))
234    }
235
236    fn get_at_index(&self, index: AccountIndex) -> Option<Box<Account>> {
237        self.with(|this| this.get_at_index(index))
238    }
239
240    fn set_at_index(&mut self, index: AccountIndex, account: Box<Account>) -> Result<(), ()> {
241        self.with(|this| this.set_at_index(index, account))
242    }
243
244    fn index_of_account(&self, account_id: AccountId) -> Option<AccountIndex> {
245        self.with(|this| this.index_of_account(account_id))
246    }
247
248    fn merkle_root(&mut self) -> Fp {
249        self.with(|this| this.merkle_root())
250    }
251
252    fn merkle_path(&mut self, addr: Address) -> Vec<MerklePath> {
253        self.with(|this| this.merkle_path(addr))
254    }
255
256    fn merkle_path_at_index(&mut self, index: AccountIndex) -> Vec<MerklePath> {
257        self.with(|this| this.merkle_path_at_index(index))
258    }
259
260    fn remove_accounts(&mut self, ids: &[AccountId]) {
261        self.with(|this| this.remove_accounts(ids))
262    }
263
264    fn detached_signal(&mut self) {
265        self.with(|this| this.detached_signal())
266    }
267
268    fn depth(&self) -> u8 {
269        self.with(|this| this.depth())
270    }
271
272    fn num_accounts(&self) -> usize {
273        self.with(|this| this.num_accounts())
274    }
275
276    fn merkle_path_at_addr(&mut self, addr: Address) -> Vec<MerklePath> {
277        self.with(|this| this.merkle_path_at_addr(addr))
278    }
279
280    fn get_inner_hash_at_addr(&mut self, addr: Address) -> Result<Fp, String> {
281        self.with(|this| this.get_inner_hash_at_addr(addr))
282    }
283
284    fn set_inner_hash_at_addr(&mut self, addr: Address, hash: Fp) -> Result<(), ()> {
285        self.with(|this| this.set_inner_hash_at_addr(addr, hash))
286    }
287
288    fn set_all_accounts_rooted_at(
289        &mut self,
290        addr: Address,
291        accounts: &[Box<Account>],
292    ) -> Result<(), ()> {
293        self.with(|this| this.set_all_accounts_rooted_at(addr, accounts))
294    }
295
296    fn get_all_accounts_rooted_at(&self, addr: Address) -> Option<Vec<(Address, Box<Account>)>> {
297        self.with(|this| this.get_all_accounts_rooted_at(addr))
298    }
299
300    fn make_space_for(&mut self, space: usize) {
301        self.with(|this| this.make_space_for(space))
302    }
303
304    fn commit(&mut self) {
305        // no-op
306    }
307}
308
309#[cfg(test)]
310mod tests {
311    use ark_ff::One;
312    use o1_utils::FieldHelpers;
313
314    #[cfg(target_family = "wasm")]
315    use wasm_bindgen_test::wasm_bindgen_test as test;
316
317    use crate::tree_version::{account_empty_legacy_hash, V1};
318
319    use super::*;
320
321    // #[test]
322    // fn test_legacy_db() {
323    //     let two: usize = 2;
324
325    //     for depth in 2..15 {
326    //         let mut db = Database::<V1>::create(depth);
327
328    //         for _ in 0..two.pow(depth as u32) {
329    //             db.create_account((), AccountLegacy::create()).unwrap();
330    //         }
331
332    //         let naccounts = db.naccounts();
333    //         assert_eq!(naccounts, two.pow(depth as u32));
334
335    //         assert_eq!(
336    //             db.create_account((), AccountLegacy::create()).unwrap_err(),
337    //             DatabaseError::OutOfLeaves
338    //         );
339
340    //         elog!("depth={:?} naccounts={:?}", depth, naccounts);
341    //     }
342    // }
343
344    #[test]
345    fn test_matrix() {
346        const DEPTH: usize = 4;
347
348        let mut matrix = HashesMatrix::new(DEPTH);
349        let one = Fp::one();
350
351        for index in 0..16 {
352            let account_index = AccountIndex::from(index);
353            let addr = Address::from_index(account_index, DEPTH);
354            matrix.set(&addr, one);
355
356            elog!("{:?} MATRIX {:#?}", index + 1, matrix);
357        }
358
359        let addr = Address::root();
360
361        matrix.set(&addr, one);
362        elog!("{:?} MATRIX {:#?}", "root", matrix);
363
364        matrix.set(&addr.child_left(), one);
365        elog!("{:?} MATRIX {:#?}", "root", matrix);
366        matrix.set(&addr.child_right(), one);
367        elog!("{:?} MATRIX {:#?}", "root", matrix);
368
369        matrix.set(&addr.child_left().child_left(), one);
370        elog!("{:?} MATRIX {:#?}", "root", matrix);
371        matrix.set(&addr.child_left().child_right(), one);
372        elog!("{:?} MATRIX {:#?}", "root", matrix);
373        matrix.set(&addr.child_right().child_left(), one);
374        elog!("{:?} MATRIX {:#?}", "root", matrix);
375        matrix.set(&addr.child_right().child_right(), one);
376        elog!("{:?} MATRIX {:#?}", "root", matrix);
377    }
378
379    #[test]
380    fn test_db_v2() {
381        let two: usize = 2;
382
383        for depth in 2..15 {
384            let mut db = Database::<V2>::create(depth);
385
386            for _ in 0..two.pow(depth as u32) {
387                let account = Account::rand();
388                let id = account.id();
389                db.get_or_create_account(id, account).unwrap();
390            }
391
392            let naccounts = db.naccounts();
393            assert_eq!(naccounts, two.pow(depth as u32));
394
395            let account = Account::create();
396            let id = account.id();
397            assert_eq!(
398                db.get_or_create_account(id, account).unwrap_err(),
399                DatabaseError::OutOfLeaves
400            );
401
402            elog!("depth={:?} naccounts={:?}", depth, naccounts);
403        }
404    }
405
406    // RUSTFLAGS="-C target-feature=+atomics,+bulk-memory,+mutable-globals" wasm-pack test --release --chrome -- -Z build-std=std,panic_abort -- hashing
407    #[cfg(target_family = "wasm")]
408    #[test]
409    fn test_hashing_tree_with_web_workers() {
410        use web_sys::console;
411
412        use openmina_core::thread;
413        use std::time::Duration;
414
415        use crate::account;
416
417        let mut msg = format!("hello");
418
419        const NACCOUNTS: u64 = 1_000;
420        const NTHREADS: usize = 8;
421
422        let mut accounts = (0..NACCOUNTS).map(|_| Account::rand()).collect::<Vec<_>>();
423
424        use wasm_bindgen::prelude::*;
425
426        fn perf_to_duration(amt: f64) -> std::time::Duration {
427            let secs = (amt as u64) / 1_000;
428            let nanos = (((amt as u64) % 1_000) as u32) * 1_000_000;
429            std::time::Duration::new(secs, nanos)
430        }
431
432        #[cfg(target_arch = "wasm32")]
433        #[wasm_bindgen(inline_js = r#"
434export function performance_now() {
435  return performance.now();
436}"#)]
437        extern "C" {
438            fn performance_now() -> f64;
439        }
440
441        thread::spawn(move || {
442            console::time_with_label("threads");
443            console::log_1(&format!("hello from first thread {:?}", thread::current().id()).into());
444
445            let start = performance_now();
446
447            let mut joins = Vec::with_capacity(NTHREADS);
448
449            for _ in 0..NTHREADS {
450                let accounts = accounts.split_off(accounts.len() - (NACCOUNTS as usize / NTHREADS));
451
452                let join = thread::spawn(move || {
453                    console::log_1(
454                        &format!("hello from thread {:?}", thread::current().id()).into(),
455                    );
456
457                    let hash = accounts.iter().map(|a| a.hash()).collect::<Vec<_>>();
458
459                    console::log_1(
460                        &format!("ending from thread {:?}", thread::current().id()).into(),
461                    );
462
463                    hash.len()
464                });
465
466                joins.push(join);
467            }
468
469            let nhashes: usize = joins.into_iter().map(|j| j.join().unwrap()).sum();
470
471            assert_eq!(nhashes, NACCOUNTS as usize);
472
473            let end = performance_now();
474
475            console::log_1(
476                &format!(
477                    "nhashes={:?} nthreads={:?} time={:?}",
478                    nhashes,
479                    NTHREADS,
480                    perf_to_duration(end - start)
481                )
482                .into(),
483            );
484            console::time_end_with_label("threads");
485        });
486    }
487
488    #[cfg(target_family = "wasm")]
489    #[test]
490    fn test_hashing_tree() {
491        use web_sys::console;
492
493        const NACCOUNTS: u64 = 1_000;
494
495        console::time_with_label("generate random accounts");
496
497        let mut db = Database::<V2>::create(20, false);
498
499        console::log_1(&format!("{:?} accounts in nodejs", NACCOUNTS).into());
500
501        let accounts = (0..NACCOUNTS).map(|_| Account::rand()).collect::<Vec<_>>();
502
503        for (index, mut account) in accounts.into_iter().enumerate() {
504            account.token_id = TokenId::from(index as u64);
505            let id = account.id();
506            db.get_or_create_account(id, account).unwrap();
507        }
508
509        console::time_end_with_label("generate random accounts");
510        assert_eq!(db.naccounts(), NACCOUNTS as usize);
511
512        console::time_with_label("compute merkle root");
513        db.merkle_root();
514
515        console::time_end_with_label("compute merkle root");
516    }
517
518    #[cfg(not(target_family = "wasm"))]
519    #[test]
520    fn test_hashing_tree() {
521        const NACCOUNTS: u64 = 1_000;
522
523        let now = redux::Instant::now();
524        let mut db = Database::<V2>::create(20);
525
526        elog!("{:?} accounts natively", NACCOUNTS);
527
528        let accounts = (0..NACCOUNTS).map(|_| Account::rand()).collect::<Vec<_>>();
529
530        for (index, mut account) in accounts.into_iter().enumerate() {
531            account.token_id = TokenId::from(index as u64);
532            let id = account.id();
533            db.get_or_create_account(id, account).unwrap();
534        }
535
536        elog!("generate random accounts {:?}", now.elapsed());
537        assert_eq!(db.naccounts(), NACCOUNTS as usize);
538
539        let now = redux::Instant::now();
540        db.merkle_root();
541        elog!("compute merkle root {:?}", now.elapsed());
542    }
543
544    #[test]
545    fn test_legacy_hash_empty() {
546        let account_empty_hash = account_empty_legacy_hash();
547        assert_eq!(
548            account_empty_hash.to_hex(),
549            "70ccdba14f829608e59a37ed98ffcaeef06dad928d568a9adbde13e3dd104a20"
550        );
551
552        for (height, s) in [
553            (
554                0,
555                "70ccdba14f829608e59a37ed98ffcaeef06dad928d568a9adbde13e3dd104a20",
556            ),
557            (
558                5,
559                "4590712e4bd873ba93d01b665940e0edc48db1a7c90859948b7799f45a443b15",
560            ),
561            (
562                10,
563                "ba083b16b757794c81233d4ebf1ab000ba4a174a8174c1e8ee8bf0846ec2e10d",
564            ),
565            (
566                11,
567                "5d65e7d5f4c5441ac614769b913400aa3201f3bf9c0f33441dbf0a33a1239822",
568            ),
569            (
570                100,
571                "0e4ecb6104658cf8c06fca64f7f1cb3b0f1a830ab50c8c7ed9de544b8e6b2530",
572            ),
573            (
574                2000,
575                "b05105f8281f75efaf3c6b324563685c8be3a01b1c7d3f314ae733d869d95209",
576            ),
577        ] {
578            let hash = V1::empty_hash_at_height(height);
579            assert_eq!(hash.to_hex(), s, "invalid hash at depth={:?}", height);
580        }
581    }
582
583    #[test]
584    fn test_hash_empty() {
585        let heights = [0, 5, 10, 11];
586
587        let hexs = [
588            "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
589            "d305ebed68f3d4ff16cfc9c6857c274bfbd4a5e83db6fb26e009f75711005524",
590            "bfae9c6290bcc9cf282889c6b880e4eac236d4e50b22395639731e1465939915",
591            "def7de4e2f2f13aa638f5671eccf9367ab9d39ae49ed683fca0169b33b31c416",
592        ];
593
594        let result: Vec<_> = heights
595            .iter()
596            .map(|height| V2::empty_hash_at_height(*height).to_hex())
597            .collect();
598
599        assert_eq!(result, hexs);
600
601        let account_empty_hash = Account::empty().hash();
602        assert_eq!(account_empty_hash.to_hex(), hexs[0]);
603    }
604
605    // /// An empty tree produces the same hash than a tree full of empty accounts
606    // #[test]
607    // fn test_root_hash_v2() {
608    //     let mut db = Database::<V2>::create(4);
609    //     for _ in 0..16 {
610    //         db.create_account((), Account::empty()).unwrap();
611    //     }
612    //     assert_eq!(
613    //         db.create_account((), Account::empty()).unwrap_err(),
614    //         DatabaseError::OutOfLeaves
615    //     );
616    //     let hash = db.root_hash();
617    //     elog!("ROOT_HASH={:?}", hash.to_string());
618    //     assert_eq!(
619    //         hash.to_hex(),
620    //         "169bada2f4bb2ea2b8189f47cf2b665e3e0fb135233242ae1b52794eb3fe7924"
621    //     );
622
623    //     let mut db = Database::<V2>::create(4);
624    //     for _ in 0..1 {
625    //         db.create_account((), Account::empty()).unwrap();
626    //     }
627    //     let hash = db.root_hash();
628    //     assert_eq!(
629    //         hash.to_hex(),
630    //         "169bada2f4bb2ea2b8189f47cf2b665e3e0fb135233242ae1b52794eb3fe7924"
631    //     );
632
633    //     let db = Database::<V2>::create(4);
634    //     let hash = db.root_hash();
635    //     assert_eq!(
636    //         hash.to_hex(),
637    //         "169bada2f4bb2ea2b8189f47cf2b665e3e0fb135233242ae1b52794eb3fe7924"
638    //     );
639    // }
640
641    /// Accounts inserted in a different order produce different root hash
642    #[test]
643    fn test_root_hash_different_orders() {
644        let mut db = Database::<V2>::create(4);
645
646        let accounts = (0..16).map(|_| Account::rand()).collect::<Vec<_>>();
647
648        for account in &accounts {
649            db.get_or_create_account(account.id(), account.clone())
650                .unwrap();
651        }
652        let root_hash_1 = db.merkle_root();
653
654        let mut db = Database::<V2>::create(4);
655        for account in accounts.iter().rev() {
656            db.get_or_create_account(account.id(), account.clone())
657                .unwrap();
658        }
659        let root_hash_2 = db.merkle_root();
660
661        // Different orders, different root hash
662        assert_ne!(root_hash_1, root_hash_2);
663
664        let mut db = Database::<V2>::create(4);
665        for account in accounts {
666            db.get_or_create_account(account.id(), account).unwrap();
667        }
668        let root_hash_3 = db.merkle_root();
669
670        // Same orders, same root hash
671        assert_eq!(root_hash_1, root_hash_3);
672    }
673
674    // /// An empty tree produces the same hash than a tree full of empty accounts
675    // #[test]
676    // fn test_root_hash_legacy() {
677    //     let mut db = Database::<V1>::create(4);
678    //     for _ in 0..16 {
679    //         db.create_account((), AccountLegacy::empty()).unwrap();
680    //     }
681    //     assert_eq!(
682    //         db.create_account((), AccountLegacy::empty()).unwrap_err(),
683    //         DatabaseError::OutOfLeaves
684    //     );
685    //     let hash = db.root_hash();
686    //     assert_eq!(
687    //         hash.to_hex(),
688    //         "2db7d27130b6fe46b95541a70bc69ac51d9ea02825f7a7ab41ec4c414989421e"
689    //     );
690
691    //     let mut db = Database::<V1>::create(4);
692    //     for _ in 0..1 {
693    //         db.create_account((), AccountLegacy::empty()).unwrap();
694    //     }
695    //     let hash = db.root_hash();
696    //     assert_eq!(
697    //         hash.to_hex(),
698    //         "2db7d27130b6fe46b95541a70bc69ac51d9ea02825f7a7ab41ec4c414989421e"
699    //     );
700
701    //     let db = Database::<V1>::create(4);
702    //     let hash = db.root_hash();
703    //     assert_eq!(
704    //         hash.to_hex(),
705    //         "2db7d27130b6fe46b95541a70bc69ac51d9ea02825f7a7ab41ec4c414989421e"
706    //     );
707    // }
708}
709
710#[cfg(test)]
711mod tests_ocaml {
712    use std::ops::ControlFlow;
713
714    use o1_utils::FieldHelpers;
715    use rand::Rng;
716
717    #[cfg(target_family = "wasm")]
718    use wasm_bindgen_test::wasm_bindgen_test as test;
719
720    use crate::scan_state::currency::Balance;
721
722    use super::*;
723
724    // "add and retrieve an account"
725    #[test]
726    fn test_add_retrieve_account() {
727        let mut db = Database::<V2>::create(4);
728
729        let account = Account::rand();
730        let location = db
731            .get_or_create_account(account.id(), account.clone())
732            .unwrap();
733        let get_account = db.get(location.addr()).unwrap();
734
735        assert_eq!(account, *get_account);
736    }
737
738    // "accounts are atomic"
739    #[test]
740    fn test_accounts_are_atomic() {
741        let mut db = Database::<V2>::create(4);
742
743        let account = Box::new(Account::rand());
744        let location: Address = db
745            .get_or_create_account(account.id(), *account.clone())
746            .unwrap()
747            .addr();
748
749        db.set(location.clone(), account.clone());
750        let loc = db.location_of_account(&account.id()).unwrap();
751
752        assert_eq!(location, loc);
753        assert_eq!(db.get(location), db.get(loc));
754    }
755
756    // "length"
757    #[test]
758    fn test_lengths() {
759        for naccounts in 50..100 {
760            let mut db = Database::<V2>::create(10);
761            let mut unique = HashSet::with_capacity(naccounts);
762
763            for _ in 0..naccounts {
764                let account = loop {
765                    let account = Account::rand();
766                    if unique.insert(account.id()) {
767                        break account;
768                    }
769                };
770
771                db.get_or_create_account(account.id(), account).unwrap();
772            }
773
774            assert_eq!(db.num_accounts(), naccounts);
775        }
776    }
777
778    // "get_or_create_acount does not update an account if key already""
779    #[test]
780    fn test_no_update_if_exist() {
781        let mut db = Database::<V2>::create(10);
782
783        let mut account1 = Account::rand();
784        account1.balance = Balance::from_u64(100);
785
786        let location1 = db
787            .get_or_create_account(account1.id(), account1.clone())
788            .unwrap();
789
790        let mut account2 = account1;
791        account2.balance = Balance::from_u64(200);
792
793        let location2 = db
794            .get_or_create_account(account2.id(), account2.clone())
795            .unwrap();
796
797        let addr1: Address = location1.clone().addr();
798        let addr2: Address = location2.clone().addr();
799
800        assert_eq!(addr1, addr2);
801        assert!(matches!(location2, GetOrCreated::Existed(_)));
802        assert_ne!(*db.get(location1.addr()).unwrap(), account2);
803    }
804
805    // "get_or_create_account t account = location_of_account account.key"
806    #[test]
807    fn test_location_of_account() {
808        for naccounts in 50..100 {
809            let mut db = Database::<V2>::create(10);
810
811            for _ in 0..naccounts {
812                let account = Account::rand();
813
814                let account_id = account.id();
815                let location = db
816                    .get_or_create_account(account_id.clone(), account)
817                    .unwrap();
818                let addr: Address = location.addr();
819
820                assert_eq!(addr, db.location_of_account(&account_id).unwrap());
821            }
822        }
823    }
824
825    // "set_inner_hash_at_addr_exn(address,hash);
826    //  get_inner_hash_at_addr_exn(address) = hash"
827    #[test]
828    fn test_set_inner_hash() {
829        // TODO
830    }
831
832    fn create_full_db(depth: usize) -> Database<V2> {
833        let mut db = Database::<V2>::create(depth as u8);
834
835        for _ in 0..2u64.pow(depth as u32) {
836            let account = Account::rand();
837            db.get_or_create_account(account.id(), account).unwrap();
838        }
839
840        db
841    }
842
843    // "set_inner_hash_at_addr_exn(address,hash);
844    //  get_inner_hash_at_addr_exn(address) = hash"
845    #[test]
846    fn test_get_set_all_same_root_hash() {
847        let mut db = create_full_db(7);
848
849        let merkle_root1 = db.merkle_root();
850        let root = Address::root();
851
852        let accounts = db.get_all_accounts_rooted_at(root.clone()).unwrap();
853        let accounts = accounts.into_iter().map(|acc| acc.1).collect::<Vec<_>>();
854        db.set_all_accounts_rooted_at(root, &accounts).unwrap();
855
856        let merkle_root2 = db.merkle_root();
857
858        assert_eq!(merkle_root1, merkle_root2);
859    }
860
861    // "set_inner_hash_at_addr_exn(address,hash);
862    //  get_inner_hash_at_addr_exn(address) = hash"
863    #[test]
864    fn test_set_batch_accounts_change_root_hash() {
865        const DEPTH: usize = 7;
866
867        for _ in 0..5 {
868            let mut db = create_full_db(DEPTH);
869
870            let addr = Address::rand_nonleaf(DEPTH);
871            let children = addr.iter_children(DEPTH);
872            let accounts = children
873                .map(|addr| (addr, Box::new(Account::rand())))
874                .collect::<Vec<_>>();
875
876            let merkle_root1 = db.merkle_root();
877            elog!("naccounts={:?}", accounts.len());
878            db.set_batch_accounts(&accounts);
879            let merkle_root2 = db.merkle_root();
880
881            assert_ne!(merkle_root1, merkle_root2);
882        }
883    }
884
885    // "We can retrieve accounts by their by key after using
886    //  set_batch_accounts""
887    #[test]
888    fn test_retrieve_account_after_set_batch() {
889        const DEPTH: usize = 7;
890
891        let mut db = Database::<V2>::create(DEPTH as u8);
892
893        let mut addr = Address::root();
894        for _ in 0..63 {
895            let account = Account::rand();
896            addr = db
897                .get_or_create_account(account.id(), account)
898                .unwrap()
899                .addr();
900        }
901
902        let last_location = db.last_filled().unwrap();
903        assert_eq!(addr, last_location);
904
905        let mut accounts = Vec::with_capacity(2u64.pow(DEPTH as u32) as usize);
906
907        while let Some(next_addr) = addr.next() {
908            accounts.push((next_addr.clone(), Box::new(Account::rand())));
909            addr = next_addr;
910        }
911
912        db.set_batch_accounts(&accounts);
913
914        for (addr, account) in &accounts {
915            let account_id = account.id();
916            let location = db.location_of_account(&account_id).unwrap();
917            let queried_account = db.get(location.clone()).unwrap();
918
919            assert_eq!(*addr, location);
920            assert_eq!(account, &queried_account);
921        }
922
923        let expected_last_location = last_location.to_index().0 + accounts.len() as u64;
924        let actual_last_location = db.last_filled().unwrap().to_index().0;
925
926        assert_eq!(expected_last_location, actual_last_location);
927    }
928
929    // "If the entire database is full,
930    //  set_all_accounts_rooted_at_exn(address,accounts);get_all_accounts_rooted_at_exn(address)
931    //  = accounts"
932    #[test]
933    fn test_set_accounts_rooted_equal_get_accounts_rooted() {
934        const DEPTH: usize = 7;
935
936        let mut db = create_full_db(DEPTH);
937
938        for _ in 0..5 {
939            let addr = Address::rand_nonleaf(DEPTH);
940            let children = addr.iter_children(DEPTH);
941            let accounts = children
942                .map(|_| Box::new(Account::rand()))
943                .collect::<Vec<_>>();
944
945            db.set_all_accounts_rooted_at(addr.clone(), &accounts)
946                .unwrap();
947            let list = db
948                .get_all_accounts_rooted_at(addr)
949                .unwrap()
950                .into_iter()
951                .map(|(_, acc)| acc)
952                .collect::<Vec<_>>();
953
954            assert!(!accounts.is_empty());
955            assert_eq!(accounts, list);
956        }
957    }
958
959    // "create_empty doesn't modify the hash"
960    #[test]
961    fn test_create_empty_doesnt_modify_hash() {
962        const DEPTH: usize = 7;
963
964        let mut db = Database::<V2>::create(DEPTH as u8);
965
966        let start_hash = db.merkle_root();
967
968        let account = Account::empty();
969        assert!(matches!(
970            db.get_or_create_account(account.id(), account).unwrap(),
971            GetOrCreated::Added(_)
972        ));
973
974        assert_eq!(start_hash, db.merkle_root());
975    }
976
977    // "get_at_index_exn t (index_of_account_exn t public_key) =
978    // account"
979    #[test]
980    fn test_get_indexed() {
981        const DEPTH: usize = 7;
982        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
983
984        let mut db = Database::<V2>::create(DEPTH as u8);
985        let mut accounts = Vec::with_capacity(NACCOUNTS);
986
987        for _ in 0..NACCOUNTS {
988            let account = Account::rand();
989            accounts.push(account.clone());
990            db.get_or_create_account(account.id(), account).unwrap();
991        }
992
993        for account in accounts {
994            let account_id = account.id();
995            let index_of_account = db.index_of_account(account_id).unwrap();
996            let indexed_account = db.get_at_index(index_of_account).unwrap();
997            assert_eq!(account, *indexed_account);
998        }
999    }
1000
1001    // "set_at_index_exn t index  account; get_at_index_exn t
1002    // index = account"
1003    #[test]
1004    fn test_set_get_indexed_equal() {
1005        const DEPTH: usize = 7;
1006        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1007
1008        let mut db = create_full_db(DEPTH);
1009
1010        for _ in 0..50 {
1011            let account = Box::new(Account::rand());
1012            let index = rand::thread_rng().gen_range(0..NACCOUNTS);
1013            let index = AccountIndex(index as u64);
1014
1015            db.set_at_index(index, account.clone()).unwrap();
1016            let at_index = db.get_at_index(index).unwrap();
1017            assert_eq!(account, at_index);
1018        }
1019    }
1020
1021    // "iter"
1022    #[test]
1023    fn test_iter() {
1024        const DEPTH: usize = 7;
1025        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1026
1027        let mut db = Database::<V2>::create(DEPTH as u8);
1028        let mut accounts = Vec::with_capacity(NACCOUNTS);
1029
1030        for _ in 0..NACCOUNTS {
1031            let account = Account::rand();
1032            accounts.push(account.clone());
1033            db.get_or_create_account(account.id(), account).unwrap();
1034        }
1035
1036        assert_eq!(accounts, db.to_list(),)
1037    }
1038
1039    // "Add 2^d accounts (for testing, d is small)"
1040    #[test]
1041    fn test_retrieve() {
1042        const DEPTH: usize = 7;
1043        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1044
1045        let mut db = Database::<V2>::create(DEPTH as u8);
1046        let mut accounts = Vec::with_capacity(NACCOUNTS);
1047
1048        for _ in 0..NACCOUNTS {
1049            let account = Box::new(Account::rand());
1050            accounts.push(account.clone());
1051            db.get_or_create_account(account.id(), *account).unwrap();
1052        }
1053
1054        let retrieved = db
1055            .get_all_accounts_rooted_at(Address::root())
1056            .unwrap()
1057            .into_iter()
1058            .map(|(_, acc)| acc)
1059            .collect::<Vec<_>>();
1060
1061        assert_eq!(accounts, retrieved);
1062    }
1063
1064    // "removing accounts restores Merkle root"
1065    #[test]
1066    fn test_remove_restore_root_hash() {
1067        const DEPTH: usize = 7;
1068        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1069
1070        let mut db = Database::<V2>::create(DEPTH as u8);
1071
1072        let root_hash = db.merkle_root();
1073
1074        let mut accounts = Vec::with_capacity(NACCOUNTS);
1075
1076        for _ in 0..NACCOUNTS {
1077            let account = Account::rand();
1078            accounts.push(account.id());
1079            db.get_or_create_account(account.id(), account).unwrap();
1080        }
1081        assert_ne!(root_hash, db.merkle_root());
1082
1083        db.remove_accounts(&accounts);
1084        assert_eq!(root_hash, db.merkle_root());
1085    }
1086
1087    // "fold over account balances"
1088    #[test]
1089    fn test_fold_over_account_balance() {
1090        const DEPTH: usize = 7;
1091        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1092
1093        let mut db = Database::<V2>::create(DEPTH as u8);
1094        let mut total_balance: u128 = 0;
1095
1096        for _ in 0..NACCOUNTS {
1097            let account = Account::rand();
1098            total_balance += account.balance.as_u64() as u128;
1099            db.get_or_create_account(account.id(), account).unwrap();
1100        }
1101
1102        let retrieved = db.fold(0u128, |acc, account| acc + account.balance.as_u64() as u128);
1103        assert_eq!(total_balance, retrieved);
1104    }
1105
1106    // "fold_until over account balances"
1107    #[test]
1108    fn test_fold_until_over_account_balance() {
1109        const DEPTH: usize = 7;
1110        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1111
1112        let mut db = Database::<V2>::create(DEPTH as u8);
1113        let mut total_balance: u128 = 0;
1114        let mut last_id: AccountId = Account::empty().id();
1115
1116        for i in 0..NACCOUNTS {
1117            let account = Account::rand();
1118            if i <= 30 {
1119                total_balance += account.balance.as_u64() as u128;
1120                last_id = account.id();
1121            }
1122            db.get_or_create_account(account.id(), account).unwrap();
1123        }
1124
1125        let retrieved = db.fold_until(0u128, |mut acc, account| {
1126            acc += account.balance.as_u64() as u128;
1127
1128            if account.id() != last_id {
1129                ControlFlow::Continue(acc)
1130            } else {
1131                ControlFlow::Break(acc)
1132            }
1133        });
1134
1135        assert_eq!(total_balance, retrieved);
1136    }
1137
1138    #[test]
1139    fn test_merkle_path_long() {
1140        const DEPTH: usize = 4;
1141        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1142
1143        let mut db = Database::<V2>::create(DEPTH as u8);
1144
1145        for index in 0..NACCOUNTS / 2 {
1146            let mut account = Account::empty();
1147            account.token_id = TokenId::from(index as u64);
1148
1149            // elog!("account{}={}", index, account.hash().to_hex());
1150
1151            let res = db.get_or_create_account(account.id(), account).unwrap();
1152            assert!(matches!(res, GetOrCreated::Added(_)));
1153        }
1154
1155        elog!("naccounts={:?}", db.last_filled());
1156
1157        let expected = [
1158            &[
1159                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1160                "19c428e06065374dcdbb9c2773d59c14a4bc5322b821b616f5ad8b95e3fce83c",
1161                "277bb79d5e2b48e92cf9e3cf169eccf199e66b1b611765bdd190ad914d50f138",
1162                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1163            ][..],
1164            &[
1165                "ea3278ff7f5c0472163846755a94643f9dea2babe2d25848294fd727d83a6630",
1166                "19c428e06065374dcdbb9c2773d59c14a4bc5322b821b616f5ad8b95e3fce83c",
1167                "277bb79d5e2b48e92cf9e3cf169eccf199e66b1b611765bdd190ad914d50f138",
1168                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1169            ][..],
1170            &[
1171                "9c461cf909421302a96f3794f198bae68d14eb542cfdae3c5942d61211cdbc3c",
1172                "c9c043aa20b69f061a06bf27e19e6c7a7c2cb94a5022a614ebfb9209cda11527",
1173                "277bb79d5e2b48e92cf9e3cf169eccf199e66b1b611765bdd190ad914d50f138",
1174                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1175            ][..],
1176            &[
1177                "225381a665a6c436f0750ce907b8077ae3670b17af0acee4a3eb98569692dd10",
1178                "c9c043aa20b69f061a06bf27e19e6c7a7c2cb94a5022a614ebfb9209cda11527",
1179                "277bb79d5e2b48e92cf9e3cf169eccf199e66b1b611765bdd190ad914d50f138",
1180                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1181            ][..],
1182            &[
1183                "6224d72dc65c9b89d5717cb43b9de5a31763192dbe316f46bb0ed2486c46d50a",
1184                "16b9cac5d2aa4e87c46520d88df96ddb6da7e2f52e23ec406fce9a06d3654f10",
1185                "a4c190a90cddf828af5c87b2b9278da29fdf46bab27642c553f281c4cb25ca1f",
1186                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1187            ][..],
1188            &[
1189                "1b1edf8a2bc43639f2dd7fbffc953a5887ca8e2f57afe2474b293e00a0c8fd13",
1190                "16b9cac5d2aa4e87c46520d88df96ddb6da7e2f52e23ec406fce9a06d3654f10",
1191                "a4c190a90cddf828af5c87b2b9278da29fdf46bab27642c553f281c4cb25ca1f",
1192                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1193            ][..],
1194            &[
1195                "bd649e2c20b743b9ecc6235f06016b4aa1263ee7cd6af77afb5358c60ca9143e",
1196                "2580091fe2ab125a78a5d8df8c017d1a0f588b871f50a2a34cd383df3d647503",
1197                "a4c190a90cddf828af5c87b2b9278da29fdf46bab27642c553f281c4cb25ca1f",
1198                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1199            ][..],
1200            &[
1201                "2834b7e93942f095625b96ce9b6b709934bbdd35bc5762f6493db73dd84b242c",
1202                "2580091fe2ab125a78a5d8df8c017d1a0f588b871f50a2a34cd383df3d647503",
1203                "a4c190a90cddf828af5c87b2b9278da29fdf46bab27642c553f281c4cb25ca1f",
1204                "63f92c64075ae8ef4d076fc7d6743e758513e7b958a4d7a6cb6744eda019d019",
1205            ][..],
1206            &[
1207                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1208                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1209                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1210                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1211            ][..],
1212            &[
1213                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1214                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1215                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1216                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1217            ][..],
1218            &[
1219                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1220                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1221                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1222                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1223            ][..],
1224            &[
1225                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1226                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1227                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1228                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1229            ][..],
1230            &[
1231                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1232                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1233                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1234                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1235            ][..],
1236            &[
1237                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1238                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1239                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1240                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1241            ][..],
1242            &[
1243                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1244                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1245                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1246                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1247            ][..],
1248            &[
1249                "f3ee39f42a7b2cac196c8eb1c9fe00f853678c920c0c9ce3724c0b7fe911c731",
1250                "64ea581ca7a7aef2b78d04e4a64d0df1da1aa5c2d32a2a34c3c8d50a2c932f07",
1251                "358495ff9f624ba2ea37d0890b8c14079fb16e3626bed5ff0447ee10ecf5f30f",
1252                "c1da0c74de92bf4c1ae893b0f70524a9c6ff4a7ad754e0fc64f5e00548b4cd3d",
1253            ][..],
1254        ];
1255
1256        let mut hashes = Vec::with_capacity(100);
1257
1258        let root = Address::root();
1259        let nchild = root.iter_children(DEPTH);
1260
1261        for child in nchild {
1262            let path = db.merkle_path(child);
1263            let path = path.iter().map(|p| p.hash().to_hex()).collect::<Vec<_>>();
1264            hashes.push(path);
1265        }
1266
1267        // elog!("expected={:#?}", expected);
1268        // elog!("computed={:#?}", hashes);
1269
1270        assert_eq!(&expected[..], hashes.as_slice());
1271    }
1272
1273    // "fold_until over account balances"
1274    #[test]
1275    fn test_merkle_path_test2() {
1276        const DEPTH: usize = 20;
1277        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1278
1279        let mut db = Database::<V2>::create(DEPTH as u8);
1280        db.merkle_path(Address::first(20));
1281    }
1282
1283    // "fold_until over account balances"
1284    // #[test]
1285    fn test_merkle_path_test() {
1286        const DEPTH: usize = 4;
1287        const NACCOUNTS: usize = 2u64.pow(DEPTH as u32) as usize;
1288
1289        elog!("empty={}", Account::empty().hash());
1290        elog!("height1={}", V2::empty_hash_at_height(1));
1291        elog!("height2={}", V2::empty_hash_at_height(2));
1292        elog!("height3={}", V2::empty_hash_at_height(3));
1293        elog!("height4={}", V2::empty_hash_at_height(4));
1294
1295        // let db = Database::<V2>::create(DEPTH as u8);
1296        // db.merkle_root();
1297        // db.merkle_path(Address::first(DEPTH));
1298
1299        // elog!("WITH_ACC");
1300
1301        // let mut db = Database::<V2>::create(DEPTH as u8);
1302        // let mut account = Account::empty();
1303        // account.token_symbol = "seb".to_string();
1304        // db.get_or_create_account(account.id(), account).unwrap();
1305        // db.merkle_root();
1306
1307        let mut db = Database::<V2>::create(DEPTH as u8);
1308
1309        // for _ in 0..NACCOUNTS {
1310        //     let account = Account::rand();
1311        //     db.get_or_create_account(account.id(), account).unwrap();
1312        // }
1313
1314        db.merkle_root();
1315
1316        db.merkle_path(Address::first(DEPTH));
1317
1318        // elog!(
1319        //     "INNER_AT_0={}",
1320        //     db.get_inner_hash_at_addr(Address::try_from("0000").unwrap())
1321        //         .unwrap()
1322        // );
1323        // elog!(
1324        //     "INNER_AT_0={}",
1325        //     db.get_inner_hash_at_addr(Address::try_from("0001").unwrap())
1326        //         .unwrap()
1327        // );
1328        // elog!(
1329        //     "INNER_AT_0={}",
1330        //     db.get_inner_hash_at_addr(Address::try_from("0010").unwrap())
1331        //         .unwrap()
1332        // );
1333        // elog!(
1334        //     "INNER_AT_0={}",
1335        //     db.get_inner_hash_at_addr(Address::try_from("0101").unwrap())
1336        //         .unwrap()
1337        // );
1338
1339        // elog!("A");
1340        // elog!(
1341        //     "INNER_AT_3={}",
1342        //     db.get_inner_hash_at_addr(Address::try_from("000").unwrap())
1343        //         .unwrap()
1344        // );
1345        // elog!(
1346        //     "INNER_AT_3={}",
1347        //     db.get_inner_hash_at_addr(Address::try_from("001").unwrap())
1348        //         .unwrap()
1349        // );
1350        // elog!(
1351        //     "INNER_AT_3={}",
1352        //     db.get_inner_hash_at_addr(Address::try_from("010").unwrap())
1353        //         .unwrap()
1354        // );
1355        // elog!(
1356        //     "INNER_AT_3={}",
1357        //     db.get_inner_hash_at_addr(Address::try_from("101").unwrap())
1358        //         .unwrap()
1359        // );
1360
1361        // elog!("A");
1362        // elog!(
1363        //     "INNER_AT_2={}",
1364        //     db.get_inner_hash_at_addr(Address::try_from("10").unwrap())
1365        //         .unwrap()
1366        // );
1367        // elog!(
1368        //     "INNER_AT_2={}",
1369        //     db.get_inner_hash_at_addr(Address::try_from("01").unwrap())
1370        //         .unwrap()
1371        // );
1372
1373        // elog!("A");
1374        // elog!(
1375        //     "INNER_AT_1={}",
1376        //     db.get_inner_hash_at_addr(Address::try_from("1").unwrap())
1377        //         .unwrap()
1378        // );
1379        // elog!(
1380        //     "INNER_AT_1={}",
1381        //     db.get_inner_hash_at_addr(Address::try_from("0").unwrap())
1382        //         .unwrap()
1383        // );
1384
1385        // elog!("A");
1386        // elog!(
1387        //     "INNER_AT_0={}",
1388        //     db.get_inner_hash_at_addr(Address::try_from("").unwrap())
1389        //         .unwrap()
1390        // );
1391    }
1392}