diff --git a/client/src/client.rs b/client/src/client.rs index 04083795644..3a3d0c31eb9 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -12,7 +12,7 @@ use eyre::{eyre, Result, WrapErr}; use http_client::WebSocketStream; use iroha_config::{GetConfiguration, PostConfiguration}; use iroha_crypto::{HashOf, KeyPair}; -use iroha_data_model::prelude::*; +use iroha_data_model::{prelude::*, query::SignedQueryRequest}; use iroha_logger::prelude::*; use iroha_telemetry::metrics::Status; use iroha_version::prelude::*; diff --git a/core/src/smartcontracts/isi/asset.rs b/core/src/smartcontracts/isi/asset.rs index fff5d2b5072..23670a7f39a 100644 --- a/core/src/smartcontracts/isi/asset.rs +++ b/core/src/smartcontracts/isi/asset.rs @@ -343,7 +343,7 @@ pub mod isi { /// Asset-related query implementations. pub mod query { - use eyre::{Result, WrapErr}; + use eyre::{Result, WrapErr as _}; use iroha_logger::prelude::*; use super::*; diff --git a/core/src/smartcontracts/isi/query.rs b/core/src/smartcontracts/isi/query.rs index 201f6217506..de475cf40f2 100644 --- a/core/src/smartcontracts/isi/query.rs +++ b/core/src/smartcontracts/isi/query.rs @@ -122,8 +122,13 @@ impl ValidQuery for QueryBox { FindTransactionByHash(query) => query.execute_into_value(wsv), FindPermissionTokensByAccountId(query) => query.execute_into_value(wsv), FindAssetDefinitionKeyValueByIdAndKey(query) => query.execute_into_value(wsv), + FindAllTriggers(query) => query.execute_into_value(wsv), + FindTriggerById(query) => query.execute_into_value(wsv), + FindTriggerKeyValueByIdAndKey(query) => query.execute_into_value(wsv), FindAllRoles(query) => query.execute_into_value(wsv), + FindAllRoleIds(query) => query.execute_into_value(wsv), FindRolesByAccountId(query) => query.execute_into_value(wsv), + FindRoleByRoleId(query) => query.execute_into_value(wsv), } } } diff --git a/core/src/smartcontracts/isi/triggers.rs b/core/src/smartcontracts/isi/triggers.rs index b1eda42481b..da8067b86cb 100644 --- a/core/src/smartcontracts/isi/triggers.rs +++ b/core/src/smartcontracts/isi/triggers.rs @@ -136,3 +136,37 @@ pub mod isi { } } } + +pub mod query { + use iroha_logger::prelude::*; + + use super::*; + use crate::{ + prelude::*, + smartcontracts::{isi::prelude::WorldTrait, query::Error}, + }; + + impl ValidQuery for FindAllActiveTriggers { + #[log] + #[metrics(+"find_all_active_triggers")] + fn execute(&self, wsv: &WorldStateView) -> Result { + Ok(wsv.world.triggers.iter().cloned().collect()) + } + } + + impl ValidQuery for FindTriggerById { + #[log] + #[metrics(+"find_trigger_by_id")] + fn execute(&self, wsv: &WorldStateView) -> Result { + todo!() + } + } + + impl ValidQuery for FindTriggerKeyValueByIdAndKey { + #[log] + #[metrics(+"find_trigger_key_value_by_id_and_key")] + fn execute(&self, wsv: &WorldStateView) -> Result { + todo!() + } + } +} diff --git a/core/src/smartcontracts/isi/world.rs b/core/src/smartcontracts/isi/world.rs index c060ffba1bc..68c1e1c6d87 100644 --- a/core/src/smartcontracts/isi/world.rs +++ b/core/src/smartcontracts/isi/world.rs @@ -1,5 +1,7 @@ //! `World`-related ISI implementations. +use iroha_telemetry::metrics; + use super::prelude::*; use crate::prelude::*; @@ -7,7 +9,6 @@ use crate::prelude::*; pub mod isi { use eyre::Result; use iroha_data_model::prelude::*; - use iroha_telemetry::metrics; use super::*; @@ -202,6 +203,7 @@ pub mod query { impl ValidQuery for FindAllRoles { #[log] + #[metrics(+"find_all_roles")] fn execute(&self, wsv: &WorldStateView) -> Result { Ok(wsv .world @@ -212,8 +214,41 @@ pub mod query { } } + #[cfg(feature = "roles")] + impl ValidQuery for FindAllRoleIds { + #[log] + #[metrics(+"find_all_role_ids")] + fn execute(&self, wsv: &WorldStateView) -> Result { + Ok(wsv + .world + .roles + .iter() + // To me, this should probably be a method, not a field. + .map(|role| role.id().clone()) + .collect()) + } + } + + #[cfg(feature = "roles")] + impl ValidQuery for FindRoleByRoleId { + #[log] + #[metrics(+"find_role_by_role_id")] + fn execute(&self, wsv: &WorldStateView) -> Result { + let role_id = self + .id + .evaluate(wsv, &Context::new()) + .map_err(|e| Error::Evaluate(e.to_string()))?; + + wsv.world.roles.get(&role_id).map_or_else( + || Err(Error::Find(Box::new(FindError::Role(role_id)))), + |role_ref| Ok(role_ref.clone()), + ) + } + } + impl ValidQuery for FindAllPeers { #[log] + #[metrics("find_all_peers")] fn execute(&self, wsv: &WorldStateView) -> Result { Ok(wsv.peers()) } diff --git a/data_model/src/query.rs b/data_model/src/query.rs index 9915eeecc43..feff5fa3183 100644 --- a/data_model/src/query.rs +++ b/data_model/src/query.rs @@ -14,7 +14,9 @@ use iroha_version::prelude::*; use parity_scale_codec::{Decode, Encode}; use serde::{Deserialize, Serialize}; -use self::{account::*, asset::*, domain::*, peer::*, permissions::*, role::*, transaction::*}; +use self::{ + account::*, asset::*, domain::*, peer::*, permissions::*, role::*, transaction::*, trigger::*, +}; use crate::{account::Account, pagination::Pagination, Identifiable, Value}; /// Sized container for all possible Queries. @@ -80,8 +82,18 @@ pub enum QueryBox { FindTransactionByHash(FindTransactionByHash), /// [`FindPermissionTokensByAccountId`] variant. FindPermissionTokensByAccountId(FindPermissionTokensByAccountId), + /// [`FindAllTriggers`] variant. + FindAllTriggers(FindAllActiveTriggers), + /// [`FindTriggerById`] variant. + FindTriggerById(FindTriggerById), + /// [`FindTriggerKeyValueByIdAndKey`] variant. + FindTriggerKeyValueByIdAndKey(FindTriggerKeyValueByIdAndKey), /// [`FindAllRoles`] variant. FindAllRoles(FindAllRoles), + /// [`FindAllRoleIds`] variant. + FindAllRoleIds(FindAllRoleIds), + /// [`FindRoleByRoleId`] variant. + FindRoleByRoleId(FindRoleByRoleId), /// [`FindRolesByAccountId`] variant. FindRolesByAccountId(FindRolesByAccountId), } @@ -219,7 +231,52 @@ pub mod role { type Output = Vec; } - /// `FindRolesByAccountId` Iroha Query will find an `Role`s for a specified account. + /// `FindAllRoles` Iroha Query will find all `Roles`s presented. + #[derive( + Debug, + Clone, + Copy, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + pub struct FindAllRoleIds {} + + impl Query for FindAllRoleIds { + type Output = Vec<::Id>; + } + + /// `FindRoleByRoleId` Iroha Query to find the [`Role`] which has the given [`Id`] + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + pub struct FindRoleByRoleId { + /// `Id` of the `Role` to find + pub id: EvaluatesTo<::Id>, + } + + impl Query for FindRoleByRoleId { + type Output = Role; + } + + /// `FindRolesByAccountId` Iroha Query will find an [`Role`]s for a specified account. #[derive( Debug, Clone, @@ -235,16 +292,16 @@ pub mod role { )] pub struct FindRolesByAccountId { /// `Id` of an account to find. - pub id: EvaluatesTo, + pub id: EvaluatesTo<::Id>, } impl Query for FindRolesByAccountId { - type Output = Vec; + type Output = Vec<::Id>; } /// The prelude re-exports most commonly used traits, structs and macros from this module. pub mod prelude { - pub use super::{FindAllRoles, FindRolesByAccountId}; + pub use super::{FindAllRoleIds, FindAllRoles, FindRoleByRoleId, FindRolesByAccountId}; } } @@ -1047,6 +1104,86 @@ pub mod peer { } } +pub mod trigger { + #[cfg(not(feature = "std"))] + use alloc::{format, string::String, vec::Vec}; + + use iroha_schema::prelude::*; + use parity_scale_codec::{Decode, Encode}; + use serde::{Deserialize, Serialize}; + + use super::Query; + use crate::{expression::EvaluatesTo, trigger::Trigger, Identifiable, Name, Value}; + + #[derive( + Debug, + Clone, + Copy, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + pub struct FindAllActiveTriggers {} + + impl Query for FindAllActiveTriggers { + type Output = Vec; + } + + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + pub struct FindTriggerById { + id: ::Id, + } + + impl Query for FindTriggerById { + type Output = Trigger; + } + + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + pub struct FindTriggerKeyValueByIdAndKey { + id: ::Id, + key: EvaluatesTo, + } + + impl Query for FindTriggerKeyValueByIdAndKey { + type Output = Value; + } + + pub mod prelude { + pub use super::{FindAllActiveTriggers, FindTriggerById, FindTriggerKeyValueByIdAndKey}; + } +} + pub mod transaction { //! Queries related to `Transaction`. @@ -1139,8 +1276,8 @@ pub mod transaction { pub mod prelude { pub use super::{ account::prelude::*, asset::prelude::*, domain::prelude::*, peer::prelude::*, - permissions::prelude::*, role::prelude::*, transaction::*, PaginatedQueryResult, Query, - QueryBox, QueryResult, SignedQueryRequest, VersionedPaginatedQueryResult, + permissions::prelude::*, role::prelude::*, transaction::*, trigger::prelude::*, + PaginatedQueryResult, Query, QueryBox, QueryResult, VersionedPaginatedQueryResult, VersionedQueryResult, }; #[cfg(feature = "warp")] diff --git a/permissions_validators/src/private_blockchain/query.rs b/permissions_validators/src/private_blockchain/query.rs index 381f69e6b3d..a2d8b9230f4 100644 --- a/permissions_validators/src/private_blockchain/query.rs +++ b/permissions_validators/src/private_blockchain/query.rs @@ -30,6 +30,10 @@ impl IsAllowed for OnlyAccountsDomain { Err("Only access to the domain of the account is permitted.".to_owned()) } FindAllRoles(_) => Ok(()), + #[cfg(feature = "roles")] + FindAllRoleIds(_) => Ok(()), + #[cfg(feature = "roles")] + FindRoleByRoleId(_) => Ok(()), FindAllPeers(_) => Ok(()), FindAccountById(query) => { let account_id = query @@ -262,6 +266,10 @@ impl IsAllowed for OnlyAccountsData { Err("Only access to the assets of the same domain is permitted.".to_owned()) } FindAllRoles(_) => Ok(()), + #[cfg(feature = "roles")] + FindAllRoleIds(_) => Ok(()), + #[cfg(feature = "roles")] + FindRoleByRoleId(_) => Ok(()), FindAllPeers(_) => Ok(()), FindAccountById(query) => { let account_id = query