Skip to content

Commit

Permalink
[refactor]: pin wsv + iterators so that they can persist between queries
Browse files Browse the repository at this point in the history
Signed-off-by: Marin Veršić <marin.versic101@gmail.com>
  • Loading branch information
mversic committed Jul 6, 2023
1 parent 83f5d95 commit 279fe39
Show file tree
Hide file tree
Showing 13 changed files with 399 additions and 364 deletions.
2 changes: 1 addition & 1 deletion core/benches/apply_blocks/apply_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn create_block(
let pending_block = PendingBlock {
header,
transactions: vec![TransactionValue {
tx: transaction,
value: transaction,
error: None,
}],
event_recommendations: Vec::new(),
Expand Down
137 changes: 65 additions & 72 deletions core/src/smartcontracts/isi/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,127 +475,121 @@ pub mod query {

use eyre::{Result, WrapErr};
use iroha_data_model::{
evaluate::ExpressionEvaluator, query::error::QueryExecutionFail as Error,
evaluate::ExpressionEvaluator,
query::{error::QueryExecutionFail as Error, MetadataValue},
};

use super::*;
use crate::smartcontracts::query::Lazy;
use crate::smartcontracts::query::WsvIterator;

impl ValidQuery for FindRolesByAccountId {
#[metrics(+"find_roles_by_account_id")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
fn execute(&self, wsv: &WorldStateView) -> Result<WsvIterator<RoleId>, Error> {
let account_id = wsv
.evaluate(&self.id)
.wrap_err("Failed to evaluate account id")
.map_err(|e| Error::Evaluate(e.to_string()))?;

iroha_logger::trace!(%account_id, roles=?wsv.world.roles);
Ok(Box::new(
wsv.map_account(&account_id, |account| &account.roles)?
.iter()
.cloned(),
))

WsvIterator::<RoleId>::new(wsv, |wsv| {
Ok(Box::new(
wsv.map_account(&account_id, |account| account.roles.iter())?
.cloned(),
))
})
}
}

impl ValidQuery for FindPermissionTokensByAccountId {
#[metrics(+"find_permission_tokens_by_account_id")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
fn execute(&self, wsv: &WorldStateView) -> Result<WsvIterator<PermissionToken>, Error> {
let account_id = wsv
.evaluate(&self.id)
.wrap_err("Failed to evaluate account id")
.map_err(|e| Error::Evaluate(e.to_string()))?;
iroha_logger::trace!(%account_id, accounts=?wsv.world.domains);
Ok(Box::new(
wsv.account_permission_tokens(&account_id)?.cloned(),
))

WsvIterator::<PermissionToken>::new(wsv, |wsv| {
Ok(Box::new(
wsv.account_permission_tokens(&account_id)?.cloned(),
))
})
}
}

impl ValidQuery for FindAllAccounts {
#[metrics(+"find_all_accounts")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
Ok(Box::new(
wsv.domains()
.values()
.flat_map(|domain| domain.accounts.values())
.cloned(),
))
fn execute(&self, wsv: &WorldStateView) -> Result<WsvIterator<Account>, Error> {
WsvIterator::<Account>::new(wsv, |wsv| {
Ok(Box::new(
wsv.domains()
.values()
.flat_map(|domain| domain.accounts.values())
.cloned(),
))
})
}
}

impl ValidQuery for FindAccountById {
#[metrics(+"find_account_by_id")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
fn execute(&self, wsv: &WorldStateView) -> Result<Account, Error> {
let id = wsv
.evaluate(&self.id)
.wrap_err("Failed to get id")
.map_err(|e| Error::Evaluate(e.to_string()))?;

iroha_logger::trace!(%id);
wsv.map_account(&id, Clone::clone).map_err(Into::into)
}
}

impl ValidQuery for FindAccountsByName {
#[metrics(+"find_account_by_name")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
fn execute(&self, wsv: &WorldStateView) -> Result<WsvIterator<Account>, Error> {
let name = wsv
.evaluate(&self.name)
.wrap_err("Failed to get account name")
.map_err(|e| Error::Evaluate(e.to_string()))?;

iroha_logger::trace!(%name);
Ok(Box::new(
wsv.domains()
.values()
.flat_map(move |domain| {
let name = name.clone();

domain
.accounts
.values()
.filter(move |account| account.id().name == name)
})
.cloned(),
))
WsvIterator::<Account>::new(wsv, |wsv| {
Ok(Box::new(
wsv.domains()
.values()
.flat_map(move |domain| {
let name = name.clone();

domain
.accounts
.values()
.filter(move |account| account.id().name == name)
})
.cloned(),
))
})
}
}

impl ValidQuery for FindAccountsByDomainId {
#[metrics(+"find_accounts_by_domain_id")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
fn execute(&self, wsv: &WorldStateView) -> Result<WsvIterator<Account>, Error> {
let id = wsv
.evaluate(&self.domain_id)
.wrap_err("Failed to get domain id")
.map_err(|e| Error::Evaluate(e.to_string()))?;

iroha_logger::trace!(%id);
Ok(Box::new(wsv.domain(&id)?.accounts.values().cloned()))
WsvIterator::<Account>::new(wsv, |wsv| {
Ok(Box::new(wsv.domain(&id)?.accounts.values().cloned()))
})
}
}

impl ValidQuery for FindAccountKeyValueByIdAndKey {
#[metrics(+"find_account_key_value_by_id_and_key")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
fn execute(&self, wsv: &WorldStateView) -> Result<MetadataValue, Error> {
let id = wsv
.evaluate(&self.id)
.wrap_err("Failed to get account id")
Expand All @@ -613,26 +607,25 @@ pub mod query {

impl ValidQuery for FindAccountsWithAsset {
#[metrics(+"find_accounts_with_asset")]
fn execute<'wsv>(
&self,
wsv: &'wsv WorldStateView,
) -> Result<<Self::Output as Lazy>::Lazy<'wsv>, Error> {
fn execute(&self, wsv: &WorldStateView) -> Result<WsvIterator<Account>, Error> {
let asset_definition_id = wsv
.evaluate(&self.asset_definition_id)
.wrap_err("Failed to get asset id")
.map_err(|e| Error::Evaluate(e.to_string()))?;
iroha_logger::trace!(%asset_definition_id);

Ok(Box::new(
wsv.map_domain(&asset_definition_id.domain_id.clone(), move |domain| {
domain.accounts.values().filter(move |account| {
let asset_id =
AssetId::new(asset_definition_id.clone(), account.id().clone());
account.assets.get(&asset_id).is_some()
})
})?
.cloned(),
))
WsvIterator::<Account>::new(wsv, |wsv| {
Ok(Box::new(
wsv.map_domain(&asset_definition_id.domain_id.clone(), move |domain| {
domain.accounts.values().filter(move |account| {
let asset_id =
AssetId::new(asset_definition_id.clone(), account.id().clone());
account.assets.get(&asset_id).is_some()
})
})?
.cloned(),
))
})
}
}
}
Loading

0 comments on commit 279fe39

Please sign in to comment.