diff --git a/client/tests/integration/triggers/data_trigger.rs b/client/tests/integration/triggers/data_trigger.rs index 46744151559..f906649c95d 100644 --- a/client/tests/integration/triggers/data_trigger.rs +++ b/client/tests/integration/triggers/data_trigger.rs @@ -1,5 +1,6 @@ use eyre::Result; use iroha_client::{client, data_model::prelude::*}; +use iroha_data_model::{trigger::Trigger, Level}; use test_network::*; #[test] @@ -108,6 +109,43 @@ fn domain_scoped_trigger_must_be_executed_only_on_events_in_its_domain() -> Resu Ok(()) } +#[test] +fn trigger_call_chain() -> Result<()> { + let (_rt, _peer, test_client) = ::new().with_port(11_245).start_with_runtime(); + wait_for_genesis_committed(&[test_client.clone()], 0); + + let account_id: AccountId = "alice@wonderland".parse()?; + let asset_definition_id = "rose#wonderland".parse()?; + let asset_id = AssetId::new(asset_definition_id, account_id.clone()); + + let prev_value = get_asset_value(&test_client, asset_id.clone())?; + + let instruction = MintExpr::new(1u32, asset_id.clone()); + // Trigger produce 5 events + let register_trigger = RegisterExpr::new(Trigger::new( + "mint_rose".parse()?, + Action::new( + [instruction.clone()], + Repeats::Indefinitely, + account_id.clone(), + DataEventFilter::AcceptAll.into(), + ), + )); + // Trigger is triggered on it's own registration + test_client.submit_blocking(register_trigger)?; + + // Every block x5 events would be produced + for _ in 0..3 { + test_client.submit_blocking(LogExpr::new(Level::INFO, "just message".to_string()))?; + } + + let new_value = get_asset_value(&test_client, asset_id)?; + // 1 + 5 + 25 + 125 = 156 + assert_eq!(new_value, prev_value + 156); + + Ok(()) +} + fn get_asset_value(client: &client::Client, asset_id: AssetId) -> Result { let asset = client.request(client::asset::by_id(asset_id))?; Ok(*TryAsRef::::try_as_ref(asset.value())?) diff --git a/core/src/smartcontracts/isi/triggers/set.rs b/core/src/smartcontracts/isi/triggers/set.rs index fb6deff9e04..63910e42aab 100644 --- a/core/src/smartcontracts/isi/triggers/set.rs +++ b/core/src/smartcontracts/isi/triggers/set.rs @@ -156,7 +156,7 @@ type WasmSmartContractMap = IndexMap, (WasmSmartContra /// Specialized structure that maps event filters to Triggers. // NB: `Set` has custom `Serialize` and `DeserializeSeed` implementations // which need to be manually updated when changing the struct -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct Set { /// Triggers using [`DataEventFilter`] data_triggers: IndexMap>, @@ -318,20 +318,6 @@ impl<'de> DeserializeSeed<'de> for WasmSeed<'_, Set> { } } -impl Clone for Set { - fn clone(&self) -> Self { - Self { - data_triggers: self.data_triggers.clone(), - pipeline_triggers: self.pipeline_triggers.clone(), - time_triggers: self.time_triggers.clone(), - by_call_triggers: self.by_call_triggers.clone(), - ids: self.ids.clone(), - original_contracts: self.original_contracts.clone(), - matched_ids: Vec::default(), - } - } -} - impl Set { /// Add trigger with [`DataEventFilter`] ///