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

contract/money: Implement support for dummy inputs.

parazyd 3 лет назад
Родитель
Сommit
bcd98952a7

+ 8 - 4
bin/drk/src/wallet_money.rs

@@ -41,8 +41,8 @@ use darkfi_money_contract::{
 use darkfi_sdk::{
     bridgetree,
     crypto::{
-        poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey, SecretKey, TokenId,
-        MONEY_CONTRACT_ID,
+        pasta_prelude::Field, poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey,
+        SecretKey, TokenId, MONEY_CONTRACT_ID,
     },
     pasta::pallas,
 };
@@ -87,7 +87,9 @@ impl Drk {
 
         if tree_needs_init {
             eprintln!("Initializing Money Merkle tree");
-            let tree = MerkleTree::new(100);
+            let mut tree = MerkleTree::new(100);
+            tree.append(MerkleNode::from(pallas::Base::ZERO));
+            let _ = tree.mark().unwrap();
             self.put_money_tree(&tree).await?;
             eprintln!("Successfully initialized Merkle tree for the Money contract");
         }
@@ -435,7 +437,9 @@ impl Drk {
     /// Reset the Money Merkle tree in the wallet
     pub async fn reset_money_tree(&self) -> Result<()> {
         eprintln!("Resetting Money Merkle tree");
-        let tree = MerkleTree::new(100);
+        let mut tree = MerkleTree::new(100);
+        tree.append(MerkleNode::from(pallas::Base::ZERO));
+        let _ = tree.mark().unwrap();
         self.put_money_tree(&tree).await?;
         eprintln!("Successfully reset Money Merkle tree");
 

+ 5 - 3
bin/faucetd/src/main.rs

@@ -34,7 +34,8 @@ use darkfi_money_contract::{
 };
 use darkfi_sdk::{
     crypto::{
-        contract_id::MONEY_CONTRACT_ID, mimc_vdf, Keypair, MerkleTree, PublicKey, DARK_TOKEN_ID,
+        contract_id::MONEY_CONTRACT_ID, mimc_vdf, pasta_prelude::Field, Keypair, MerkleNode,
+        MerkleTree, PublicKey, DARK_TOKEN_ID,
     },
     num_bigint::BigUint,
     num_traits::Num,
@@ -73,7 +74,7 @@ use darkfi::{
     tx::Transaction,
     util::{async_util::sleep, parse::decode_base10, path::expand_path},
     wallet::{WalletDb, WalletPtr},
-    zk::{halo2::Field, proof::ProvingKey, vm::ZkCircuit, vm_heap::empty_witnesses},
+    zk::{proof::ProvingKey, vm::ZkCircuit, vm_heap::empty_witnesses},
     zkas::ZkBinary,
     Error, Result,
 };
@@ -304,7 +305,8 @@ impl Faucetd {
             }
 
             Err(_) => {
-                let tree = MerkleTree::new(100);
+                let mut tree = MerkleTree::new(100);
+                tree.append(MerkleNode::from(pallas::Base::ZERO));
                 let tree_bytes = serialize(&tree);
                 let query = format!(
                     "DELETE FROM {}; INSERT INTO {} ({}) VALUES (?1)",

+ 8 - 1
src/contract/money/proof/burn_v1.zk

@@ -68,8 +68,15 @@ circuit "Burn_V1" {
 		user_data,
 	);
 
+	# With this, we can actually produce a fake coin of value 0
+	# above and use it as a dummy input. The inclusion merkle tree
+	# has a 0x00 leaf at position 0, so zero_cond will output value
+	# iff value is 0 - which is equivalent to 0x00 so that's the
+	# trick we use to make the inclusion proof.
+	coin_incl = zero_cond(value, C);
+
 	# Merkle root
-	root = merkle_root(leaf_pos, path, C);
+	root = merkle_root(leaf_pos, path, coin_incl);
 	constrain_instance(root);
 
 	# Export user_data

+ 7 - 4
src/contract/money/src/entrypoint.rs

@@ -17,10 +17,11 @@
  */
 
 use darkfi_sdk::{
-    crypto::{ContractId, MerkleTree, PublicKey},
+    crypto::{pasta_prelude::Field, ContractId, MerkleNode, MerkleTree, PublicKey},
     db::{db_init, db_lookup, db_set, zkas_db_set},
     error::{ContractError, ContractResult},
     msg,
+    pasta::pallas,
     util::set_return_data,
     ContractCall,
 };
@@ -144,10 +145,12 @@ fn init_contract(cid: ContractId, ix: &[u8]) -> ContractResult {
         Err(_) => {
             let info_db = db_init(cid, MONEY_CONTRACT_INFO_TREE)?;
 
-            // Create the incrementalmerkletree for seen coins
-            let coin_tree = MerkleTree::new(100);
-            let mut coin_tree_data = vec![];
+            // Create the incrementalmerkletree for seen coins and initialize
+            // it with a "fake" coin that can be used for dummy inputs.
+            let mut coin_tree = MerkleTree::new(100);
+            coin_tree.append(MerkleNode::from(pallas::Base::ZERO));
 
+            let mut coin_tree_data = vec![];
             coin_tree_data.write_u32(0)?;
             coin_tree.encode(&mut coin_tree_data)?;
 

+ 5 - 3
src/contract/test-harness/src/lib.rs

@@ -44,9 +44,10 @@ use darkfi_money_contract::{
 use darkfi_sdk::{
     blockchain::Slot,
     crypto::{
-        poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey, SecretKey,
-        CONSENSUS_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID,
+        pasta_prelude::Field, poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey,
+        SecretKey, CONSENSUS_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID,
     },
+    pasta::pallas,
 };
 use darkfi_serial::{deserialize, serialize};
 use log::{info, warn};
@@ -150,7 +151,8 @@ impl Wallet {
         let validator = Validator::new(&sled_db, config).await?;
 
         // Create necessary Merkle trees for tracking
-        let money_merkle_tree = MerkleTree::new(100);
+        let mut money_merkle_tree = MerkleTree::new(100);
+        money_merkle_tree.append(MerkleNode::from(pallas::Base::ZERO));
         let consensus_staked_merkle_tree = MerkleTree::new(100);
         let consensus_unstaked_merkle_tree = MerkleTree::new(100);
 

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

@@ -48,7 +48,7 @@ use darkfi_serial::{deserialize, serialize};
 use log::debug;
 
 /// Update this if any circuits are changed
-const VKS_HASH: &str = "e57436271c01c4775cff640ff4d1809f98374268769d23343f5aa6e58444b41a";
+const VKS_HASH: &str = "63c998f32a8822e9353d7f5794ae2abb1a5b4f77ce4e926cdecd41102e1aac21";
 
 fn vks_path() -> Result<PathBuf> {
     let output = Command::new("git").arg("rev-parse").arg("--show-toplevel").output()?.stdout;