contract/deployooor: Add initial integration test

This commit is contained in:
parazyd
2024-01-09 14:12:42 +01:00
parent fecab39d77
commit b232d9a85a
7 changed files with 157 additions and 6 deletions

2
Cargo.lock generated
View File

@@ -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",
]

View File

@@ -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]

View File

@@ -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

View File

@@ -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

View File

@@ -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(())
})
}

View File

@@ -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(())
}
}

View File

@@ -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 {