Преглед на файлове

contract/deployooor: Add initial integration test

parazyd преди 2 години
родител
ревизия
b232d9a85a

+ 2 - 0
Cargo.lock

@@ -1972,11 +1972,13 @@ name = "darkfi_deployooor_contract"
 version = "0.4.1"
 dependencies = [
  "darkfi",
+ "darkfi-contract-test-harness",
  "darkfi-sdk",
  "darkfi-serial",
  "getrandom 0.2.11",
  "log",
  "rand 0.8.5",
+ "smol",
  "thiserror",
  "wasmparser 0.118.1",
 ]

+ 5 - 0
src/contract/deployooor/Cargo.toml

@@ -20,6 +20,11 @@ darkfi = { path = "../../../", features = ["zk"], optional = true }
 log = { version = "0.4.20", optional = true }
 rand = { version = "0.8.5", optional = true }
 
+# These are used for integration tests
+[dev-dependencies]
+darkfi-contract-test-harness = {path = "../test-harness"}
+smol = "1.3.0"
+
 # We need to disable random using "custom" which makes the crate a noop
 # so the wasm32-unknown-unknown target is enabled.
 [target.'cfg(target_arch = "wasm32")'.dependencies]

+ 9 - 1
src/contract/deployooor/Makefile

@@ -43,6 +43,14 @@ $(WASM_BIN): $(WASM_SRC) $(PROOFS_BIN)
 		--release --package $(PKGNAME)
 	cp -f ../../../target/$(WASM_TARGET)/release/$@ $@
 
+test-integration: all
+	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) test --target=$(RUST_TARGET) \
+		--release --package $(PKGNAME) \
+		--features=no-entrypoint,client \
+		--test integration
+
+test: test-integration
+
 clippy: all
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clippy --target=$(WASM_TARGET) \
 		--release --package $(PKGNAME)
@@ -57,4 +65,4 @@ clean:
 		--release --package $(PKGNAME)
 	rm -f $(PROOFS_BIN) $(WASM_BIN)
 
-.PHONY: all clippy clean
+.PHONY: all test-integration test clippy clean

+ 1 - 1
src/contract/deployooor/src/entrypoint.rs

@@ -52,7 +52,7 @@ darkfi_sdk::define_contract!(
 /// with initial data if necessary.
 fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
     // Set up the zkas circuit tree
-    let derive_cid_bincode = include_bytes!("../proof/derive_contract_id.zk");
+    let derive_cid_bincode = include_bytes!("../proof/derive_contract_id.zk.bin");
     zkas_db_set(&derive_cid_bincode[..])?;
 
     // Set up a database tree for arbitrary data

+ 48 - 0
src/contract/deployooor/tests/integration.rs

@@ -0,0 +1,48 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2023 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi::Result;
+use darkfi_contract_test_harness::{init_logger, Holder, TestHarness};
+use log::info;
+
+#[test]
+#[ignore]
+fn deploy_integration() -> Result<()> {
+    smol::block_on(async {
+        init_logger();
+
+        // Slot to verify against
+        let current_slot = 0;
+
+        // Initialize harness
+        let mut th = TestHarness::new(&["money".to_string(), "deployooor".to_string()]).await?;
+
+        // WASM bincode to deploy
+        let wasm_bincode = include_bytes!("../../dao/darkfi_dao_contract.wasm");
+
+        info!("[Alice] Building deploy tx");
+        let (deploy_tx, deploy_params) =
+            th.deploy_contract(&Holder::Alice, wasm_bincode.to_vec())?;
+
+        info!("[Alice] Executing deploy tx");
+        th.execute_deploy_tx(&Holder::Alice, &deploy_tx, &deploy_params, current_slot).await?;
+
+        // Thanks for reading
+        Ok(())
+    })
+}

+ 79 - 0
src/contract/test-harness/src/contract_deploy.rs

@@ -0,0 +1,79 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2023 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi::{
+    tx::{ContractCallLeaf, Transaction, TransactionBuilder},
+    Result,
+};
+use darkfi_deployooor_contract::{
+    client::deploy_v1::DeployCallBuilder, DeployFunction, DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1,
+};
+use darkfi_sdk::{crypto::DEPLOYOOOR_CONTRACT_ID, deploy::DeployParamsV1, ContractCall};
+use darkfi_serial::Encodable;
+use rand::rngs::OsRng;
+
+use super::{Holder, TestHarness};
+
+impl TestHarness {
+    pub fn deploy_contract(
+        &mut self,
+        holder: &Holder,
+        wasm_bincode: Vec<u8>,
+    ) -> Result<(Transaction, DeployParamsV1)> {
+        let wallet = self.holders.get(holder).unwrap();
+        let deploy_keypair = wallet.contract_deploy_authority;
+
+        let (derivecid_pk, derivecid_zkbin) =
+            self.proving_keys.get(&DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1.to_string()).unwrap();
+
+        let builder = DeployCallBuilder {
+            deploy_keypair,
+            wasm_bincode,
+            deploy_ix: vec![],
+            derivecid_zkbin: derivecid_zkbin.clone(),
+            derivecid_pk: derivecid_pk.clone(),
+        };
+
+        let debris = builder.build()?;
+
+        let mut data = vec![DeployFunction::DeployV1 as u8];
+        debris.params.encode(&mut data)?;
+        let call = ContractCall { contract_id: *DEPLOYOOOR_CONTRACT_ID, data };
+        let mut tx_builder =
+            TransactionBuilder::new(ContractCallLeaf { call, proofs: debris.proofs }, vec![])?;
+        let mut tx = tx_builder.build()?;
+        let sigs = tx.create_sigs(&mut OsRng, &[deploy_keypair.secret])?;
+        tx.signatures = vec![sigs];
+
+        Ok((tx, debris.params))
+    }
+
+    pub async fn execute_deploy_tx(
+        &mut self,
+        holder: &Holder,
+        tx: &Transaction,
+        _params: &DeployParamsV1,
+        slot: u64,
+    ) -> Result<()> {
+        let wallet = self.holders.get_mut(holder).unwrap();
+
+        wallet.validator.add_transactions(&[tx.clone()], slot, true).await?;
+
+        Ok(())
+    }
+}

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

@@ -40,8 +40,8 @@ use darkfi_sdk::{
     blockchain::{PidOutput, PreviousSlot, Slot},
     bridgetree,
     crypto::{
-        pasta_prelude::Field, poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey,
-        SecretKey, TokenId,
+        pasta_prelude::Field, poseidon_hash, ContractId, Keypair, MerkleNode, MerkleTree,
+        Nullifier, PublicKey, SecretKey, TokenId,
     },
     pasta::pallas,
 };
@@ -58,6 +58,7 @@ mod consensus_proposal;
 mod consensus_stake;
 mod consensus_unstake;
 mod consensus_unstake_request;
+mod contract_deploy;
 mod dao_exec;
 mod dao_mint;
 mod dao_propose;
@@ -77,8 +78,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,
@@ -125,6 +126,7 @@ pub enum TxAction {
 pub struct Wallet {
     pub keypair: Keypair,
     pub token_mint_authority: Keypair,
+    pub contract_deploy_authority: Keypair,
     pub validator: ValidatorPtr,
     pub money_merkle_tree: MerkleTree,
     pub consensus_staked_merkle_tree: MerkleTree,
@@ -182,10 +184,12 @@ impl Wallet {
         let spent_money_coins = vec![];
 
         let token_mint_authority = Keypair::random(&mut OsRng);
+        let contract_deploy_authority = Keypair::random(&mut OsRng);
 
         Ok(Self {
             keypair,
             token_mint_authority,
+            contract_deploy_authority,
             validator,
             money_merkle_tree,
             consensus_staked_merkle_tree,
@@ -494,6 +498,11 @@ impl TestHarness {
         TokenId::derive_public(holder.token_mint_authority.public)
     }
 
+    pub fn contract_id(&self, holder: &Holder) -> ContractId {
+        let holder = self.holders.get(holder).unwrap();
+        ContractId::derive_public(holder.contract_deploy_authority.public)
+    }
+
     pub fn statistics(&self) {
         info!("==================== Statistics ====================");
         for (action, tx_action_benchmark) in &self.tx_action_benchmarks {