diff --git a/src/contract/money/src/entrypoint/fee_v1.rs b/src/contract/money/src/entrypoint/fee_v1.rs index 2b9c05461..4bd5a1ab2 100644 --- a/src/contract/money/src/entrypoint/fee_v1.rs +++ b/src/contract/money/src/entrypoint/fee_v1.rs @@ -18,12 +18,19 @@ use darkfi_sdk::{ crypto::{ - pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, MerkleNode, PublicKey, + pasta_prelude::*, + pedersen_commitment_u64, poseidon_hash, + smt::{ + wasmdb::{SmtWasmDbStorage, SmtWasmFp}, + PoseidonFp, EMPTY_NODES_FP, + }, + ContractId, MerkleNode, PublicKey, }, dark_tree::DarkLeaf, db::{db_contains_key, db_get, db_lookup, db_set}, error::{ContractError, ContractResult}, - merkle_add, msg, + merkle::{merkle_add, sparse_merkle_insert_batch}, + msg, pasta::pallas, ContractCall, }; @@ -131,8 +138,13 @@ pub(crate) fn money_fee_process_instruction_v1( return Err(MoneyError::CoinMerkleRootNotFound.into()) } + let hasher = PoseidonFp::new(); + let empty_leaf = pallas::Base::ZERO; + let smt_store = SmtWasmDbStorage::new(nullifiers_db); + let smt = SmtWasmFp::new(smt_store, hasher, &EMPTY_NODES_FP); + // The nullifiers should not already exist. It is the double-spend protection. - if db_contains_key(nullifiers_db, &serialize(¶ms.input.nullifier))? { + if smt.get_leaf(¶ms.input.nullifier.inner()) != empty_leaf { msg!("[FeeV1] Error: Duplicate nullifier found"); return Err(MoneyError::DuplicateNullifier.into()) } @@ -195,7 +207,9 @@ pub(crate) fn money_fee_process_update_v1( let coin_roots_db = db_lookup(cid, MONEY_CONTRACT_COIN_ROOTS_TREE)?; db_set(info_db, MONEY_CONTRACT_TOTAL_FEES_PAID, &serialize(&update.fee))?; - db_set(nullifiers_db, &serialize(&update.nullifier), &[])?; + + sparse_merkle_insert_batch(nullifiers_db, &[update.nullifier.inner()])?; + db_set(coins_db, &serialize(&update.coin), &[])?; merkle_add( diff --git a/src/contract/money/src/entrypoint/swap_v1.rs b/src/contract/money/src/entrypoint/swap_v1.rs index d411a8d02..79b4622c5 100644 --- a/src/contract/money/src/entrypoint/swap_v1.rs +++ b/src/contract/money/src/entrypoint/swap_v1.rs @@ -17,11 +17,20 @@ */ use darkfi_sdk::{ - crypto::ContractId, + crypto::{ + pasta_prelude::*, + smt::{ + wasmdb::{SmtWasmDbStorage, SmtWasmFp}, + PoseidonFp, EMPTY_NODES_FP, + }, + ContractId, + }, dark_tree::DarkLeaf, db::{db_contains_key, db_lookup}, error::{ContractError, ContractResult}, - msg, ContractCall, + msg, + pasta::pallas, + ContractCall, }; use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; @@ -100,6 +109,11 @@ pub(crate) fn money_otcswap_process_instruction_v1( return Err(MoneyError::TokenMismatch.into()) } + let hasher = PoseidonFp::new(); + let empty_leaf = pallas::Base::ZERO; + let smt_store = SmtWasmDbStorage::new(nullifiers_db); + let smt = SmtWasmFp::new(smt_store, hasher, &EMPTY_NODES_FP); + msg!("[OtcSwapV1] Iterating over anonymous inputs"); for (i, input) in params.inputs.iter().enumerate() { // For now, make sure that the inputs' spend hooks are zero. @@ -119,7 +133,7 @@ pub(crate) fn money_otcswap_process_instruction_v1( // The nullifiers should not already exist. It is the double-spend protection. if new_nullifiers.contains(&input.nullifier) || - db_contains_key(nullifiers_db, &serialize(&input.nullifier))? + smt.get_leaf(&input.nullifier.inner()) != empty_leaf { msg!("[OtcSwapV1] Error: Duplicate nullifier found in input {}", i); return Err(MoneyError::DuplicateNullifier.into())