diff --git a/src/types/mod.rs b/src/types/mod.rs index bb370413d..e0590bb6d 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -329,6 +329,30 @@ pub struct AccountInfo { pub account_address: AccountAddress, } +impl From<&AccountInfo> for AccountAccessStructure { + fn from(value: &AccountInfo) -> Self { + Self { + keys: value + .account_credentials + .iter() + .map(|(idx, v)| { + let key = match v.value { + crate::id::types::AccountCredentialWithoutProofs::Initial { ref icdv } => { + icdv.cred_account.clone() + } + crate::id::types::AccountCredentialWithoutProofs::Normal { + ref cdv, + .. + } => cdv.cred_key_info.clone(), + }; + (*idx, key) + }) + .collect(), + threshold: value.account_threshold, + } + } +} + #[derive(SerdeSerialize, SerdeDeserialize, Debug, PartialEq)] #[serde(rename_all = "camelCase")] /// The state of consensus parameters, and allowed participants (i.e., bakers). diff --git a/src/v2/mod.rs b/src/v2/mod.rs index 9723f97f1..fedf730da 100644 --- a/src/v2/mod.rs +++ b/src/v2/mod.rs @@ -12,8 +12,8 @@ use crate::{ ContractContext, InstanceInfo, InvokeContractResult, ModuleReference, WasmModule, }, transactions::{self, InitContractPayload, UpdateContractPayload, UpdateInstruction}, - AbsoluteBlockHeight, AccountInfo, CredentialRegistrationID, Energy, Memo, Nonce, - RegisteredData, SpecialTransactionOutcome, TransactionStatus, UpdateSequenceNumber, + AbsoluteBlockHeight, AccountInfo, BlockItemSummary, CredentialRegistrationID, Energy, Memo, + Nonce, RegisteredData, SpecialTransactionOutcome, TransactionStatus, UpdateSequenceNumber, }, }; use concordium_base::{ @@ -39,7 +39,7 @@ use concordium_base::{ }, }; pub use endpoints::{QueryError, QueryResult, RPCError, RPCResult}; -use futures::{Stream, StreamExt}; +use futures::{Stream, StreamExt, TryStreamExt}; pub use http::uri::Scheme; use num::{BigUint, ToPrimitive}; use std::{collections::HashMap, num::ParseIntError, str::FromStr}; @@ -2104,6 +2104,35 @@ impl Client { }) } + /// Get the specific **block item** if it is finalized. + /// If the transaction does not exist in a finalized block + /// [`QueryError::NotFound`] is returned. + /// + /// **Note that this is not an efficient method** since the node API does + /// not allow for retrieving just the specific block item, but rather + /// requires retrieving the full block. Use it for testing and debugging + /// only. + /// + /// The return value is a triple of the [`BlockItem`], the hash of the block + /// in which it is finalized, and the outcome in the form of + /// [`BlockItemSummary`]. + pub async fn get_finalized_block_item( + &mut self, + th: TransactionHash, + ) -> endpoints::QueryResult<(BlockItem, BlockHash, BlockItemSummary)> { + let status = self.get_block_item_status(&th).await?; + let Some((bh, status)) = status.is_finalized() else { + return Err(QueryError::NotFound); + }; + let mut response = self.get_block_items(bh).await?.response; + while let Some(tx) = response.try_next().await? { + if tx.hash() == th { + return Ok((tx, *bh, status.clone())); + } + } + Err(endpoints::QueryError::NotFound) + } + /// Shut down the node. /// Return a GRPC error if the shutdown failed. pub async fn shutdown(&mut self) -> endpoints::RPCResult<()> {