From 7a179b70d21b267243c9d9e578630d82efd0024b Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Mon, 3 Jun 2024 14:45:37 +0300 Subject: [PATCH 1/7] feat!: Add args payload to by call triggers Signed-off-by: Shanin Roman --- configs/swarm/executor.wasm | Bin 500979 -> 501629 bytes core/src/smartcontracts/isi/triggers/mod.rs | 15 ++++++------- core/src/state.rs | 7 +----- data_model/src/events/execute_trigger.rs | 10 +++++++++ data_model/src/isi.rs | 23 +++++++++++++++++--- docs/source/references/schema.json | 11 ++++++++++ 6 files changed, 49 insertions(+), 17 deletions(-) diff --git a/configs/swarm/executor.wasm b/configs/swarm/executor.wasm index 2fb1146f22d01a0638733c3053c00ac34e335279..5a17bbb7aa83c955543d522649a62869e08ac20a 100644 GIT binary patch delta 106537 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 z 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 Aod5s; delta 105492 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 diff --git a/core/src/smartcontracts/isi/triggers/mod.rs b/core/src/smartcontracts/isi/triggers/mod.rs index 03e15e11d27..a6950a792ab 100644 --- a/core/src/smartcontracts/isi/triggers/mod.rs +++ b/core/src/smartcontracts/isi/triggers/mod.rs @@ -276,6 +276,12 @@ pub mod isi { ) -> Result<(), Error> { let id = &self.trigger; + let event = ExecuteTriggerEvent { + trigger_id: id.clone(), + authority: authority.clone(), + args: self.args, + }; + state_transaction .world .triggers @@ -283,11 +289,6 @@ pub mod isi { let allow_execute = if let TriggeringEventFilterBox::ExecuteTrigger(filter) = action.clone_and_box().filter { - let event = ExecuteTriggerEvent { - trigger_id: id.clone(), - authority: authority.clone(), - }; - filter.matches(&event) || action.authority() == authority } else { false @@ -305,9 +306,7 @@ pub mod isi { .ok_or_else(|| Error::Find(FindError::Trigger(id.clone()))) .and_then(core::convert::identity)?; - state_transaction - .world - .execute_trigger(id.clone(), authority); + state_transaction.world.execute_trigger(event); Ok(()) } diff --git a/core/src/state.rs b/core/src/state.rs index 2c711280929..7335d11de48 100644 --- a/core/src/state.rs +++ b/core/src/state.rs @@ -904,12 +904,7 @@ impl WorldTransaction<'_, '_> { /// then *trigger* will be executed on the **current** block /// - If this method is called by ISI inside *trigger*, /// then *trigger* will be executed on the **next** block - pub fn execute_trigger(&mut self, trigger_id: TriggerId, authority: &AccountId) { - let event = ExecuteTriggerEvent { - trigger_id, - authority: authority.clone(), - }; - + pub fn execute_trigger(&mut self, event: ExecuteTriggerEvent) { self.triggers.handle_execute_trigger_event(event.clone()); self.events_buffer.push(event.into()); } diff --git a/data_model/src/events/execute_trigger.rs b/data_model/src/events/execute_trigger.rs index 4a43f3b9f19..59324f91329 100644 --- a/data_model/src/events/execute_trigger.rs +++ b/data_model/src/events/execute_trigger.rs @@ -33,6 +33,9 @@ mod model { pub trigger_id: TriggerId, /// Authority of user who tries to execute trigger pub authority: AccountId, + /// Args to pass for trigger execution + #[getset(skip)] + pub args: Option, } /// Filter for trigger execution [`Event`] @@ -59,6 +62,13 @@ mod model { } } +impl ExecuteTriggerEvent { + /// Args to pass for trigger execution + pub fn args(&self) -> Option<&JsonString> { + self.args.as_ref() + } +} + impl ExecuteTriggerEventFilter { /// Creates a new [`ExecuteTriggerEventFilter`] accepting all [`ExecuteTriggerEvent`]s #[must_use] diff --git a/data_model/src/isi.rs b/data_model/src/isi.rs index b9203bb93c5..ca8e675c034 100644 --- a/data_model/src/isi.rs +++ b/data_model/src/isi.rs @@ -924,13 +924,30 @@ mod transparent { isi! { /// Instruction to execute specified trigger - #[derive(Constructor, Display)] + #[derive(Display)] #[display(fmt = "EXECUTE `{trigger}`")] - #[serde(transparent)] - #[repr(transparent)] pub struct ExecuteTrigger { /// Id of a trigger to execute pub trigger: TriggerId, + /// Arguments to trigger execution + pub args: Option, + } + } + + impl ExecuteTrigger { + /// Constructor for [`Self`] + pub fn new(trigger: TriggerId) -> Self { + Self { + trigger, + args: None, + } + } + + /// Add trigger execution args + #[must_use] + pub fn with_args(mut self, args: &T) -> Self { + self.args = Some(JsonString::new(args)); + self } } diff --git a/docs/source/references/schema.json b/docs/source/references/schema.json index 1ad22b2b46f..b8ef73c6e7e 100644 --- a/docs/source/references/schema.json +++ b/docs/source/references/schema.json @@ -1379,6 +1379,10 @@ { "name": "trigger", "type": "TriggerId" + }, + { + "name": "args", + "type": "Option" } ] }, @@ -1391,6 +1395,10 @@ { "name": "authority", "type": "AccountId" + }, + { + "name": "args", + "type": "Option" } ] }, @@ -2593,6 +2601,9 @@ "Option": { "Option": "IpfsPath" }, + "Option": { + "Option": "JsonString" + }, "Option": { "Option": "Name" }, From 599102c76e00d6cf2135916879576d6bde824823 Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Mon, 3 Jun 2024 16:41:52 +0300 Subject: [PATCH 2/7] test: check argument passing to trigger Signed-off-by: Shanin Roman --- .../integration/smartcontracts/Cargo.toml | 1 + .../mint_rose_trigger_args/Cargo.toml | 21 ++++++++ .../mint_rose_trigger_args/src/lib.rs | 45 +++++++++++++++++ .../integration/triggers/by_call_trigger.rs | 49 +++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml create mode 100644 client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs diff --git a/client/tests/integration/smartcontracts/Cargo.toml b/client/tests/integration/smartcontracts/Cargo.toml index 0f3b30ee49c..167394d6f1b 100644 --- a/client/tests/integration/smartcontracts/Cargo.toml +++ b/client/tests/integration/smartcontracts/Cargo.toml @@ -11,6 +11,7 @@ resolver = "2" members = [ "create_nft_for_every_user_trigger", "mint_rose_trigger", + "mint_rose_trigger_args", "executor_with_admin", "executor_with_custom_permission", "executor_with_custom_parameter", diff --git a/client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml b/client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml new file mode 100644 index 00000000000..996db21fa07 --- /dev/null +++ b/client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "mint_rose_args" + +edition.workspace = true +version.workspace = true +authors.workspace = true + +license.workspace = true + +[lib] +crate-type = ['cdylib'] + +[dependencies] +iroha_trigger.workspace = true + +panic-halt.workspace = true +lol_alloc.workspace = true +getrandom.workspace = true + +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true, default-features = false } \ No newline at end of file diff --git a/client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs b/client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs new file mode 100644 index 00000000000..f9f18f0b913 --- /dev/null +++ b/client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs @@ -0,0 +1,45 @@ +//! trigger which mints rose for its owner based on input args. + +#![no_std] + +#[cfg(not(test))] +extern crate panic_halt; + +use core::str::FromStr as _; + +use iroha_trigger::{debug::dbg_panic, prelude::*}; +use lol_alloc::{FreeListAllocator, LockedAllocator}; +use serde::{Deserialize, Serialize}; + +#[global_allocator] +static ALLOC: LockedAllocator = LockedAllocator::new(FreeListAllocator::new()); + +getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); + +#[derive(Serialize, Deserialize)] +struct Args { + val: u32, +} + +/// Mint 1 rose for owner +#[iroha_trigger::main] +fn main(_id: TriggerId, owner: AccountId, event: EventBox) { + let rose_definition_id = AssetDefinitionId::from_str("rose#wonderland") + .dbg_expect("Failed to parse `rose#wonderland` asset definition id"); + let rose_id = AssetId::new(rose_definition_id, owner); + + let args: Args = match event { + EventBox::ExecuteTrigger(event) => event + .args() + .dbg_expect("Trigger expect parameters") + .try_into_any() + .dbg_expect("Failed to parse args"), + _ => dbg_panic("Only work as by call trigger"), + }; + + let val = args.val; + + Mint::asset_numeric(val, rose_id) + .execute() + .dbg_expect("Failed to mint rose"); +} diff --git a/client/tests/integration/triggers/by_call_trigger.rs b/client/tests/integration/triggers/by_call_trigger.rs index 52a3096d1e7..6f3a32b2db3 100644 --- a/client/tests/integration/triggers/by_call_trigger.rs +++ b/client/tests/integration/triggers/by_call_trigger.rs @@ -13,6 +13,7 @@ use iroha::{ use iroha_executor_data_model::permission::trigger::CanRegisterUserTrigger; use iroha_genesis::GenesisBlock; use iroha_logger::info; +use serde::{Deserialize, Serialize}; use test_network::{Peer as TestPeer, *}; use test_samples::ALICE_ID; use tokio::runtime::Runtime; @@ -648,3 +649,51 @@ fn build_register_trigger_isi( ), )) } + +#[test] +fn call_execute_trigger_with_args() -> Result<()> { + let (_rt, _peer, mut test_client) = ::new().with_port(11_265).start_with_runtime(); + wait_for_genesis_committed(&vec![test_client.clone()], 0); + + let asset_definition_id = "rose#wonderland".parse()?; + let account_id = ALICE_ID.clone(); + let asset_id = AssetId::new(asset_definition_id, account_id.clone()); + let prev_value = get_asset_value(&mut test_client, asset_id.clone()); + + let trigger_id = TriggerId::from_str(TRIGGER_NAME)?; + let wasm = + iroha_wasm_builder::Builder::new("tests/integration/smartcontracts/mint_rose_trigger_args") + .show_output() + .build()? + .optimize()? + .into_bytes()?; + let wasm = WasmSmartContract::from_compiled(wasm); + let trigger = Trigger::new( + trigger_id.clone(), + Action::new( + wasm.clone(), + Repeats::Indefinitely, + account_id.clone(), + ExecuteTriggerEventFilter::new() + .for_trigger(trigger_id.clone()) + .under_authority(account_id.clone()), + ), + ); + + test_client.submit_blocking(Register::trigger(trigger))?; + + let args: Args = Args { val: 42 }; + let call_trigger = ExecuteTrigger::new(trigger_id).with_args(&args); + test_client.submit_blocking(call_trigger)?; + + let new_value = get_asset_value(&mut test_client, asset_id); + assert_eq!(new_value, prev_value.checked_add(numeric!(42)).unwrap()); + + Ok(()) +} + +/// Mirror trigger args for `mint_rose_trigger_args` +#[derive(Serialize, Deserialize)] +struct Args { + val: u32, +} From 48cea68f180a19b9bc8bfa3f8eb906dd0071c434 Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Thu, 20 Jun 2024 18:06:25 +0300 Subject: [PATCH 3/7] feat: create multisig account register trigger Signed-off-by: Shanin Roman --- .../integration/smartcontracts/Cargo.toml | 2 + .../smartcontracts/multisig/Cargo.toml | 24 ++++ .../smartcontracts/multisig/src/lib.rs | 130 ++++++++++++++++++ .../multisig_register/Cargo.toml | 25 ++++ .../smartcontracts/multisig_register/build.rs | 20 +++ .../multisig_register/src/lib.rs | 104 ++++++++++++++ data_model/src/lib.rs | 2 +- 7 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 client/tests/integration/smartcontracts/multisig/Cargo.toml create mode 100644 client/tests/integration/smartcontracts/multisig/src/lib.rs create mode 100644 client/tests/integration/smartcontracts/multisig_register/Cargo.toml create mode 100644 client/tests/integration/smartcontracts/multisig_register/build.rs create mode 100644 client/tests/integration/smartcontracts/multisig_register/src/lib.rs diff --git a/client/tests/integration/smartcontracts/Cargo.toml b/client/tests/integration/smartcontracts/Cargo.toml index 167394d6f1b..3e058bf4d77 100644 --- a/client/tests/integration/smartcontracts/Cargo.toml +++ b/client/tests/integration/smartcontracts/Cargo.toml @@ -22,6 +22,8 @@ members = [ "executor_custom_data_model", "query_assets_and_save_cursor", "smart_contract_can_filter_queries", + "multisig_register", + "multisig", ] [profile.dev] diff --git a/client/tests/integration/smartcontracts/multisig/Cargo.toml b/client/tests/integration/smartcontracts/multisig/Cargo.toml new file mode 100644 index 00000000000..f35eb103395 --- /dev/null +++ b/client/tests/integration/smartcontracts/multisig/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "multisig" + +edition.workspace = true +version.workspace = true +authors.workspace = true + +license.workspace = true + +[lib] +crate-type = ['cdylib'] + +[dependencies] +iroha_trigger.workspace = true + +panic-halt.workspace = true +lol_alloc.workspace = true +getrandom.workspace = true + +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true, default-features = false } + +[build-dependencies] +iroha_wasm_builder = { version = "=2.0.0-pre-rc.21", path = "../../../../../wasm_builder" } \ No newline at end of file diff --git a/client/tests/integration/smartcontracts/multisig/src/lib.rs b/client/tests/integration/smartcontracts/multisig/src/lib.rs new file mode 100644 index 00000000000..2a0a196ba12 --- /dev/null +++ b/client/tests/integration/smartcontracts/multisig/src/lib.rs @@ -0,0 +1,130 @@ +//! Trigger to control multisignature account + +#![no_std] + +extern crate alloc; +#[cfg(not(test))] +extern crate panic_halt; + +use alloc::{collections::btree_set::BTreeSet, format, vec::Vec}; + +use iroha_trigger::{debug::dbg_panic, prelude::*}; +use lol_alloc::{FreeListAllocator, LockedAllocator}; +use serde::{Deserialize, Serialize}; + +#[global_allocator] +static ALLOC: LockedAllocator = LockedAllocator::new(FreeListAllocator::new()); + +getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); + +#[derive(Serialize, Deserialize)] +enum Args { + /// Accept instruction proposal and initialize votes with the proposer's one + Instruction(Vec), + /// Accept vote for certain instruction + Vote(HashOf>), +} + +#[iroha_trigger::main] +fn main(id: TriggerId, _owner: AccountId, event: EventBox) { + let (args, signatory): (Args, AccountId) = match event { + EventBox::ExecuteTrigger(event) => ( + event + .args() + .dbg_expect("trigger expect args") + .try_into_any() + .dbg_expect("failed to parse arguments"), + event.authority().clone(), + ), + _ => dbg_panic("only work as by call trigger"), + }; + + let instructions_hash = match &args { + Args::Instruction(instructions) => HashOf::new(instructions), + Args::Vote(instructions_hash) => *instructions_hash, + }; + let votes_metadata_key: Name = format!("{instructions_hash}/votes").parse().unwrap(); + let instructions_metadata_key: Name = + format!("{instructions_hash}/instructions").parse().unwrap(); + + let (votes, instructions) = match args { + Args::Instruction(instructions) => { + FindTriggerKeyValueByIdAndKey::new(id.clone(), votes_metadata_key.clone()) + .execute() + .expect_err("instructions are already submitted"); + + let votes = BTreeSet::from([signatory.clone()]); + + SetKeyValue::trigger( + id.clone(), + instructions_metadata_key.clone(), + JsonString::new(&instructions), + ) + .execute() + .dbg_unwrap(); + + SetKeyValue::trigger( + id.clone(), + votes_metadata_key.clone(), + JsonString::new(&votes), + ) + .execute() + .dbg_unwrap(); + + (votes, instructions) + } + Args::Vote(_instructions_hash) => { + let mut votes: BTreeSet = + FindTriggerKeyValueByIdAndKey::new(id.clone(), votes_metadata_key.clone()) + .execute() + .dbg_expect("instructions should be submitted first") + .into_inner() + .try_into_any() + .dbg_unwrap(); + + votes.insert(signatory.clone()); + + SetKeyValue::trigger( + id.clone(), + votes_metadata_key.clone(), + JsonString::new(&votes), + ) + .execute() + .dbg_unwrap(); + + let instructions: Vec = + FindTriggerKeyValueByIdAndKey::new(id.clone(), instructions_metadata_key.clone()) + .execute() + .dbg_unwrap() + .into_inner() + .try_into_any() + .dbg_unwrap(); + + (votes, instructions) + } + }; + + let signatories: BTreeSet = + FindTriggerKeyValueByIdAndKey::new(id.clone(), "signatories".parse().unwrap()) + .execute() + .dbg_unwrap() + .into_inner() + .try_into_any() + .dbg_unwrap(); + + // Require N of N signatures + if votes.is_superset(&signatories) { + // Cleanup votes and instructions + RemoveKeyValue::trigger(id.clone(), votes_metadata_key) + .execute() + .dbg_unwrap(); + RemoveKeyValue::trigger(id.clone(), instructions_metadata_key) + .execute() + .dbg_unwrap(); + + // Execute instructions proposal which collected enough votes + for isi in instructions { + isi.execute().dbg_unwrap(); + } + } +} diff --git a/client/tests/integration/smartcontracts/multisig_register/Cargo.toml b/client/tests/integration/smartcontracts/multisig_register/Cargo.toml new file mode 100644 index 00000000000..08442628486 --- /dev/null +++ b/client/tests/integration/smartcontracts/multisig_register/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "multisig_register" + +edition.workspace = true +version.workspace = true +authors.workspace = true + +license.workspace = true + +[lib] +crate-type = ['cdylib'] + +[dependencies] +iroha_trigger.workspace = true +iroha_executor_data_model.workspace = true + +panic-halt.workspace = true +lol_alloc.workspace = true +getrandom.workspace = true + +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true, default-features = false } + +[build-dependencies] +iroha_wasm_builder = { version = "=2.0.0-pre-rc.21", path = "../../../../../wasm_builder" } \ No newline at end of file diff --git a/client/tests/integration/smartcontracts/multisig_register/build.rs b/client/tests/integration/smartcontracts/multisig_register/build.rs new file mode 100644 index 00000000000..2195810702a --- /dev/null +++ b/client/tests/integration/smartcontracts/multisig_register/build.rs @@ -0,0 +1,20 @@ +//! Compile trigger to handle multisig actions + +use std::{io::Write, path::Path}; + +const TRIGGER_DIR: &str = "../multisig"; + +fn main() -> Result<(), Box> { + println!("cargo::rerun-if-changed={}", TRIGGER_DIR); + + let out_dir = std::env::var("OUT_DIR").unwrap(); + let wasm = iroha_wasm_builder::Builder::new(TRIGGER_DIR) + .show_output() + .build()? + .optimize()? + .into_bytes()?; + + let mut file = std::fs::File::create(Path::new(&out_dir).join("multisig.wasm"))?; + file.write_all(&wasm)?; + Ok(()) +} diff --git a/client/tests/integration/smartcontracts/multisig_register/src/lib.rs b/client/tests/integration/smartcontracts/multisig_register/src/lib.rs new file mode 100644 index 00000000000..ae587cc59c9 --- /dev/null +++ b/client/tests/integration/smartcontracts/multisig_register/src/lib.rs @@ -0,0 +1,104 @@ +//! Trigger which register multisignature account and create trigger to control it + +#![no_std] + +extern crate alloc; +#[cfg(not(test))] +extern crate panic_halt; + +use alloc::{collections::btree_set::BTreeSet, format}; + +use iroha_executor_data_model::permission::trigger::CanExecuteUserTrigger; +use iroha_trigger::{ + debug::dbg_panic, prelude::*, smart_contract::data_model::account::NewAccount, +}; +use lol_alloc::{FreeListAllocator, LockedAllocator}; +use serde::{Deserialize, Serialize}; + +#[global_allocator] +static ALLOC: LockedAllocator = LockedAllocator::new(FreeListAllocator::new()); + +getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); + +// Trigger wasm code for handling multisig logic +const WASM: &[u8] = core::include_bytes!(concat!(core::env!("OUT_DIR"), "/multisig.wasm")); + +#[derive(Serialize, Deserialize)] +struct Args { + // Account id of multisig account should be manually checked to not have corresponding private key (or having master key is ok) + account: NewAccount, + // List of accounts responsible for handling multisig account + signatories: BTreeSet, +} + +#[iroha_trigger::main] +fn main(_id: TriggerId, _owner: AccountId, event: EventBox) { + let args: Args = match event { + EventBox::ExecuteTrigger(event) => event + .args() + .dbg_expect("trigger expect args") + .try_into_any() + .dbg_expect("failed to parse args"), + _ => dbg_panic("Only work as by call trigger"), + }; + + let account_id = args.account.id().clone(); + + Register::account(args.account) + .execute() + .dbg_expect("failed to register multisig account"); + + let trigger_id: TriggerId = format!( + "{}_{}_multisig_trigger", + account_id.signatory(), + account_id.domain() + ) + .parse() + .dbg_expect("failed to parse trigger id"); + + let payload = WasmSmartContract::from_compiled(WASM.to_vec()); + let trigger = Trigger::new( + trigger_id.clone(), + Action::new( + payload, + Repeats::Indefinitely, + account_id.clone(), + ExecuteTriggerEventFilter::new().for_trigger(trigger_id.clone()), + ), + ); + + Register::trigger(trigger) + .execute() + .dbg_expect("failed to register multisig trigger"); + + let role_id: RoleId = format!( + "{}_{}_signatories", + account_id.signatory(), + account_id.domain() + ) + .parse() + .dbg_expect("failed to parse role"); + + let can_execute_multisig_trigger = CanExecuteUserTrigger { + trigger: trigger_id.clone(), + }; + let role = Role::new(role_id.clone()).add_permission(can_execute_multisig_trigger); + + Register::role(role) + .execute() + .dbg_expect("failed to register multisig role"); + + SetKeyValue::trigger( + trigger_id, + "signatories".parse().unwrap(), + JsonString::new(&args.signatories), + ) + .execute() + .dbg_unwrap(); + + for signatory in args.signatories { + Grant::role(role_id.clone(), signatory) + .execute() + .dbg_expect("failed to grant multisig role to account"); + } +} diff --git a/data_model/src/lib.rs b/data_model/src/lib.rs index 5b7417b53fa..a86d786812b 100644 --- a/data_model/src/lib.rs +++ b/data_model/src/lib.rs @@ -635,7 +635,7 @@ mod ffi { #[allow(ambiguous_glob_reexports)] pub mod prelude { //! Prelude: re-export of most commonly used traits, structs and macros in this crate. - pub use iroha_crypto::PublicKey; + pub use iroha_crypto::{HashOf, PublicKey}; pub use iroha_primitives::{ json::*, numeric::{numeric, Numeric, NumericSpec}, From a2960fe9b17cc871a2ed53f83f6d549ced067fe6 Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Fri, 28 Jun 2024 14:48:33 +0300 Subject: [PATCH 4/7] test: add multisignature account test Signed-off-by: Shanin Roman --- client/tests/integration/mod.rs | 1 + client/tests/integration/multisig.rs | 172 +++++++++++++++++++++++++++ 2 files changed, 173 insertions(+) create mode 100644 client/tests/integration/multisig.rs diff --git a/client/tests/integration/mod.rs b/client/tests/integration/mod.rs index 13b8bd2528c..c76d8dbbee5 100644 --- a/client/tests/integration/mod.rs +++ b/client/tests/integration/mod.rs @@ -3,6 +3,7 @@ mod asset_propagation; mod domain_owner_permissions; mod events; mod extra_functional; +mod multisig; mod non_mintable; mod pagination; mod permissions; diff --git a/client/tests/integration/multisig.rs b/client/tests/integration/multisig.rs new file mode 100644 index 00000000000..f8f1a5f0356 --- /dev/null +++ b/client/tests/integration/multisig.rs @@ -0,0 +1,172 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + str::FromStr, +}; + +use eyre::Result; +use iroha::{ + client::{self, ClientQueryError}, + crypto::KeyPair, + data_model::{ + account::NewAccount, + prelude::*, + transaction::{TransactionBuilder, WasmSmartContract}, + }, +}; +use iroha_data_model::parameter::SmartContractParameter; +use nonzero_ext::nonzero; +use serde::{Deserialize, Serialize}; +use test_network::*; +use test_samples::{gen_account_in, ALICE_ID}; + +/// Mirror trigger args for `multisig_register` +#[derive(Serialize, Deserialize)] +struct MultisigRegisterArgs { + // Account id of multisig account should be manually checked to not have corresponding private key (or having master key is ok) + account: NewAccount, + // List of accounts responsible for handling multisig account + signatories: BTreeSet, +} + +/// Mirror trigger args for `multisig` +#[derive(Serialize, Deserialize)] +enum MultisigArgs { + /// Accept instruction proposal and initialize votes with the proposer's one + Instruction(Vec), + /// Accept vote for certain instruction + Vote(HashOf>), +} + +#[test] +fn mutlisig() -> Result<()> { + let (_rt, _peer, test_client) = ::new().with_port(11_400).start_with_runtime(); + wait_for_genesis_committed(&vec![test_client.clone()], 0); + + test_client.submit_all_blocking([ + SetParameter::new(Parameter::SmartContract(SmartContractParameter::Fuel( + nonzero!(100_000_000_u64), + ))), + SetParameter::new(Parameter::Executor(SmartContractParameter::Fuel(nonzero!( + 100_000_000_u64 + )))), + ])?; + + let account_id = ALICE_ID.clone(); + let multisig_register_trigger_id = TriggerId::from_str("multisig_register")?; + + let wasm = + iroha_wasm_builder::Builder::new("tests/integration/smartcontracts/multisig_register") + .show_output() + .build()? + .optimize()? + .into_bytes()?; + let wasm = WasmSmartContract::from_compiled(wasm); + + let trigger = Trigger::new( + multisig_register_trigger_id.clone(), + Action::new( + wasm.clone(), + Repeats::Indefinitely, + account_id.clone(), + ExecuteTriggerEventFilter::new().for_trigger(multisig_register_trigger_id.clone()), + ), + ); + + // Register trigger which would allow multisig account creation in wonderland domain + // Access to call this trigger shouldn't be restricted + test_client.submit_blocking(Register::trigger(trigger))?; + + // Create multisig account id and destroy it's private key + let multisig_account_id = gen_account_in("wonderland").0; + + let multisig_trigger_id: TriggerId = format!( + "{}_{}_multisig_trigger", + multisig_account_id.signatory(), + multisig_account_id.domain() + ) + .parse()?; + + let signatories = core::iter::repeat_with(|| gen_account_in("wonderland")) + .take(5) + .collect::>(); + + let args = MultisigRegisterArgs { + account: Account::new(multisig_account_id.clone()), + signatories: signatories.keys().cloned().collect(), + }; + + test_client.submit_all_blocking( + signatories + .keys() + .cloned() + .map(Account::new) + .map(Register::account), + )?; + + let call_trigger = ExecuteTrigger::new(multisig_register_trigger_id).with_args(&args); + test_client.submit_blocking(call_trigger)?; + + // Check that multisig account exist + let account = test_client + .request(client::account::by_id(multisig_account_id.clone())) + .expect("multisig account should be created after the call to register multisig trigger"); + + assert_eq!(account.id(), &multisig_account_id); + + // Check that multisig trigger exist + let trigger = test_client + .request(client::trigger::by_id(multisig_trigger_id.clone())) + .expect("multisig trigger should be created after the call to register multisig trigger"); + + assert_eq!(trigger.id(), &multisig_trigger_id); + + let domain_id: DomainId = "domain_controlled_by_multisig".parse().unwrap(); + let isi = vec![InstructionBox::from(Register::domain(Domain::new( + domain_id.clone(), + )))]; + let isi_hash = HashOf::new(&isi); + + let mut signatories_iter = signatories.into_iter(); + + if let Some((signatory, key_pair)) = signatories_iter.next() { + let args = MultisigArgs::Instruction(isi); + let call_trigger = ExecuteTrigger::new(multisig_trigger_id.clone()).with_args(&args); + test_client.submit_transaction_blocking( + &TransactionBuilder::new(test_client.chain.clone(), signatory) + .with_instructions([call_trigger]) + .sign(key_pair.private_key()), + )?; + } + + // Check that domain isn't created yet + let err = test_client + .request(client::domain::by_id(domain_id.clone())) + .expect_err("domain shouldn't be created before enough votes are collected"); + assert!(matches!( + err, + ClientQueryError::Validation(iroha_data_model::ValidationFail::QueryFailed( + iroha_data_model::query::error::QueryExecutionFail::Find( + iroha_data_model::query::error::FindError::Domain(err_domain_id) + ) + )) if domain_id == err_domain_id + )); + + for (signatory, key_pair) in signatories_iter { + let args = MultisigArgs::Vote(isi_hash); + let call_trigger = ExecuteTrigger::new(multisig_trigger_id.clone()).with_args(&args); + test_client.submit_transaction_blocking( + &TransactionBuilder::new(test_client.chain.clone(), signatory) + .with_instructions([call_trigger]) + .sign(key_pair.private_key()), + )?; + } + + // Check that new domain was created and multisig account is owner + let domain = test_client + .request(client::domain::by_id(domain_id.clone())) + .expect("domain should be created after enough votes are collected"); + + assert_eq!(domain.owned_by(), &multisig_account_id); + + Ok(()) +} From 25443a6f8277a65f5878c4d306020b07c8c814d5 Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Wed, 3 Jul 2024 11:04:05 +0300 Subject: [PATCH 5/7] refactor: move multisig args into custom executor data model Signed-off-by: Shanin Roman --- client/tests/integration/multisig.rs | 28 ++----------------- .../executor_custom_data_model/src/lib.rs | 1 + .../src/multisig.rs | 24 ++++++++++++++++ .../smartcontracts/multisig/Cargo.toml | 1 + .../smartcontracts/multisig/src/lib.rs | 20 ++++--------- .../multisig_register/Cargo.toml | 1 + .../multisig_register/src/lib.rs | 18 +++--------- 7 files changed, 40 insertions(+), 53 deletions(-) create mode 100644 client/tests/integration/smartcontracts/executor_custom_data_model/src/multisig.rs diff --git a/client/tests/integration/multisig.rs b/client/tests/integration/multisig.rs index f8f1a5f0356..5d92c330b8c 100644 --- a/client/tests/integration/multisig.rs +++ b/client/tests/integration/multisig.rs @@ -1,42 +1,20 @@ -use std::{ - collections::{BTreeMap, BTreeSet}, - str::FromStr, -}; +use std::{collections::BTreeMap, str::FromStr}; +use executor_custom_data_model::multisig::{MultisigArgs, MultisigRegisterArgs}; use eyre::Result; use iroha::{ client::{self, ClientQueryError}, crypto::KeyPair, data_model::{ - account::NewAccount, prelude::*, transaction::{TransactionBuilder, WasmSmartContract}, }, }; use iroha_data_model::parameter::SmartContractParameter; use nonzero_ext::nonzero; -use serde::{Deserialize, Serialize}; use test_network::*; use test_samples::{gen_account_in, ALICE_ID}; -/// Mirror trigger args for `multisig_register` -#[derive(Serialize, Deserialize)] -struct MultisigRegisterArgs { - // Account id of multisig account should be manually checked to not have corresponding private key (or having master key is ok) - account: NewAccount, - // List of accounts responsible for handling multisig account - signatories: BTreeSet, -} - -/// Mirror trigger args for `multisig` -#[derive(Serialize, Deserialize)] -enum MultisigArgs { - /// Accept instruction proposal and initialize votes with the proposer's one - Instruction(Vec), - /// Accept vote for certain instruction - Vote(HashOf>), -} - #[test] fn mutlisig() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(11_400).start_with_runtime(); @@ -129,7 +107,7 @@ fn mutlisig() -> Result<()> { let mut signatories_iter = signatories.into_iter(); if let Some((signatory, key_pair)) = signatories_iter.next() { - let args = MultisigArgs::Instruction(isi); + let args = MultisigArgs::Instructions(isi); let call_trigger = ExecuteTrigger::new(multisig_trigger_id.clone()).with_args(&args); test_client.submit_transaction_blocking( &TransactionBuilder::new(test_client.chain.clone(), signatory) diff --git a/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs b/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs index 4db9f68bde5..9c4eae98337 100644 --- a/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs +++ b/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs @@ -5,6 +5,7 @@ extern crate alloc; pub mod complex_isi; +pub mod multisig; pub mod parameters; pub mod permissions; pub mod simple_isi; diff --git a/client/tests/integration/smartcontracts/executor_custom_data_model/src/multisig.rs b/client/tests/integration/smartcontracts/executor_custom_data_model/src/multisig.rs new file mode 100644 index 00000000000..916fa06eaf6 --- /dev/null +++ b/client/tests/integration/smartcontracts/executor_custom_data_model/src/multisig.rs @@ -0,0 +1,24 @@ +//! Arguments to register and manage multisig account + +use alloc::{collections::btree_set::BTreeSet, vec::Vec}; + +use iroha_data_model::{account::NewAccount, prelude::*}; +use serde::{Deserialize, Serialize}; + +/// Arguments to multisig account register trigger +#[derive(Serialize, Deserialize)] +pub struct MultisigRegisterArgs { + // Account id of multisig account should be manually checked to not have corresponding private key (or having master key is ok) + pub account: NewAccount, + // List of accounts responsible for handling multisig account + pub signatories: BTreeSet, +} + +/// Arguments to multisig account manager trigger +#[derive(Serialize, Deserialize)] +pub enum MultisigArgs { + /// Accept instructions proposal and initialize votes with the proposer's one + Instructions(Vec), + /// Accept vote for certain instructions + Vote(HashOf>), +} diff --git a/client/tests/integration/smartcontracts/multisig/Cargo.toml b/client/tests/integration/smartcontracts/multisig/Cargo.toml index f35eb103395..956becaf9a5 100644 --- a/client/tests/integration/smartcontracts/multisig/Cargo.toml +++ b/client/tests/integration/smartcontracts/multisig/Cargo.toml @@ -12,6 +12,7 @@ crate-type = ['cdylib'] [dependencies] iroha_trigger.workspace = true +executor_custom_data_model.workspace = true panic-halt.workspace = true lol_alloc.workspace = true diff --git a/client/tests/integration/smartcontracts/multisig/src/lib.rs b/client/tests/integration/smartcontracts/multisig/src/lib.rs index 2a0a196ba12..f26a9af2c5a 100644 --- a/client/tests/integration/smartcontracts/multisig/src/lib.rs +++ b/client/tests/integration/smartcontracts/multisig/src/lib.rs @@ -8,26 +8,18 @@ extern crate panic_halt; use alloc::{collections::btree_set::BTreeSet, format, vec::Vec}; +use executor_custom_data_model::multisig::MultisigArgs; use iroha_trigger::{debug::dbg_panic, prelude::*}; use lol_alloc::{FreeListAllocator, LockedAllocator}; -use serde::{Deserialize, Serialize}; #[global_allocator] static ALLOC: LockedAllocator = LockedAllocator::new(FreeListAllocator::new()); getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); -#[derive(Serialize, Deserialize)] -enum Args { - /// Accept instruction proposal and initialize votes with the proposer's one - Instruction(Vec), - /// Accept vote for certain instruction - Vote(HashOf>), -} - #[iroha_trigger::main] fn main(id: TriggerId, _owner: AccountId, event: EventBox) { - let (args, signatory): (Args, AccountId) = match event { + let (args, signatory): (MultisigArgs, AccountId) = match event { EventBox::ExecuteTrigger(event) => ( event .args() @@ -40,15 +32,15 @@ fn main(id: TriggerId, _owner: AccountId, event: EventBox) { }; let instructions_hash = match &args { - Args::Instruction(instructions) => HashOf::new(instructions), - Args::Vote(instructions_hash) => *instructions_hash, + MultisigArgs::Instructions(instructions) => HashOf::new(instructions), + MultisigArgs::Vote(instructions_hash) => *instructions_hash, }; let votes_metadata_key: Name = format!("{instructions_hash}/votes").parse().unwrap(); let instructions_metadata_key: Name = format!("{instructions_hash}/instructions").parse().unwrap(); let (votes, instructions) = match args { - Args::Instruction(instructions) => { + MultisigArgs::Instructions(instructions) => { FindTriggerKeyValueByIdAndKey::new(id.clone(), votes_metadata_key.clone()) .execute() .expect_err("instructions are already submitted"); @@ -73,7 +65,7 @@ fn main(id: TriggerId, _owner: AccountId, event: EventBox) { (votes, instructions) } - Args::Vote(_instructions_hash) => { + MultisigArgs::Vote(_instructions_hash) => { let mut votes: BTreeSet = FindTriggerKeyValueByIdAndKey::new(id.clone(), votes_metadata_key.clone()) .execute() diff --git a/client/tests/integration/smartcontracts/multisig_register/Cargo.toml b/client/tests/integration/smartcontracts/multisig_register/Cargo.toml index 08442628486..c4d39bd128f 100644 --- a/client/tests/integration/smartcontracts/multisig_register/Cargo.toml +++ b/client/tests/integration/smartcontracts/multisig_register/Cargo.toml @@ -13,6 +13,7 @@ crate-type = ['cdylib'] [dependencies] iroha_trigger.workspace = true iroha_executor_data_model.workspace = true +executor_custom_data_model.workspace = true panic-halt.workspace = true lol_alloc.workspace = true diff --git a/client/tests/integration/smartcontracts/multisig_register/src/lib.rs b/client/tests/integration/smartcontracts/multisig_register/src/lib.rs index ae587cc59c9..f3f2dfb6530 100644 --- a/client/tests/integration/smartcontracts/multisig_register/src/lib.rs +++ b/client/tests/integration/smartcontracts/multisig_register/src/lib.rs @@ -6,14 +6,12 @@ extern crate alloc; #[cfg(not(test))] extern crate panic_halt; -use alloc::{collections::btree_set::BTreeSet, format}; +use alloc::format; +use executor_custom_data_model::multisig::MultisigRegisterArgs; use iroha_executor_data_model::permission::trigger::CanExecuteUserTrigger; -use iroha_trigger::{ - debug::dbg_panic, prelude::*, smart_contract::data_model::account::NewAccount, -}; +use iroha_trigger::{debug::dbg_panic, prelude::*}; use lol_alloc::{FreeListAllocator, LockedAllocator}; -use serde::{Deserialize, Serialize}; #[global_allocator] static ALLOC: LockedAllocator = LockedAllocator::new(FreeListAllocator::new()); @@ -23,17 +21,9 @@ getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); // Trigger wasm code for handling multisig logic const WASM: &[u8] = core::include_bytes!(concat!(core::env!("OUT_DIR"), "/multisig.wasm")); -#[derive(Serialize, Deserialize)] -struct Args { - // Account id of multisig account should be manually checked to not have corresponding private key (or having master key is ok) - account: NewAccount, - // List of accounts responsible for handling multisig account - signatories: BTreeSet, -} - #[iroha_trigger::main] fn main(_id: TriggerId, _owner: AccountId, event: EventBox) { - let args: Args = match event { + let args: MultisigRegisterArgs = match event { EventBox::ExecuteTrigger(event) => event .args() .dbg_expect("trigger expect args") From 5cb73f73c5c1596efde80ce19373237a70ba0eb4 Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Thu, 4 Jul 2024 10:51:46 +0300 Subject: [PATCH 6/7] refactor: remove redundant clones Signed-off-by: Shanin Roman --- client/tests/integration/multisig.rs | 2 +- client/tests/integration/triggers/by_call_trigger.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/tests/integration/multisig.rs b/client/tests/integration/multisig.rs index 5d92c330b8c..ffd131e1b0b 100644 --- a/client/tests/integration/multisig.rs +++ b/client/tests/integration/multisig.rs @@ -43,7 +43,7 @@ fn mutlisig() -> Result<()> { let trigger = Trigger::new( multisig_register_trigger_id.clone(), Action::new( - wasm.clone(), + wasm, Repeats::Indefinitely, account_id.clone(), ExecuteTriggerEventFilter::new().for_trigger(multisig_register_trigger_id.clone()), diff --git a/client/tests/integration/triggers/by_call_trigger.rs b/client/tests/integration/triggers/by_call_trigger.rs index 6f3a32b2db3..fe412d15c70 100644 --- a/client/tests/integration/triggers/by_call_trigger.rs +++ b/client/tests/integration/triggers/by_call_trigger.rs @@ -671,7 +671,7 @@ fn call_execute_trigger_with_args() -> Result<()> { let trigger = Trigger::new( trigger_id.clone(), Action::new( - wasm.clone(), + wasm, Repeats::Indefinitely, account_id.clone(), ExecuteTriggerEventFilter::new() From a346c1d45e2434ec4ab2065071c88ada5d1aaf8d Mon Sep 17 00:00:00 2001 From: Shanin Roman Date: Thu, 4 Jul 2024 12:59:15 +0300 Subject: [PATCH 7/7] refactor: move mint rose args into custom executor Signed-off-by: Shanin Roman --- .../executor_custom_data_model/src/lib.rs | 1 + .../executor_custom_data_model/src/mint_rose_args.rs | 10 ++++++++++ .../smartcontracts/mint_rose_trigger_args/Cargo.toml | 3 ++- .../smartcontracts/mint_rose_trigger_args/src/lib.rs | 8 ++------ .../integration/smartcontracts/multisig/Cargo.toml | 2 +- .../smartcontracts/multisig_register/Cargo.toml | 2 +- client/tests/integration/triggers/by_call_trigger.rs | 10 ++-------- 7 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 client/tests/integration/smartcontracts/executor_custom_data_model/src/mint_rose_args.rs diff --git a/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs b/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs index 9c4eae98337..62cf2d4c6a2 100644 --- a/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs +++ b/client/tests/integration/smartcontracts/executor_custom_data_model/src/lib.rs @@ -5,6 +5,7 @@ extern crate alloc; pub mod complex_isi; +pub mod mint_rose_args; pub mod multisig; pub mod parameters; pub mod permissions; diff --git a/client/tests/integration/smartcontracts/executor_custom_data_model/src/mint_rose_args.rs b/client/tests/integration/smartcontracts/executor_custom_data_model/src/mint_rose_args.rs new file mode 100644 index 00000000000..a07fb859706 --- /dev/null +++ b/client/tests/integration/smartcontracts/executor_custom_data_model/src/mint_rose_args.rs @@ -0,0 +1,10 @@ +//! Arguments to mint rose with args trigger + +use serde::{Deserialize, Serialize}; + +/// Arguments to mint rose with args trigger +#[derive(Serialize, Deserialize)] +pub struct MintRoseArgs { + // Amount to mint + pub val: u32, +} diff --git a/client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml b/client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml index 996db21fa07..19715ff3417 100644 --- a/client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml +++ b/client/tests/integration/smartcontracts/mint_rose_trigger_args/Cargo.toml @@ -12,10 +12,11 @@ crate-type = ['cdylib'] [dependencies] iroha_trigger.workspace = true +executor_custom_data_model.workspace = true panic-halt.workspace = true lol_alloc.workspace = true getrandom.workspace = true serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true, default-features = false } \ No newline at end of file +serde_json = { workspace = true, default-features = false } diff --git a/client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs b/client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs index f9f18f0b913..eda3d291902 100644 --- a/client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs +++ b/client/tests/integration/smartcontracts/mint_rose_trigger_args/src/lib.rs @@ -7,6 +7,7 @@ extern crate panic_halt; use core::str::FromStr as _; +use executor_custom_data_model::mint_rose_args::MintRoseArgs; use iroha_trigger::{debug::dbg_panic, prelude::*}; use lol_alloc::{FreeListAllocator, LockedAllocator}; use serde::{Deserialize, Serialize}; @@ -16,11 +17,6 @@ static ALLOC: LockedAllocator = LockedAllocator::new(FreeList getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom); -#[derive(Serialize, Deserialize)] -struct Args { - val: u32, -} - /// Mint 1 rose for owner #[iroha_trigger::main] fn main(_id: TriggerId, owner: AccountId, event: EventBox) { @@ -28,7 +24,7 @@ fn main(_id: TriggerId, owner: AccountId, event: EventBox) { .dbg_expect("Failed to parse `rose#wonderland` asset definition id"); let rose_id = AssetId::new(rose_definition_id, owner); - let args: Args = match event { + let args: MintRoseArgs = match event { EventBox::ExecuteTrigger(event) => event .args() .dbg_expect("Trigger expect parameters") diff --git a/client/tests/integration/smartcontracts/multisig/Cargo.toml b/client/tests/integration/smartcontracts/multisig/Cargo.toml index 956becaf9a5..3c4c6db935b 100644 --- a/client/tests/integration/smartcontracts/multisig/Cargo.toml +++ b/client/tests/integration/smartcontracts/multisig/Cargo.toml @@ -22,4 +22,4 @@ serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, default-features = false } [build-dependencies] -iroha_wasm_builder = { version = "=2.0.0-pre-rc.21", path = "../../../../../wasm_builder" } \ No newline at end of file +iroha_wasm_builder = { version = "=2.0.0-pre-rc.21", path = "../../../../../wasm_builder" } diff --git a/client/tests/integration/smartcontracts/multisig_register/Cargo.toml b/client/tests/integration/smartcontracts/multisig_register/Cargo.toml index c4d39bd128f..09d62f6c25e 100644 --- a/client/tests/integration/smartcontracts/multisig_register/Cargo.toml +++ b/client/tests/integration/smartcontracts/multisig_register/Cargo.toml @@ -23,4 +23,4 @@ serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, default-features = false } [build-dependencies] -iroha_wasm_builder = { version = "=2.0.0-pre-rc.21", path = "../../../../../wasm_builder" } \ No newline at end of file +iroha_wasm_builder = { version = "=2.0.0-pre-rc.21", path = "../../../../../wasm_builder" } diff --git a/client/tests/integration/triggers/by_call_trigger.rs b/client/tests/integration/triggers/by_call_trigger.rs index fe412d15c70..293982cee0e 100644 --- a/client/tests/integration/triggers/by_call_trigger.rs +++ b/client/tests/integration/triggers/by_call_trigger.rs @@ -1,5 +1,6 @@ use std::{str::FromStr as _, sync::mpsc, thread, time::Duration}; +use executor_custom_data_model::mint_rose_args::MintRoseArgs; use eyre::{eyre, Result, WrapErr}; use iroha::{ client::{self, Client}, @@ -13,7 +14,6 @@ use iroha::{ use iroha_executor_data_model::permission::trigger::CanRegisterUserTrigger; use iroha_genesis::GenesisBlock; use iroha_logger::info; -use serde::{Deserialize, Serialize}; use test_network::{Peer as TestPeer, *}; use test_samples::ALICE_ID; use tokio::runtime::Runtime; @@ -682,7 +682,7 @@ fn call_execute_trigger_with_args() -> Result<()> { test_client.submit_blocking(Register::trigger(trigger))?; - let args: Args = Args { val: 42 }; + let args: MintRoseArgs = MintRoseArgs { val: 42 }; let call_trigger = ExecuteTrigger::new(trigger_id).with_args(&args); test_client.submit_blocking(call_trigger)?; @@ -691,9 +691,3 @@ fn call_execute_trigger_with_args() -> Result<()> { Ok(()) } - -/// Mirror trigger args for `mint_rose_trigger_args` -#[derive(Serialize, Deserialize)] -struct Args { - val: u32, -}