Skip to content

Commit

Permalink
[feature] hyperledger-iroha#4390: include trigger id in trigger entry…
Browse files Browse the repository at this point in the history
…point

Signed-off-by: Marin Veršić <marin.versic101@gmail.com>
  • Loading branch information
mversic committed Mar 27, 2024
1 parent 1f0e21d commit 4bc8833
Show file tree
Hide file tree
Showing 19 changed files with 188 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ static ALLOC: LockedAllocator<FreeListAllocator> = LockedAllocator::new(FreeList
getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom);

#[iroha_trigger::main]
fn main(_owner: AccountId, _event: Event) {
fn main(id: TriggerId, _owner: AccountId, _event: Event) {
iroha_trigger::log::info!("Executing trigger");

let accounts_cursor = FindAllAccounts.execute().dbg_unwrap();
Expand Down Expand Up @@ -45,7 +45,7 @@ fn main(_owner: AccountId, _event: Event) {
.dbg_unwrap();
metadata.insert_with_limits(name, true, limits).dbg_unwrap();

let nft_id = generate_new_nft_id(account.id());
let nft_id = generate_new_nft_id(id, account.id());
let nft_definition = AssetDefinition::store(nft_id.clone())
.mintable_once()
.with_metadata(metadata);
Expand All @@ -61,7 +61,7 @@ fn main(_owner: AccountId, _event: Event) {
iroha_trigger::log::info!("Smart contract executed successfully");
}

fn generate_new_nft_id(account_id: &AccountId) -> AssetDefinitionId {
fn generate_new_nft_id(trigger_id: TriggerId, account_id: &AccountId) -> AssetDefinitionId {
let assets = FindAssetsByAccountId::new(account_id.clone())
.execute()
.dbg_unwrap();
Expand All @@ -73,11 +73,14 @@ fn generate_new_nft_id(account_id: &AccountId) -> AssetDefinitionId {
.count()
.checked_add(1)
.dbg_unwrap();

iroha_trigger::log::debug!(&format!("New number: {}", new_number));
let prefix = FindTriggerKeyValueByIdAndKey::new(trigger_id, "PREFIX".parse().unwrap())
.execute()
.dbg_unwrap();

format!(
"nft_number_{}_for_{}#{}",
new_number,
"{prefix}_{new_number}_for_{}#{}",
account_id.name(),
account_id.domain_id()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ getrandom::register_custom_getrandom!(iroha_trigger::stub_getrandom);

/// Mint 1 rose for owner
#[iroha_trigger::main]
fn main(owner: AccountId, _event: Event) {
fn main(_id: TriggerId, owner: AccountId, _event: Event) {
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);
Expand Down
23 changes: 18 additions & 5 deletions client/tests/integration/triggers/time_trigger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ fn time_trigger_execution_count_error_should_be_less_than_15_percent() -> Result

let schedule = TimeSchedule::starting_at(start_time).with_period(PERIOD);
let instruction = Mint::asset_numeric(1u32, asset_id.clone());
let trigger_id: TriggerId = "mint_rose".parse()?;
let register_trigger = Register::trigger(Trigger::new(
"mint_rose".parse()?,
trigger_id.clone(),
Action::new(
vec![instruction],
Repeats::Indefinitely,
Expand All @@ -58,6 +59,7 @@ fn time_trigger_execution_count_error_should_be_less_than_15_percent() -> Result
test_client.submit(register_trigger)?;

submit_sample_isi_on_every_block_commit(
trigger_id,
event_listener,
&mut test_client,
&account_id,
Expand Down Expand Up @@ -104,8 +106,9 @@ fn change_asset_metadata_after_1_sec() -> Result<()> {
let schedule = TimeSchedule::starting_at(start_time + PERIOD);
let instruction =
SetKeyValue::asset_definition(asset_definition_id.clone(), key.clone(), 3_u32);
let trigger_id: TriggerId = "change_rose_metadata".parse().expect("Valid");
let register_trigger = Register::trigger(Trigger::new(
"change_rose_metadata".parse().expect("Valid"),
trigger_id.clone(),
Action::new(
vec![instruction],
Repeats::from(1_u32),
Expand All @@ -115,6 +118,7 @@ fn change_asset_metadata_after_1_sec() -> Result<()> {
));
test_client.submit(register_trigger)?;
submit_sample_isi_on_every_block_commit(
trigger_id,
event_listener,
&mut test_client,
&account_id,
Expand Down Expand Up @@ -223,19 +227,21 @@ fn mint_nft_for_every_user_every_1_sec() -> Result<()> {
let start_time = current_time();
let schedule =
TimeSchedule::starting_at(start_time).with_period(Duration::from_millis(TRIGGER_PERIOD_MS));
let trigger_id: TriggerId = "mint_nft_for_all".parse()?;
let register_trigger = Register::trigger(Trigger::new(
"mint_nft_for_all".parse()?,
trigger_id.clone(),
Action::new(
WasmSmartContract::from_compiled(wasm),
Repeats::Indefinitely,
alice_id.clone(),
TimeEventFilter::new(ExecutionTime::Schedule(schedule)),
),
));
test_client.submit(register_trigger)?;
test_client.submit_blocking(register_trigger)?;

// Time trigger will be executed on block commits, so we have to produce some transactions
submit_sample_isi_on_every_block_commit(
trigger_id,
event_listener,
&mut test_client,
&alice_id,
Expand Down Expand Up @@ -292,12 +298,15 @@ fn get_asset_value(client: &mut Client, asset_id: AssetId) -> Numeric {

/// Submit some sample ISIs to create new blocks
fn submit_sample_isi_on_every_block_commit(
trigger_id: TriggerId,
block_committed_event_listener: impl Iterator<Item = Result<Event>>,
test_client: &mut Client,
account_id: &AccountId,
timeout: Duration,
times: usize,
) -> Result<()> {
let prefix = SetKeyValue::trigger(trigger_id, "PREFIX".parse()?, "nft_number".to_owned());

for _ in block_committed_event_listener.take(times) {
std::thread::sleep(timeout);
// ISI just to create a new block
Expand All @@ -306,7 +315,11 @@ fn submit_sample_isi_on_every_block_commit(
"key".parse::<Name>()?,
String::from("value"),
);
test_client.submit(sample_isi)?;

test_client.submit_all(vec![
InstructionBox::from(prefix.clone()),
sample_isi.into(),
])?;
}

Ok(())
Expand Down
6 changes: 4 additions & 2 deletions config/src/parameters/actual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,11 @@ pub struct ChainWide {
pub block_time: Duration,
pub commit_time: Duration,
pub transaction_limits: TransactionLimits,
pub asset_metadata_limits: MetadataLimits,
pub domain_metadata_limits: MetadataLimits,
pub asset_definition_metadata_limits: MetadataLimits,
pub account_metadata_limits: MetadataLimits,
pub domain_metadata_limits: MetadataLimits,
pub asset_metadata_limits: MetadataLimits,
pub trigger_metadata_limits: MetadataLimits,
pub ident_length_limits: LengthLimits,
pub executor_runtime: WasmRuntime,
pub wasm_runtime: WasmRuntime,
Expand All @@ -204,6 +205,7 @@ impl Default for ChainWide {
account_metadata_limits: defaults::chain_wide::DEFAULT_METADATA_LIMITS,
asset_definition_metadata_limits: defaults::chain_wide::DEFAULT_METADATA_LIMITS,
asset_metadata_limits: defaults::chain_wide::DEFAULT_METADATA_LIMITS,
trigger_metadata_limits: defaults::chain_wide::DEFAULT_METADATA_LIMITS,
ident_length_limits: defaults::chain_wide::DEFAULT_IDENT_LENGTH_LIMITS,
executor_runtime: WasmRuntime::default(),
wasm_runtime: WasmRuntime::default(),
Expand Down
7 changes: 5 additions & 2 deletions config/src/parameters/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,10 +566,11 @@ pub struct ChainWide {
pub block_time: Duration,
pub commit_time: Duration,
pub transaction_limits: TransactionLimits,
pub asset_metadata_limits: MetadataLimits,
pub domain_metadata_limits: MetadataLimits,
pub asset_definition_metadata_limits: MetadataLimits,
pub account_metadata_limits: MetadataLimits,
pub domain_metadata_limits: MetadataLimits,
pub asset_metadata_limits: MetadataLimits,
pub trigger_metadata_limits: MetadataLimits,
pub ident_length_limits: LengthLimits,
pub executor_fuel_limit: u64,
pub executor_max_memory: HumanBytes<u32>,
Expand All @@ -585,6 +586,7 @@ impl ChainWide {
commit_time,
transaction_limits,
asset_metadata_limits,
trigger_metadata_limits,
asset_definition_metadata_limits,
account_metadata_limits,
domain_metadata_limits,
Expand All @@ -601,6 +603,7 @@ impl ChainWide {
commit_time,
transaction_limits,
asset_metadata_limits,
trigger_metadata_limits,
asset_definition_metadata_limits,
account_metadata_limits,
domain_metadata_limits,
Expand Down
16 changes: 10 additions & 6 deletions config/src/parameters/user/boilerplate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,10 +656,11 @@ pub struct ChainWidePartial {
pub block_time: UserField<HumanDuration>,
pub commit_time: UserField<HumanDuration>,
pub transaction_limits: UserField<TransactionLimits>,
pub asset_metadata_limits: UserField<MetadataLimits>,
pub domain_metadata_limits: UserField<MetadataLimits>,
pub asset_definition_metadata_limits: UserField<MetadataLimits>,
pub account_metadata_limits: UserField<MetadataLimits>,
pub domain_metadata_limits: UserField<MetadataLimits>,
pub asset_metadata_limits: UserField<MetadataLimits>,
pub trigger_metadata_limits: UserField<MetadataLimits>,
pub ident_length_limits: UserField<LengthLimits>,
pub executor_fuel_limit: UserField<u64>,
pub executor_max_memory: UserField<HumanBytes<u32>>,
Expand All @@ -682,17 +683,20 @@ impl UnwrapPartial for ChainWidePartial {
transaction_limits: self
.transaction_limits
.unwrap_or(DEFAULT_TRANSACTION_LIMITS),
asset_metadata_limits: self
.asset_metadata_limits
domain_metadata_limits: self
.domain_metadata_limits
.unwrap_or(DEFAULT_METADATA_LIMITS),
asset_definition_metadata_limits: self
.asset_definition_metadata_limits
.unwrap_or(DEFAULT_METADATA_LIMITS),
account_metadata_limits: self
.account_metadata_limits
.unwrap_or(DEFAULT_METADATA_LIMITS),
domain_metadata_limits: self
.domain_metadata_limits
asset_metadata_limits: self
.asset_metadata_limits
.unwrap_or(DEFAULT_METADATA_LIMITS),
trigger_metadata_limits: self
.trigger_metadata_limits
.unwrap_or(DEFAULT_METADATA_LIMITS),
ident_length_limits: self
.ident_length_limits
Expand Down
6 changes: 3 additions & 3 deletions core/src/smartcontracts/isi/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@ pub mod isi {
state_transaction
.world
.emit_events(Some(AccountEvent::MetadataInserted(MetadataChanged {
target_id: account_id.clone(),
key: self.key.clone(),
target_id: account_id,
key: self.key,
value: self.value,
})));

Expand Down Expand Up @@ -316,7 +316,7 @@ pub mod isi {
state_transaction
.world
.emit_events(Some(AccountEvent::MetadataRemoved(MetadataChanged {
target_id: account_id.clone(),
target_id: account_id,
key: self.key,
value,
})));
Expand Down
2 changes: 2 additions & 0 deletions core/src/smartcontracts/isi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ impl Execute for SetKeyValueBox {
Self::Account(isi) => isi.execute(authority, state_transaction),
Self::AssetDefinition(isi) => isi.execute(authority, state_transaction),
Self::Asset(isi) => isi.execute(authority, state_transaction),
Self::Trigger(isi) => isi.execute(authority, state_transaction),
}
}
}
Expand All @@ -196,6 +197,7 @@ impl Execute for RemoveKeyValueBox {
Self::Account(isi) => isi.execute(authority, state_transaction),
Self::AssetDefinition(isi) => isi.execute(authority, state_transaction),
Self::Asset(isi) => isi.execute(authority, state_transaction),
Self::Trigger(isi) => isi.execute(authority, state_transaction),
}
}
}
Expand Down
66 changes: 66 additions & 0 deletions core/src/smartcontracts/isi/triggers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,72 @@ pub mod isi {
}
}

impl Execute for SetKeyValue<Trigger> {
#[metrics(+"set_trigger_key_value")]
fn execute(
self,
_authority: &AccountId,
state_transaction: &mut StateTransaction<'_, '_>,
) -> Result<(), Error> {
let trigger_id = self.object_id;

let trigger_metadata_limits = state_transaction.config.account_metadata_limits;
state_transaction
.world
.triggers
.inspect_by_id_mut(&trigger_id, |action| {
action.metadata_mut().insert_with_limits(
self.key.clone(),
self.value.clone(),
trigger_metadata_limits,
)
})
.ok_or(FindError::Trigger(trigger_id.clone()))??;

state_transaction
.world
.emit_events(Some(TriggerEvent::MetadataInserted(MetadataChanged {
target_id: trigger_id,
key: self.key,
value: self.value,
})));

Ok(())
}
}

impl Execute for RemoveKeyValue<Trigger> {
#[metrics(+"remove_trigger_key_value")]
fn execute(
self,
_authority: &AccountId,
state_transaction: &mut StateTransaction<'_, '_>,
) -> Result<(), Error> {
let trigger_id = self.object_id;

let value = state_transaction
.world
.triggers
.inspect_by_id_mut(&trigger_id, |action| {
action
.metadata_mut()
.remove(&self.key)
.ok_or_else(|| FindError::MetadataKey(self.key.clone()))
})
.ok_or(FindError::Trigger(trigger_id.clone()))??;

state_transaction
.world
.emit_events(Some(TriggerEvent::MetadataRemoved(MetadataChanged {
target_id: trigger_id,
key: self.key,
value,
})));

Ok(())
}
}

impl Execute for ExecuteTrigger {
#[metrics(+"execute_trigger")]
fn execute(
Expand Down
8 changes: 8 additions & 0 deletions core/src/smartcontracts/isi/triggers/specialized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ pub trait LoadedActionTrait {
/// Get action metadata
fn metadata(&self) -> &Metadata;

/// Get action metadata
fn metadata_mut(&mut self) -> &mut Metadata;

/// Check if action is mintable.
fn mintable(&self) -> bool;

Expand Down Expand Up @@ -181,10 +184,15 @@ impl<F: EventFilter + Into<TriggeringEventFilterBox> + Clone> LoadedActionTrait
&self.authority
}

/// Get action metadata
fn metadata(&self) -> &Metadata {
&self.metadata
}

fn metadata_mut(&mut self) -> &mut Metadata {
&mut self.metadata
}

fn mintable(&self) -> bool {
self.filter.mintable()
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/smartcontracts/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@ pub mod state {
/// Trigger execution state
#[derive(Constructor)]
pub struct Trigger {
pub(in super::super) id: TriggerId,

/// Event which activated this trigger
pub(in super::super) triggering_event: Event,
}
Expand Down Expand Up @@ -985,7 +987,7 @@ impl<'wrld, 'block: 'wrld, 'state: 'block> Runtime<state::Trigger<'wrld, 'block,
self.config,
span,
state::chain_state::WithMut(state_transaction),
state::specific::Trigger::new(event),
state::specific::Trigger::new(id.clone(), event),
);

let mut store = self.create_store(state);
Expand All @@ -1006,6 +1008,7 @@ impl<'wrld, 'block: 'wrld, 'state: 'block> Runtime<state::Trigger<'wrld, 'block,
#[codec::wrap]
fn get_trigger_payload(state: &state::Trigger) -> payloads::Trigger {
payloads::Trigger {
id: state.specific_state.id.clone(),
owner: state.authority.clone(),
event: state.specific_state.triggering_event.clone(),
}
Expand Down
Loading

0 comments on commit 4bc8833

Please sign in to comment.