diff --git a/client/benches/tps/utils.rs b/client/benches/tps/utils.rs index b29ec8e56ae..ba6f83b22ef 100644 --- a/client/benches/tps/utils.rs +++ b/client/benches/tps/utils.rs @@ -173,8 +173,8 @@ impl MeasurerUnit { let listener = self.client.clone(); let (init_sender, init_receiver) = mpsc::channel(); let event_filter = PipelineEventFilter::new() - .entity_kind(PipelineEntityKind::Block) - .status_kind(PipelineStatusKind::Committed); + .from_entity_of_kind(PipelineEntityKind::Block) + .with_status(PipelineStatusKind::Committed); let blocks_expected = self.config.blocks as usize; let name = self.name; let handle = thread::spawn(move || -> Result<()> { diff --git a/client/src/client.rs b/client/src/client.rs index 123b6bee244..e84d3fc2485 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -603,7 +603,9 @@ impl Client { let mut event_iterator = { let event_iterator_result = tokio::time::timeout_at( deadline, - self.listen_for_events_async(PipelineEventFilter::new().hash(hash.into())), + self.listen_for_events_async( + PipelineEventFilter::new().from_entity_with_hash(hash.into()), + ), ) .await .map_err(Into::into) @@ -915,7 +917,7 @@ impl Client { /// - Forwards from [`events_api::AsyncEventStream::new`] pub async fn listen_for_events_async( &self, - event_filter: impl Into, + event_filter: impl Into + Send, ) -> Result { let event_filter = event_filter.into(); iroha_logger::trace!(?event_filter, "Async listening with"); diff --git a/client/tests/integration/domain_owner_permissions.rs b/client/tests/integration/domain_owner_permissions.rs index e0478762dbb..7c9a79319e7 100644 --- a/client/tests/integration/domain_owner_permissions.rs +++ b/client/tests/integration/domain_owner_permissions.rs @@ -307,11 +307,9 @@ fn domain_owner_trigger_permissions() -> Result<()> { trigger_instructions, Repeats::from(2_u32), bob_id, - // FIXME: due to restriction in `ExecuteTriggerEventFilter` it's impossible to execute trigger on behalf of multiple users - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - alice_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new().from_trigger(trigger_id.clone()), + ), ), )); test_client.submit_blocking(register_trigger)?; diff --git a/client/tests/integration/events/data.rs b/client/tests/integration/events/data.rs index 3136f369860..4250ff2b682 100644 --- a/client/tests/integration/events/data.rs +++ b/client/tests/integration/events/data.rs @@ -138,7 +138,7 @@ fn transaction_execution_should_produce_events( let listener = client.clone(); let (init_sender, init_receiver) = mpsc::channel(); let (event_sender, event_receiver) = mpsc::channel(); - let event_filter = DataEventFilter::ByAny; + let event_filter = DataEventFilter::Any; thread::spawn(move || -> Result<()> { let event_iterator = listener.listen_for_events(event_filter)?; init_sender.send(())?; @@ -182,7 +182,7 @@ fn produce_multiple_events() -> Result<()> { let listener = client.clone(); let (init_sender, init_receiver) = mpsc::channel(); let (event_sender, event_receiver) = mpsc::channel(); - let event_filter = DataEventFilter::ByAny; + let event_filter = DataEventFilter::Any; thread::spawn(move || -> Result<()> { let event_iterator = listener.listen_for_events(event_filter)?; init_sender.send(())?; diff --git a/client/tests/integration/events/notification.rs b/client/tests/integration/events/notification.rs index 8c817ad749c..d43f49f21c9 100644 --- a/client/tests/integration/events/notification.rs +++ b/client/tests/integration/events/notification.rs @@ -21,10 +21,11 @@ fn trigger_completion_success_should_produce_event() -> Result<()> { vec![InstructionBox::from(instruction)], Repeats::Indefinitely, asset_id.account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - asset_id.account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(asset_id.account_id), + ), ), )); test_client.submit_blocking(register_trigger)?; @@ -34,12 +35,12 @@ fn trigger_completion_success_should_produce_event() -> Result<()> { let thread_client = test_client.clone(); let (sender, receiver) = mpsc::channel(); let _handle = thread::spawn(move || -> Result<()> { - let mut event_it = thread_client.listen_for_events( - NotificationEventFilter::ByTriggerCompleted(TriggerCompletedEventFilter::new( - Some(trigger_id), - Some(TriggerCompletedOutcomeType::Success), - )), - )?; + let mut event_it = + thread_client.listen_for_events(NotificationEventFilter::ByTriggerCompleted( + TriggerCompletedEventFilter::new() + .from_trigger(trigger_id) + .with_outcome(TriggerCompletedOutcomeType::Success), + ))?; if event_it.next().is_some() { sender.send(())?; return Ok(()); @@ -69,10 +70,11 @@ fn trigger_completion_failure_should_produce_event() -> Result<()> { vec![InstructionBox::from(instruction)], Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id), + ), ), )); test_client.submit_blocking(register_trigger)?; @@ -82,12 +84,12 @@ fn trigger_completion_failure_should_produce_event() -> Result<()> { let thread_client = test_client.clone(); let (sender, receiver) = mpsc::channel(); let _handle = thread::spawn(move || -> Result<()> { - let mut event_it = thread_client.listen_for_events( - NotificationEventFilter::ByTriggerCompleted(TriggerCompletedEventFilter::new( - Some(trigger_id), - Some(TriggerCompletedOutcomeType::Failure), - )), - )?; + let mut event_it = + thread_client.listen_for_events(NotificationEventFilter::ByTriggerCompleted( + TriggerCompletedEventFilter::new() + .from_trigger(trigger_id) + .with_outcome(TriggerCompletedOutcomeType::Failure), + ))?; if event_it.next().is_some() { sender.send(())?; return Ok(()); diff --git a/client/tests/integration/events/pipeline.rs b/client/tests/integration/events/pipeline.rs index 6f443b36186..83673beeb55 100644 --- a/client/tests/integration/events/pipeline.rs +++ b/client/tests/integration/events/pipeline.rs @@ -84,9 +84,9 @@ impl Checker { .listener .listen_for_events( PipelineEventFilter::new() - .entity_kind(PipelineEntityKind::Transaction) - .status_kind(status_kind) - .hash(*self.hash), + .from_entity_of_kind(PipelineEntityKind::Transaction) + .with_status(status_kind) + .from_entity_with_hash(*self.hash), ) .expect("Failed to create event iterator."); let event_result = event_iterator.next().expect("Stream closed"); @@ -101,8 +101,8 @@ fn committed_block_must_be_available_in_kura() { wait_for_genesis_committed(&[client.clone()], 0); let event_filter = PipelineEventFilter::new() - .entity_kind(PipelineEntityKind::Block) - .status_kind(PipelineStatusKind::Committed); + .from_entity_of_kind(PipelineEntityKind::Block) + .with_status(PipelineStatusKind::Committed); let mut event_iter = client .listen_for_events(event_filter) .expect("Failed to subscribe for events"); diff --git a/client/tests/integration/triggers/by_call_trigger.rs b/client/tests/integration/triggers/by_call_trigger.rs index f5f6a2675ac..8d00b074e1d 100644 --- a/client/tests/integration/triggers/by_call_trigger.rs +++ b/client/tests/integration/triggers/by_call_trigger.rs @@ -59,8 +59,11 @@ fn execute_trigger_should_produce_event() -> Result<()> { let thread_client = test_client.clone(); let (sender, receiver) = mpsc::channel(); let _handle = thread::spawn(move || -> Result<()> { - let mut event_it = thread_client - .listen_for_events(ExecuteTriggerEventFilter::new(trigger_id, account_id))?; + let mut event_it = thread_client.listen_for_events( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id) + .under_authority(account_id), + )?; if event_it.next().is_some() { sender.send(())?; return Ok(()); @@ -121,10 +124,11 @@ fn trigger_failure_should_not_cancel_other_triggers_execution() -> Result<()> { bad_trigger_instructions, Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - bad_trigger_id.clone(), - account_id.clone(), - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(bad_trigger_id.clone()) + .under_authority(account_id.clone()), + ), ), )); test_client.submit(register_bad_trigger)?; @@ -173,10 +177,11 @@ fn trigger_should_not_be_executed_with_zero_repeats_count() -> Result<()> { trigger_instructions, Repeats::from(1_u32), account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id), + ), ), )); test_client.submit_blocking(register_trigger)?; @@ -234,10 +239,11 @@ fn trigger_should_be_able_to_modify_its_own_repeats_count() -> Result<()> { trigger_instructions, Repeats::from(1_u32), account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id), + ), ), )); test_client.submit_blocking(register_trigger)?; @@ -274,10 +280,11 @@ fn unregister_trigger() -> Result<()> { Vec::::new(), Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id), + ), ), ); let register_trigger = Register::trigger(trigger.clone()); @@ -351,10 +358,11 @@ fn trigger_in_genesis_using_base64() -> Result<()> { .wrap_err("Can't deserialize wasm using base64")?, Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id.clone(), - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id.clone()), + ), ), ); @@ -401,10 +409,11 @@ fn trigger_should_be_able_to_modify_other_trigger() -> Result<()> { trigger_unregister_instructions, Repeats::from(1_u32), account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id_unregister.clone(), - account_id.clone(), - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id_unregister.clone()) + .under_authority(account_id.clone()), + ), ), )); test_client.submit_blocking(register_trigger)?; @@ -417,10 +426,11 @@ fn trigger_should_be_able_to_modify_other_trigger() -> Result<()> { trigger_should_be_unregistered_instructions, Repeats::from(1_u32), account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id_to_be_unregistered.clone(), - account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id_to_be_unregistered.clone()) + .under_authority(account_id), + ), ), )); test_client.submit_blocking(register_trigger)?; @@ -461,10 +471,11 @@ fn trigger_burn_repetitions() -> Result<()> { trigger_instructions, Repeats::from(1_u32), account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id), + ), ), )); test_client.submit_blocking(register_trigger)?; @@ -505,10 +516,11 @@ fn unregistering_one_of_two_triggers_with_identical_wasm_should_not_cause_origin wasm.clone(), Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id, - account_id.clone(), - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id) + .under_authority(account_id.clone()), + ), ), ) }; @@ -550,10 +562,11 @@ fn build_register_trigger_isi( trigger_instructions, Repeats::Indefinitely, asset_id.account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id, - asset_id.account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id) + .under_authority(asset_id.account_id), + ), ), )) } diff --git a/client/tests/integration/triggers/data_trigger.rs b/client/tests/integration/triggers/data_trigger.rs index f06e51fe4c2..f7040f228ad 100644 --- a/client/tests/integration/triggers/data_trigger.rs +++ b/client/tests/integration/triggers/data_trigger.rs @@ -20,10 +20,9 @@ fn must_execute_both_triggers() -> Result<()> { [instruction.clone()], Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::Data(DataEventFilter::ByAccount(AccountEventFilter { - id_matcher: None, - event_matcher: Some(AccountEventMatcher::ByCreated), - })), + TriggeringEventFilterBox::Data(DataEventFilter::Account( + AccountEventFilter::new().only_events(AccountEventMatcher::Created), + )), ), )); test_client.submit_blocking(register_trigger)?; @@ -34,10 +33,9 @@ fn must_execute_both_triggers() -> Result<()> { [instruction], Repeats::Indefinitely, account_id, - TriggeringEventFilterBox::Data(DataEventFilter::ByDomain(DomainEventFilter { - id_matcher: None, - event_matcher: Some(DomainEventMatcher::ByCreated), - })), + TriggeringEventFilterBox::Data(DataEventFilter::Domain( + DomainEventFilter::new().only_events(DomainEventMatcher::Created), + )), ), )); test_client.submit_blocking(register_trigger)?; @@ -88,10 +86,9 @@ fn domain_scoped_trigger_must_be_executed_only_on_events_in_its_domain() -> Resu [Mint::asset_quantity(1_u32, asset_id.clone())], Repeats::Indefinitely, account_id, - TriggeringEventFilterBox::Data(DataEventFilter::ByAccount(AccountEventFilter { - id_matcher: None, - event_matcher: Some(AccountEventMatcher::ByCreated), - })), + TriggeringEventFilterBox::Data(DataEventFilter::Account( + AccountEventFilter::new().only_events(AccountEventMatcher::Created), + )), ), )); test_client.submit_blocking(register_trigger)?; diff --git a/client/tests/integration/triggers/event_trigger.rs b/client/tests/integration/triggers/event_trigger.rs index fcc0717f8d4..67dcd9b4840 100644 --- a/client/tests/integration/triggers/event_trigger.rs +++ b/client/tests/integration/triggers/event_trigger.rs @@ -24,11 +24,8 @@ fn test_mint_asset_when_new_asset_definition_created() -> Result<()> { vec![instruction], Repeats::Indefinitely, account_id, - TriggeringEventFilterBox::Data(DataEventFilter::ByAssetDefinition( - AssetDefinitionEventFilter { - id_matcher: None, - event_matcher: Some(AssetDefinitionEventMatcher::ByCreated), - }, + TriggeringEventFilterBox::Data(DataEventFilter::AssetDefinition( + AssetDefinitionEventFilter::new().only_events(AssetDefinitionEventMatcher::Created), )), ), )); diff --git a/client/tests/integration/triggers/time_trigger.rs b/client/tests/integration/triggers/time_trigger.rs index 183822471d2..7dacdb6113e 100644 --- a/client/tests/integration/triggers/time_trigger.rs +++ b/client/tests/integration/triggers/time_trigger.rs @@ -270,8 +270,8 @@ fn get_block_committed_event_listener( client: &Client, ) -> Result>> { let block_filter = PipelineEventFilter::new() - .entity_kind(PipelineEntityKind::Block) - .status_kind(PipelineStatusKind::Committed); + .from_entity_of_kind(PipelineEntityKind::Block) + .with_status(PipelineStatusKind::Committed); client.listen_for_events(block_filter) } diff --git a/client/tests/integration/triggers/trigger_rollback.rs b/client/tests/integration/triggers/trigger_rollback.rs index 9125cb98eba..f5d79fe21ec 100644 --- a/client/tests/integration/triggers/trigger_rollback.rs +++ b/client/tests/integration/triggers/trigger_rollback.rs @@ -28,10 +28,11 @@ fn failed_trigger_revert() -> Result<()> { instructions, Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id, - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id), + ), ), )); let _ = client.submit_blocking(register_trigger); diff --git a/client_cli/src/main.rs b/client_cli/src/main.rs index be9a96ad5a1..8603f6cce75 100644 --- a/client_cli/src/main.rs +++ b/client_cli/src/main.rs @@ -315,7 +315,7 @@ mod events { fn run(self, context: &mut dyn RunContext) -> Result<()> { let filter = match self { Args::Pipeline => EventFilterBox::Pipeline(PipelineEventFilter::new()), - Args::Data => EventFilterBox::Data(DataEventFilter::ByAny), + Args::Data => EventFilterBox::Data(DataEventFilter::Any), Args::Notification => EventFilterBox::Notification(NotificationEventFilter::ByAny), }; listen(filter, context) diff --git a/core/src/smartcontracts/isi/mod.rs b/core/src/smartcontracts/isi/mod.rs index 1a7aa3efc7b..d517faa95bf 100644 --- a/core/src/smartcontracts/isi/mod.rs +++ b/core/src/smartcontracts/isi/mod.rs @@ -406,10 +406,11 @@ mod tests { Vec::::new(), Repeats::Indefinitely, account_id.clone(), - TriggeringEventFilterBox::ExecuteTrigger(ExecuteTriggerEventFilter::new( - trigger_id.clone(), - account_id.clone(), - )), + TriggeringEventFilterBox::ExecuteTrigger( + ExecuteTriggerEventFilter::new() + .from_trigger(trigger_id.clone()) + .under_authority(account_id.clone()), + ), ), )); diff --git a/data_model/src/events/data/filters.rs b/data_model/src/events/data/filters.rs index cfcb20f9079..3fef9ae6e51 100644 --- a/data_model/src/events/data/filters.rs +++ b/data_model/src/events/data/filters.rs @@ -1,13 +1,12 @@ //! This module contains filters for data events. //! //! (almost) Each event in [`super::events`], there's two corresponding types in this module: -//! - `*EventMatcher` - matches one event kind (e.g. [`super::events::AccountEvent::Created`] with [`AccountEventMatcher::ByCreated`]) +//! - `*EventMatcher` - matches one event kind (e.g. [`super::events::AccountEvent::Created`] with [`AccountEventMatcher::Created`]) //! - `*EventFilter` - struct combining an optional id matcher and an optional event matcher -//! -//! The ones not having a filter are [`super::events::ConfigurationEvent`] and [`super::events::ExecutorEvent`] (TODO: why?). use core::fmt::Debug; +use getset::Getters; use iroha_data_model_derive::model; pub use self::model::*; @@ -18,206 +17,423 @@ pub mod model { use super::*; #[derive( - Debug, Clone, PartialEq, Eq, FromVariant, Decode, Encode, Deserialize, Serialize, IntoSchema, + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + FromVariant, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, )] pub enum DataEventFilter { /// Matches any data events ([`DataEvent`]) - ByAny, - /// Matches only [`PeerEvent`]s - ByPeer(PeerEventFilter), - /// Matches only [`DomainEvent`]s - ByDomain(DomainEventFilter), - /// Matches only [`AccountEvent`]s - ByAccount(AccountEventFilter), - /// Matches only [`AssetEvent`]s - ByAsset(AssetEventFilter), - /// Matches only [`AssetDefinitionEvent`]s - ByAssetDefinition(AssetDefinitionEventFilter), - /// Matches only [`TriggerEvent`]s - ByTrigger(TriggerEventFilter), - /// Matches only [`RoleEvent`]s - ByRole(RoleEventFilter), + Any, + /// Matches [`PeerEvent`]s + Peer(PeerEventFilter), + /// Matches [`DomainEvent`]s + Domain(DomainEventFilter), + /// Matches [`AccountEvent`]s + Account(AccountEventFilter), + /// Matches [`AssetEvent`]s + Asset(AssetEventFilter), + /// Matches [`AssetDefinitionEvent`]s + AssetDefinition(AssetDefinitionEventFilter), + /// Matches [`TriggerEvent`]s + Trigger(TriggerEventFilter), + /// Matches [`RoleEvent`]s + Role(RoleEventFilter), // We didn't have filters for these events before the refactor. Should we? // Configuration(ConfigurationEventFilter), // Executor(ExecutorEventFilter), } /// An event filter for [`PeerEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Getters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub struct PeerEventFilter { - pub id_matcher: Option, - pub event_matcher: Option, + /// If specified matches only events originating from this peer + pub(super) id_matcher: Option, + /// If specified matches only events of this type + pub(super) event_matcher: Option, } /// An event matcher for [`PeerEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub enum PeerEventMatcher { - /// Matches only [`PeerEvent::Added`] - ByAdded, - /// Matches only [`PeerEvent::Removed`] - ByRemoved, + /// Matches [`PeerEvent::Added`] + Added, + /// Matches [`PeerEvent::Removed`] + Removed, } /// An event filter for [`DomainEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Getters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub struct DomainEventFilter { /// If specified matches only events originating from this domain - pub id_matcher: Option, + pub(super) id_matcher: Option, /// If specified matches only events of this type - pub event_matcher: Option, + pub(super) event_matcher: Option, } /// An event matcher for [`DomainEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub enum DomainEventMatcher { - /// Matches only [`DomainEvent::Created`] - ByCreated, - /// Matches only [`DomainEvent::Deleted`] - ByDeleted, - /// Matches only [`DomainEvent::MetadataInserted`] - ByMetadataInserted, - /// Matches only [`DomainEvent::MetadataRemoved`] - ByMetadataRemoved, - /// Matches only [`DomainEvent::OwnerChanged`] - ByOwnerChanged, + /// Matches [`DomainEvent::Created`] + Created, + /// Matches [`DomainEvent::Deleted`] + Deleted, + /// Matches [`DomainEvent::MetadataInserted`] + MetadataInserted, + /// Matches [`DomainEvent::MetadataRemoved`] + MetadataRemoved, + /// Matches [`DomainEvent::OwnerChanged`] + OwnerChanged, // we allow filtering for nested events, but if you need to specify an id matcher for, for example, AccountId, you need to use AccountFilter - /// Matches only [`DomainEvent::Account`] - ByAccountAny, - /// Matches only [`DomainEvent::AssetDefinition`] - ByAssetDefinitionAny, + /// Matches any [`DomainEvent::Account`]. To further filter by account events, use [`AccountEventFilter`] + AnyAccount, + /// Matches any [`DomainEvent::AssetDefinition`]. To further filter by asset definition events, use [`AssetDefinitionEventFilter`] + AnyAssetDefinition, } /// An event filter for [`AccountEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Getters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub struct AccountEventFilter { /// If specified matches only events originating from this account - pub id_matcher: Option, + pub(super) id_matcher: Option, /// If specified matches only events of this type - pub event_matcher: Option, + pub(super) event_matcher: Option, } /// An event matcher for [`AccountEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub enum AccountEventMatcher { - /// Matches only [`AccountEvent::Created`] - ByCreated, - /// Matches only [`AccountEvent::Deleted`] - ByDeleted, - /// Matches only [`AccountEvent::AuthenticationAdded`] - ByAuthenticationAdded, - /// Matches only [`AccountEvent::AuthenticationRemoved`] - ByAuthenticationRemoved, - /// Matches only [`AccountEvent::PermissionAdded`] - ByPermissionAdded, - /// Matches only [`AccountEvent::PermissionRemoved`] - ByPermissionRemoved, - /// Matches only [`AccountEvent::RoleRevoked`] - ByRoleRevoked, - /// Matches only [`AccountEvent::RoleGranted`] - ByRoleGranted, - /// Matches only [`AccountEvent::MetadataInserted`] - ByMetadataInserted, - /// Matches only [`AccountEvent::MetadataRemoved`] - ByMetadataRemoved, + /// Matches [`AccountEvent::Created`] + Created, + /// Matches [`AccountEvent::Deleted`] + Deleted, + /// Matches [`AccountEvent::AuthenticationAdded`] + AuthenticationAdded, + /// Matches [`AccountEvent::AuthenticationRemoved`] + AuthenticationRemoved, + /// Matches [`AccountEvent::PermissionAdded`] + PermissionAdded, + /// Matches [`AccountEvent::PermissionRemoved`] + PermissionRemoved, + /// Matches [`AccountEvent::RoleRevoked`] + RoleRevoked, + /// Matches [`AccountEvent::RoleGranted`] + RoleGranted, + /// Matches [`AccountEvent::MetadataInserted`] + MetadataInserted, + /// Matches [`AccountEvent::MetadataRemoved`] + MetadataRemoved, // nested events - /// Matches only [`AccountEvent::Asset`] - ByAssetAny, + /// Matches any [`AccountEvent::Asset`]. To further filter by asset events, use [`AssetEventFilter`] + AnyAsset, } /// An event filter for [`AssetEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Getters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub struct AssetEventFilter { /// If specified matches only events originating from this asset - pub id_matcher: Option, + pub(super) id_matcher: Option, /// If specified matches only events of this type - pub event_matcher: Option, + pub(super) event_matcher: Option, } /// An event matcher for [`AssetEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub enum AssetEventMatcher { - /// Matches only [`AssetEvent::Created`] - ByCreated, - /// Matches only [`AssetEvent::Deleted`] - ByDeleted, - /// Matches only [`AssetEvent::Added`] - ByAdded, - /// Matches only [`AssetEvent::Removed`] - ByRemoved, - /// Matches only [`AssetEvent::MetadataInserted`] - ByMetadataInserted, - /// Matches only [`AssetEvent::MetadataRemoved`] - ByMetadataRemoved, + /// Matches [`AssetEvent::Created`] + Created, + /// Matches [`AssetEvent::Deleted`] + Deleted, + /// Matches [`AssetEvent::Added`] + Added, + /// Matches [`AssetEvent::Removed`] + Removed, + /// Matches [`AssetEvent::MetadataInserted`] + MetadataInserted, + /// Matches [`AssetEvent::MetadataRemoved`] + MetadataRemoved, } /// An event filter for [`AssetDefinitionEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Getters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub struct AssetDefinitionEventFilter { /// If specified matches only events originating from this asset definition - pub id_matcher: Option, + pub(super) id_matcher: Option, /// If specified matches only events of this type - pub event_matcher: Option, + pub(super) event_matcher: Option, } /// An event matcher for [`AssetDefinitionEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub enum AssetDefinitionEventMatcher { - /// Matches only [`AssetDefinitionEvent::Created`] - ByCreated, - /// Matches only [`AssetDefinitionEvent::MintabilityChanged`] - ByMintabilityChanged, - /// Matches only [`AssetDefinitionEvent::OwnerChanged`] - ByOwnerChanged, - /// Matches only [`AssetDefinitionEvent::Deleted`] - ByDeleted, - /// Matches only [`AssetDefinitionEvent::MetadataInserted`] - ByMetadataInserted, - /// Matches only [`AssetDefinitionEvent::MetadataRemoved`] - ByMetadataRemoved, - /// Matches only [`AssetDefinitionEvent::TotalQuantityChanged`] - ByTotalQuantityChanged, + /// Matches [`AssetDefinitionEvent::Created`] + Created, + /// Matches [`AssetDefinitionEvent::MintabilityChanged`] + MintabilityChanged, + /// Matches [`AssetDefinitionEvent::OwnerChanged`] + OwnerChanged, + /// Matches [`AssetDefinitionEvent::Deleted`] + Deleted, + /// Matches [`AssetDefinitionEvent::MetadataInserted`] + MetadataInserted, + /// Matches [`AssetDefinitionEvent::MetadataRemoved`] + MetadataRemoved, + /// Matches [`AssetDefinitionEvent::TotalQuantityChanged`] + TotalQuantityChanged, } /// An event filter for [`TriggerEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Getters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub struct TriggerEventFilter { /// If specified matches only events originating from this trigger - pub id_matcher: Option, + pub(super) id_matcher: Option, /// If specified matches only events of this type - pub event_matcher: Option, + pub(super) event_matcher: Option, } /// An event matcher for [`TriggerEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub enum TriggerEventMatcher { - /// Matches only [`TriggerEvent::Created`] - ByCreated, - /// Matches only [`TriggerEvent::Deleted`] - ByDeleted, - /// Matches only [`TriggerEvent::Extended`] - ByExtended, - /// Matches only [`TriggerEvent::Shortened`] - ByShortened, + /// Matches [`TriggerEvent::Created`] + Created, + /// Matches [`TriggerEvent::Deleted`] + Deleted, + /// Matches [`TriggerEvent::Extended`] + Extended, + /// Matches [`TriggerEvent::Shortened`] + Shortened, } /// An event filter for [`RoleEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Default, + Getters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub struct RoleEventFilter { /// If specified matches only events originating from this role - pub id_matcher: Option, + pub(super) id_matcher: Option, /// If specified matches only events of this type - pub event_matcher: Option, + pub(super) event_matcher: Option, } /// An event matcher for [`RoleEvent`]s - #[derive(Debug, Clone, PartialEq, Eq, Decode, Encode, Deserialize, Serialize, IntoSchema)] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] pub enum RoleEventMatcher { - /// Matches only [`RoleEvent::Created`] - ByCreated, - /// Matches only [`RoleEvent::Deleted`] - ByDeleted, - /// Matches only [`RoleEvent::PermissionRemoved`] - ByPermissionRemoved, + /// Matches [`RoleEvent::Created`] + Created, + /// Matches [`RoleEvent::Deleted`] + Deleted, + /// Matches [`RoleEvent::PermissionRemoved`] + PermissionRemoved, + } +} + +impl PeerEventFilter { + /// Creates a new [`PeerEventFilter`] accepting all [`PeerEvent`]s. + pub const fn new() -> Self { + Self { + id_matcher: None, + event_matcher: None, + } + } + + /// Modifies a [`PeerEventFilter`] to accept only [`PeerEvent`]s originating from ids matching `id_matcher`. + pub fn only_id(mut self, id_matcher: PeerId) -> Self { + self.id_matcher = Some(id_matcher); + self + } + + /// Modifies a [`PeerEventFilter`] to accept only [`PeerEvent`]s of types matching `event_matcher`. + pub const fn only_events(mut self, event_matcher: PeerEventMatcher) -> Self { + self.event_matcher = Some(event_matcher); + self } } @@ -228,8 +444,6 @@ impl EventFilter for PeerEventFilter { fn matches(&self, event: &Self::Event) -> bool { use PeerEventMatcher::*; - use super::PeerEvent::*; - if let Some(id_matcher) = &self.id_matcher { if id_matcher != event.origin_id() { return false; @@ -237,8 +451,8 @@ impl EventFilter for PeerEventFilter { } if let Some(event_matcher) = &self.event_matcher { match (event_matcher, event) { - (ByAdded, Added(_)) => true, - (ByRemoved, Removed(_)) => true, + (Added, PeerEvent::Added(_)) => true, + (Removed, PeerEvent::Removed(_)) => true, _ => false, } } else { @@ -247,6 +461,28 @@ impl EventFilter for PeerEventFilter { } } +impl DomainEventFilter { + /// Creates a new [`DomainEventFilter`] accepting all [`DomainEvent`]s. + pub const fn new() -> Self { + Self { + id_matcher: None, + event_matcher: None, + } + } + + /// Modifies a [`DomainEventFilter`] to accept only [`DomainEvent`]s originating from ids matching `id_matcher`. + pub fn only_id(mut self, id_matcher: DomainId) -> Self { + self.id_matcher = Some(id_matcher); + self + } + + /// Modifies a [`DomainEventFilter`] to accept only [`DomainEvent`]s of types matching `event_matcher`. + pub const fn only_events(mut self, event_matcher: DomainEventMatcher) -> Self { + self.event_matcher = Some(event_matcher); + self + } +} + #[cfg(feature = "transparent_api")] impl EventFilter for DomainEventFilter { type Event = super::DomainEvent; @@ -254,8 +490,6 @@ impl EventFilter for DomainEventFilter { fn matches(&self, event: &Self::Event) -> bool { use DomainEventMatcher::*; - use super::DomainEvent::*; - if let Some(id_matcher) = &self.id_matcher { if id_matcher != event.origin_id() { return false; @@ -263,13 +497,13 @@ impl EventFilter for DomainEventFilter { } if let Some(event_matcher) = &self.event_matcher { match (event_matcher, event) { - (ByCreated, Created(_)) => true, - (ByDeleted, Deleted(_)) => true, - (ByMetadataInserted, MetadataInserted(_)) => true, - (ByMetadataRemoved, MetadataRemoved(_)) => true, - (ByOwnerChanged, OwnerChanged(_)) => true, - (ByAccountAny, Account(_)) => true, - (ByAssetDefinitionAny, AssetDefinition(_)) => true, + (Created, DomainEvent::Created(_)) => true, + (Deleted, DomainEvent::Deleted(_)) => true, + (MetadataInserted, DomainEvent::MetadataInserted(_)) => true, + (MetadataRemoved, DomainEvent::MetadataRemoved(_)) => true, + (OwnerChanged, DomainEvent::OwnerChanged(_)) => true, + (AnyAccount, DomainEvent::Account(_)) => true, + (AnyAssetDefinition, DomainEvent::AssetDefinition(_)) => true, _ => false, } } else { @@ -278,6 +512,28 @@ impl EventFilter for DomainEventFilter { } } +impl AccountEventFilter { + /// Creates a new [`AccountEventFilter`] accepting all [`AccountEvent`]s. + pub const fn new() -> Self { + Self { + id_matcher: None, + event_matcher: None, + } + } + + /// Modifies a [`AccountEventFilter`] to accept only [`AccountEvent`]s originating from ids matching `id_matcher`. + pub fn only_id(mut self, id_matcher: AccountId) -> Self { + self.id_matcher = Some(id_matcher); + self + } + + /// Modifies a [`AccountEventFilter`] to accept only [`AccountEvent`]s of types matching `event_matcher`. + pub const fn only_events(mut self, event_matcher: AccountEventMatcher) -> Self { + self.event_matcher = Some(event_matcher); + self + } +} + #[cfg(feature = "transparent_api")] impl super::EventFilter for AccountEventFilter { type Event = super::AccountEvent; @@ -285,8 +541,6 @@ impl super::EventFilter for AccountEventFilter { fn matches(&self, event: &Self::Event) -> bool { use AccountEventMatcher::*; - use super::AccountEvent::*; - if let Some(id_matcher) = &self.id_matcher { if id_matcher != event.origin_id() { return false; @@ -294,17 +548,17 @@ impl super::EventFilter for AccountEventFilter { } if let Some(event_matcher) = &self.event_matcher { match (event_matcher, event) { - (ByCreated, Created(_)) => true, - (ByDeleted, Deleted(_)) => true, - (ByAuthenticationAdded, AuthenticationAdded(_)) => true, - (ByAuthenticationRemoved, AuthenticationRemoved(_)) => true, - (ByPermissionAdded, PermissionAdded(_)) => true, - (ByPermissionRemoved, PermissionRemoved(_)) => true, - (ByRoleRevoked, RoleRevoked(_)) => true, - (ByRoleGranted, RoleGranted(_)) => true, - (ByMetadataInserted, MetadataInserted(_)) => true, - (ByMetadataRemoved, MetadataRemoved(_)) => true, - (ByAssetAny, Asset(_)) => true, + (Created, AccountEvent::Created(_)) => true, + (Deleted, AccountEvent::Deleted(_)) => true, + (AuthenticationAdded, AccountEvent::AuthenticationAdded(_)) => true, + (AuthenticationRemoved, AccountEvent::AuthenticationRemoved(_)) => true, + (PermissionAdded, AccountEvent::PermissionAdded(_)) => true, + (PermissionRemoved, AccountEvent::PermissionRemoved(_)) => true, + (RoleRevoked, AccountEvent::RoleRevoked(_)) => true, + (RoleGranted, AccountEvent::RoleGranted(_)) => true, + (MetadataInserted, AccountEvent::MetadataInserted(_)) => true, + (MetadataRemoved, AccountEvent::MetadataRemoved(_)) => true, + (AnyAsset, AccountEvent::Asset(_)) => true, _ => false, } } else { @@ -313,6 +567,28 @@ impl super::EventFilter for AccountEventFilter { } } +impl AssetEventFilter { + /// Creates a new [`AssetEventFilter`] accepting all [`AssetEvent`]s. + pub const fn new() -> Self { + Self { + id_matcher: None, + event_matcher: None, + } + } + + /// Modifies a [`AssetEventFilter`] to accept only [`AssetEvent`]s originating from ids matching `id_matcher`. + pub fn only_from(mut self, id_matcher: AssetId) -> Self { + self.id_matcher = Some(id_matcher); + self + } + + /// Modifies a [`AssetEventFilter`] to accept only [`AssetEvent`]s of types matching `event_matcher`. + pub const fn only_events(mut self, event_matcher: AssetEventMatcher) -> Self { + self.event_matcher = Some(event_matcher); + self + } +} + #[cfg(feature = "transparent_api")] impl super::EventFilter for AssetEventFilter { type Event = super::AssetEvent; @@ -320,8 +596,6 @@ impl super::EventFilter for AssetEventFilter { fn matches(&self, event: &Self::Event) -> bool { use AssetEventMatcher::*; - use super::AssetEvent::*; - if let Some(id_matcher) = &self.id_matcher { if id_matcher != event.origin_id() { return false; @@ -329,12 +603,12 @@ impl super::EventFilter for AssetEventFilter { } if let Some(event_matcher) = &self.event_matcher { match (event_matcher, event) { - (ByCreated, Created(_)) => true, - (ByDeleted, Deleted(_)) => true, - (ByAdded, Added(_)) => true, - (ByRemoved, Removed(_)) => true, - (ByMetadataInserted, MetadataInserted(_)) => true, - (ByMetadataRemoved, MetadataRemoved(_)) => true, + (Created, AssetEvent::Created(_)) => true, + (Deleted, AssetEvent::Deleted(_)) => true, + (Added, AssetEvent::Added(_)) => true, + (Removed, AssetEvent::Removed(_)) => true, + (MetadataInserted, AssetEvent::MetadataInserted(_)) => true, + (MetadataRemoved, AssetEvent::MetadataRemoved(_)) => true, _ => false, } } else { @@ -343,6 +617,28 @@ impl super::EventFilter for AssetEventFilter { } } +impl AssetDefinitionEventFilter { + /// Creates a new [`AssetDefinitionEventFilter`] accepting all [`AssetDefinitionEvent`]s. + pub const fn new() -> Self { + Self { + id_matcher: None, + event_matcher: None, + } + } + + /// Modifies a [`AssetDefinitionEventFilter`] to accept only [`AssetDefinitionEvent`]s originating from ids matching `id_matcher`. + pub fn only_from(mut self, id_matcher: AssetDefinitionId) -> Self { + self.id_matcher = Some(id_matcher); + self + } + + /// Modifies a [`AssetDefinitionEventFilter`] to accept only [`AssetDefinitionEvent`]s of types matching `event_matcher`. + pub const fn only_events(mut self, event_matcher: AssetDefinitionEventMatcher) -> Self { + self.event_matcher = Some(event_matcher); + self + } +} + #[cfg(feature = "transparent_api")] impl super::EventFilter for AssetDefinitionEventFilter { type Event = super::AssetDefinitionEvent; @@ -350,8 +646,6 @@ impl super::EventFilter for AssetDefinitionEventFilter { fn matches(&self, event: &Self::Event) -> bool { use AssetDefinitionEventMatcher::*; - use super::AssetDefinitionEvent::*; - if let Some(id_matcher) = &self.id_matcher { if id_matcher != event.origin_id() { return false; @@ -359,13 +653,13 @@ impl super::EventFilter for AssetDefinitionEventFilter { } if let Some(event_matcher) = &self.event_matcher { match (event_matcher, event) { - (ByCreated, Created(_)) => true, - (ByMintabilityChanged, MintabilityChanged(_)) => true, - (ByOwnerChanged, OwnerChanged(_)) => true, - (ByDeleted, Deleted(_)) => true, - (ByMetadataInserted, MetadataInserted(_)) => true, - (ByMetadataRemoved, MetadataRemoved(_)) => true, - (ByTotalQuantityChanged, TotalQuantityChanged(_)) => true, + (Created, AssetDefinitionEvent::Created(_)) => true, + (MintabilityChanged, AssetDefinitionEvent::MintabilityChanged(_)) => true, + (OwnerChanged, AssetDefinitionEvent::OwnerChanged(_)) => true, + (Deleted, AssetDefinitionEvent::Deleted(_)) => true, + (MetadataInserted, AssetDefinitionEvent::MetadataInserted(_)) => true, + (MetadataRemoved, AssetDefinitionEvent::MetadataRemoved(_)) => true, + (TotalQuantityChanged, AssetDefinitionEvent::TotalQuantityChanged(_)) => true, _ => false, } } else { @@ -374,6 +668,28 @@ impl super::EventFilter for AssetDefinitionEventFilter { } } +impl TriggerEventFilter { + /// Creates a new [`TriggerEventFilter`] accepting all [`TriggerEvent`]s. + pub const fn new() -> Self { + Self { + id_matcher: None, + event_matcher: None, + } + } + + /// Modifies a [`TriggerEventFilter`] to accept only [`TriggerEvent`]s originating from ids matching `id_matcher`. + pub fn only_from(mut self, id_matcher: TriggerId) -> Self { + self.id_matcher = Some(id_matcher); + self + } + + /// Modifies a [`TriggerEventFilter`] to accept only [`TriggerEvent`]s of types matching `event_matcher`. + pub const fn only_events(mut self, event_matcher: TriggerEventMatcher) -> Self { + self.event_matcher = Some(event_matcher); + self + } +} + #[cfg(feature = "transparent_api")] impl super::EventFilter for TriggerEventFilter { type Event = super::TriggerEvent; @@ -381,8 +697,6 @@ impl super::EventFilter for TriggerEventFilter { fn matches(&self, event: &Self::Event) -> bool { use TriggerEventMatcher::*; - use super::TriggerEvent::*; - if let Some(id_matcher) = &self.id_matcher { if id_matcher != event.origin_id() { return false; @@ -390,10 +704,10 @@ impl super::EventFilter for TriggerEventFilter { } if let Some(event_matcher) = &self.event_matcher { match (event_matcher, event) { - (ByCreated, Created(_)) => true, - (ByDeleted, Deleted(_)) => true, - (ByExtended, Extended(_)) => true, - (ByShortened, Shortened(_)) => true, + (Created, TriggerEvent::Created(_)) => true, + (Deleted, TriggerEvent::Deleted(_)) => true, + (Extended, TriggerEvent::Extended(_)) => true, + (Shortened, TriggerEvent::Shortened(_)) => true, _ => false, } } else { @@ -402,6 +716,28 @@ impl super::EventFilter for TriggerEventFilter { } } +impl RoleEventFilter { + /// Creates a new [`RoleEventFilter`] accepting all [`RoleEvent`]s. + pub const fn new() -> Self { + Self { + id_matcher: None, + event_matcher: None, + } + } + + /// Modifies a [`RoleEventFilter`] to accept only [`RoleEvent`]s originating from ids matching `id_matcher`. + pub fn only_from(mut self, id_matcher: RoleId) -> Self { + self.id_matcher = Some(id_matcher); + self + } + + /// Modifies a [`RoleEventFilter`] to accept only [`RoleEvent`]s of types matching `event_matcher`. + pub const fn only_events(mut self, event_matcher: RoleEventMatcher) -> Self { + self.event_matcher = Some(event_matcher); + self + } +} + #[cfg(feature = "transparent_api")] impl super::EventFilter for RoleEventFilter { type Event = super::RoleEvent; @@ -409,8 +745,6 @@ impl super::EventFilter for RoleEventFilter { fn matches(&self, event: &Self::Event) -> bool { use RoleEventMatcher::*; - use super::RoleEvent::*; - if let Some(id_matcher) = &self.id_matcher { if id_matcher != event.origin_id() { return false; @@ -418,9 +752,9 @@ impl super::EventFilter for RoleEventFilter { } if let Some(event_matcher) = &self.event_matcher { match (event_matcher, event) { - (ByCreated, Created(_)) => true, - (ByDeleted, Deleted(_)) => true, - (ByPermissionRemoved, PermissionRemoved(_)) => true, + (Created, RoleEvent::Created(_)) => true, + (Deleted, RoleEvent::Deleted(_)) => true, + (PermissionRemoved, RoleEvent::PermissionRemoved(_)) => true, _ => false, } } else { @@ -434,22 +768,24 @@ impl EventFilter for DataEventFilter { type Event = DataEvent; fn matches(&self, event: &DataEvent) -> bool { - use DataEvent::*; use DataEventFilter::*; match (self, event) { - (ByAny, _) => true, - (ByPeer(filter), Peer(event)) => filter.matches(event), - (ByDomain(filter), Domain(event)) => filter.matches(event), - (ByAccount(filter), Domain(DomainEvent::Account(event))) => filter.matches(event), - (ByAsset(filter), Domain(DomainEvent::Account(AccountEvent::Asset(event)))) => { + (Any, _) => true, + (Peer(filter), DataEvent::Peer(event)) => filter.matches(event), + (Domain(filter), DataEvent::Domain(event)) => filter.matches(event), + (Account(filter), DataEvent::Domain(DomainEvent::Account(event))) => { filter.matches(event) } - (ByAssetDefinition(filter), Domain(DomainEvent::AssetDefinition(event))) => { + ( + Asset(filter), + DataEvent::Domain(DomainEvent::Account(AccountEvent::Asset(event))), + ) => filter.matches(event), + (AssetDefinition(filter), DataEvent::Domain(DomainEvent::AssetDefinition(event))) => { filter.matches(event) } - (ByTrigger(filter), Trigger(event)) => filter.matches(event), - (ByRole(filter), Role(event)) => filter.matches(event), + (Trigger(filter), DataEvent::Trigger(event)) => filter.matches(event), + (Role(filter), DataEvent::Role(event)) => filter.matches(event), _ => false, } } @@ -520,15 +856,15 @@ mod tests { DomainEvent::Account(AccountEvent::Asset(AssetEvent::Created(asset))).into(); // test how the differently nested filters with with the events - let domain_filter = DataEventFilter::ByDomain(DomainEventFilter { + let domain_filter = DataEventFilter::Domain(DomainEventFilter { id_matcher: Some(domain_id), event_matcher: None, }); - let account_filter = DataEventFilter::ByAccount(AccountEventFilter { + let account_filter = DataEventFilter::Account(AccountEventFilter { id_matcher: Some(account_id), event_matcher: None, }); - let asset_filter = DataEventFilter::ByAsset(AssetEventFilter { + let asset_filter = DataEventFilter::Asset(AssetEventFilter { id_matcher: Some(asset_id), event_matcher: None, }); diff --git a/data_model/src/events/execute_trigger.rs b/data_model/src/events/execute_trigger.rs index 4825c1141b2..bb085224f9a 100644 --- a/data_model/src/events/execute_trigger.rs +++ b/data_model/src/events/execute_trigger.rs @@ -1,6 +1,5 @@ //! Trigger execution event and filter -use derive_more::Constructor; use getset::Getters; use iroha_data_model_derive::model; @@ -44,7 +43,8 @@ pub mod model { Ord, PartialEq, Eq, - Constructor, + Default, + Getters, Decode, Encode, Deserialize, @@ -53,9 +53,37 @@ pub mod model { )] pub struct ExecuteTriggerEventFilter { /// Id of trigger catch executions of - pub(super) trigger_id: TriggerId, + pub(super) trigger_id: Option, /// Authority of user who owns trigger - pub(super) authority: AccountId, + pub(super) authority: Option, + } +} + +impl ExecuteTriggerEventFilter { + /// Creates a new [`ExecuteTriggerEventFilter`] accepting all [`ExecuteTriggerEvent`]s + #[must_use] + #[inline] + pub const fn new() -> Self { + Self { + trigger_id: None, + authority: None, + } + } + + /// Modifies a [`ExecuteTriggerEventFilter`] to accept only [`ExecuteTriggerEvent`]s originating from a specific trigger + #[must_use] + #[inline] + pub fn from_trigger(mut self, trigger_id: TriggerId) -> Self { + self.trigger_id = Some(trigger_id); + self + } + + /// Modifies a [`ExecuteTriggerEventFilter`] to accept only [`ExecuteTriggerEvent`]s from triggers executed under specific authority + #[must_use] + #[inline] + pub fn under_authority(mut self, authority: AccountId) -> Self { + self.authority = Some(authority); + self } } @@ -67,7 +95,18 @@ impl EventFilter for ExecuteTriggerEventFilter { /// /// Event considered as matched if trigger ids are equal fn matches(&self, event: &ExecuteTriggerEvent) -> bool { - self.trigger_id == event.trigger_id && self.authority == event.authority + if let Some(trigger_id) = &self.trigger_id { + if trigger_id != &event.trigger_id { + return false; + } + } + if let Some(authority) = &self.authority { + if authority != &event.authority { + return false; + } + } + + true } } diff --git a/data_model/src/events/mod.rs b/data_model/src/events/mod.rs index d6a42cf050d..8c3517ecdcc 100644 --- a/data_model/src/events/mod.rs +++ b/data_model/src/events/mod.rs @@ -68,7 +68,18 @@ pub mod model { /// Event filter. #[allow(variant_size_differences)] #[derive( - Debug, Clone, PartialEq, Eq, FromVariant, Decode, Encode, Deserialize, Serialize, IntoSchema, + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + FromVariant, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, )] // TODO: Temporarily made opaque #[ffi_type(opaque)] @@ -88,7 +99,18 @@ pub mod model { /// Event filter which could be attached to trigger. #[allow(variant_size_differences)] #[derive( - Debug, Clone, PartialEq, Eq, FromVariant, Decode, Encode, Deserialize, Serialize, IntoSchema, + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + FromVariant, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, )] // TODO: Temporarily made opaque #[ffi_type(opaque)] diff --git a/data_model/src/events/notification.rs b/data_model/src/events/notification.rs index 3eb484095b9..50f9e9c15fc 100644 --- a/data_model/src/events/notification.rs +++ b/data_model/src/events/notification.rs @@ -128,7 +128,7 @@ pub mod model { Eq, PartialOrd, Ord, - Constructor, + Default, Getters, Decode, Encode, @@ -139,8 +139,8 @@ pub mod model { #[ffi_type] #[getset(get = "pub")] pub struct TriggerCompletedEventFilter { - trigger_id: Option, - outcome_type: Option, + pub(super) trigger_id: Option, + pub(super) outcome_type: Option, } } @@ -160,6 +160,34 @@ impl super::EventFilter for NotificationEventFilter { } } +impl TriggerCompletedEventFilter { + /// Creates a new [`TriggerCompletedEventFilter`] accepting all [`TriggerCompletedEvent`]s + #[must_use] + #[inline] + pub const fn new() -> Self { + Self { + trigger_id: None, + outcome_type: None, + } + } + + /// Modifies a [`TriggerCompletedEventFilter`] to accept only [`TriggerCompletedEvent`]s originating from a specific trigger + #[must_use] + #[inline] + pub fn from_trigger(mut self, trigger_id: TriggerId) -> Self { + self.trigger_id = Some(trigger_id); + self + } + + /// Modifies a [`TriggerCompletedEventFilter`] to accept only [`TriggerCompletedEvent`]s with a specific outcome + #[must_use] + #[inline] + pub const fn with_outcome(mut self, outcome_type: TriggerCompletedOutcomeType) -> Self { + self.outcome_type = Some(outcome_type); + self + } +} + #[cfg(feature = "transparent_api")] impl super::EventFilter for TriggerCompletedEventFilter { type Event = TriggerCompletedEvent; @@ -220,69 +248,65 @@ mod tests { let event_2_success = TriggerCompletedEvent::new(trigger_id_2.clone(), TriggerCompletedOutcome::Success); - let filter_accept_all = TriggerCompletedEventFilter::new(None, None); + let filter_accept_all = TriggerCompletedEventFilter::new(); assert!(filter_accept_all.matches(&event_1_failure)); assert!(filter_accept_all.matches(&event_1_success)); assert!(filter_accept_all.matches(&event_2_failure)); assert!(filter_accept_all.matches(&event_2_success)); let filter_accept_success = - TriggerCompletedEventFilter::new(None, Some(TriggerCompletedOutcomeType::Success)); + TriggerCompletedEventFilter::new().with_outcome(TriggerCompletedOutcomeType::Success); assert!(!filter_accept_success.matches(&event_1_failure)); assert!(filter_accept_success.matches(&event_1_success)); assert!(!filter_accept_success.matches(&event_2_failure)); assert!(filter_accept_success.matches(&event_2_success)); let filter_accept_failure = - TriggerCompletedEventFilter::new(None, Some(TriggerCompletedOutcomeType::Failure)); + TriggerCompletedEventFilter::new().with_outcome(TriggerCompletedOutcomeType::Failure); assert!(filter_accept_failure.matches(&event_1_failure)); assert!(!filter_accept_failure.matches(&event_1_success)); assert!(filter_accept_failure.matches(&event_2_failure)); assert!(!filter_accept_failure.matches(&event_2_success)); - let filter_accept_1 = TriggerCompletedEventFilter::new(Some(trigger_id_1.clone()), None); + let filter_accept_1 = TriggerCompletedEventFilter::new().from_trigger(trigger_id_1.clone()); assert!(filter_accept_1.matches(&event_1_failure)); assert!(filter_accept_1.matches(&event_1_success)); assert!(!filter_accept_1.matches(&event_2_failure)); assert!(!filter_accept_1.matches(&event_2_success)); - let filter_accept_1_failure = TriggerCompletedEventFilter::new( - Some(trigger_id_1.clone()), - Some(TriggerCompletedOutcomeType::Failure), - ); + let filter_accept_1_failure = TriggerCompletedEventFilter::new() + .from_trigger(trigger_id_1.clone()) + .with_outcome(TriggerCompletedOutcomeType::Failure); assert!(filter_accept_1_failure.matches(&event_1_failure)); assert!(!filter_accept_1_failure.matches(&event_1_success)); assert!(!filter_accept_1_failure.matches(&event_2_failure)); assert!(!filter_accept_1_failure.matches(&event_2_success)); - let filter_accept_1_success = TriggerCompletedEventFilter::new( - Some(trigger_id_1), - Some(TriggerCompletedOutcomeType::Success), - ); + let filter_accept_1_success = TriggerCompletedEventFilter::new() + .from_trigger(trigger_id_1) + .with_outcome(TriggerCompletedOutcomeType::Success); assert!(!filter_accept_1_success.matches(&event_1_failure)); assert!(filter_accept_1_success.matches(&event_1_success)); assert!(!filter_accept_1_success.matches(&event_2_failure)); assert!(!filter_accept_1_success.matches(&event_2_success)); - let filter_accept_2 = TriggerCompletedEventFilter::new(Some(trigger_id_2.clone()), None); + let filter_accept_2 = TriggerCompletedEventFilter::new().from_trigger(trigger_id_2.clone()); assert!(!filter_accept_2.matches(&event_1_failure)); assert!(!filter_accept_2.matches(&event_1_success)); assert!(filter_accept_2.matches(&event_2_failure)); assert!(filter_accept_2.matches(&event_2_success)); - let filter_accept_2_failure = TriggerCompletedEventFilter::new( - Some(trigger_id_2.clone()), - Some(TriggerCompletedOutcomeType::Failure), - ); + let filter_accept_2_failure = TriggerCompletedEventFilter::new() + .from_trigger(trigger_id_2.clone()) + .with_outcome(TriggerCompletedOutcomeType::Failure); assert!(!filter_accept_2_failure.matches(&event_1_failure)); assert!(!filter_accept_2_failure.matches(&event_1_success)); assert!(filter_accept_2_failure.matches(&event_2_failure)); assert!(!filter_accept_2_failure.matches(&event_2_success)); - let filter_accept_2_success = TriggerCompletedEventFilter::new( - Some(trigger_id_2), - Some(TriggerCompletedOutcomeType::Success), - ); + let filter_accept_2_success = TriggerCompletedEventFilter::new() + .from_trigger(trigger_id_2) + .with_outcome(TriggerCompletedOutcomeType::Success); assert!(!filter_accept_2_success.matches(&event_1_failure)); assert!(!filter_accept_2_success.matches(&event_1_success)); assert!(!filter_accept_2_success.matches(&event_2_failure)); diff --git a/data_model/src/events/pipeline.rs b/data_model/src/events/pipeline.rs index 49b43d4f0a7..060e1fe1798 100644 --- a/data_model/src/events/pipeline.rs +++ b/data_model/src/events/pipeline.rs @@ -28,6 +28,7 @@ pub mod model { PartialOrd, Ord, Default, + Getters, Decode, Encode, Serialize, @@ -154,33 +155,37 @@ pub mod model { } impl PipelineEventFilter { - /// Construct [`EventFilter`]. + /// Creates a new [`PipelineEventFilter`] accepting all [`PipelineEvent`]s #[must_use] #[inline] - pub fn new() -> Self { - Self::default() + pub const fn new() -> Self { + Self { + status_kind: None, + entity_kind: None, + hash: None, + } } - /// Filter by [`EntityKind`]. + /// Modifies a [`PipelineEventFilter`] to accept only [`PipelineEvent`]s originating from a specific entity kind (block/transaction). #[must_use] #[inline] - pub const fn entity_kind(mut self, entity_kind: PipelineEntityKind) -> Self { + pub const fn from_entity_of_kind(mut self, entity_kind: PipelineEntityKind) -> Self { self.entity_kind = Some(entity_kind); self } - /// Filter by [`StatusKind`]. + /// Modifies a [`PipelineEventFilter`] to accept only [`PipelineEvent`]s with a specific status. #[must_use] #[inline] - pub const fn status_kind(mut self, status_kind: PipelineStatusKind) -> Self { + pub const fn with_status(mut self, status_kind: PipelineStatusKind) -> Self { self.status_kind = Some(status_kind); self } - /// Filter by [`struct@Hash`]. + /// Modifies a [`PipelineEventFilter`] to accept only [`PipelineEvent`]s originating from an antity with specified hash. #[must_use] #[inline] - pub const fn hash(mut self, hash: Hash) -> Self { + pub const fn from_entity_with_hash(mut self, hash: Hash) -> Self { self.hash = Some(hash); self } @@ -277,7 +282,7 @@ mod tests { events .iter() .filter(|&event| PipelineEventFilter::new() - .hash(Hash::prehashed([0_u8; Hash::LENGTH])) + .from_entity_with_hash(Hash::prehashed([0_u8; Hash::LENGTH])) .matches(event)) .cloned() .collect::>() @@ -291,7 +296,7 @@ mod tests { events .iter() .filter(|&event| PipelineEventFilter::new() - .entity_kind(PipelineEntityKind::Block) + .from_entity_of_kind(PipelineEntityKind::Block) .matches(event)) .cloned() .collect::>() @@ -305,8 +310,8 @@ mod tests { events .iter() .filter(|&event| PipelineEventFilter::new() - .entity_kind(PipelineEntityKind::Transaction) - .hash(Hash::prehashed([2_u8; Hash::LENGTH])) + .from_entity_of_kind(PipelineEntityKind::Transaction) + .from_entity_with_hash(Hash::prehashed([2_u8; Hash::LENGTH])) .matches(event)) .cloned() .collect::>() diff --git a/tools/parity_scale_decoder/samples/trigger.bin b/tools/parity_scale_decoder/samples/trigger.bin index 57c9ef7d4e1..2eb148f65c4 100644 Binary files a/tools/parity_scale_decoder/samples/trigger.bin and b/tools/parity_scale_decoder/samples/trigger.bin differ diff --git a/tools/parity_scale_decoder/samples/trigger.json b/tools/parity_scale_decoder/samples/trigger.json index c743227478a..060b9519892 100644 --- a/tools/parity_scale_decoder/samples/trigger.json +++ b/tools/parity_scale_decoder/samples/trigger.json @@ -19,9 +19,9 @@ "authority": "alice@wonderland", "filter": { "Data": { - "ByDomain": { - "origin_filter": null, - "event_filter": "ByAccount" + "Domain": { + "id_matcher": null, + "event_matcher": "AnyAccount" } } }, diff --git a/tools/parity_scale_decoder/src/main.rs b/tools/parity_scale_decoder/src/main.rs index 38942336c91..9a3a25213f2 100644 --- a/tools/parity_scale_decoder/src/main.rs +++ b/tools/parity_scale_decoder/src/main.rs @@ -264,10 +264,7 @@ mod tests { vec![Mint::asset_quantity(1_u32, rose_id)], Repeats::Indefinitely, account_id, - EventFilterBox::Data(DataEventFilter::ByDomain(DomainEventFilter { - id_matcher: None, - event_matcher: None, - })), + EventFilterBox::Data(DataEventFilter::Domain(DomainEventFilter::new())), ); let trigger = Trigger::new(trigger_id, action);