Просмотр исходного кода

fee/swap: migrate nullifiers to SMT to match money::transfer()

zero 2 лет назад
Родитель
Сommit
031aac7f65

+ 18 - 4
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(&params.input.nullifier))? {
+    if smt.get_leaf(&params.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(

+ 17 - 3
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())