From f9b97d29aa19b6b8ccb005feae014b703c136945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20Ver=C5=A1i=C4=87?= Date: Tue, 20 Feb 2024 09:47:38 +0300 Subject: [PATCH] [fix] #4082: Remove cloning for query execution in wasm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marin Veršić --- configs/swarm/executor.wasm | Bin 586412 -> 588908 bytes core/src/smartcontracts/wasm.rs | 29 +- data_model/src/isi.rs | 5 +- data_model/src/query/mod.rs | 280 +++++++------------- data_model/src/smart_contract.rs | 63 ----- smart_contract/executor/derive/src/token.rs | 2 +- smart_contract/src/lib.rs | 130 +++++---- 7 files changed, 197 insertions(+), 312 deletions(-) diff --git a/configs/swarm/executor.wasm b/configs/swarm/executor.wasm index afde5635a2dcb9dc1e2dc215eff9e458eac5ed9e..2e5a1d20aa018254a1351b0c230022bd3c846134 100644 GIT binary patch delta 80481 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

ujj=@iGpcz) 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 VfmWXa-mlEj$#`n}RSS;khXIgprIG*u diff --git a/core/src/smartcontracts/wasm.rs b/core/src/smartcontracts/wasm.rs index ec431e8e458..ad7b2f4f75b 100644 --- a/core/src/smartcontracts/wasm.rs +++ b/core/src/smartcontracts/wasm.rs @@ -13,17 +13,15 @@ use iroha_data_model::{ isi::InstructionBox, permission::PermissionTokenSchema, prelude::*, - query::{QueryBox, QueryId, QueryRequest, QueryWithParameters}, - smart_contract::{ - payloads::{self, Validate}, - SmartContractQueryRequest, - }, + query::{QueryBox, QueryRequest, QueryWithParameters}, + smart_contract::payloads::{self, Validate}, BatchedResponse, Level as LogLevel, ValidationFail, }; use iroha_logger::debug; // NOTE: Using error_span so that span info is logged on every event use iroha_logger::{error_span as wasm_log_span, prelude::tracing::Span}; use iroha_wasm_codec::{self as codec, WasmUsize}; +use parity_scale_codec::Decode; use wasmtime::{ Caller, Config as WasmtimeConfig, Engine, Linker, Module, Store, StoreLimits, StoreLimitsBuilder, TypedFunc, @@ -74,7 +72,7 @@ mod import { use super::super::*; - pub trait ExecuteOperations { + pub(crate) trait ExecuteOperations { /// Execute `query` on host #[codec::wrap_trait_fn] fn execute_query( @@ -243,6 +241,11 @@ pub mod error { /// [`Result`] type for this module pub type Result = core::result::Result; +#[cfg_attr(test, derive(parity_scale_codec::Encode))] +#[derive(Debug, derive_more::Display, Decode)] +#[repr(transparent)] +pub(crate) struct SmartContractQueryRequest(pub QueryRequest); + /// Create [`Module`] from bytes. /// /// # Errors @@ -1748,12 +1751,14 @@ mod tests { let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let mut wsv = WorldStateView::new(world_with_test_account(&authority), kura, query_handle); - let query_hex = encode_hex(SmartContractQueryRequest::query( - QueryBox::from(FindAccountById::new(authority.clone())), - Sorting::default(), - Pagination::default(), - FetchSize::default(), - )); + let query_hex = encode_hex(SmartContractQueryRequest(QueryRequest::Query( + QueryWithParameters::new( + FindAccountById::new(authority.clone()).into(), + Sorting::default(), + Pagination::default(), + FetchSize::default(), + ), + ))); let wat = format!( r#" diff --git a/data_model/src/isi.rs b/data_model/src/isi.rs index 5e9388f64cf..55dc7775daa 100644 --- a/data_model/src/isi.rs +++ b/data_model/src/isi.rs @@ -1359,7 +1359,7 @@ pub mod error { asset::AssetValueType, metadata, query::error::{FindError, QueryExecutionFail}, - IdBox, Value, + IdBox, }; #[model] @@ -1367,7 +1367,7 @@ pub mod error { use serde::{Deserialize, Serialize}; use super::*; - use crate::asset::AssetDefinitionId; + use crate::{asset::AssetDefinitionId, Value}; /// Instruction execution error type #[derive( @@ -1633,6 +1633,7 @@ pub mod error { Self::Evaluate(InstructionEvaluationError::Type(err)) } } + impl From for MathError { fn from(err: FixedPointOperationError) -> Self { match err { diff --git a/data_model/src/query/mod.rs b/data_model/src/query/mod.rs index 0501691ab85..9fce496e897 100644 --- a/data_model/src/query/mod.rs +++ b/data_model/src/query/mod.rs @@ -15,7 +15,7 @@ use core::{cmp::Ordering, num::NonZeroU32, time::Duration}; pub use cursor::ForwardCursor; use derive_more::{Constructor, Display}; use iroha_crypto::{PublicKey, SignatureOf}; -use iroha_data_model_derive::model; +use iroha_data_model_derive::{model, EnumRef}; use iroha_macro::FromVariant; use iroha_schema::IntoSchema; use iroha_version::prelude::*; @@ -32,6 +32,7 @@ use self::{ use crate::{ account::{Account, AccountId}, block::SignedBlock, + events::TriggeringFilterBox, seal, transaction::{SignedTransaction, TransactionPayload, TransactionValue}, Identifiable, Value, @@ -103,12 +104,18 @@ pub type QueryId = String; pub trait Query: Into + seal::Sealed { /// Output type of query type Output: Into + TryFrom; + + /// [`Encode`] [`Self`] as [`QueryBox`]. + /// + /// Used to avoid an unnecessary clone + fn encode_as_query_box(&self) -> Vec; } #[model] pub mod model { use getset::Getters; use iroha_crypto::HashOf; + use strum::EnumDiscriminants; use super::*; use crate::{block::SignedBlock, permission::PermissionTokenId}; @@ -123,6 +130,8 @@ pub mod model { Eq, PartialOrd, Ord, + EnumRef, + EnumDiscriminants, FromVariant, Decode, Encode, @@ -130,6 +139,13 @@ pub mod model { Serialize, IntoSchema, )] + #[enum_ref(derive(Encode, FromVariant))] + #[strum_discriminants( + vis(pub(crate)), + name(QueryType), + derive(Encode), + allow(clippy::enum_variant_names) + )] #[ffi_type] #[allow(missing_docs)] pub enum QueryBox { @@ -244,6 +260,69 @@ pub mod model { } } +macro_rules! impl_query { + ($($ty:ty => $output:ty),+ $(,)?) => { $( + impl Query for $ty { + type Output = $output; + + fn encode_as_query_box(&self) -> Vec { + QueryBoxRef::from(self).encode() + } + } )+ + } +} + +impl_query! { + FindAllRoles => Vec, + FindAllRoleIds => Vec, + FindRolesByAccountId => Vec, + FindRoleByRoleId => crate::role::Role, + FindPermissionTokenSchema => crate::permission::PermissionTokenSchema, + FindPermissionTokensByAccountId => Vec, + FindAllAccounts => Vec, + FindAccountById => crate::account::Account, + FindAccountKeyValueByIdAndKey => MetadataValue, + FindAccountsByName => Vec, + FindAccountsByDomainId => Vec, + FindAccountsWithAsset => Vec, + FindAllAssets => Vec, + FindAllAssetsDefinitions => Vec, + FindAssetById => crate::asset::Asset, + FindAssetDefinitionById => crate::asset::AssetDefinition, + FindAssetsByName => Vec, + FindAssetsByAccountId => Vec, + FindAssetsByAssetDefinitionId => Vec, + FindAssetsByDomainId => Vec, + FindAssetsByDomainIdAndAssetDefinitionId => Vec, + FindAssetQuantityById => crate::NumericValue, + FindTotalAssetQuantityByAssetDefinitionId => crate::NumericValue, + FindAssetKeyValueByIdAndKey => MetadataValue, + FindAssetDefinitionKeyValueByIdAndKey => MetadataValue, + FindAllDomains => Vec, + FindDomainById => crate::domain::Domain, + FindDomainKeyValueByIdAndKey => MetadataValue, + FindAllPeers => Vec, + FindAllParameters => Vec, + FindAllActiveTriggerIds => Vec, + FindTriggerById => crate::trigger::Trigger, + FindTriggerKeyValueByIdAndKey => MetadataValue, + FindTriggersByDomainId => Vec>, + FindAllTransactions => Vec, + FindTransactionsByAccountId => Vec, + FindTransactionByHash => TransactionQueryOutput, + FindAllBlocks => Vec, + FindAllBlockHeaders => Vec, + FindBlockHeaderByHash => crate::block::BlockHeader, +} + +impl Query for QueryBox { + type Output = Value; + + fn encode_as_query_box(&self) -> Vec { + self.encode() + } +} + impl From for Value { #[inline] fn from(source: MetadataValue) -> Self { @@ -258,10 +337,6 @@ impl From for MetadataValue { } } -impl Query for QueryBox { - type Output = Value; -} - impl AsRef for TransactionQueryOutput { fn as_ref(&self) -> &SignedTransaction { &self.transaction.value @@ -294,8 +369,9 @@ pub mod role { use alloc::{format, string::String, vec::Vec}; use derive_more::Display; + use parity_scale_codec::Encode; - use super::Query; + use super::{Query, QueryType}; use crate::prelude::*; queries! { @@ -336,22 +412,6 @@ pub mod role { } } - impl Query for FindAllRoles { - type Output = Vec; - } - - impl Query for FindAllRoleIds { - type Output = Vec; - } - - impl Query for FindRolesByAccountId { - type Output = Vec; - } - - impl Query for FindRoleByRoleId { - type Output = Role; - } - /// The prelude re-exports most commonly used traits, structs and macros from this module. pub mod prelude { pub use super::{FindAllRoleIds, FindAllRoles, FindRoleByRoleId, FindRolesByAccountId}; @@ -365,8 +425,9 @@ pub mod permission { use alloc::{format, string::String, vec::Vec}; use derive_more::Display; + use parity_scale_codec::Encode; - use super::Query; + use super::{Query, QueryType}; use crate::{ permission::{self, PermissionTokenSchema}, prelude::*, @@ -391,14 +452,6 @@ pub mod permission { } } - impl Query for FindPermissionTokenSchema { - type Output = PermissionTokenSchema; - } - - impl Query for FindPermissionTokensByAccountId { - type Output = Vec; - } - /// The prelude re-exports most commonly used traits, structs and macros from this module. pub mod prelude { pub use super::{FindPermissionTokenSchema, FindPermissionTokensByAccountId}; @@ -412,8 +465,9 @@ pub mod account { use alloc::{format, string::String, vec::Vec}; use derive_more::Display; + use parity_scale_codec::Encode; - use super::{MetadataValue, Query}; + use super::{MetadataValue, Query, QueryType}; use crate::prelude::*; queries! { @@ -485,30 +539,6 @@ pub mod account { } } - impl Query for FindAllAccounts { - type Output = Vec; - } - - impl Query for FindAccountById { - type Output = Account; - } - - impl Query for FindAccountKeyValueByIdAndKey { - type Output = MetadataValue; - } - - impl Query for FindAccountsByName { - type Output = Vec; - } - - impl Query for FindAccountsByDomainId { - type Output = Vec; - } - - impl Query for FindAccountsWithAsset { - type Output = Vec; - } - /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{ @@ -527,10 +557,9 @@ pub mod asset { use alloc::{format, string::String, vec::Vec}; use derive_more::Display; - use iroha_data_model_derive::model; + use parity_scale_codec::Encode; - pub use self::model::*; - use super::{MetadataValue, Query}; + use super::{MetadataValue, Query, QueryType}; use crate::prelude::*; queries! { @@ -680,58 +709,6 @@ pub mod asset { } } - impl Query for FindAllAssets { - type Output = Vec; - } - - impl Query for FindAllAssetsDefinitions { - type Output = Vec; - } - - impl Query for FindAssetById { - type Output = Asset; - } - - impl Query for FindAssetDefinitionById { - type Output = AssetDefinition; - } - - impl Query for FindAssetsByName { - type Output = Vec; - } - - impl Query for FindAssetsByAccountId { - type Output = Vec; - } - - impl Query for FindAssetsByAssetDefinitionId { - type Output = Vec; - } - - impl Query for FindAssetsByDomainId { - type Output = Vec; - } - - impl Query for FindAssetsByDomainIdAndAssetDefinitionId { - type Output = Vec; - } - - impl Query for FindAssetQuantityById { - type Output = NumericValue; - } - - impl Query for FindTotalAssetQuantityByAssetDefinitionId { - type Output = NumericValue; - } - - impl Query for FindAssetKeyValueByIdAndKey { - type Output = MetadataValue; - } - - impl Query for FindAssetDefinitionKeyValueByIdAndKey { - type Output = MetadataValue; - } - /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{ @@ -753,8 +730,9 @@ pub mod domain { use alloc::{format, string::String, vec::Vec}; use derive_more::Display; + use parity_scale_codec::Encode; - use super::{MetadataValue, Query}; + use super::{MetadataValue, Query, QueryType}; use crate::prelude::*; queries! { @@ -788,18 +766,6 @@ pub mod domain { } } - impl Query for FindAllDomains { - type Output = Vec; - } - - impl Query for FindDomainById { - type Output = Domain; - } - - impl Query for FindDomainKeyValueByIdAndKey { - type Output = MetadataValue; - } - /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{FindAllDomains, FindDomainById, FindDomainKeyValueByIdAndKey}; @@ -813,9 +779,9 @@ pub mod peer { use alloc::{format, string::String, vec::Vec}; use derive_more::Display; + use parity_scale_codec::Encode; - use super::Query; - use crate::{parameter::Parameter, peer::Peer}; + use super::{Query, QueryType}; queries! { /// [`FindAllPeers`] Iroha Query finds all trusted [`Peer`]s presented in current Iroha [`Peer`]. @@ -832,14 +798,6 @@ pub mod peer { pub struct FindAllParameters; } - impl Query for FindAllPeers { - type Output = Vec; - } - - impl Query for FindAllParameters { - type Output = Vec; - } - /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{FindAllParameters, FindAllPeers}; @@ -852,11 +810,11 @@ pub mod trigger { use alloc::{format, string::String, vec::Vec}; use derive_more::Display; + use parity_scale_codec::Encode; - use super::{MetadataValue, Query}; + use super::{MetadataValue, Query, QueryType}; use crate::{ domain::prelude::*, - events::TriggeringFilterBox, prelude::InstructionBox, trigger::{Trigger, TriggerId}, Executable, Identifiable, Name, Value, @@ -906,22 +864,6 @@ pub mod trigger { } } - impl Query for FindAllActiveTriggerIds { - type Output = Vec; - } - - impl Query for FindTriggerById { - type Output = Trigger; - } - - impl Query for FindTriggerKeyValueByIdAndKey { - type Output = MetadataValue; - } - - impl Query for FindTriggersByDomainId { - type Output = Vec>; - } - pub mod prelude { //! Prelude Re-exports most commonly used traits, structs and macros from this crate. pub use super::{ @@ -941,8 +883,9 @@ pub mod transaction { use derive_more::Display; use iroha_crypto::HashOf; + use parity_scale_codec::Encode; - use super::{Query, TransactionQueryOutput}; + use super::{Query, QueryType, TransactionQueryOutput}; use crate::{account::AccountId, prelude::Account, transaction::SignedTransaction}; queries! { @@ -977,18 +920,6 @@ pub mod transaction { } } - impl Query for FindAllTransactions { - type Output = Vec; - } - - impl Query for FindTransactionsByAccountId { - type Output = Vec; - } - - impl Query for FindTransactionByHash { - type Output = TransactionQueryOutput; - } - /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{FindAllTransactions, FindTransactionByHash, FindTransactionsByAccountId}; @@ -1005,9 +936,10 @@ pub mod block { use derive_more::Display; use iroha_crypto::HashOf; + use parity_scale_codec::{Decode, Encode}; - use super::Query; - use crate::block::{BlockHeader, SignedBlock}; + use super::{Query, QueryType}; + use crate::block::SignedBlock; queries! { /// [`FindAllBlocks`] Iroha Query lists all blocks sorted by @@ -1036,18 +968,6 @@ pub mod block { } } - impl Query for FindAllBlocks { - type Output = Vec; - } - - impl Query for FindAllBlockHeaders { - type Output = Vec; - } - - impl Query for FindBlockHeaderByHash { - type Output = BlockHeader; - } - /// The prelude re-exports most commonly used traits, structs and macros from this crate. pub mod prelude { pub use super::{FindAllBlockHeaders, FindAllBlocks, FindBlockHeaderByHash}; @@ -1201,7 +1121,7 @@ pub mod http { impl QueryBuilder { /// Construct a new request with the `query`. - pub fn new(query: impl Into, authority: AccountId) -> Self { + pub fn new(query: impl Query, authority: AccountId) -> Self { Self { payload: QueryPayload { query: query.into(), diff --git a/data_model/src/smart_contract.rs b/data_model/src/smart_contract.rs index 6e363f07218..379da0585d9 100644 --- a/data_model/src/smart_contract.rs +++ b/data_model/src/smart_contract.rs @@ -1,16 +1,5 @@ //! This module contains data and structures related only to smart contract execution -use parity_scale_codec::{Decode, Encode}; - -pub use self::model::*; -use crate::{ - prelude::FetchSize, - query::{ - cursor::ForwardCursor, sorting::Sorting, Pagination, QueryBox, QueryRequest, - QueryWithParameters, - }, -}; - pub mod payloads { //! Payloads with function arguments for different entrypoints @@ -52,55 +41,3 @@ pub mod payloads { pub target: T, } } - -#[crate::model] -pub mod model { - use super::*; - - /// Request type for `execute_query()` function. - #[derive(Debug, derive_more::Display, Clone, Decode, Encode)] - pub struct SmartContractQueryRequest(pub QueryRequest); -} - -impl SmartContractQueryRequest { - /// Construct a new request containing query. - pub fn query( - query: QueryBox, - sorting: Sorting, - pagination: Pagination, - fetch_size: FetchSize, - ) -> Self { - Self(QueryRequest::Query(QueryWithParameters::new( - query, sorting, pagination, fetch_size, - ))) - } - - /// Construct a new request containing cursor. - pub fn cursor(cursor: ForwardCursor) -> Self { - Self(QueryRequest::Cursor(cursor)) - } - - /// Unwrap [`Self`] if it was previously constructed with [`query()`](Self::query). - /// - /// # Panics - /// - /// Panics if [`Self`] was constructed with [`cursor()`](Self::cursor). - pub fn unwrap_query(self) -> (QueryBox, Sorting, Pagination) { - match self.0 { - QueryRequest::Query(query) => (query.query, query.sorting, query.pagination), - QueryRequest::Cursor(_) => panic!("Expected query, got cursor"), - } - } - - /// Unwrap [`Self`] if it was previously constructed with [`cursor()`](Self::cursor). - /// - /// # Panics - /// - /// Panics if [`Self`] was constructed with [`query()`](Self::query). - pub fn unwrap_cursor(self) -> ForwardCursor { - match self.0 { - QueryRequest::Query(_) => panic!("Expected cursor, got query"), - QueryRequest::Cursor(cursor) => cursor, - } - } -} diff --git a/smart_contract/executor/derive/src/token.rs b/smart_contract/executor/derive/src/token.rs index a68c22ebcb4..e9c2b03f271 100644 --- a/smart_contract/executor/derive/src/token.rs +++ b/smart_contract/executor/derive/src/token.rs @@ -25,7 +25,7 @@ fn impl_token(ident: &syn2::Ident, generics: &syn2::Generics) -> proc_macro2::To fn is_owned_by(&self, account_id: &::iroha_executor::data_model::account::AccountId) -> bool { let account_tokens_cursor = ::iroha_executor::smart_contract::debug::DebugExpectExt::dbg_expect( ::iroha_executor::smart_contract::ExecuteQueryOnHost::execute( - ::iroha_executor::data_model::query::permission::FindPermissionTokensByAccountId::new( + &::iroha_executor::data_model::query::permission::FindPermissionTokensByAccountId::new( account_id.clone(), ) ), diff --git a/smart_contract/src/lib.rs b/smart_contract/src/lib.rs index 1654b9e8bc5..fc36ba36cb3 100644 --- a/smart_contract/src/lib.rs +++ b/smart_contract/src/lib.rs @@ -12,7 +12,6 @@ use data_model::{ isi::Instruction, prelude::*, query::{cursor::ForwardCursor, sorting::Sorting, Pagination, Query}, - smart_contract::SmartContractQueryRequest, BatchedResponse, }; use derive_more::Display; @@ -130,44 +129,44 @@ impl ExecuteOnHost for I { } } +#[derive(Debug, Encode)] +enum QueryRequest<'a, Q> { + Query(QueryWithParameters<'a, Q>), + Cursor(&'a ForwardCursor), +} + /// Generic query request containing additional parameters. #[derive(Debug)] -pub struct QueryRequest { - query: Q, +pub struct QueryWithParameters<'a, Q> { + query: &'a Q, sorting: Sorting, pagination: Pagination, fetch_size: FetchSize, } -impl From> for SmartContractQueryRequest { - fn from(query_request: QueryRequest) -> Self { - SmartContractQueryRequest::query( - query_request.query.into(), - query_request.sorting, - query_request.pagination, - query_request.fetch_size, - ) +impl Encode for QueryWithParameters<'_, Q> { + fn encode(&self) -> Vec { + let mut output = self.query.encode_as_query_box(); + self.sorting.encode_to(&mut output); + self.pagination.encode_to(&mut output); + self.fetch_size.encode_to(&mut output); + output } } /// Implementing queries can be executed on the host -/// -/// TODO: `&self` should be enough pub trait ExecuteQueryOnHost: Sized { /// Query output type. type Output; - /// Type of [`QueryRequest`]. - type QueryRequest; - /// Apply sorting to a query - fn sort(self, sorting: Sorting) -> Self::QueryRequest; + fn sort(&self, sorting: Sorting) -> QueryWithParameters; /// Apply pagination to a query - fn paginate(self, pagination: Pagination) -> Self::QueryRequest; + fn paginate(&self, pagination: Pagination) -> QueryWithParameters; /// Set fetch size for a query. Default is [`DEFAULT_FETCH_SIZE`] - fn fetch_size(self, fetch_size: FetchSize) -> Self::QueryRequest; + fn fetch_size(&self, fetch_size: FetchSize) -> QueryWithParameters; /// Execute query on the host /// @@ -175,7 +174,7 @@ pub trait ExecuteQueryOnHost: Sized { /// /// - If query validation failed /// - If query execution failed - fn execute(self) -> Result, ValidationFail>; + fn execute(&self) -> Result, ValidationFail>; } impl ExecuteQueryOnHost for Q @@ -185,10 +184,9 @@ where >::Error: core::fmt::Debug, { type Output = Q::Output; - type QueryRequest = QueryRequest; - fn sort(self, sorting: Sorting) -> Self::QueryRequest { - QueryRequest { + fn sort(&self, sorting: Sorting) -> QueryWithParameters { + QueryWithParameters { query: self, sorting, pagination: Pagination::default(), @@ -196,8 +194,8 @@ where } } - fn paginate(self, pagination: Pagination) -> Self::QueryRequest { - QueryRequest { + fn paginate(&self, pagination: Pagination) -> QueryWithParameters { + QueryWithParameters { query: self, sorting: Sorting::default(), pagination, @@ -205,8 +203,8 @@ where } } - fn fetch_size(self, fetch_size: FetchSize) -> Self::QueryRequest { - QueryRequest { + fn fetch_size(&self, fetch_size: FetchSize) -> QueryWithParameters { + QueryWithParameters { query: self, sorting: Sorting::default(), pagination: Pagination::default(), @@ -214,8 +212,8 @@ where } } - fn execute(self) -> Result, ValidationFail> { - QueryRequest { + fn execute(&self) -> Result, ValidationFail> { + QueryWithParameters { query: self, sorting: Sorting::default(), pagination: Pagination::default(), @@ -225,50 +223,56 @@ where } } -impl ExecuteQueryOnHost for QueryRequest +impl QueryWithParameters<'_, Q> where Q: Query + Encode, Q::Output: DecodeAll, >::Error: core::fmt::Debug, { - type Output = Q::Output; - type QueryRequest = Self; - - fn sort(mut self, sorting: Sorting) -> Self { + /// Apply sorting to a query + #[must_use] + pub fn sort(mut self, sorting: Sorting) -> Self { self.sorting = sorting; self } - fn paginate(mut self, pagination: Pagination) -> Self { + /// Apply pagination to a query + #[must_use] + pub fn paginate(mut self, pagination: Pagination) -> Self { self.pagination = pagination; self } - fn fetch_size(mut self, fetch_size: FetchSize) -> Self::QueryRequest { + /// Set fetch size for a query. Default is [`DEFAULT_FETCH_SIZE`] + #[must_use] + pub fn fetch_size(mut self, fetch_size: FetchSize) -> Self { self.fetch_size = fetch_size; self } - #[allow(irrefutable_let_patterns)] - fn execute(self) -> Result, ValidationFail> { + /// Execute query on the host + /// + /// # Errors + /// + /// - If query validation failed + /// - If query execution failed + pub fn execute(self) -> Result, ValidationFail> { #[cfg(not(test))] use host::execute_query as host_execute_query; #[cfg(test)] use tests::_iroha_smart_contract_execute_query_mock as host_execute_query; - let wasm_query_request = SmartContractQueryRequest::from(self); - // Safety: - `host_execute_query` doesn't take ownership of it's pointer parameter // - ownership of the returned result is transferred into `_decode_from_raw` let res: Result, ValidationFail> = unsafe { decode_with_length_prefix_from_raw(encode_and_execute( - &wasm_query_request, + &QueryRequest::Query(self), host_execute_query, )) }; let (value, cursor) = res?.into(); - let typed_value = Self::Output::try_from(value).expect("Query output has incorrect type"); + let typed_value = Q::Output::try_from(value).expect("Query output has incorrect type"); Ok(QueryOutputCursor { batch: typed_value, cursor, @@ -337,30 +341,23 @@ impl> IntoIterator for QueryOutputCursor> { /// /// - Failed to get next batch of results from the host /// - Failed to convert batch of results into the requested type -/// -/// # Panics -/// -/// Panics if response from host is not [`BatchedResponse::V1`]. pub struct QueryOutputCursorIterator { iter: as IntoIterator>::IntoIter, cursor: ForwardCursor, } impl> QueryOutputCursorIterator { - #[allow(irrefutable_let_patterns)] fn next_batch(&self) -> Result>> { #[cfg(not(test))] use host::execute_query as host_execute_query; #[cfg(test)] use tests::_iroha_smart_contract_execute_query_mock as host_execute_query; - let wasm_query_request = SmartContractQueryRequest::cursor(self.cursor.clone()); - // Safety: - `host_execute_query` doesn't take ownership of it's pointer parameter // - ownership of the returned result is transferred into `_decode_from_raw` let res: Result, ValidationFail> = unsafe { decode_with_length_prefix_from_raw(encode_and_execute( - &wasm_query_request, + &QueryRequest::::Cursor(&self.cursor), host_execute_query, )) }; @@ -403,10 +400,6 @@ pub enum QueryOutputCursorError { Conversion(ErrorTryFromEnum), } -/// World state view of the host -#[derive(Debug, Clone, Copy)] -pub struct Host; - /// Get payload for smart contract `main()` entrypoint. #[cfg(not(test))] pub fn get_smart_contract_payload() -> payloads::SmartContract { @@ -458,10 +451,39 @@ mod tests { use data_model::{query::asset::FindAssetQuantityById, BatchedResponseV1}; use iroha_smart_contract_utils::encode_with_length_prefix; + use parity_scale_codec::Decode; use webassembly_test::webassembly_test; use super::*; + #[derive(Decode)] + struct QueryWithParameters { + query: Q, + sorting: Sorting, + pagination: Pagination, + #[allow(dead_code)] + fetch_size: FetchSize, + } + + #[derive(Decode)] + enum QueryRequest { + Query(QueryWithParameters), + Cursor(#[allow(unused_tuple_struct_fields)] ForwardCursor), + } + + #[derive(Decode)] + #[repr(transparent)] + struct SmartContractQueryRequest(pub QueryRequest); + + impl SmartContractQueryRequest { + fn unwrap_query(self) -> (QueryBox, Sorting, Pagination) { + match self.0 { + QueryRequest::Query(query) => (query.query, query.sorting, query.pagination), + QueryRequest::Cursor(_) => panic!("Expected query, got cursor"), + } + } + } + const QUERY_RESULT: Result, ValidationFail> = Ok(QueryOutputCursor { batch: Value::Numeric(NumericValue::U32(1234_u32)), cursor: ForwardCursor::new(None, None),