Ver Fonte

wasm tests: add option to generate a CSV of benchmarks

zero há 2 anos atrás
pai
commit
05ea80bd99

+ 2 - 1
src/contract/dao/tests/integration.rs

@@ -54,7 +54,8 @@ fn integration_test() -> Result<()> {
         let mut th = TestHarness::new(&HOLDERS, false).await?;
         let mut th = TestHarness::new(&HOLDERS, false).await?;
 
 
         // We'll use the ALICE token as the DAO governance token
         // We'll use the ALICE token as the DAO governance token
-        let wallet = th.holders.get(&Holder::Alice).unwrap();
+        let wallet = th.holders.get_mut(&Holder::Alice).unwrap();
+        //wallet.bench_wasm = true;
         let mint_authority = wallet.token_mint_authority;
         let mint_authority = wallet.token_mint_authority;
         let gov_token_blind = BaseBlind::random(&mut OsRng);
         let gov_token_blind = BaseBlind::random(&mut OsRng);
 
 

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

@@ -103,7 +103,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("deploy::deploy", tx, block_height, self.verify_fees).await?;
 
 
         if !append {
         if !append {
             return Ok(vec![])
             return Ok(vec![])

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

@@ -260,7 +260,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("dao::exec", tx, block_height, self.verify_fees).await?;
 
 
         if !append {
         if !append {
             return Ok(vec![])
             return Ok(vec![])

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

@@ -107,7 +107,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("dao::mint", tx, block_height, self.verify_fees).await?;
 
 
         if !append {
         if !append {
             return Ok(vec![])
             return Ok(vec![])

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

@@ -185,7 +185,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("dao::propose", tx, block_height, self.verify_fees).await?;
 
 
         if !append {
         if !append {
             return Ok(vec![])
             return Ok(vec![])

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

@@ -148,7 +148,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("dao::vote", tx, block_height, self.verify_fees).await?;
 
 
         if !append {
         if !append {
             return Ok(vec![])
             return Ok(vec![])

+ 75 - 2
src/contract/test-harness/src/lib.rs

@@ -16,10 +16,15 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
  */
 
 
-use std::{collections::HashMap, io::Cursor};
+use std::{
+    collections::HashMap,
+    io::{Cursor, Write},
+};
 
 
 use darkfi::{
 use darkfi::{
-    blockchain::BlockInfo,
+    blockchain::{BlockInfo, BlockchainOverlay},
+    runtime::vm_runtime::Runtime,
+    tx::Transaction,
     util::{pcg::Pcg32, time::Timestamp},
     util::{pcg::Pcg32, time::Timestamp},
     validator::{Validator, ValidatorConfig, ValidatorPtr},
     validator::{Validator, ValidatorConfig, ValidatorPtr},
     zk::{empty_witnesses, halo2::Field, ProvingKey, ZkCircuit},
     zk::{empty_witnesses, halo2::Field, ProvingKey, ZkCircuit},
@@ -33,6 +38,7 @@ use darkfi_sdk::{
     crypto::{Keypair, MerkleNode, MerkleTree},
     crypto::{Keypair, MerkleNode, MerkleTree},
     pasta::pallas,
     pasta::pallas,
 };
 };
+use darkfi_serial::{Encodable, WriteExt};
 use log::debug;
 use log::debug;
 use num_bigint::BigUint;
 use num_bigint::BigUint;
 
 
@@ -128,6 +134,8 @@ pub struct Wallet {
     pub dao_leafs: HashMap<DaoBulla, bridgetree::Position>,
     pub dao_leafs: HashMap<DaoBulla, bridgetree::Position>,
     /// Dao Proposal snapshots
     /// Dao Proposal snapshots
     pub dao_prop_leafs: HashMap<DaoProposalBulla, (bridgetree::Position, MerkleTree)>,
     pub dao_prop_leafs: HashMap<DaoProposalBulla, (bridgetree::Position, MerkleTree)>,
+    /// Create bench.csv file
+    pub bench_wasm: bool,
 }
 }
 
 
 impl Wallet {
 impl Wallet {
@@ -174,8 +182,24 @@ impl Wallet {
             spent_money_coins: vec![],
             spent_money_coins: vec![],
             dao_leafs: HashMap::new(),
             dao_leafs: HashMap::new(),
             dao_prop_leafs: HashMap::new(),
             dao_prop_leafs: HashMap::new(),
+            bench_wasm: false,
         })
         })
     }
     }
+
+    pub async fn add_transaction(
+        &mut self,
+        callname: &str,
+        tx: Transaction,
+        block_height: u64,
+        verify_fees: bool,
+    ) -> Result<()> {
+        if self.bench_wasm {
+            benchmark_wasm_calls(callname, &self.validator, &tx, block_height);
+        }
+
+        self.validator.add_transactions(&[tx], block_height, true, verify_fees).await?;
+        Ok(())
+    }
 }
 }
 
 
 /// Native contract test harness instance
 /// Native contract test harness instance
@@ -253,3 +277,52 @@ impl TestHarness {
         }
         }
     }
     }
 }
 }
+
+fn benchmark_wasm_calls(
+    callname: &str,
+    validator: &Validator,
+    tx: &Transaction,
+    block_height: u64,
+) {
+    let mut file = std::fs::OpenOptions::new()
+        .write(true)
+        .create(true)
+        .append(true)
+        .open("bench.csv")
+        .unwrap();
+
+    for (idx, call) in tx.calls.iter().enumerate() {
+        let overlay = BlockchainOverlay::new(&validator.blockchain).expect("blockchain overlay");
+        let wasm = overlay.lock().unwrap().wasm_bincode.get(call.data.contract_id).unwrap();
+        let mut runtime = Runtime::new(&wasm, overlay.clone(), call.data.contract_id, block_height)
+            .expect("runtime");
+        let mut payload = vec![];
+        payload.write_u32(idx as u32).unwrap(); // Call index
+        tx.calls.encode(&mut payload).unwrap(); // Actual call data
+
+        let mut times = [0; 3];
+        let now = std::time::Instant::now();
+        let _metadata = runtime.metadata(&payload).expect("metadata");
+        times[0] = now.elapsed().as_millis();
+
+        let now = std::time::Instant::now();
+        let update = runtime.exec(&payload).expect("exec");
+        times[1] = now.elapsed().as_millis();
+
+        let now = std::time::Instant::now();
+        runtime.apply(&update).expect("update");
+        times[2] = now.elapsed().as_millis();
+
+        writeln!(
+            file,
+            "{}, {}, {}, {}, {}, {}",
+            callname,
+            tx.hash().unwrap(),
+            idx,
+            times[0],
+            times[1],
+            times[2]
+        )
+        .unwrap();
+    }
+}

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

@@ -163,7 +163,7 @@ impl TestHarness {
     ) -> Result<Vec<OwnCoin>> {
     ) -> Result<Vec<OwnCoin>> {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("money::fee", tx, block_height, self.verify_fees).await?;
         wallet.money_merkle_tree.append(MerkleNode::from(params.output.coin.inner()));
         wallet.money_merkle_tree.append(MerkleNode::from(params.output.coin.inner()));
 
 
         // Attempt to decrypt the output note to see if this is a coin for the holder
         // Attempt to decrypt the output note to see if this is a coin for the holder

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

@@ -90,7 +90,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("money::genesis_mint", tx, block_height, self.verify_fees).await?;
 
 
         if !append {
         if !append {
             return Ok(vec![])
             return Ok(vec![])

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

@@ -186,7 +186,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("money::otc_swap", tx, block_height, self.verify_fees).await?;
 
 
         let mut found_owncoins = vec![];
         let mut found_owncoins = vec![];
 
 

+ 2 - 2
src/contract/test-harness/src/money_token.rs

@@ -183,7 +183,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("money::token_mint", tx, block_height, self.verify_fees).await?;
 
 
         // Iterate over all inputs to mark any spent coins
         // Iterate over all inputs to mark any spent coins
         if let Some(ref fee_params) = fee_params {
         if let Some(ref fee_params) = fee_params {
@@ -335,7 +335,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("money::token_freeze", tx, block_height, self.verify_fees).await?;
 
 
         let mut found_owncoins = vec![];
         let mut found_owncoins = vec![];
         if let Some(ref fee_params) = fee_params {
         if let Some(ref fee_params) = fee_params {

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

@@ -126,7 +126,7 @@ impl TestHarness {
         let wallet = self.holders.get_mut(holder).unwrap();
         let wallet = self.holders.get_mut(holder).unwrap();
 
 
         // Execute the transaction
         // Execute the transaction
-        wallet.validator.add_transactions(&[tx], block_height, true, self.verify_fees).await?;
+        wallet.add_transaction("money::transfer", tx, block_height, self.verify_fees).await?;
 
 
         // Iterate over all inputs to mark any spent coins
         // Iterate over all inputs to mark any spent coins
         let mut inputs: Vec<Input> = call_params.inputs.to_vec();
         let mut inputs: Vec<Input> = call_params.inputs.to_vec();