Przeglądaj źródła

contract/test-harness: Use precompiled zk proving keys

parazyd 3 lat temu
rodzic
commit
05991cda50

+ 1 - 0
src/contract/test-harness/.gitignore

@@ -1 +1,2 @@
 vks.bin
+pks.bin

+ 3 - 1
src/contract/test-harness/src/consensus_genesis_stake.rs

@@ -41,8 +41,10 @@ impl TestHarness {
         amount: u64,
     ) -> Result<(Transaction, ConsensusGenesisStakeParamsV1)> {
         let wallet = self.holders.get(holder).unwrap();
+
         let (mint_pk, mint_zkbin) =
-            self.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
+            wallet.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::ConsensusGenesisStake).unwrap();
         let timer = Instant::now();

+ 3 - 1
src/contract/test-harness/src/consensus_proposal.rs

@@ -44,8 +44,10 @@ impl TestHarness {
         staked_oc: &ConsensusOwnCoin,
     ) -> Result<(Transaction, ConsensusProposalParamsV1, SecretKey, SecretKey)> {
         let wallet = self.holders.get(holder).unwrap();
+
         let (proposal_pk, proposal_zkbin) =
-            self.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1).unwrap();
+            wallet.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1.to_string()).unwrap();
+
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::ConsensusProposal).unwrap();
         let timer = Instant::now();

+ 5 - 2
src/contract/test-harness/src/consensus_stake.rs

@@ -45,9 +45,12 @@ impl TestHarness {
         serial: pallas::Base,
     ) -> Result<(Transaction, ConsensusStakeParamsV1, SecretKey)> {
         let wallet = self.holders.get(holder).unwrap();
+
         let (mint_pk, mint_zkbin) =
-            self.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
-        let (burn_pk, burn_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1).unwrap();
+            wallet.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+        let (burn_pk, burn_zkbin) =
+            wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string()).unwrap();
+
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::ConsensusStake).unwrap();
         let epoch = wallet.validator.read().await.consensus.time_keeper.slot_epoch(slot);

+ 6 - 3
src/contract/test-harness/src/consensus_unstake.rs

@@ -44,9 +44,12 @@ impl TestHarness {
         staked_oc: &ConsensusOwnCoin,
     ) -> Result<(Transaction, MoneyUnstakeParamsV1, SecretKey)> {
         let wallet = self.holders.get(holder).unwrap();
+
         let (burn_pk, burn_zkbin) =
-            self.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1).unwrap();
-        let (mint_pk, mint_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
+            wallet.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1.to_string()).unwrap();
+        let (mint_pk, mint_zkbin) =
+            wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::ConsensusUnstake).unwrap();
         let timer = Instant::now();
@@ -74,7 +77,7 @@ impl TestHarness {
         // Building Money::Unstake params
         let money_unstake_call_debris = MoneyUnstakeCallBuilder {
             owncoin: staked_oc.clone(),
-            recipient: self.holders.get_mut(holder).unwrap().keypair.public,
+            recipient: self.holders.get(holder).unwrap().keypair.public,
             value_blind: consensus_unstake_value_blind,
             nullifier: consensus_unstake_params.input.nullifier,
             merkle_root: consensus_unstake_params.input.merkle_root,

+ 4 - 2
src/contract/test-harness/src/consensus_unstake_request.rs

@@ -44,10 +44,12 @@ impl TestHarness {
         staked_oc: &ConsensusOwnCoin,
     ) -> Result<(Transaction, ConsensusUnstakeReqParamsV1, SecretKey, SecretKey)> {
         let wallet = self.holders.get(holder).unwrap();
+
         let (burn_pk, burn_zkbin) =
-            self.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1).unwrap();
+            wallet.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1.to_string()).unwrap();
         let (mint_pk, mint_zkbin) =
-            self.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
+            wallet.proving_keys.get(&CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::ConsensusUnstakeRequest).unwrap();
         let epoch = wallet.validator.read().await.consensus.time_keeper.slot_epoch(slot);

+ 8 - 4
src/contract/test-harness/src/dao_exec.rs

@@ -51,10 +51,15 @@ impl TestHarness {
         yes_vote_blind: pallas::Scalar,
         all_vote_blind: pallas::Scalar,
     ) -> Result<(Transaction, MoneyTransferParamsV1, DaoExecParams)> {
-        let (mint_pk, mint_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
-        let (burn_pk, burn_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1).unwrap();
+        let dao_wallet = self.holders.get(&Holder::Dao).unwrap();
+
+        let (mint_pk, mint_zkbin) =
+            dao_wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+        let (burn_pk, burn_zkbin) =
+            dao_wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string()).unwrap();
         let (dao_exec_pk, dao_exec_zkbin) =
-            self.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_EXEC_NS).unwrap();
+            dao_wallet.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_EXEC_NS.to_string()).unwrap();
+
         let tx_action_benchmark = self.tx_action_benchmarks.get_mut(&TxAction::DaoExec).unwrap();
         let timer = Instant::now();
 
@@ -69,7 +74,6 @@ impl TestHarness {
         let change_user_data = dao_bulla.inner();
         let change_user_data_blind = pallas::Base::random(&mut OsRng);
 
-        let dao_wallet = self.holders.get(&Holder::Dao).unwrap();
         let coins: Vec<OwnCoin> = dao_wallet
             .unspent_money_coins
             .iter()

+ 5 - 1
src/contract/test-harness/src/dao_mint.rs

@@ -37,8 +37,12 @@ impl TestHarness {
         dao_info: &DaoInfo,
         dao_kp: &Keypair,
     ) -> Result<(Transaction, DaoMintParams)> {
+        // We assume DAO Holder exists at least
+        let wallet = self.holders.get(&Holder::Dao).unwrap();
+
         let (dao_mint_pk, dao_mint_zkbin) =
-            self.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_MINT_NS).unwrap();
+            wallet.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_MINT_NS.to_string()).unwrap();
+
         let tx_action_benchmark = self.tx_action_benchmarks.get_mut(&TxAction::DaoMint).unwrap();
         let timer = Instant::now();
 

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

@@ -45,14 +45,16 @@ impl TestHarness {
         dao: &DaoInfo,
         dao_bulla: &DaoBulla,
     ) -> Result<(Transaction, DaoProposeParams, DaoProposalInfo)> {
+        let wallet = self.holders.get(proposer).unwrap();
+
         let (dao_propose_burn_pk, dao_propose_burn_zkbin) =
-            self.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS).unwrap();
+            wallet.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS.to_string()).unwrap();
         let (dao_propose_main_pk, dao_propose_main_zkbin) =
-            self.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS).unwrap();
+            wallet.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS.to_string()).unwrap();
+
         let tx_action_benchmark = self.tx_action_benchmarks.get_mut(&TxAction::DaoPropose).unwrap();
         let timer = Instant::now();
 
-        let wallet = self.holders.get(proposer).unwrap();
         let propose_owncoin: OwnCoin = wallet
             .unspent_money_coins
             .iter()

+ 4 - 4
src/contract/test-harness/src/dao_vote.rs

@@ -45,15 +45,15 @@ impl TestHarness {
         proposal: &DaoProposalInfo,
         proposal_bulla: &DaoProposalBulla,
     ) -> Result<(Transaction, DaoVoteParams)> {
+        let wallet = self.holders.get(voter).unwrap();
+
         let (dao_vote_burn_pk, dao_vote_burn_zkbin) =
-            self.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_VOTE_BURN_NS).unwrap();
+            wallet.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_VOTE_BURN_NS.to_string()).unwrap();
         let (dao_vote_main_pk, dao_vote_main_zkbin) =
-            self.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS).unwrap();
+            wallet.proving_keys.get(&DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS.to_string()).unwrap();
         let tx_action_benchmark = self.tx_action_benchmarks.get_mut(&TxAction::DaoVote).unwrap();
         let timer = Instant::now();
 
-        let wallet = self.holders.get(voter).unwrap();
-
         let (_proposal_leaf_pos, money_merkle_tree) =
             wallet.dao_prop_leafs.get(proposal_bulla).unwrap();
 

+ 21 - 84
src/contract/test-harness/src/lib.rs

@@ -16,11 +16,10 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use std::{collections::HashMap, time::Instant};
+use std::{collections::HashMap, io::Cursor, time::Instant};
 
 use darkfi::{
     blockchain::BlockInfo,
-    runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
     tx::Transaction,
     util::{
         pcg::Pcg32,
@@ -32,30 +31,20 @@ use darkfi::{
     zkas::ZkBinary,
     Result,
 };
-use darkfi_dao_contract::{
-    model::{DaoBulla, DaoProposalBulla},
-    DAO_CONTRACT_ZKAS_DAO_EXEC_NS, DAO_CONTRACT_ZKAS_DAO_MINT_NS,
-    DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS, DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS,
-    DAO_CONTRACT_ZKAS_DAO_VOTE_BURN_NS, DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS,
-};
+use darkfi_dao_contract::model::{DaoBulla, DaoProposalBulla};
 use darkfi_money_contract::{
     client::{ConsensusNote, ConsensusOwnCoin, MoneyNote, OwnCoin},
     model::{ConsensusOutput, Output},
-    CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1, CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1,
-    CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1, MONEY_CONTRACT_ZKAS_BURN_NS_V1,
-    MONEY_CONTRACT_ZKAS_MINT_NS_V1, MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1,
-    MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1,
 };
 use darkfi_sdk::{
     blockchain::Slot,
     bridgetree,
     crypto::{
         pasta_prelude::Field, poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey,
-        SecretKey, TokenId, CONSENSUS_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID,
+        SecretKey, TokenId,
     },
     pasta::pallas,
 };
-use darkfi_serial::{deserialize, serialize};
 use log::{info, warn};
 use rand::rngs::OsRng;
 
@@ -85,8 +74,8 @@ pub fn init_logger() {
     // We check this error so we can execute same file tests in parallel,
     // otherwise second one fails to init logger here.
     if simplelog::TermLogger::init(
-        simplelog::LevelFilter::Info,
-        //simplelog::LevelFilter::Debug,
+        //simplelog::LevelFilter::Info,
+        simplelog::LevelFilter::Debug,
         //simplelog::LevelFilter::Trace,
         cfg.build(),
         simplelog::TerminalMode::Mixed,
@@ -133,6 +122,7 @@ pub struct Wallet {
     pub keypair: Keypair,
     pub token_mint_authority: Keypair,
     pub validator: ValidatorPtr,
+    pub proving_keys: HashMap<String, (ProvingKey, ZkBinary)>,
     pub money_merkle_tree: MerkleTree,
     pub consensus_staked_merkle_tree: MerkleTree,
     pub consensus_unstaked_merkle_tree: MerkleTree,
@@ -155,8 +145,17 @@ impl Wallet {
         let wallet = WalletDb::new(None, None)?;
         let sled_db = sled::Config::new().temporary(true).open()?;
 
-        // Use pregenerated vks
-        vks::inject(&sled_db)?;
+        // Use pregenerated vks and get pregenerated pks
+        let pks = vks::inject(&sled_db)?;
+
+        let mut proving_keys = HashMap::new();
+        for (bincode, namespace, pk) in pks {
+            let mut reader = Cursor::new(pk);
+            let zkbin = ZkBinary::decode(&bincode)?;
+            let circuit = ZkCircuit::new(empty_witnesses(&zkbin), &zkbin);
+            let _pk = ProvingKey::read(&mut reader, circuit)?;
+            proving_keys.insert(namespace, (_pk, zkbin));
+        }
 
         // Generate validator
         // NOTE: we are not using consensus constants here so we
@@ -187,6 +186,7 @@ impl Wallet {
 
         Ok(Self {
             keypair,
+            proving_keys,
             token_mint_authority,
             validator,
             money_merkle_tree,
@@ -205,13 +205,12 @@ impl Wallet {
 
 pub struct TestHarness {
     pub holders: HashMap<Holder, Wallet>,
-    pub proving_keys: HashMap<&'static str, (ProvingKey, ZkBinary)>,
     pub tx_action_benchmarks: HashMap<TxAction, TxActionBenchmarks>,
     pub genesis_block: blake3::Hash,
 }
 
 impl TestHarness {
-    pub async fn new(contracts: &[String]) -> Result<Self> {
+    pub async fn new(_contracts: &[String]) -> Result<Self> {
         let mut holders = HashMap::new();
         let mut genesis_block = BlockInfo::default();
         genesis_block.header.timestamp = Timestamp(1689772567);
@@ -226,7 +225,7 @@ impl TestHarness {
 
         let alice_kp = Keypair::random(&mut rng);
         let alice = Wallet::new(alice_kp, &genesis_block, &faucet_pubkeys).await?;
-        // Alice is inserted at end of function
+        holders.insert(Holder::Alice, alice);
 
         let bob_kp = Keypair::random(&mut rng);
         let bob = Wallet::new(bob_kp, &genesis_block, &faucet_pubkeys).await?;
@@ -244,60 +243,6 @@ impl TestHarness {
         let dao = Wallet::new(dao_kp, &genesis_block, &faucet_pubkeys).await?;
         holders.insert(Holder::Dao, dao);
 
-        // Get the zkas circuits and build proving keys
-        let mut proving_keys = HashMap::new();
-        let alice_sled = alice.validator.read().await.blockchain.sled_db.clone();
-
-        macro_rules! mkpk {
-            ($db:expr, $ns:expr) => {
-                info!("Building ProvingKey for {}", $ns);
-                let zkas_bytes = $db.get(&serialize(&$ns))?.unwrap();
-                let (zkbin, _): (Vec<u8>, Vec<u8>) = deserialize(&zkas_bytes)?;
-                let zkbin = ZkBinary::decode(&zkbin)?;
-                let witnesses = empty_witnesses(&zkbin);
-                let circuit = ZkCircuit::new(witnesses, &zkbin);
-                let pk = ProvingKey::build(13, &circuit);
-                proving_keys.insert($ns, (pk, zkbin));
-            };
-        }
-
-        if contracts.contains(&"money".to_string()) {
-            let db_handle = alice.validator.read().await.blockchain.contracts.lookup(
-                &alice_sled,
-                &MONEY_CONTRACT_ID,
-                SMART_CONTRACT_ZKAS_DB_NAME,
-            )?;
-            mkpk!(db_handle, MONEY_CONTRACT_ZKAS_MINT_NS_V1);
-            mkpk!(db_handle, MONEY_CONTRACT_ZKAS_BURN_NS_V1);
-            mkpk!(db_handle, MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1);
-            mkpk!(db_handle, MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1);
-        }
-
-        if contracts.contains(&"consensus".to_string()) {
-            let db_handle = alice.validator.read().await.blockchain.contracts.lookup(
-                &alice_sled,
-                &CONSENSUS_CONTRACT_ID,
-                SMART_CONTRACT_ZKAS_DB_NAME,
-            )?;
-            mkpk!(db_handle, CONSENSUS_CONTRACT_ZKAS_MINT_NS_V1);
-            mkpk!(db_handle, CONSENSUS_CONTRACT_ZKAS_BURN_NS_V1);
-            mkpk!(db_handle, CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1);
-        }
-
-        if contracts.contains(&"dao".to_string()) {
-            let db_handle = alice.validator.read().await.blockchain.contracts.lookup(
-                &alice_sled,
-                &DAO_CONTRACT_ID,
-                SMART_CONTRACT_ZKAS_DB_NAME,
-            )?;
-            mkpk!(db_handle, DAO_CONTRACT_ZKAS_DAO_EXEC_NS);
-            mkpk!(db_handle, DAO_CONTRACT_ZKAS_DAO_MINT_NS);
-            mkpk!(db_handle, DAO_CONTRACT_ZKAS_DAO_VOTE_BURN_NS);
-            mkpk!(db_handle, DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS);
-            mkpk!(db_handle, DAO_CONTRACT_ZKAS_DAO_PROPOSE_BURN_NS);
-            mkpk!(db_handle, DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS);
-        }
-
         // Build benchmarks map
         let mut tx_action_benchmarks = HashMap::new();
         tx_action_benchmarks.insert(TxAction::MoneyAirdrop, TxActionBenchmarks::default());
@@ -317,15 +262,7 @@ impl TestHarness {
         tx_action_benchmarks.insert(TxAction::DaoVote, TxActionBenchmarks::default());
         tx_action_benchmarks.insert(TxAction::DaoExec, TxActionBenchmarks::default());
 
-        // Alice jumps down the rabbit hole
-        holders.insert(Holder::Alice, alice);
-
-        Ok(Self {
-            holders,
-            proving_keys,
-            tx_action_benchmarks,
-            genesis_block: genesis_block.blockhash(),
-        })
+        Ok(Self { holders, tx_action_benchmarks, genesis_block: genesis_block.blockhash() })
     }
 
     pub async fn execute_erroneous_txs(

+ 4 - 2
src/contract/test-harness/src/money_airdrop.rs

@@ -47,8 +47,10 @@ impl TestHarness {
     ) -> Result<(Transaction, MoneyTransferParamsV1)> {
         let recipient = self.holders.get(holder).unwrap().keypair.public;
         let faucet = self.holders.get(&Holder::Faucet).unwrap();
-        let (mint_pk, mint_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
-        let (burn_pk, burn_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1).unwrap();
+        let (mint_pk, mint_zkbin) =
+            faucet.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+        let (burn_pk, burn_zkbin) =
+            faucet.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string()).unwrap();
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::MoneyAirdrop).unwrap();
         let timer = Instant::now();

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

@@ -40,7 +40,8 @@ impl TestHarness {
         amount: u64,
     ) -> Result<(Transaction, MoneyTokenMintParamsV1)> {
         let wallet = self.holders.get(holder).unwrap();
-        let (mint_pk, mint_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
+        let (mint_pk, mint_zkbin) =
+            wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::MoneyGenesisMint).unwrap();
         let timer = Instant::now();

+ 4 - 2
src/contract/test-harness/src/money_otc_swap.rs

@@ -44,8 +44,10 @@ impl TestHarness {
     ) -> Result<(Transaction, MoneyTransferParamsV1)> {
         let wallet0 = self.holders.get(holder0).unwrap();
         let wallet1 = self.holders.get(holder1).unwrap();
-        let (mint_pk, mint_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
-        let (burn_pk, burn_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1).unwrap();
+        let (mint_pk, mint_zkbin) =
+            wallet0.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+        let (burn_pk, burn_zkbin) =
+            wallet0.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string()).unwrap();
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::MoneyOtcSwap).unwrap();
         let timer = Instant::now();

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

@@ -43,12 +43,17 @@ impl TestHarness {
         spend_hook: Option<pallas::Base>,
         user_data: Option<pallas::Base>,
     ) -> Result<(Transaction, MoneyTokenMintParamsV1)> {
+        let wallet = self.holders.get(holder).unwrap();
+        let mint_authority = wallet.token_mint_authority;
+
         let rcpt = self.holders.get(recipient).unwrap().keypair.public;
-        let mint_authority = self.holders.get(holder).unwrap().token_mint_authority;
+
         let (mint_pk, mint_zkbin) =
-            self.proving_keys.get(&MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1).unwrap();
+            wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1.to_string()).unwrap();
+
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::MoneyTokenMint).unwrap();
+
         let timer = Instant::now();
 
         let builder = TokenMintCallBuilder {
@@ -106,9 +111,10 @@ impl TestHarness {
         &mut self,
         holder: &Holder,
     ) -> Result<(Transaction, MoneyTokenFreezeParamsV1)> {
-        let mint_authority = self.holders.get(holder).unwrap().token_mint_authority;
+        let wallet = self.holders.get(holder).unwrap();
+        let mint_authority = wallet.token_mint_authority;
         let (frz_pk, frz_zkbin) =
-            self.proving_keys.get(&MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1).unwrap();
+            wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1.to_string()).unwrap();
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::MoneyTokenFreeze).unwrap();
         let timer = Instant::now();

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

@@ -45,8 +45,10 @@ impl TestHarness {
     ) -> Result<(Transaction, MoneyTransferParamsV1, Vec<OwnCoin>)> {
         let wallet = self.holders.get(holder).unwrap();
         let rcpt = self.holders.get(recipient).unwrap().keypair.public;
-        let (mint_pk, mint_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1).unwrap();
-        let (burn_pk, burn_zkbin) = self.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1).unwrap();
+        let (mint_pk, mint_zkbin) =
+            wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string()).unwrap();
+        let (burn_pk, burn_zkbin) =
+            wallet.proving_keys.get(&MONEY_CONTRACT_ZKAS_BURN_NS_V1.to_string()).unwrap();
         let tx_action_benchmark =
             self.tx_action_benchmarks.get_mut(&TxAction::MoneyTransfer).unwrap();
         let timer = Instant::now();

+ 56 - 14
src/contract/test-harness/src/vks.rs

@@ -25,7 +25,7 @@ use std::{
 
 use darkfi::{
     runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
-    zk::{empty_witnesses, VerifyingKey, ZkCircuit},
+    zk::{empty_witnesses, ProvingKey, VerifyingKey, ZkCircuit},
     zkas::ZkBinary,
     Result,
 };
@@ -48,23 +48,29 @@ use darkfi_serial::{deserialize, serialize};
 use log::debug;
 
 /// Update this if any circuits are changed
-const VKS_HASH: &str = "1a514858c589cf2b6f28930d7f6fbae9f7455661d68a7944b776a947811b3430";
+const VKS_HASH: &str = "afcbea36961a5b526dae2c448170953d9c16368211cc8c355f154caf1ac313d7";
+const PKS_HASH: &str = "6cf2bf9b2ffbc68c8f778971725de180862a040446db7d4f5bcc12e1e4552d7d";
 
-fn vks_path() -> Result<PathBuf> {
+fn pks_path(typ: &str) -> Result<PathBuf> {
     let output = Command::new("git").arg("rev-parse").arg("--show-toplevel").output()?.stdout;
     let mut path = PathBuf::from(String::from_utf8(output[..output.len() - 1].to_vec())?);
     path.push("src");
     path.push("contract");
     path.push("test-harness");
-    path.push("vks.bin");
+    path.push(typ);
     Ok(path)
 }
 
 /// (Bincode, Namespace, VK)
 pub type Vks = Vec<(Vec<u8>, String, Vec<u8>)>;
+pub type Pks = Vec<(Vec<u8>, String, Vec<u8>)>;
 
-fn read_or_gen_vks() -> Result<Vks> {
-    let vks_path = vks_path()?;
+fn read_or_gen_vks_and_pks() -> Result<(Pks, Vks)> {
+    let vks_path = pks_path("vks.bin")?;
+    let pks_path = pks_path("pks.bin")?;
+
+    let mut vks = None;
+    let mut pks = None;
 
     if vks_path.exists() {
         debug!("Found vks.bin");
@@ -75,16 +81,39 @@ fn read_or_gen_vks() -> Result<Vks> {
         let known_hash = blake3::Hash::from_hex(VKS_HASH)?;
         let found_hash = blake3::hash(&data);
 
-        debug!("Known hash: {}", known_hash);
-        debug!("Found hash: {}", found_hash);
+        debug!("Known VKS hash: {}", known_hash);
+        debug!("Found VKS hash: {}", found_hash);
 
         if known_hash == found_hash {
-            return Ok(deserialize(&data)?)
+            vks = Some(deserialize(&data)?)
         }
 
         drop(f);
     }
 
+    if pks_path.exists() {
+        debug!("Found pks.bin");
+        let mut f = File::open(pks_path.clone())?;
+        let mut data = vec![];
+        f.read_to_end(&mut data)?;
+
+        let known_hash = blake3::Hash::from_hex(PKS_HASH)?;
+        let found_hash = blake3::hash(&data);
+
+        debug!("Known PKS hash: {}", known_hash);
+        debug!("Found PKS hash: {}", found_hash);
+
+        if known_hash == found_hash {
+            pks = Some(deserialize(&data)?)
+        }
+
+        drop(f);
+    }
+
+    if pks.is_some() && vks.is_some() {
+        return Ok((pks.unwrap(), vks.unwrap()))
+    }
+
     let bins = vec![
         // Money
         &include_bytes!("../../money/proof/mint_v1.zk.bin")[..],
@@ -107,6 +136,7 @@ fn read_or_gen_vks() -> Result<Vks> {
     ];
 
     let mut vks = vec![];
+    let mut pks = vec![];
 
     for bincode in bins.iter() {
         let zkbin = ZkBinary::decode(bincode)?;
@@ -116,7 +146,12 @@ fn read_or_gen_vks() -> Result<Vks> {
         let vk = VerifyingKey::build(13, &circuit);
         let mut vk_buf = vec![];
         vk.write(&mut vk_buf)?;
-        vks.push((bincode.to_vec(), zkbin.namespace, vk_buf))
+        vks.push((bincode.to_vec(), zkbin.namespace.clone(), vk_buf));
+
+        let pk = ProvingKey::build(13, &circuit);
+        let mut pk_buf = vec![];
+        pk.write(&mut pk_buf)?;
+        pks.push((bincode.to_vec(), zkbin.namespace, pk_buf));
     }
 
     debug!("Writing to {:?}", vks_path);
@@ -126,12 +161,19 @@ fn read_or_gen_vks() -> Result<Vks> {
     debug!("vks.bin {}", hash);
     f.write_all(&ser)?;
 
-    Ok(vks)
+    debug!("Writing to {:?}", pks_path);
+    let mut f = File::create(pks_path)?;
+    let ser = serialize(&pks);
+    let hash = blake3::hash(&ser);
+    debug!("pks.bin {}", hash);
+    f.write_all(&ser)?;
+
+    Ok((pks, vks))
 }
 
-pub fn inject(sled_db: &sled::Db) -> Result<()> {
+pub fn inject(sled_db: &sled::Db) -> Result<Pks> {
     // Use pregenerated vks
-    let vks = read_or_gen_vks()?;
+    let (pks, vks) = read_or_gen_vks_and_pks()?;
 
     // Inject them into the db
     let money_zkas_tree_ptr = MONEY_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME);
@@ -191,5 +233,5 @@ pub fn inject(sled_db: &sled::Db) -> Result<()> {
         }
     }
 
-    Ok(())
+    Ok(pks)
 }