From 6ddb245152aeac03ae9c48c00e67fb48399c1ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lasse=20M=C3=B8ldrup?= Date: Wed, 27 Sep 2023 13:26:32 +0200 Subject: [PATCH] Refactor generator based on PR feedback --- deps/concordium-rust-sdk | 2 +- generator/Cargo.lock | 27 +-- generator/src/generator.rs | 439 ++++++++++++++++++------------------- generator/src/main.rs | 28 ++- 4 files changed, 242 insertions(+), 254 deletions(-) diff --git a/deps/concordium-rust-sdk b/deps/concordium-rust-sdk index 736c0203..1462970d 160000 --- a/deps/concordium-rust-sdk +++ b/deps/concordium-rust-sdk @@ -1 +1 @@ -Subproject commit 736c020379d9249111c07374c6f8417cff7fce40 +Subproject commit 1462970dbc045f1b1b64eb3fdca7ddae0321d3ae diff --git a/generator/Cargo.lock b/generator/Cargo.lock index 9fa2d33b..0855a058 100644 --- a/generator/Cargo.lock +++ b/generator/Cargo.lock @@ -467,8 +467,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "concordium-contracts-common" -version = "7.0.0" +version = "8.0.0" dependencies = [ + "base64 0.21.0", "bs58", "chrono", "concordium-contracts-common-derive", @@ -486,16 +487,16 @@ dependencies = [ [[package]] name = "concordium-contracts-common-derive" -version = "3.0.0" +version = "4.0.0" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] name = "concordium-rust-sdk" -version = "3.0.0" +version = "3.0.1" dependencies = [ "aes-gcm", "anyhow", @@ -524,7 +525,7 @@ dependencies = [ [[package]] name = "concordium-smart-contract-engine" -version = "2.0.0" +version = "3.0.0" dependencies = [ "anyhow", "byteorder", @@ -547,7 +548,7 @@ dependencies = [ [[package]] name = "concordium-wasm" -version = "2.0.0" +version = "3.0.0" dependencies = [ "anyhow", "concordium-contracts-common", @@ -558,7 +559,7 @@ dependencies = [ [[package]] name = "concordium_base" -version = "2.0.0" +version = "3.0.1" dependencies = [ "aes", "anyhow", @@ -606,7 +607,7 @@ version = "1.0.0" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] @@ -1480,23 +1481,23 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] diff --git a/generator/src/generator.rs b/generator/src/generator.rs index a7f0a979..38fe012d 100644 --- a/generator/src/generator.rs +++ b/generator/src/generator.rs @@ -1,18 +1,23 @@ use anyhow::Context; use concordium_rust_sdk::{ - cis2::{AdditionalData, Receiver, TokenAmount, TokenId, Transfer, TransferParams}, + base::cis4_types::CredentialInfo, + cis2::{ + AdditionalData, Cis2Contract, Cis2TransactionMetadata, Receiver, TokenAmount, TokenId, + Transfer, + }, + cis4::{Cis4Contract, Cis4TransactionMetadata}, common::{ types::{Amount, KeyPair, TransactionTime}, Deserial, }, - contract_client::{MetadataUrl, SchemaRef}, + contract_client::{ContractTransactionMetadata, MetadataUrl, SchemaRef}, id::types::AccountAddress, smart_contracts::{common as concordium_std, common::Timestamp}, types::{ - smart_contracts::{OwnedContractName, OwnedParameter, OwnedReceiveName, WasmModule}, + smart_contracts::{OwnedContractName, OwnedParameter, WasmModule}, transactions::{ - send, AccountTransaction, BlockItem, EncodedPayload, InitContractPayload, - UpdateContractPayload, + send, send::GivenEnergy, AccountTransaction, BlockItem, EncodedPayload, + InitContractPayload, }, Address, ContractAddress, Energy, NodeDetails, Nonce, WalletAccount, }, @@ -21,14 +26,14 @@ use concordium_rust_sdk::{ }; use futures::TryStreamExt; use rand::{rngs::StdRng, Rng, SeedableRng}; -use std::{collections, collections::BTreeMap, io::Cursor, sync::Arc}; +use std::{collections, collections::BTreeMap, io::Cursor}; use crate::{CcdArgs, Mode, TransferCis2Args}; -// All contracts are taken from +// All contracts were taken from // https://github.com/Concordium/concordium-rust-smart-contracts/tree/fcc668d87207aaf07b43f5a3b02b6d0a634368d0/examples -// They were built by running `cargo concordium build` in their respective -// directories. +// They were built by running `cargo concordium build` (cargo-concordium version +// 3.0.0, Rust version 1.70.0) in their respective directories. const MINT_CIS2_MODULE: &[u8] = include_bytes!("../resources/cis2_nft.wasm.v1"); const TRANSFER_CIS2_MODULE: &[u8] = include_bytes!("../resources/cis2_multi.wasm.v1"); const WCCD_MODULE: &[u8] = include_bytes!("../resources/cis2_wccd.wasm.v1"); @@ -45,65 +50,51 @@ struct ContractDeploymentInfo { init_energy: Energy, } -/// A transaction generator. -pub trait Generate { - /// Generate a transaction. Will be called in a loop. - fn generate(&mut self) -> anyhow::Result>; -} - -#[derive(Clone)] -/// Arguments used by all transaction generators. -pub struct CommonArgs { - pub client: v2::Client, - pub keys: Arc, - pub tps: u16, - pub expiry: u32, -} - -impl CommonArgs { +impl ContractDeploymentInfo { /// Deploys and initializes a contract based on a [`ContractDeploymentInfo`] /// and an [`OwnedParameter`] to the init function. Also uses and increments /// a supplied nonce. async fn deploy_and_init_contract( - &mut self, - info: ContractDeploymentInfo, + &self, + client: &mut v2::Client, + args: &CommonArgs, param: OwnedParameter, nonce: &mut Nonce, ) -> anyhow::Result { println!("Deploying and initializing contract..."); // Deploy module. - let expiry: TransactionTime = TransactionTime::seconds_after(self.expiry); - let module = WasmModule::deserial(&mut Cursor::new(info.module))?; + let expiry: TransactionTime = TransactionTime::seconds_after(args.expiry); + let module = WasmModule::deserial(&mut Cursor::new(self.module))?; let mod_ref = module.get_module_ref(); - let deploy_tx = send::deploy_module(&*self.keys, self.keys.address, *nonce, expiry, module); + let deploy_tx = send::deploy_module(&args.keys, args.keys.address, *nonce, expiry, module); nonce.next_mut(); let item = BlockItem::AccountTransaction(deploy_tx); - self.client.send_block_item(&item).await?; + client.send_block_item(&item).await?; // We don't need to wait for deployment finalization, so we can send the init // transaction. let payload = InitContractPayload { amount: Amount::zero(), mod_ref, - init_name: OwnedContractName::new(info.name.into())?, + init_name: OwnedContractName::new(self.name.into())?, param, }; let init_tx = send::init_contract( - &*self.keys, - self.keys.address, + &args.keys, + args.keys.address, *nonce, expiry, payload, - info.init_energy, + self.init_energy, ); nonce.next_mut(); let item = BlockItem::AccountTransaction(init_tx); - let transaction_hash = self.client.send_block_item(&item).await?; + let transaction_hash = client.send_block_item(&item).await?; // Wait until contract is initialized. - let (_, summary) = self.client.wait_until_finalized(&transaction_hash).await?; + let (_, summary) = client.wait_until_finalized(&transaction_hash).await?; anyhow::ensure!( summary.is_success(), "Contract init transaction failed (hash = {transaction_hash})." @@ -118,30 +109,24 @@ impl CommonArgs { .context("Transaction was not a contract init") .map(|init| init.address) } +} - fn make_update_contract_transaction( - &self, - payload: UpdateContractPayload, - energy: Energy, - nonce: &mut Nonce, - ) -> anyhow::Result> { - let expiry = TransactionTime::seconds_after(self.expiry); - let tx = send::update_contract( - &*self.keys, - self.keys.address, - *nonce, - expiry, - payload, - energy, - ); - nonce.next_mut(); - Ok(tx) - } +/// A transaction generator. +pub trait Generate { + /// Generate a transaction. Will be called in a loop. + fn generate(&mut self) -> anyhow::Result>; +} + +/// Arguments used by all transaction generators. +pub struct CommonArgs { + pub keys: WalletAccount, + pub expiry: u32, } pub async fn generate_transactions( - mut args: CommonArgs, + mut client: v2::Client, mut generator: impl Generate + Send + 'static, + tps: u16, ) -> anyhow::Result<()> { // Create a channel between the task signing and the task sending transactions. let (sender, mut rx) = tokio::sync::mpsc::channel(100); @@ -156,7 +141,7 @@ pub async fn generate_transactions( }); let mut interval = tokio::time::interval(tokio::time::Duration::from_micros( - 1_000_000 / u64::from(args.tps), + 1_000_000 / u64::from(tps), )); loop { interval.tick().await; @@ -164,7 +149,7 @@ pub async fn generate_transactions( let nonce = tx.header.nonce; let energy = tx.header.energy_amount; let item = BlockItem::AccountTransaction(tx); - let transaction_hash = args.client.send_block_item(&item).await?; + let transaction_hash = client.send_block_item(&item).await?; println!( "{}: Transaction {} submitted (nonce = {nonce}, energy = {energy}).", chrono::Utc::now(), @@ -188,11 +173,15 @@ pub struct CcdGenerator { } impl CcdGenerator { - pub async fn instantiate(mut args: CommonArgs, ccd_args: CcdArgs) -> anyhow::Result { + pub async fn instantiate( + mut client: v2::Client, + args: CommonArgs, + ccd_args: CcdArgs, + ) -> anyhow::Result { // Get the list of receivers. let accounts: Vec = match ccd_args.receivers { None => { - args.client + client .get_account_list(BlockIdentifier::LastFinal) .await .context("Could not obtain a list of accounts.")? @@ -212,7 +201,7 @@ impl CcdGenerator { let (random, accounts) = match ccd_args.mode { Some(Mode::Random) => (true, accounts), Some(Mode::Every(n)) if n > 0 => { - let ni = args.client.get_node_info().await?; + let ni = client.get_node_info().await?; if let NodeDetails::Node(nd) = ni.details { let baker = nd .baker() @@ -232,8 +221,7 @@ impl CcdGenerator { }; // Get the initial nonce. - let nonce = args - .client + let nonce = client .get_next_account_sequence_number(&args.keys.address) .await?; anyhow::ensure!(nonce.all_final, "Not all transactions are finalized."); @@ -262,7 +250,7 @@ impl Generate for CcdGenerator { let expiry = TransactionTime::seconds_after(self.args.expiry); let tx = send::transfer( - &*self.args.keys, + &self.args.keys, self.args.keys.address, self.nonce, expiry, @@ -280,10 +268,10 @@ impl Generate for CcdGenerator { /// A generator that makes transactions that mints CIS-2 NFT tokens for the /// sender. pub struct MintCis2Generator { - args: CommonArgs, - contract_address: ContractAddress, - nonce: Nonce, - next_id: u32, + client: Cis2Contract, + args: CommonArgs, + nonce: Nonce, + next_id: u32, } #[derive(concordium_std::Serial)] @@ -294,10 +282,9 @@ struct MintCis2NftParams { } impl MintCis2Generator { - pub async fn instantiate(mut args: CommonArgs) -> anyhow::Result { + pub async fn instantiate(mut client: v2::Client, args: CommonArgs) -> anyhow::Result { // Get the initial nonce. - let mut nonce = args - .client + let mut nonce = client .get_next_account_sequence_number(&args.keys.address) .await?; @@ -307,14 +294,20 @@ impl MintCis2Generator { name: "init_cis2_nft", init_energy: Energy::from(2397), }; - let contract_address = args - .deploy_and_init_contract(info, OwnedParameter::empty(), &mut nonce.nonce) + let contract_address = info + .deploy_and_init_contract( + &mut client, + &args, + OwnedParameter::empty(), + &mut nonce.nonce, + ) .await .context("Could not deploy/init the contract.")?; + let client = Cis2Contract::create(client, contract_address).await?; Ok(Self { + client, args, - contract_address, nonce: nonce.nonce, next_id: 0, }) @@ -329,16 +322,20 @@ impl Generate for MintCis2Generator { tokens: [TokenId::new_u32(self.next_id)].into(), }; - let payload = UpdateContractPayload { - amount: Amount::zero(), - address: self.contract_address, - receive_name: OwnedReceiveName::new("cis2_nft.mint".into())?, - message: OwnedParameter::from_serial(¶ms)?, + let metadata = ContractTransactionMetadata { + sender_address: self.args.keys.address, + nonce: self.nonce, + expiry: TransactionTime::seconds_after(self.args.expiry), + energy: GivenEnergy::Absolute(Energy::from(3500)), + amount: Amount::zero(), }; - let energy = Energy::from(3500); - let tx = self - .args - .make_update_contract_transaction(payload, energy, &mut self.nonce)?; + let tx = self.client.make_update::<_, anyhow::Error>( + &self.args.keys, + &metadata, + "mint", + ¶ms, + )?; + self.nonce.next_mut(); self.next_id += 1; Ok(tx) @@ -348,11 +345,11 @@ impl Generate for MintCis2Generator { /// A generator that makes transactions that transfer CIS-2 tokens to a list of /// accounts. pub struct TransferCis2Generator { - args: CommonArgs, - contract_address: ContractAddress, - accounts: Vec, - nonce: Nonce, - count: usize, + client: Cis2Contract, + args: CommonArgs, + accounts: Vec, + nonce: Nonce, + count: usize, } #[derive(concordium_std::Serial)] @@ -369,13 +366,14 @@ struct MintCis2TokenParams { impl TransferCis2Generator { pub async fn instantiate( - mut args: CommonArgs, + mut client: v2::Client, + args: CommonArgs, transfer_cis2_args: TransferCis2Args, ) -> anyhow::Result { // Get the list of receivers. let accounts: Vec = match transfer_cis2_args.receivers { None => { - args.client + client .get_account_list(BlockIdentifier::LastFinal) .await .context("Could not obtain a list of accounts.")? @@ -392,8 +390,7 @@ impl TransferCis2Generator { anyhow::ensure!(!accounts.is_empty(), "List of receivers must not be empty."); // Get the initial nonce. - let mut nonce = args - .client + let mut nonce = client .get_next_account_sequence_number(&args.keys.address) .await?; @@ -403,11 +400,18 @@ impl TransferCis2Generator { name: "init_cis2_multi", init_energy: Energy::from(2353), }; - let contract_address = args - .deploy_and_init_contract(info, OwnedParameter::empty(), &mut nonce.nonce) + let contract_address = info + .deploy_and_init_contract( + &mut client, + &args, + OwnedParameter::empty(), + &mut nonce.nonce, + ) .await .context("Could not deploy/init the contract.")?; + let mut client = Cis2Contract::create(client, contract_address).await?; + // The rest of the function mints u64::MAX tokens for the sender. println!("Minting u64::MAX tokens for ourselves..."); @@ -420,19 +424,22 @@ impl TransferCis2Generator { tokens: [(TokenId::new_u8(0), param)].into(), }; - let payload = UpdateContractPayload { - amount: Amount::zero(), - address: contract_address, - receive_name: OwnedReceiveName::new("cis2_multi.mint".into())?, - message: OwnedParameter::from_serial(¶ms)?, + let metadata = ContractTransactionMetadata { + sender_address: args.keys.address, + nonce: nonce.nonce, + expiry: TransactionTime::seconds_after(args.expiry), + energy: GivenEnergy::Absolute(Energy::from(2740)), + amount: Amount::zero(), }; + let transaction_hash = client + .update::<_, anyhow::Error>(&args.keys, &metadata, "mint", ¶ms) + .await?; + nonce.nonce.next_mut(); - let mint_tx = - args.make_update_contract_transaction(payload, Energy::from(2740), &mut nonce.nonce)?; - let block_item = BlockItem::AccountTransaction(mint_tx); - let transaction_hash = args.client.send_block_item(&block_item).await?; - - let (_, summary) = args.client.wait_until_finalized(&transaction_hash).await?; + let (_, summary) = client + .client + .wait_until_finalized(&transaction_hash) + .await?; anyhow::ensure!( summary.is_success(), "Mint transaction failed (hash = {transaction_hash})." @@ -443,8 +450,8 @@ impl TransferCis2Generator { ); Ok(Self { + client, args, - contract_address, accounts, nonce: nonce.nonce, count: 0, @@ -455,27 +462,25 @@ impl TransferCis2Generator { impl Generate for TransferCis2Generator { fn generate(&mut self) -> anyhow::Result> { let next_account = self.accounts[self.count % self.accounts.len()]; - let params = TransferParams::new( - [Transfer { - token_id: TokenId::new_u8(0), - amount: TokenAmount::from(1u32), - from: Address::Account(self.args.keys.address), - to: Receiver::Account(next_account), - data: AdditionalData::new(vec![])?, - }] - .to_vec(), - )?; + let transfer = Transfer { + token_id: TokenId::new_u8(0), + amount: TokenAmount::from(1u32), + from: Address::Account(self.args.keys.address), + to: Receiver::Account(next_account), + data: AdditionalData::new(vec![])?, + }; - let payload = UpdateContractPayload { - amount: Amount::zero(), - address: self.contract_address, - receive_name: OwnedReceiveName::new("cis2_multi.transfer".into())?, - message: OwnedParameter::from_serial(¶ms)?, + let metadata = Cis2TransactionMetadata { + sender_address: self.args.keys.address, + nonce: self.nonce, + expiry: TransactionTime::seconds_after(self.args.expiry), + energy: GivenEnergy::Absolute(Energy::from(3500)), + amount: Amount::zero(), }; - let energy = Energy::from(3500); let tx = self - .args - .make_update_contract_transaction(payload, energy, &mut self.nonce)?; + .client + .make_transfer_single(&self.args.keys, metadata, transfer)?; + self.nonce.next_mut(); self.count += 1; Ok(tx) @@ -484,10 +489,10 @@ impl Generate for TransferCis2Generator { /// A generator that makes transactions that wrap, unwrap, and transfer WCCDs. pub struct WccdGenerator { - args: CommonArgs, - contract_address: ContractAddress, - nonce: Nonce, - count: usize, + client: Cis2Contract, + args: CommonArgs, + nonce: Nonce, + count: usize, } #[derive(concordium_std::Serial)] @@ -511,10 +516,9 @@ struct UnwrapParams { } impl WccdGenerator { - pub async fn instantiate(mut args: CommonArgs) -> anyhow::Result { + pub async fn instantiate(mut client: v2::Client, args: CommonArgs) -> anyhow::Result { // Get the initial nonce. - let mut nonce = args - .client + let mut nonce = client .get_next_account_sequence_number(&args.keys.address) .await?; @@ -527,9 +531,10 @@ impl WccdGenerator { url: "https://example.com".into(), hash: None, }; - let contract_address = args + let contract_address = info .deploy_and_init_contract( - info, + &mut client, + &args, OwnedParameter::from_serial(¶ms)?, &mut nonce.nonce, ) @@ -539,8 +544,7 @@ impl WccdGenerator { // Give everyone on the network a wCCD token to increase the size of the state // of the contract. println!("Minting wCCD tokens for everyone..."); - let receivers: Vec<_> = args - .client + let receivers: Vec<_> = client .get_account_list(BlockIdentifier::LastFinal) .await .context("Could not obtain a list of accounts.")? @@ -548,26 +552,25 @@ impl WccdGenerator { .try_collect() .await?; + let mut client = Cis2Contract::create(client, contract_address).await?; + for recv in receivers { let params = WrapParams { to: Receiver::Account(recv), data: AdditionalData::new(vec![])?, }; - let payload = UpdateContractPayload { - amount: Amount::from_micro_ccd(1), - address: contract_address, - receive_name: OwnedReceiveName::new("cis2_wCCD.wrap".into())?, - message: OwnedParameter::from_serial(¶ms)?, + let metadata = ContractTransactionMetadata { + sender_address: args.keys.address, + nonce: nonce.nonce, + expiry: TransactionTime::seconds_after(args.expiry), + energy: GivenEnergy::Absolute(Energy::from(3500)), + amount: Amount::from_micro_ccd(1), }; - - let wrap_tx = args.make_update_contract_transaction( - payload, - Energy::from(3500), - &mut nonce.nonce, - )?; - let block_item = BlockItem::AccountTransaction(wrap_tx); - let transaction_hash = args.client.send_block_item(&block_item).await?; + let transaction_hash = client + .update::<_, anyhow::Error>(&args.keys, &metadata, "wrap", ¶ms) + .await?; + nonce.nonce.next_mut(); println!( "{}: Transferred 1 wCCD to {recv} (hash = {transaction_hash}).", chrono::Utc::now(), @@ -575,8 +578,8 @@ impl WccdGenerator { } Ok(Self { + client, args, - contract_address, nonce: nonce.nonce, count: 0, }) @@ -585,44 +588,46 @@ impl WccdGenerator { impl Generate for WccdGenerator { fn generate(&mut self) -> anyhow::Result> { + let mut metadata = ContractTransactionMetadata { + sender_address: self.args.keys.address, + nonce: self.nonce, + expiry: TransactionTime::seconds_after(self.args.expiry), + energy: GivenEnergy::Absolute(Energy::from(3500)), + amount: Amount::zero(), + }; + // We modulate between wrapping, transferring, and unwrapping. All wCCD are // minted for and transferred to our own account, which is fine for testing, // since there is no special logic for this in the contract. - let payload = match self.count % 3 { + let tx = match self.count % 3 { // Wrap 0 => { let params = WrapParams { to: Receiver::Account(self.args.keys.address), data: AdditionalData::new(vec![])?, }; - - UpdateContractPayload { - amount: Amount::from_micro_ccd(1), - address: self.contract_address, - receive_name: OwnedReceiveName::new("cis2_wCCD.wrap".into())?, - message: OwnedParameter::from_serial(¶ms)?, - } + metadata.amount = Amount::from_micro_ccd(1); + + self.client.make_update::<_, anyhow::Error>( + &self.args.keys, + &metadata, + "wrap", + ¶ms, + )? } // Transfer 1 => { - let params = TransferParams::new( - [Transfer { - // The token id of wCCD is 0. - token_id: TokenId::new(vec![])?, - amount: TokenAmount::from(1u32), - from: Address::Account(self.args.keys.address), - to: Receiver::Account(self.args.keys.address), - data: AdditionalData::new(vec![])?, - }] - .to_vec(), - )?; - - UpdateContractPayload { - amount: Amount::zero(), - address: self.contract_address, - receive_name: OwnedReceiveName::new("cis2_wCCD.transfer".into())?, - message: OwnedParameter::from_serial(¶ms)?, - } + let transfer = Transfer { + // The token id of wCCD is the empty list of bytes. + token_id: TokenId::new(vec![])?, + amount: TokenAmount::from(1u32), + from: Address::Account(self.args.keys.address), + to: Receiver::Account(self.args.keys.address), + data: AdditionalData::new(vec![])?, + }; + + self.client + .make_transfer_single(&self.args.keys, metadata, transfer)? } // Unwrap _ => { @@ -633,20 +638,15 @@ impl Generate for WccdGenerator { data: AdditionalData::new(vec![])?, }; - UpdateContractPayload { - amount: Amount::zero(), - address: self.contract_address, - receive_name: OwnedReceiveName::new("cis2_wCCD.unwrap".into())?, - message: OwnedParameter::from_serial(¶ms)?, - } + self.client.make_update::<_, anyhow::Error>( + &self.args.keys, + &metadata, + "unwrap", + ¶ms, + )? } }; - - let tx = self.args.make_update_contract_transaction( - payload, - Energy::from(3500), - &mut self.nonce, - )?; + self.nonce.next_mut(); self.count += 1; Ok(tx) @@ -655,10 +655,10 @@ impl Generate for WccdGenerator { /// A generator that makes transactions that register dummy Web3 ID credentials. pub struct RegisterCredentialsGenerator { - args: CommonArgs, - contract_address: ContractAddress, - nonce: Nonce, - rng: StdRng, + client: Cis4Contract, + args: CommonArgs, + nonce: Nonce, + rng: StdRng, } #[derive(concordium_std::Serial)] @@ -678,15 +678,6 @@ struct RegisterCredentialsInitParams { revocation_keys: Vec, } -#[derive(concordium_std::Serial)] -struct CredentialInfo { - holder_id: CredentialHolderId, - holder_revocable: bool, - valid_from: Timestamp, - valid_until: Option, - metadata_url: MetadataUrl, -} - #[derive(concordium_std::Serial)] struct RegisterCredentialParams { credential_info: CredentialInfo, @@ -695,10 +686,9 @@ struct RegisterCredentialParams { } impl RegisterCredentialsGenerator { - pub async fn instantiate(mut args: CommonArgs) -> anyhow::Result { + pub async fn instantiate(mut client: v2::Client, args: CommonArgs) -> anyhow::Result { // Get the initial nonce. - let mut nonce = args - .client + let mut nonce = client .get_next_account_sequence_number(&args.keys.address) .await?; @@ -725,18 +715,20 @@ impl RegisterCredentialsGenerator { revocation_keys: vec![], }; - let contract_address = args + let contract_address = info .deploy_and_init_contract( - info, + &mut client, + &args, OwnedParameter::from_serial(¶ms)?, &mut nonce.nonce, ) .await .context("Could not deploy/init the contract.")?; + let client = Cis4Contract::create(client, contract_address).await?; Ok(Self { + client, args, - contract_address, nonce: nonce.nonce, rng, }) @@ -748,28 +740,25 @@ impl Generate for RegisterCredentialsGenerator { // Create 32 byte holder id. let public_key = KeyPair::generate(&mut self.rng).public; - let params = RegisterCredentialParams { - // The credential details don't matter, since we are just testing tps. - credential_info: CredentialInfo { - holder_id: CredentialHolderId::new(public_key), - holder_revocable: false, - valid_from: Timestamp::from_timestamp_millis(0), - valid_until: None, - metadata_url: MetadataUrl::new("https://example.com".into(), None)?, - }, - auxiliary_data: vec![], + let cred_info = CredentialInfo { + holder_id: CredentialHolderId::new(public_key), + holder_revocable: false, + valid_from: Timestamp::from_timestamp_millis(0), + valid_until: None, + metadata_url: MetadataUrl::new("https://example.com".into(), None)?, }; - let payload = UpdateContractPayload { - amount: Amount::zero(), - address: self.contract_address, - receive_name: OwnedReceiveName::new("credential_registry.registerCredential".into())?, - message: OwnedParameter::from_serial(¶ms)?, + let metadata = Cis4TransactionMetadata { + sender_address: self.args.keys.address, + nonce: self.nonce, + expiry: TransactionTime::seconds_after(self.args.expiry), + energy: GivenEnergy::Absolute(Energy::from(5000)), + amount: Amount::zero(), }; - let energy = Energy::from(5000); - let tx = self - .args - .make_update_contract_transaction(payload, energy, &mut self.nonce)?; + let tx = + self.client + .make_register_credential(&self.args.keys, &metadata, &cred_info, &[])?; + self.nonce.next_mut(); Ok(tx) } diff --git a/generator/src/main.rs b/generator/src/main.rs index 68db846e..77a19c0f 100644 --- a/generator/src/main.rs +++ b/generator/src/main.rs @@ -10,7 +10,7 @@ use generator::{ generate_transactions, CcdGenerator, CommonArgs, MintCis2Generator, RegisterCredentialsGenerator, TransferCis2Generator, WccdGenerator, }; -use std::{path::PathBuf, str::FromStr, sync::Arc}; +use std::{path::PathBuf, str::FromStr}; mod generator; @@ -124,35 +124,33 @@ async fn main() -> anyhow::Result<()> { let keys: WalletAccount = WalletAccount::from_json_file(app.account).context("Could not parse the keys file.")?; - let args = CommonArgs { - client, - keys: Arc::new(keys), - tps: app.tps, + keys, expiry: app.expiry, }; match app.command { Command::Ccd(ccd_args) => { - let generator = CcdGenerator::instantiate(args.clone(), ccd_args).await?; - generate_transactions(args, generator).await + let generator = CcdGenerator::instantiate(client.clone(), args, ccd_args).await?; + generate_transactions(client, generator, app.tps).await } Command::MintNfts => { - let generator = MintCis2Generator::instantiate(args.clone()).await?; - generate_transactions(args, generator).await + let generator = MintCis2Generator::instantiate(client.clone(), args).await?; + generate_transactions(client, generator, app.tps).await } Command::TransferCis2(transfer_cis2_args) => { let generator = - TransferCis2Generator::instantiate(args.clone(), transfer_cis2_args).await?; - generate_transactions(args, generator).await + TransferCis2Generator::instantiate(client.clone(), args, transfer_cis2_args) + .await?; + generate_transactions(client, generator, app.tps).await } Command::Wccd => { - let generator = WccdGenerator::instantiate(args.clone()).await?; - generate_transactions(args, generator).await + let generator = WccdGenerator::instantiate(client.clone(), args).await?; + generate_transactions(client, generator, app.tps).await } Command::RegisterCredentials => { - let generator = RegisterCredentialsGenerator::instantiate(args.clone()).await?; - generate_transactions(args, generator).await + let generator = RegisterCredentialsGenerator::instantiate(client.clone(), args).await?; + generate_transactions(client, generator, app.tps).await } } }