Skip to content

Commit

Permalink
Added new query FindTransactionByHash. (#1517)
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Ponomarev <ponomarev@soramitsu.co.jp>

Co-authored-by: Artem Ponomarev <ponomarev@soramitsu.co.jp>
  • Loading branch information
GaroRobe and Artem Ponomarev authored Oct 12, 2021
1 parent 0a6b130 commit f234960
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 3 deletions.
5 changes: 5 additions & 0 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,11 @@ pub mod transaction {
) -> FindTransactionsByAccountId {
FindTransactionsByAccountId::new(account_id)
}

/// Get query to retrieve transaction by hash
pub fn by_hash(hash: impl Into<EvaluatesTo<Hash>>) -> FindTransactionByHash {
FindTransactionByHash::new(hash)
}
}

/// URI that `Client` uses to route outgoing requests.
Expand Down
1 change: 1 addition & 0 deletions core/src/smartcontracts/isi/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ impl<W: WorldTrait> Query<W> for QueryBox {
FindAssetKeyValueByIdAndKey(query) => query.execute_into_value(wsv),
FindAccountKeyValueByIdAndKey(query) => query.execute_into_value(wsv),
FindTransactionsByAccountId(query) => query.execute_into_value(wsv),
FindTransactionByHash(query) => query.execute_into_value(wsv),
FindPermissionTokensByAccountId(query) => query.execute_into_value(wsv),
FindAssetDefinitionKeyValueByIdAndKey(query) => query.execute_into_value(wsv),

Expand Down
15 changes: 15 additions & 0 deletions core/src/smartcontracts/isi/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,18 @@ impl<W: WorldTrait> Query<W> for FindTransactionsByAccountId {
Ok(wsv.transactions_values_by_account_id(&id))
}
}

impl<W: WorldTrait> Query<W> for FindTransactionByHash {
#[iroha_logger::log]
fn execute(&self, wsv: &WorldStateView<W>) -> Result<Self::Output> {
let hash = self
.hash
.evaluate(wsv, &Context::default())
.wrap_err("Failed to get hash")?;
if !wsv.has_transaction(&hash) {
return Err(eyre!("Transaction not found"));
};
wsv.transaction_value_by_hash(&hash)
.ok_or_else(|| eyre!("Failed to fetch transaction"))
}
}
22 changes: 22 additions & 0 deletions core/src/wsv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,28 @@ impl<W: WorldTrait> WorldStateView<W> {
self.transactions.get(transaction_hash).is_some()
}

/// Find a transaction by provided hash
pub fn transaction_value_by_hash(&self, transaction_hash: &Hash) -> Option<TransactionValue> {
self.blocks.iter().find_map(|b| {
b.as_inner_v1()
.rejected_transactions
.iter()
.find(|e| e.hash() == *transaction_hash)
.cloned()
.map(TransactionValue::RejectedTransaction)
.ok_or_else(|| {
b.as_inner_v1()
.transactions
.iter()
.find(|e| e.hash() == *transaction_hash)
.cloned()
.map(VersionedTransaction::from)
.map(TransactionValue::Transaction)
})
.ok()
})
}

/// Get committed and rejected transaction of the account.
pub fn transactions_values_by_account_id(
&self,
Expand Down
6 changes: 4 additions & 2 deletions data_model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use std::{convert::TryFrom, error, fmt::Debug, ops::RangeInclusive};

use eyre::{eyre, Result, WrapErr};
use iroha_crypto::PublicKey;
use iroha_crypto::{Hash, PublicKey};
use iroha_derive::FromVariant;
use iroha_macro::error::ErrorTryFromEnum;
use iroha_schema::prelude::*;
Expand Down Expand Up @@ -192,6 +192,8 @@ pub enum Value {
TransactionValue(TransactionValue),
/// Permission token.
PermissionToken(PermissionToken),
/// Hash
Hash(Hash),
}

#[allow(clippy::len_without_is_empty)]
Expand All @@ -202,7 +204,7 @@ impl Value {

match self {
U32(_) | Id(_) | PublicKey(_) | Bool(_) | Parameter(_) | Identifiable(_)
| String(_) | Fixed(_) | TransactionValue(_) | PermissionToken(_) => 1,
| String(_) | Fixed(_) | TransactionValue(_) | PermissionToken(_) | Hash(_) => 1,
Vec(v) => v.iter().map(Self::len).sum::<usize>() + 1,
SignatureCheckCondition(s) => s.0.len(),
}
Expand Down
39 changes: 38 additions & 1 deletion data_model/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ pub enum QueryBox {
FindAllPeers(FindAllPeers),
/// `FindTransactionsByAccountId` variant.
FindTransactionsByAccountId(FindTransactionsByAccountId),
/// `FindTransactionByHash` variant.
FindTransactionByHash(FindTransactionByHash),
/// `FindAllRoles` variant.
#[cfg(feature = "roles")]
FindAllRoles(FindAllRoles),
Expand Down Expand Up @@ -1048,6 +1050,7 @@ pub mod transaction {

#![allow(clippy::missing_inline_in_public_items)]

use iroha_crypto::Hash;
use iroha_derive::Io;
use iroha_schema::prelude::*;
use parity_scale_codec::{Decode, Encode};
Expand Down Expand Up @@ -1090,9 +1093,43 @@ pub mod transaction {
FindTransactionsByAccountId { account_id }
}
}

/// `FindTransactionByHash` Iroha Query will find a transaction (if any)
/// with corresponding hash value
#[derive(
Clone,
Debug,
Io,
Serialize,
Deserialize,
Encode,
Decode,
PartialEq,
Eq,
PartialOrd,
Ord,
IntoSchema,
)]
pub struct FindTransactionByHash {
/// Transaction hash.
pub hash: EvaluatesTo<Hash>,
}

impl QueryOutput for FindTransactionByHash {
type Output = TransactionValue;
}

impl FindTransactionByHash {
///Default [`FindTransactionByHash`] constructor.
pub fn new(hash: impl Into<EvaluatesTo<Hash>>) -> Self {
let hash = hash.into();
FindTransactionByHash { hash }
}
}

/// The prelude re-exports most commonly used traits, structs and macros from this crate.
pub mod prelude {
pub use super::FindTransactionsByAccountId;
pub use super::{FindTransactionByHash, FindTransactionsByAccountId};
}
}

Expand Down
2 changes: 2 additions & 0 deletions permissions_validators/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ pub mod private_blockchain {
))
}
}
FindTransactionByHash(_query) => Ok(()),
#[cfg(feature = "roles")]
FindRolesByAccountId(query) => {
let account_id = query
Expand Down Expand Up @@ -542,6 +543,7 @@ pub mod private_blockchain {
Err(format!("Cannot access another account: {}.", account_id))
}
}
FindTransactionByHash(_query) => Ok(()),
#[cfg(feature = "roles")]
FindRolesByAccountId(query) => {
let account_id = query
Expand Down

0 comments on commit f234960

Please sign in to comment.