darkfi_sdk/crypto/smt/
wasmdb.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19use num_bigint::BigUint;
20
21use super::{PoseidonFp, SparseMerkleTree, StorageAdapter, SMT_FP_DEPTH};
22use crate::{
23    crypto::pasta_prelude::*,
24    error::ContractResult,
25    msg,
26    pasta::pallas,
27    wasm::db::{db_del, db_get, db_set, DbHandle},
28};
29
30pub type SmtWasmFp = SparseMerkleTree<
31    'static,
32    SMT_FP_DEPTH,
33    { SMT_FP_DEPTH + 1 },
34    pallas::Base,
35    PoseidonFp,
36    SmtWasmDbStorage,
37>;
38
39pub struct SmtWasmDbStorage {
40    db: DbHandle,
41}
42
43impl SmtWasmDbStorage {
44    pub fn new(db: DbHandle) -> Self {
45        Self { db }
46    }
47}
48
49impl StorageAdapter for SmtWasmDbStorage {
50    type Value = pallas::Base;
51
52    fn put(&mut self, key: BigUint, value: pallas::Base) -> ContractResult {
53        db_set(self.db, &key.to_bytes_le(), &value.to_repr())
54    }
55
56    fn get(&self, key: &BigUint) -> Option<pallas::Base> {
57        let Ok(value) = db_get(self.db, &key.to_bytes_le()) else {
58            msg!("[WasmDbStorage] get() for DB failed");
59            return None
60        };
61
62        let value = value?;
63
64        let mut repr = [0; 32];
65        repr.copy_from_slice(&value);
66
67        pallas::Base::from_repr(repr).into()
68    }
69
70    fn del(&mut self, key: &BigUint) -> ContractResult {
71        db_del(self.db, &key.to_bytes_le())
72    }
73}