Pārlūkot izejas kodu

Fixup rebase artifacts

parazyd 2 gadi atpakaļ
vecāks
revīzija
a516ec90e0

+ 2 - 2
bin/drk/src/dao.rs

@@ -1522,12 +1522,12 @@ impl Drk {
 
         let auth_calls = vec![
             DaoAuthCall {
-                contract_id: DAO_CONTRACT_ID.inner(),
+                contract_id: *DAO_CONTRACT_ID,
                 function_code: DaoFunction::AuthMoneyTransfer as u8,
                 auth_data: proposal_data,
             },
             DaoAuthCall {
-                contract_id: MONEY_CONTRACT_ID.inner(),
+                contract_id: *MONEY_CONTRACT_ID,
                 function_code: MoneyFunction::TransferV1 as u8,
                 auth_data: vec![],
             },

+ 8 - 12
bin/drk/src/money.rs

@@ -34,8 +34,8 @@ use darkfi_money_contract::{
 use darkfi_sdk::{
     bridgetree,
     crypto::{
-        note::AeadEncryptedNote, poseidon_hash, BaseBlind, FuncId, Keypair, MerkleNode, MerkleTree,
-        PublicKey, ScalarBlind, SecretKey, MONEY_CONTRACT_ID,
+        note::AeadEncryptedNote, BaseBlind, FuncId, Keypair, MerkleNode, MerkleTree, PublicKey,
+        ScalarBlind, SecretKey, MONEY_CONTRACT_ID,
     },
     pasta::pallas,
 };
@@ -453,6 +453,7 @@ impl Drk {
             };
             let secret: SecretKey = deserialize(secret_bytes)?;
 
+            // TODO: Remove from SQL store, can be derived ondemand
             let Value::Blob(ref nullifier_bytes) = row[10] else {
                 return Err(Error::ParseFailed("[get_coins] Nullifier bytes parsing failed"))
             };
@@ -477,7 +478,7 @@ impl Drk {
                 token_blind,
                 memo: memo.clone(),
             };
-            let owncoin = OwnCoin { coin, note, secret, nullifier, leaf_position };
+            let owncoin = OwnCoin { coin, note, secret, leaf_position };
 
             owncoins.push((owncoin, is_spent))
         }
@@ -701,13 +702,8 @@ impl Drk {
                     eprintln!("Witnessing coin in Merkle tree");
                     let leaf_position = tree.mark().unwrap();
 
-                    let owncoin = OwnCoin {
-                        coin: *coin,
-                        note: note.clone(),
-                        secret: *secret,
-                        nullifier: Nullifier::from(poseidon_hash([secret.inner(), coin.inner()])),
-                        leaf_position,
-                    };
+                    let owncoin =
+                        OwnCoin { coin: *coin, note: note.clone(), secret: *secret, leaf_position };
 
                     owncoins.push(owncoin);
                 }
@@ -757,7 +753,7 @@ impl Drk {
                 serialize(&owncoin.note.value_blind),
                 serialize(&owncoin.note.token_blind),
                 serialize(&owncoin.secret),
-                serialize(&owncoin.nullifier),
+                serialize(&owncoin.nullifier()),
                 serialize(&owncoin.leaf_position),
                 serialize(&owncoin.note.memo),
             ];
@@ -808,7 +804,7 @@ impl Drk {
         }
 
         for (coin, _) in self.get_coins(false).await? {
-            if nullifiers.contains(&coin.nullifier) {
+            if nullifiers.contains(&coin.nullifier()) {
                 if let Err(e) = self.mark_spent_coin(&coin.coin).await {
                     return Err(Error::RusqliteError(format!(
                         "[mark_spent_coins] Marking spent coin failed: {e:?}"

+ 1 - 1
bin/lilith/src/main.rs

@@ -182,7 +182,7 @@ impl Lilith {
             }
 
             // Don't refine nodes that we are already connected to.
-            if p2p.exists(&url).await {
+            if p2p.exists(url).await {
                 continue
             }
 

+ 1 - 1
src/contract/dao/src/entrypoint/exec.rs

@@ -100,7 +100,7 @@ pub(crate) fn dao_exec_process_instruction(
         // Auth modules should check the direct parent is DAO::exec().
         // Doing anything else is potentially risky.
 
-        let contract_id = child_call.contract_id.inner();
+        let contract_id = child_call.contract_id;
         let function_code = child_call.data[0];
 
         // Check they match the auth call spec

+ 1 - 1
src/contract/dao/src/model.rs

@@ -23,7 +23,7 @@ use darkfi_sdk::{
     crypto::{
         note::{AeadEncryptedNote, ElGamalEncryptedNote},
         pasta_prelude::*,
-        poseidon_hash, ContractId, MerkleNode, Nullifier, PublicKey, TokenId,
+        poseidon_hash, BaseBlind, ContractId, MerkleNode, PublicKey,
     },
     error::ContractError,
     pasta::pallas,

+ 8 - 149
src/contract/money/src/client/fee_v1.rs

@@ -16,172 +16,31 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use std::collections::HashMap;
-
 use darkfi::{
-    blockchain::BlockchainOverlayPtr,
-    tx::TransactionBuilder,
-    validator::verification::verify_transaction,
-    zk::{halo2::Value, Proof, ProvingKey, VerifyingKey, Witness, ZkCircuit},
+    zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
     zkas::ZkBinary,
-    ClientFailed, Result,
+    Result,
 };
 use darkfi_sdk::{
     bridgetree::{self, Hashable},
     crypto::{
-        note::AeadEncryptedNote,
-        pasta_prelude::{Curve, CurveAffine, Field},
-        pedersen_commitment_u64, poseidon_hash, BaseBlind, Blind, FuncId, Keypair, MerkleNode,
-        MerkleTree, PublicKey, ScalarBlind, SecretKey,
+        pasta_prelude::{Curve, CurveAffine},
+        pedersen_commitment_u64, poseidon_hash, BaseBlind, FuncId, MerkleNode, PublicKey,
+        ScalarBlind, SecretKey,
     },
     pasta::pallas,
 };
-use log::{error, info};
 use rand::rngs::OsRng;
 
 use crate::{
-    client::{compute_remainder_blind, Coin, MoneyNote, OwnCoin},
-    model::{
-        CoinAttributes, Input, MoneyFeeParamsV1, Nullifier, NullifierAttributes, Output,
-        DARK_TOKEN_ID,
-    },
+    client::{Coin, MoneyNote},
+    model::{CoinAttributes, Nullifier, NullifierAttributes},
 };
 
 /// Fixed gas used by the fee call.
 /// This is the minimum gas any fee-paying transaction will use.
 pub const FEE_CALL_GAS: u64 = 41_000_000;
 
-/// Append a fee-paying call to the given `TransactionBuilder`.
-///
-/// * `keypair`: Caller's keypair
-/// * `coin`: `OwnCoin` to use in this builder
-/// * `tree`: Merkle tree of coins used to create inclusion proofs
-/// * `fee_zkbin`: `Fee_V1` zkas circuit ZkBinary
-/// * `fee_pk`: `Fee_V1` zk circuit proving key
-/// * `tx_builder`: `TransactionBuilder of the tx we want to pay fee for
-/// * `overlay`: `BlockchainOverlayPtr` against which to verify the tx
-/// * `time_keeper`: `TimeKeeper` needed for tx verification
-/// * `verifying_keys`: ZK verifying keys needed for tx verification
-#[allow(clippy::too_many_arguments)]
-pub async fn append_fee_call(
-    keypair: &Keypair,
-    coin: &OwnCoin,
-    tree: MerkleTree,
-    fee_zkbin: &ZkBinary,
-    fee_pk: &ProvingKey,
-    tx_builder: &mut TransactionBuilder,
-    overlay: &BlockchainOverlayPtr,
-    verifying_block_height: u64,
-    verifying_keys: &mut HashMap<[u8; 32], HashMap<String, VerifyingKey>>,
-) -> Result<(MoneyFeeParamsV1, FeeCallSecrets)> {
-    assert!(coin.note.value > 0);
-    assert_eq!(coin.note.token_id, *DARK_TOKEN_ID);
-    assert_eq!(coin.note.user_data, pallas::Base::ZERO);
-    assert_eq!(coin.note.spend_hook, FuncId::none());
-
-    // First we will verify the fee-less transaction to see how much gas
-    // it uses for execution and verification.
-    let tx = tx_builder.build()?;
-    let mut gas_used = FEE_CALL_GAS;
-    gas_used +=
-        verify_transaction(overlay, verifying_block_height, &tx, verifying_keys, false).await?;
-
-    // TODO: We could actually take a set of coins and then find one with
-    //       enough value, instead of expecting one. It depends, the API
-    //       is a bit weird.
-
-    if coin.note.value < gas_used {
-        error!(
-            target: "money_contract::client::fee_v1",
-            "Not enough value in given OwnCoin for fee, have {}, need {}",
-            coin.note.value, gas_used,
-        );
-        return Err(ClientFailed::NotEnoughValue(coin.note.value).into())
-    }
-
-    let change_value = coin.note.value - gas_used;
-
-    let input = FeeCallInput {
-        leaf_position: coin.leaf_position,
-        merkle_path: tree.witness(coin.leaf_position, 0).unwrap(),
-        secret: coin.secret,
-        note: coin.note.clone(),
-        user_data_blind: Blind::random(&mut OsRng),
-    };
-
-    let output = FeeCallOutput {
-        public_key: keypair.public,
-        value: change_value,
-        token_id: coin.note.token_id,
-        spend_hook: FuncId::none(),
-        user_data: pallas::Base::ZERO,
-        blind: Blind::random(&mut OsRng),
-    };
-
-    let token_blind = Blind::random(&mut OsRng);
-
-    let input_value_blind = Blind::random(&mut OsRng);
-    let fee_value_blind = Blind::random(&mut OsRng);
-    let output_value_blind = compute_remainder_blind(&[input_value_blind], &[fee_value_blind]);
-
-    let signature_secret = SecretKey::random(&mut OsRng);
-
-    info!(target: "money_contract::client::fee_v1", "Creating Fee_V1 ZK proof...");
-    let (proof, public_inputs) = create_fee_proof(
-        fee_zkbin,
-        fee_pk,
-        &input,
-        input_value_blind,
-        &output,
-        output_value_blind,
-        output.spend_hook,
-        output.user_data,
-        output.blind,
-        token_blind,
-        signature_secret,
-    )?;
-
-    // Encrypted note for the output
-    let note = MoneyNote {
-        value: output.value,
-        token_id: output.token_id,
-        spend_hook: output.spend_hook,
-        user_data: output.user_data,
-        coin_blind: output.blind,
-        value_blind: output_value_blind,
-        token_blind,
-        memo: vec![],
-    };
-
-    let encrypted_note = AeadEncryptedNote::encrypt(&note, &output.public_key, &mut OsRng)?;
-
-    let params = MoneyFeeParamsV1 {
-        input: Input {
-            value_commit: public_inputs.input_value_commit,
-            token_commit: public_inputs.token_commit,
-            nullifier: public_inputs.nullifier,
-            merkle_root: public_inputs.merkle_root,
-            user_data_enc: public_inputs.input_user_data_enc,
-            signature_public: public_inputs.signature_public,
-        },
-        output: Output {
-            value_commit: public_inputs.output_value_commit,
-            token_commit: public_inputs.token_commit,
-            coin: public_inputs.output_coin,
-            note: encrypted_note,
-        },
-        fee_value_blind,
-        token_blind,
-    };
-
-    let secrets =
-        FeeCallSecrets { proof, signature_secret, note, input_value_blind, output_value_blind };
-
-    // TODO: Append call to tx builder
-
-    Ok((params, secrets))
-}
-
 /// Private values related to the Fee call
 pub struct FeeCallSecrets {
     /// The ZK proof created in this builder
@@ -313,7 +172,7 @@ pub fn create_fee_proof(
         token_id: output.token_id,
         spend_hook: output_spend_hook,
         user_data: output_user_data,
-        blind: output_coin_blind.clone(),
+        blind: output_coin_blind,
     }
     .to_coin();
 

+ 2 - 2
src/contract/money/src/client/mod.rs

@@ -32,7 +32,7 @@ use darkfi_sdk::{
     bridgetree,
     crypto::{
         pasta_prelude::{Field, PrimeField},
-        poseidon_hash, BaseBlind, Blind, FuncId, Nullifier, ScalarBlind, SecretKey, TokenId,
+        poseidon_hash, BaseBlind, Blind, FuncId, ScalarBlind, SecretKey,
     },
     pasta::pallas,
 };
@@ -122,7 +122,7 @@ impl Hash for OwnCoin {
 pub fn compute_remainder_blind(
     input_blinds: &[ScalarBlind],
     output_blinds: &[ScalarBlind],
-) -> pallas::Scalar {
+) -> ScalarBlind {
     let mut total = pallas::Scalar::ZERO;
 
     for input_blind in input_blinds {

+ 6 - 3
src/contract/money/src/client/transfer_v1/builder.rs

@@ -22,7 +22,10 @@ use darkfi::{
 };
 use darkfi_sdk::{
     bridgetree,
-    crypto::{note::AeadEncryptedNote, pasta_prelude::*, MerkleNode, SecretKey, TokenId},
+    crypto::{
+        note::AeadEncryptedNote, pasta_prelude::*, BaseBlind, Blind, MerkleNode, ScalarBlind,
+        SecretKey,
+    },
     pasta::pallas,
 };
 use log::{debug, info};
@@ -30,7 +33,7 @@ use rand::rngs::OsRng;
 
 use super::proof::{create_transfer_burn_proof, create_transfer_mint_proof};
 use crate::{
-    client::{compute_remainder_blind, MoneyNote, OwnCoin},
+    client::{compute_remainder_blind, MoneyNote, OwnCoin, TokenId},
     model::{CoinAttributes, Input, MoneyTransferParamsV1, Output},
 };
 
@@ -79,7 +82,7 @@ impl TransferCallBuilder {
         let mut signature_secrets = vec![];
         let mut proofs = vec![];
 
-        let token_blind = pallas::Base::random(&mut OsRng);
+        let token_blind = BaseBlind::random(&mut OsRng);
         let mut input_blinds = vec![];
         let mut output_blinds = vec![];
 

+ 1 - 1
src/contract/money/src/entrypoint/transfer_v1.rs

@@ -29,7 +29,7 @@ use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
 
 use crate::{
     error::MoneyError,
-    model::{MoneyTransferParamsV1, MoneyTransferUpdateV1, DARK_TOKEN_ID},
+    model::{MoneyTransferParamsV1, MoneyTransferUpdateV1},
     MoneyFunction, MONEY_CONTRACT_COINS_TREE, MONEY_CONTRACT_COIN_MERKLE_TREE,
     MONEY_CONTRACT_COIN_ROOTS_TREE, MONEY_CONTRACT_INFO_TREE, MONEY_CONTRACT_LATEST_COIN_ROOT,
     MONEY_CONTRACT_NULLIFIERS_TREE, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,

+ 6 - 6
src/contract/test-harness/src/dao_exec.rs

@@ -18,7 +18,6 @@
 
 use darkfi::{
     tx::{ContractCallLeaf, Transaction, TransactionBuilder},
-    zk::halo2::Field,
     Result,
 };
 use darkfi_dao_contract::{
@@ -33,11 +32,12 @@ use darkfi_money_contract::{
     MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
 };
 use darkfi_sdk::{
-    contract_id::{DAO_CONTRACT_ID, MONEY_CONTRACT_ID},
-    crypto::{DAO_CONTRACT_ID, MONEY_CONTRACT_ID},
-    dark_tree::{DarkLeaf, DarkTree},
-    pasta::pallas,
-    pedersen_commitment_u64, ContractCall, FuncRef, MerkleNode, SecretKey,
+    crypto::{
+        contract_id::{DAO_CONTRACT_ID, MONEY_CONTRACT_ID},
+        pedersen_commitment_u64, Blind, FuncRef, MerkleNode, ScalarBlind, SecretKey,
+    },
+    dark_tree::DarkTree,
+    ContractCall,
 };
 use darkfi_serial::AsyncEncodable;
 use log::debug;

+ 1 - 2
src/contract/test-harness/src/dao_propose.rs

@@ -18,7 +18,6 @@
 
 use darkfi::{
     tx::{ContractCallLeaf, Transaction, TransactionBuilder},
-    zk::halo2::Field,
     Result,
 };
 use darkfi_dao_contract::{
@@ -35,7 +34,7 @@ use darkfi_money_contract::{
 use darkfi_sdk::{
     crypto::{
         contract_id::{DAO_CONTRACT_ID, MONEY_CONTRACT_ID},
-        Blind, MerkleNode, SecretKey, DAO_CONTRACT_ID, MONEY_CONTRACT_ID,
+        Blind, MerkleNode, SecretKey,
     },
     pasta::pallas,
     ContractCall,

+ 1 - 4
src/contract/test-harness/src/lib.rs

@@ -27,10 +27,7 @@ use darkfi::{
     Result,
 };
 use darkfi_dao_contract::model::{DaoBulla, DaoProposalBulla};
-use darkfi_money_contract::{
-    client::{MoneyNote, OwnCoin},
-    model::{Coin, Nullifier, Output},
-};
+use darkfi_money_contract::client::OwnCoin;
 use darkfi_sdk::{
     bridgetree,
     crypto::{Keypair, MerkleNode, MerkleTree},

+ 13 - 13
src/contract/test-harness/src/money_fee.rs

@@ -29,13 +29,13 @@ use darkfi_money_contract::{
         fee_v1::{create_fee_proof, FeeCallInput, FeeCallOutput, FEE_CALL_GAS},
         MoneyNote, OwnCoin,
     },
-    model::{Input, MoneyFeeParamsV1, Output},
+    model::{token_id::DARK_TOKEN_ID, Input, MoneyFeeParamsV1, Output},
     MoneyFunction, MONEY_CONTRACT_ZKAS_FEE_NS_V1,
 };
 use darkfi_sdk::{
     crypto::{
-        contract_id::MONEY_CONTRACT_ID, note::AeadEncryptedNote, token_id::DARK_TOKEN_ID, FuncId,
-        MerkleNode, SecretKey,
+        contract_id::MONEY_CONTRACT_ID, note::AeadEncryptedNote, BaseBlind, Blind, FuncId,
+        MerkleNode, ScalarBlind, SecretKey,
     },
     pasta::pallas,
     ContractCall,
@@ -69,22 +69,22 @@ impl TestHarness {
             merkle_path: wallet.money_merkle_tree.witness(coin.leaf_position, 0).unwrap(),
             secret: coin.secret,
             note: coin.note.clone(),
-            user_data_blind: pallas::Base::random(&mut OsRng),
+            user_data_blind: Blind::random(&mut OsRng),
         };
 
         let output = FeeCallOutput {
             public_key: wallet.keypair.public,
             value: coin.note.value - FEE_CALL_GAS,
             token_id: coin.note.token_id,
-            blind: pallas::Base::random(&mut OsRng),
+            blind: Blind::random(&mut OsRng),
             spend_hook: FuncId::none(),
             user_data: pallas::Base::ZERO,
         };
 
         // Generate blinding factors
-        let token_blind = pallas::Base::random(&mut OsRng);
-        let input_value_blind = pallas::Scalar::random(&mut OsRng);
-        let fee_value_blind = pallas::Scalar::random(&mut OsRng);
+        let token_blind = BaseBlind::random(&mut OsRng);
+        let input_value_blind = ScalarBlind::random(&mut OsRng);
+        let fee_value_blind = ScalarBlind::random(&mut OsRng);
         let output_value_blind = compute_remainder_blind(&[input_value_blind], &[fee_value_blind]);
 
         // Generate an ephemeral signing key
@@ -234,22 +234,22 @@ impl TestHarness {
             merkle_path: wallet.money_merkle_tree.witness(coin.leaf_position, 0).unwrap(),
             secret: coin.secret,
             note: coin.note.clone(),
-            user_data_blind: pallas::Base::random(&mut OsRng),
+            user_data_blind: BaseBlind::random(&mut OsRng),
         };
 
         let output = FeeCallOutput {
             public_key: wallet.keypair.public,
             value: change_value,
             token_id: coin.note.token_id,
-            blind: pallas::Base::random(&mut OsRng),
+            blind: BaseBlind::random(&mut OsRng),
             spend_hook: FuncId::none(),
             user_data: pallas::Base::ZERO,
         };
 
         // Create blinding factors
-        let token_blind = pallas::Base::random(&mut OsRng);
-        let input_value_blind = pallas::Scalar::random(&mut OsRng);
-        let fee_value_blind = pallas::Scalar::random(&mut OsRng);
+        let token_blind = BaseBlind::random(&mut OsRng);
+        let input_value_blind = ScalarBlind::random(&mut OsRng);
+        let fee_value_blind = ScalarBlind::random(&mut OsRng);
         let output_value_blind = compute_remainder_blind(&[input_value_blind], &[fee_value_blind]);
 
         // Create an ephemeral signing key

+ 1 - 1
src/contract/test-harness/src/money_otc_swap.rs

@@ -27,7 +27,7 @@ use darkfi_money_contract::{
     MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
 };
 use darkfi_sdk::{
-    crypto::{contract_id::MONEY_CONTRACT_ID, Blind, FuncId, MerkleNode, MONEY_CONTRACT_ID},
+    crypto::{contract_id::MONEY_CONTRACT_ID, BaseBlind, Blind, FuncId, MerkleNode},
     pasta::pallas,
     ContractCall,
 };

+ 4 - 7
src/contract/test-harness/src/money_token.rs

@@ -34,11 +34,8 @@ use darkfi_money_contract::{
     MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1,
 };
 use darkfi_sdk::{
-    crypto::{
-        contract_id::MONEY_CONTRACT_ID, poseidon_hash, Blind, FuncId, FuncRef, MerkleNode,
-        MONEY_CONTRACT_ID,
-    },
-    dark_tree::{DarkLeaf, DarkTree},
+    crypto::{poseidon_hash, BaseBlind, Blind, FuncId, FuncRef, MerkleNode, MONEY_CONTRACT_ID},
+    dark_tree::DarkTree,
     pasta::pallas,
     ContractCall,
 };
@@ -82,7 +79,7 @@ impl TestHarness {
         .to_func_id();
 
         let (mint_auth_x, mint_auth_y) = mint_authority.public.xy();
-        let token_blind = pallas::Base::random(&mut OsRng);
+        let token_blind = BaseBlind::random(&mut OsRng);
 
         let token_attrs = TokenAttributes {
             auth_parent: auth_func_id,
@@ -267,7 +264,7 @@ impl TestHarness {
         .to_func_id();
 
         let (mint_auth_x, mint_auth_y) = mint_authority.public.xy();
-        let token_blind = pallas::Base::random(&mut OsRng);
+        let token_blind = BaseBlind::random(&mut OsRng);
 
         let token_attrs = TokenAttributes {
             auth_parent: auth_func_id,

+ 4 - 6
src/contract/test-harness/src/money_transfer.rs

@@ -21,15 +21,13 @@ use darkfi::{
     Result,
 };
 use darkfi_money_contract::{
-    client::{transfer_v1::make_transfer_call, OwnCoin},
-    model::{MoneyTransferParamsV1, TokenId},
+    client::{transfer_v1::make_transfer_call, MoneyNote, OwnCoin},
+    model::{Input, MoneyFeeParamsV1, MoneyTransferParamsV1, Output, TokenId},
     MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
 };
 use darkfi_sdk::{
-    client::{transfer_v1::make_transfer_call, MoneyNote, OwnCoin},
-    crypto::{contract_id::MONEY_CONTRACT_ID, MerkleNode, TokenId, MONEY_CONTRACT_ID},
-    model::{Input, MoneyFeeParamsV1, MoneyTransferParamsV1, Output},
-    ContractCall, MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
+    crypto::{contract_id::MONEY_CONTRACT_ID, MerkleNode},
+    ContractCall,
 };
 use darkfi_serial::AsyncEncodable;
 use log::debug;

+ 1 - 0
src/validator/mod.rs

@@ -18,6 +18,7 @@
 
 use std::sync::Arc;
 
+use darkfi_sdk::crypto::MerkleTree;
 use darkfi_serial::serialize_async;
 use log::{debug, error, info, warn};
 use num_bigint::BigUint;