Skip to content

Commit

Permalink
[feature] #2050: Add role-related queries.
Browse files Browse the repository at this point in the history
[feature] #1986: Add Trigger-related queries.
Signed-off-by: Aleksandr Petrosyan <[email protected]>
  • Loading branch information
appetrosyan committed Apr 28, 2022
1 parent 4925e69 commit 7654a69
Show file tree
Hide file tree
Showing 12 changed files with 423 additions and 97 deletions.
5 changes: 4 additions & 1 deletion cli/src/torii/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ use iroha_core::{
wsv::WorldTrait,
};
use iroha_crypto::SignatureOf;
use iroha_data_model::{prelude::*, query};
use iroha_data_model::{
prelude::*,
query::{self, SignedQueryRequest},
};
#[cfg(feature = "telemetry")]
use iroha_telemetry::metrics::Status;
use parity_scale_codec::{Decode, Encode};
Expand Down
2 changes: 1 addition & 1 deletion client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use eyre::{eyre, Result, WrapErr};
use http_default::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::*;
Expand Down
2 changes: 1 addition & 1 deletion core/src/smartcontracts/isi/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down
5 changes: 5 additions & 0 deletions core/src/smartcontracts/isi/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,13 @@ impl<W: WorldTrait> ValidQuery<W> for QueryBox {
FindTransactionByHash(query) => query.execute_into_value(wsv),
FindPermissionTokensByAccountId(query) => query.execute_into_value(wsv),
FindAssetDefinitionKeyValueByIdAndKey(query) => query.execute_into_value(wsv),
FindAllActiveTriggerIds(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),
}
}
}
Expand Down
58 changes: 58 additions & 0 deletions core/src/smartcontracts/isi/triggers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,61 @@ pub mod isi {
}
}
}

pub mod query {
//! Queries associated to triggers.
use iroha_logger::prelude::*;

use super::*;
use crate::{
prelude::*,
smartcontracts::{isi::prelude::WorldTrait, query::Error, Evaluate as _, FindError},
};

impl<W: WorldTrait> ValidQuery<W> for FindAllActiveTriggerIds {
#[log]
#[metrics(+"find_all_active_triggers")]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output, Error> {
Ok(wsv.world.triggers.clone().into())
}
}

impl<W: WorldTrait> ValidQuery<W> for FindTriggerById {
#[log]
#[metrics(+"find_trigger_by_id")]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output, Error> {
let id = self
.id
.evaluate(wsv, &Context::new())
.map_err(|e| Error::Evaluate(format!("Failed to evaluate trigger id. {}", e)))?;
let action = wsv.world.triggers.get(&id)?;

// TODO: Should we redact the metadata if the account is not the technical account/owner?
Ok(Trigger {
id,
action: action.clone(),
})
}
}

impl<W: WorldTrait> ValidQuery<W> for FindTriggerKeyValueByIdAndKey {
#[log]
#[metrics(+"find_trigger_key_value_by_id_and_key")]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output, Error> {
let id = self
.id
.evaluate(wsv, &Context::new())
.map_err(|e| Error::Evaluate(format!("Failed to evaluate trigger id. {}", e)))?;
let action = wsv.world.triggers.get(&id)?;
let key = self
.key
.evaluate(wsv, &Context::new())
.map_err(|e| Error::Evaluate(format!("Failed to evaluate key. {}", e)))?;
action
.metadata
.get(&key)
.map(Clone::clone)
.ok_or_else(|| FindError::MetadataKey(key).into())
}
}
}
35 changes: 34 additions & 1 deletion core/src/smartcontracts/isi/world.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
//! `World`-related ISI implementations.

use iroha_telemetry::metrics;

use super::prelude::*;
use crate::prelude::*;

/// Iroha Special Instructions that have `World` as their target.
pub mod isi {
use eyre::Result;
use iroha_data_model::prelude::*;
use iroha_telemetry::metrics;

use super::*;

Expand Down Expand Up @@ -202,6 +203,7 @@ pub mod query {

impl<W: WorldTrait> ValidQuery<W> for FindAllRoles {
#[log]
#[metrics(+"find_all_roles")]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output, Error> {
Ok(wsv
.world
Expand All @@ -212,8 +214,39 @@ pub mod query {
}
}

impl<W: WorldTrait> ValidQuery<W> for FindAllRoleIds {
#[log]
#[metrics(+"find_all_role_ids")]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output, Error> {
Ok(wsv
.world
.roles
.iter()
// To me, this should probably be a method, not a field.
.map(|role| role.id().clone())
.collect())
}
}

impl<W: WorldTrait> ValidQuery<W> for FindRoleByRoleId {
#[log]
#[metrics(+"find_role_by_role_id")]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output, Error> {
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<W: WorldTrait> ValidQuery<W> for FindAllPeers {
#[log]
#[metrics("find_all_peers")]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output, Error> {
Ok(wsv.peers())
}
Expand Down
24 changes: 17 additions & 7 deletions core/src/triggers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ pub struct TriggerSet(
DashMap<trigger::Id, Action>, // TODO: Consider tree structures.
);

impl From<TriggerSet> for Vec<trigger::Id> {
fn from(TriggerSet(map): TriggerSet) -> Self {
map.iter()
.map(|reference| reference.key().clone())
.collect()
}
}

impl TriggerSet {
/// Add another trigger to the [`TriggerSet`].
///
Expand All @@ -46,13 +54,8 @@ impl TriggerSet {
///
/// # Errors
/// - If [`TriggerSet`] doesn't contain the trigger with the given `id`.
pub fn get(
&self,
id: &trigger::Id,
) -> Result<impl Deref<Target = Action> + '_, smartcontracts::Error> {
self.0
.get(id)
.ok_or_else(|| smartcontracts::Error::Find(Box::new(FindError::Trigger(id.clone()))))
pub fn get(&self, id: &trigger::Id) -> Result<impl Deref<Target = Action> + '_, FindError> {
self.0.get(id).ok_or_else(|| FindError::Trigger(id.clone()))
}

/// Remove a trigger from the [`TriggerSet`].
Expand All @@ -76,6 +79,13 @@ impl TriggerSet {
self.0.contains_key(key)
}

/// Forward the internal immutable iterator.
pub fn iter(
&self,
) -> dashmap::iter::Iter<iroha_data_model::trigger::Id, iroha_data_model::trigger::Action> {
self.0.iter()
}

/// Modify repetitions of the hook identified by [`trigger::Id`].
///
/// # Errors
Expand Down
Loading

0 comments on commit 7654a69

Please sign in to comment.