Everything has lifetime from ClientAtBlock

This commit is contained in:
James Wilson
2025-12-09 16:59:04 +00:00
parent 744a513aeb
commit b75ce69b76
11 changed files with 249 additions and 226 deletions
+16 -16
View File
@@ -39,42 +39,42 @@ where
Client: OfflineClientAtBlockT<T>,
{
/// Construct and submit transactions.
pub fn tx(&self) -> TransactionsClient<T, Client> {
TransactionsClient::new(self.client.clone())
pub fn tx(&self) -> TransactionsClient<'_, T, Client> {
TransactionsClient::new(&self.client)
}
/// Access storage at this block.
pub fn storage(&self) -> StorageClient<T, Client> {
StorageClient::new(self.client.clone())
pub fn storage(&self) -> StorageClient<'_, T, Client> {
StorageClient::new(&self.client)
}
/// Access constants at this block.
pub fn constants(&self) -> ConstantsClient<T, Client> {
ConstantsClient::new(self.client.clone())
pub fn constants(&self) -> ConstantsClient<'_, T, Client> {
ConstantsClient::new(&self.client)
}
/// Access custom values at this block.
pub fn custom_values(&self) -> CustomValuesClient<T, Client> {
CustomValuesClient::new(self.client.clone())
pub fn custom_values(&self) -> CustomValuesClient<'_, T, Client> {
CustomValuesClient::new(&self.client)
}
/// Work with the extrinsics in this block.
pub fn extrinsics(&self) -> ExtrinsicsClient<T, Client> {
ExtrinsicsClient::new(self.client.clone())
pub fn extrinsics(&self) -> ExtrinsicsClient<'_, T, Client> {
ExtrinsicsClient::new(&self.client)
}
/// Work with the events at this block.
pub fn events(&self) -> EventsClient<T, Client> {
EventsClient::new(self.client.clone())
pub fn events(&self) -> EventsClient<'_, T, Client> {
EventsClient::new(&self.client)
}
/// Access runtime APIs at this block.
pub fn runtime_apis(&self) -> RuntimeApisClient<T, Client> {
RuntimeApisClient::new(self.client.clone())
pub fn runtime_apis(&self) -> RuntimeApisClient<'_, T, Client> {
RuntimeApisClient::new(&self.client)
}
pub fn view_functions(&self) -> ViewFunctionsClient<T, Client> {
ViewFunctionsClient::new(self.client.clone())
pub fn view_functions(&self) -> ViewFunctionsClient<'_, T, Client> {
ViewFunctionsClient::new(&self.client)
}
/// Obtain a reference to the metadata.
+5 -5
View File
@@ -10,13 +10,13 @@ pub mod address;
/// A client for working with storage entries.
#[derive(Clone)]
pub struct ConstantsClient<T, Client> {
client: Client,
pub struct ConstantsClient<'atblock, T, Client> {
client: &'atblock Client,
marker: PhantomData<T>,
}
impl<T, Client> ConstantsClient<T, Client> {
pub(crate) fn new(client: Client) -> Self {
impl<'atblock, T, Client> ConstantsClient<'atblock, T, Client> {
pub(crate) fn new(client: &'atblock Client) -> Self {
ConstantsClient {
client,
marker: PhantomData,
@@ -24,7 +24,7 @@ impl<T, Client> ConstantsClient<T, Client> {
}
}
impl<T: Config, Client: OfflineClientAtBlockT<T>> ConstantsClient<T, Client> {
impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>> ConstantsClient<'atblock, T, Client> {
/// Run the validation logic against some constant address you'd like to access. Returns `Ok(())`
/// if the address is valid (or if it's not possible to check since the address has no validation hash).
/// Return an error if the address was not valid or something went wrong trying to validate it (ie
+7 -5
View File
@@ -11,14 +11,14 @@ pub mod address;
/// A client for accessing custom values stored in the metadata.
#[derive_where(Clone; Client)]
pub struct CustomValuesClient<T, Client> {
client: Client,
pub struct CustomValuesClient<'atblock, T, Client> {
client: &'atblock Client,
marker: std::marker::PhantomData<T>,
}
impl<T, Client> CustomValuesClient<T, Client> {
impl<'atblock, T, Client> CustomValuesClient<'atblock, T, Client> {
/// Create a new [`CustomValuesClient`].
pub(crate) fn new(client: Client) -> Self {
pub(crate) fn new(client: &'atblock Client) -> Self {
Self {
client,
marker: std::marker::PhantomData,
@@ -26,7 +26,9 @@ impl<T, Client> CustomValuesClient<T, Client> {
}
}
impl<T: Config, Client: OfflineClientAtBlockT<T>> CustomValuesClient<T, Client> {
impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>>
CustomValuesClient<'atblock, T, Client>
{
/// Run the validation logic against some custom value address you'd like to access. Returns `Ok(())`
/// if the address is valid (or if it's not possible to check since the address has no validation hash).
/// Returns an error if the address was not valid (wrong name, type or raw bytes)
+29 -27
View File
@@ -13,13 +13,13 @@ use subxt_metadata::Metadata;
pub use decode_as_event::DecodeAsEvent;
/// A client for working with events.
pub struct EventsClient<T, Client> {
client: Client,
pub struct EventsClient<'atblock, T, Client> {
client: &'atblock Client,
marker: PhantomData<T>,
}
impl<T, Client> EventsClient<T, Client> {
pub(crate) fn new(client: Client) -> Self {
impl<'atblock, T, Client> EventsClient<'atblock, T, Client> {
pub(crate) fn new(client: &'atblock Client) -> Self {
EventsClient {
client,
marker: PhantomData,
@@ -27,12 +27,12 @@ impl<T, Client> EventsClient<T, Client> {
}
}
impl<T: Config, Client: OfflineClientAtBlockT<T>> EventsClient<T, Client> {
impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>> EventsClient<'atblock, T, Client> {
/// Work with the block event bytes given.
///
/// No attempt to validate the provided bytes is made here; if invalid bytes are
/// provided then attempting to iterate and decode them will fail.
pub fn from_bytes(&self, event_bytes: Vec<u8>) -> Events<T> {
pub fn from_bytes(&self, event_bytes: Vec<u8>) -> Events<'atblock, T> {
// event_bytes is a SCALE encoded vector of events. So, pluck the
// compact encoded length from the front, leaving the remaining bytes
// for our iterating to decode.
@@ -46,8 +46,8 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> EventsClient<T, Client> {
let start_idx = event_bytes.len() - cursor.len();
Events {
metadata: self.client.metadata(),
event_bytes,
metadata: self.client.metadata_ref(),
event_bytes: event_bytes.into(),
start_idx,
num_events,
marker: PhantomData,
@@ -55,10 +55,10 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> EventsClient<T, Client> {
}
}
impl<T: Config, Client: OnlineClientAtBlockT<T>> EventsClient<T, Client> {
impl<'atblock, T: Config, Client: OnlineClientAtBlockT<T>> EventsClient<'atblock, T, Client> {
/// Fetch the events at this block.
pub async fn fetch(&self) -> Result<Events<T>, EventsError> {
let client = &self.client;
pub async fn fetch(&self) -> Result<Events<'atblock, T>, EventsError> {
let client = self.client;
// Fetch the bytes. Ensure things work if we get 0 bytes back.
let block_hash = client.block_hash();
@@ -75,18 +75,18 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> EventsClient<T, Client> {
/// The events at some block.
#[derive(Debug)]
pub struct Events<T> {
metadata: Arc<Metadata>,
pub struct Events<'atblock, T> {
metadata: &'atblock Metadata,
// Note; raw event bytes are prefixed with a Compact<u32> containing
// the number of events to be decoded. The start_idx reflects that, so
// that we can skip over those bytes when decoding them
event_bytes: Vec<u8>,
event_bytes: Arc<[u8]>,
start_idx: usize,
num_events: u32,
marker: core::marker::PhantomData<T>,
}
impl<T: Config> Events<T> {
impl<'atblock, T: Config> Events<'atblock, T> {
/// The number of events.
pub fn len(&self) -> u32 {
self.num_events
@@ -108,9 +108,11 @@ impl<T: Config> Events<T> {
/// details. If an error occurs, all subsequent iterations return `None`.
// Dev note: The returned iterator is 'static + Send so that we can box it up and make
// use of it with our `FilterEvents` stuff.
pub fn iter(&'_ self) -> impl Iterator<Item = Result<Event<'_, T>, EventsError>> + Send + Sync {
pub fn iter(
&'_ self,
) -> impl Iterator<Item = Result<Event<'atblock, T>, EventsError>> + Send + Sync {
// The event bytes ignoring the compact encoded length on the front:
let event_bytes = &*self.event_bytes;
let event_bytes = self.event_bytes.clone();
let metadata = &*self.metadata;
let num_events = self.num_events;
@@ -120,7 +122,7 @@ impl<T: Config> Events<T> {
if event_bytes.len() <= pos || num_events == index {
None
} else {
match Event::decode_from(metadata, event_bytes, pos, index) {
match Event::decode_from(metadata, event_bytes.clone(), pos, index) {
Ok(event_details) => {
// Skip over decoded bytes in next iteration:
pos += event_details.bytes().len();
@@ -171,12 +173,12 @@ pub enum Phase {
/// The event details.
#[derive(Debug, Clone)]
pub struct Event<'events, T: Config> {
pallet_name: &'events str,
event_name: &'events str,
metadata: &'events Metadata,
pub struct Event<'atblock, T: Config> {
pallet_name: &'atblock str,
event_name: &'atblock str,
metadata: &'atblock Metadata,
// all of the event bytes (not just this one).
all_bytes: &'events [u8],
all_bytes: Arc<[u8]>,
// event phase.
phase: Phase,
/// The index of the event in the list of events in a given block.
@@ -195,14 +197,14 @@ pub struct Event<'events, T: Config> {
topics: Vec<HashFor<T>>,
}
impl<'events, T: Config> Event<'events, T> {
impl<'atblock, T: Config> Event<'atblock, T> {
/// Attempt to dynamically decode a single event from our events input.
fn decode_from(
metadata: &'events Metadata,
all_bytes: &'events [u8],
metadata: &'atblock Metadata,
all_bytes: Arc<[u8]>,
start_idx: usize,
index: u32,
) -> Result<Event<'events, T>, EventsError> {
) -> Result<Event<'atblock, T>, EventsError> {
let input = &mut &all_bytes[start_idx..];
let phase = Phase::decode(input).map_err(EventsError::CannotDecodePhase)?;
+52 -52
View File
@@ -19,13 +19,13 @@ pub use extrinsic_transaction_extensions::{
};
/// A client for working with extrinsics.
pub struct ExtrinsicsClient<T, Client> {
client: Client,
pub struct ExtrinsicsClient<'atblock, T, Client> {
client: &'atblock Client,
marker: PhantomData<T>,
}
impl<T, Client> ExtrinsicsClient<T, Client> {
pub(crate) fn new(client: Client) -> Self {
impl<'atblock, T, Client> ExtrinsicsClient<'atblock, T, Client> {
pub(crate) fn new(client: &'atblock Client) -> Self {
ExtrinsicsClient {
client,
marker: PhantomData,
@@ -33,24 +33,24 @@ impl<T, Client> ExtrinsicsClient<T, Client> {
}
}
impl<T: Config, Client: OfflineClientAtBlockT<T>> ExtrinsicsClient<T, Client> {
impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>> ExtrinsicsClient<'atblock, T, Client> {
/// Work with the block body bytes given.
///
/// No attempt to validate the provided bytes is made here; if invalid bytes are
/// provided then attempting to iterate and decode them will fail.
pub async fn from_bytes(&self, extrinsics: Vec<Vec<u8>>) -> Extrinsics<T, Client> {
pub async fn from_bytes(&self, extrinsics: Vec<Vec<u8>>) -> Extrinsics<'atblock, T, Client> {
Extrinsics {
client: self.client.clone(),
client: self.client,
extrinsics: Arc::new(extrinsics),
marker: PhantomData,
}
}
}
impl<T: Config, Client: OnlineClientAtBlockT<T>> ExtrinsicsClient<T, Client> {
impl<'atblock, T: Config, Client: OnlineClientAtBlockT<T>> ExtrinsicsClient<'atblock, T, Client> {
/// Fetch the extrinsics at this block.
pub async fn fetch(&self) -> Result<Extrinsics<T, Client>, ExtrinsicError> {
let client = &self.client;
pub async fn fetch(&self) -> Result<Extrinsics<'atblock, T, Client>, ExtrinsicError> {
let client = self.client;
let block_hash = client.block_hash();
let extrinsics = client
.backend()
@@ -60,7 +60,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> ExtrinsicsClient<T, Client> {
.ok_or_else(|| ExtrinsicError::BlockNotFound(block_hash.into()))?;
Ok(Extrinsics {
client: client.clone(),
client,
extrinsics: Arc::new(extrinsics),
marker: PhantomData,
})
@@ -69,13 +69,13 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> ExtrinsicsClient<T, Client> {
/// The extrinsics in a block.
#[derive(Debug, Clone)]
pub struct Extrinsics<T, C> {
client: C,
pub struct Extrinsics<'atblock, T, C> {
client: &'atblock C,
extrinsics: Arc<Vec<Vec<u8>>>,
marker: PhantomData<T>,
}
impl<T: Config, C: OfflineClientAtBlockT<T>> Extrinsics<T, C> {
impl<'atblock, T: Config, C: OfflineClientAtBlockT<T>> Extrinsics<'atblock, T, C> {
/// The number of extrinsics.
pub fn len(&self) -> usize {
self.extrinsics.len()
@@ -94,7 +94,8 @@ impl<T: Config, C: OfflineClientAtBlockT<T>> Extrinsics<T, C> {
) -> impl Iterator<Item = Result<Extrinsic<'_, T, C>, ExtrinsicDecodeErrorAt>> {
let hasher = self.client.hasher();
let metadata = self.client.metadata_ref();
let client = &self.client;
let client = self.client;
let all_extrinsic_bytes = self.extrinsics.clone();
self.extrinsics
.iter()
@@ -122,8 +123,8 @@ impl<T: Config, C: OfflineClientAtBlockT<T>> Extrinsics<T, C> {
Ok(Extrinsic {
client: client,
index: extrinsic_index,
info,
extrinsic: &**extrinsic_bytes,
info: Arc::new(info),
extrinsics: Arc::clone(&all_extrinsic_bytes),
hasher,
metadata,
})
@@ -148,29 +149,28 @@ impl<T: Config, C: OfflineClientAtBlockT<T>> Extrinsics<T, C> {
}
/// A single extrinsic in a block.
pub struct Extrinsic<'extrinsics, T: Config, C> {
client: &'extrinsics C,
pub struct Extrinsic<'atblock, T: Config, C> {
client: &'atblock C,
/// The index of the extrinsic in the block.
index: usize,
/// Information about the extrinsic
info: ExtrinsicInfo<'extrinsics, u32>,
/// Extrinsic bytes and decode info.
extrinsic: &'extrinsics [u8],
info: Arc<ExtrinsicInfo<'atblock, u32>>,
/// All extrinsic bytes. use the index to select the correct bytes.
extrinsics: Arc<Vec<Vec<u8>>>,
/// Hash the extrinsic if we want.
hasher: &'extrinsics T::Hasher,
hasher: &'atblock T::Hasher,
/// Subxt metadata to fetch the extrinsic metadata.
metadata: &'extrinsics Metadata,
metadata: &'atblock Metadata,
}
impl<'extrinsics, T, C> Extrinsic<'extrinsics, T, C>
impl<'atblock, T, C> Extrinsic<'atblock, T, C>
where
T: Config,
C: OfflineClientAtBlockT<T>,
{
/// Calculate and return the hash of the extrinsic, based on the configured hasher.
pub fn hash(&self) -> HashFor<T> {
// Use hash(), not hash_of(), because we don't want to double encode the bytes.
self.hasher.hash(self.extrinsic)
self.hasher.hash(&self.extrinsics[self.index])
}
/// Is the extrinsic signed?
@@ -204,8 +204,8 @@ where
}
/// Return the extrinsic bytes.
pub fn bytes(&self) -> &'extrinsics [u8] {
self.extrinsic
pub fn bytes(&self) -> &[u8] {
&self.extrinsics[self.index]
}
/// Return only the bytes representing this extrinsic call:
@@ -216,8 +216,8 @@ where
/// # Note
///
/// Please use [`Self::bytes`] if you want to get all extrinsic bytes.
pub fn call_data_bytes(&self) -> &'extrinsics [u8] {
&self.extrinsic[self.info.call_data_range()]
pub fn call_data_bytes(&self) -> &[u8] {
&self.bytes()[self.info.call_data_range()]
}
/// Return the bytes representing the fields stored in this extrinsic.
@@ -226,8 +226,8 @@ where
///
/// This is a subset of [`Self::call_bytes`] that does not include the
/// first two bytes that denote the pallet index and the variant index.
pub fn call_data_field_bytes(&self) -> &'extrinsics [u8] {
&self.extrinsic[self.info.call_data_args_range()]
pub fn call_data_field_bytes(&self) -> &[u8] {
&self.bytes()[self.info.call_data_args_range()]
}
/// Return only the bytes of the address that signed this extrinsic.
@@ -235,17 +235,17 @@ where
/// # Note
///
/// Returns `None` if the extrinsic is not signed.
pub fn address_bytes(&self) -> Option<&'extrinsics [u8]> {
pub fn address_bytes(&self) -> Option<&[u8]> {
self.info
.signature_payload()
.map(|s| &self.extrinsic[s.address_range()])
.map(|s| &self.bytes()[s.address_range()])
}
/// Returns Some(signature_bytes) if the extrinsic was signed otherwise None is returned.
pub fn signature_bytes(&self) -> Option<&'extrinsics [u8]> {
pub fn signature_bytes(&self) -> Option<&[u8]> {
self.info
.signature_payload()
.map(|s| &self.extrinsic[s.signature_range()])
.map(|s| &self.bytes()[s.signature_range()])
}
/// Returns the signed extension `extra` bytes of the extrinsic.
@@ -257,16 +257,19 @@ where
pub fn transaction_extensions_bytes(&self) -> Option<&[u8]> {
self.info
.transaction_extension_payload()
.map(|t| &self.extrinsic[t.range()])
.map(|t| &self.bytes()[t.range()])
}
/// Returns `None` if the extrinsic is not signed.
pub fn transaction_extensions(
&self,
) -> Option<ExtrinsicTransactionExtensions<'extrinsics, '_, T>> {
) -> Option<ExtrinsicTransactionExtensions<'atblock, '_, T>> {
let bytes = self.bytes();
let metadata = self.metadata;
self.info
.transaction_extension_payload()
.map(|t| ExtrinsicTransactionExtensions::new(self.extrinsic, self.metadata, t))
.map(move |t| ExtrinsicTransactionExtensions::new(bytes, metadata, t))
}
/// Return true if this [`Extrinsic`] matches the provided type.
@@ -334,20 +337,20 @@ where
}
}
impl<'extrinsics, T, C> Extrinsic<'extrinsics, T, C>
impl<'atblock, T, C> Extrinsic<'atblock, T, C>
where
T: Config,
C: OnlineClientAtBlockT<T>,
{
/// The events associated with the extrinsic.
pub async fn events(&self) -> Result<ExtrinsicEvents<T>, EventsError> {
ExtrinsicEvents::fetch(self.client.clone(), self.hash(), self.index()).await
pub async fn events(&self) -> Result<ExtrinsicEvents<'atblock, T>, EventsError> {
ExtrinsicEvents::fetch(self.client, self.hash(), self.index()).await
}
}
/// The events associated with a given extrinsic.
#[derive(Debug)]
pub struct ExtrinsicEvents<T: Config> {
pub struct ExtrinsicEvents<'atblock, T: Config> {
// The hash of the extrinsic (handy to expose here because
// this type is returned from TxProgress things in the most
// basic flows, so it's the only place people can access it
@@ -356,19 +359,16 @@ pub struct ExtrinsicEvents<T: Config> {
// The index of the extrinsic:
extrinsic_index: usize,
// All of the events in the block:
events: crate::events::Events<T>,
events: crate::events::Events<'atblock, T>,
}
impl<T: Config> ExtrinsicEvents<T> {
impl<'atblock, T: Config> ExtrinsicEvents<'atblock, T> {
pub(crate) async fn fetch(
client: impl OnlineClientAtBlockT<T>,
client: &'atblock impl OnlineClientAtBlockT<T>,
extrinsic_hash: HashFor<T>,
extrinsic_index: usize,
) -> Result<Self, EventsError> {
let events = crate::client::ClientAtBlock::new(client)
.events()
.fetch()
.await?;
let events = crate::events::EventsClient::new(client).fetch().await?;
Ok(ExtrinsicEvents {
extrinsic_hash,
extrinsic_index,
@@ -387,7 +387,7 @@ impl<T: Config> ExtrinsicEvents<T> {
}
/// Return all of the events in the block that the extrinsic is in.
pub fn all_events_in_block(&self) -> &events::Events<T> {
pub fn all_events_in_block(&self) -> &events::Events<'atblock, T> {
&self.events
}
@@ -10,20 +10,18 @@ use subxt_metadata::Metadata;
/// The signed extensions of an extrinsic.
#[derive(Debug, Clone)]
pub struct ExtrinsicTransactionExtensions<'extrinsics, 'extrinsic, T: Config> {
bytes: &'extrinsics [u8],
metadata: &'extrinsics Metadata,
decoded_info: &'extrinsic ExtrinsicExtensionsInfo<'extrinsics, u32>,
pub struct ExtrinsicTransactionExtensions<'atblock, 'extrinsic, T: Config> {
bytes: &'extrinsic [u8],
metadata: &'atblock Metadata,
decoded_info: &'extrinsic ExtrinsicExtensionsInfo<'atblock, u32>,
marker: core::marker::PhantomData<T>,
}
impl<'extrinsics, 'extrinsic, T: Config>
ExtrinsicTransactionExtensions<'extrinsics, 'extrinsic, T>
{
impl<'atblock, 'extrinsic, T: Config> ExtrinsicTransactionExtensions<'atblock, 'extrinsic, T> {
pub(crate) fn new(
bytes: &'extrinsics [u8],
metadata: &'extrinsics Metadata,
decoded_info: &'extrinsic ExtrinsicExtensionsInfo<'extrinsics, u32>,
bytes: &'extrinsic [u8],
metadata: &'atblock Metadata,
decoded_info: &'extrinsic ExtrinsicExtensionsInfo<'atblock, u32>,
) -> Self {
Self {
bytes,
@@ -36,10 +34,10 @@ impl<'extrinsics, 'extrinsic, T: Config>
/// Returns an iterator over each of the signed extension details of the extrinsic.
pub fn iter(
&self,
) -> impl Iterator<Item = ExtrinsicTransactionExtension<'extrinsics, 'extrinsic, T>> {
) -> impl Iterator<Item = ExtrinsicTransactionExtension<'atblock, 'extrinsic, T>> {
self.decoded_info
.iter()
.map(|s| ExtrinsicTransactionExtension {
.map(move |s| ExtrinsicTransactionExtension {
bytes: &self.bytes[s.range()],
ty_id: *s.ty(),
identifier: s.name(),
@@ -85,17 +83,17 @@ impl<'extrinsics, 'extrinsic, T: Config>
/// A single signed extension
#[derive(Debug, Clone)]
pub struct ExtrinsicTransactionExtension<'extrinsics, 'extrinsic, T: Config> {
bytes: &'extrinsics [u8],
pub struct ExtrinsicTransactionExtension<'atblock, 'extrinsic, T: Config> {
bytes: &'extrinsic [u8],
ty_id: u32,
identifier: &'extrinsic str,
metadata: &'extrinsics Metadata,
metadata: &'atblock Metadata,
_marker: core::marker::PhantomData<T>,
}
impl<'extrinsics, 'extrinsic, T: Config> ExtrinsicTransactionExtension<'extrinsics, 'extrinsic, T> {
impl<'atblock, 'extrinsic, T: Config> ExtrinsicTransactionExtension<'atblock, 'extrinsic, T> {
/// The bytes representing this signed extension.
pub fn bytes(&self) -> &'extrinsics [u8] {
pub fn bytes(&self) -> &'extrinsic [u8] {
self.bytes
}
+6 -6
View File
@@ -14,14 +14,14 @@ pub mod payload;
/// Execute runtime API calls.
#[derive_where(Clone; Client)]
pub struct RuntimeApisClient<T: Config, Client> {
client: Client,
pub struct RuntimeApisClient<'atblock, T: Config, Client> {
client: &'atblock Client,
marker: PhantomData<T>,
}
impl<T: Config, Client> RuntimeApisClient<T, Client> {
impl<'atblock, T: Config, Client> RuntimeApisClient<'atblock, T, Client> {
/// Create a new [`RuntimeApi`]
pub(crate) fn new(client: Client) -> Self {
pub(crate) fn new(client: &'atblock Client) -> Self {
Self {
client,
marker: PhantomData,
@@ -29,7 +29,7 @@ impl<T: Config, Client> RuntimeApisClient<T, Client> {
}
}
impl<T, Client> RuntimeApisClient<T, Client>
impl<'atblock, T, Client> RuntimeApisClient<'atblock, T, Client>
where
T: Config,
Client: OfflineClientAtBlockT<T>,
@@ -85,7 +85,7 @@ where
}
}
impl<T, Client> RuntimeApisClient<T, Client>
impl<'atblock, T, Client> RuntimeApisClient<'atblock, T, Client>
where
T: Config,
Client: OnlineClientAtBlockT<T>,
+10 -10
View File
@@ -23,13 +23,13 @@ pub mod address;
/// A client for working with storage entries.
#[derive(Clone)]
pub struct StorageClient<T, Client> {
client: Client,
pub struct StorageClient<'atblock, T, Client> {
client: &'atblock Client,
marker: PhantomData<T>,
}
impl<T, Client> StorageClient<T, Client> {
pub(crate) fn new(client: Client) -> Self {
impl<'atblock, T, Client> StorageClient<'atblock, T, Client> {
pub(crate) fn new(client: &'atblock Client) -> Self {
StorageClient {
client,
marker: PhantomData,
@@ -37,7 +37,7 @@ impl<T, Client> StorageClient<T, Client> {
}
}
impl<T: Config, Client: OfflineClientAtBlockT<T>> StorageClient<T, Client> {
impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>> StorageClient<'atblock, T, Client> {
/// When the provided `address` is statically generated via the `#[subxt]` macro, this validates
/// that the shape of the storage value is the same as the shape expected by the static address.
///
@@ -74,27 +74,27 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> StorageClient<T, Client> {
pub fn entry<Addr: Address>(
&self,
address: Addr,
) -> Result<StorageEntry<'_, T, Client, Addr>, StorageError> {
) -> Result<StorageEntry<'atblock, T, Client, Addr>, StorageError> {
self.validate(&address)?;
StorageEntry::new(&self.client, address)
StorageEntry::new(self.client, address)
}
/// Iterate over all of the storage entries listed in the metadata for the current block. This does **not** include well known
/// storage entries like `:code` which are not listed in the metadata.
pub fn entries(&self) -> impl Iterator<Item = StorageEntryRef<'_, T, Client>> {
pub fn entries(&self) -> impl Iterator<Item = StorageEntryRef<'atblock, T, Client>> {
let metadata = self.client.metadata_ref();
Entry::tuples_of(metadata.storage_entries()).map(|(pallet_name, entry_name)| {
StorageEntryRef {
pallet_name: pallet_name.clone(),
entry_name,
client: &self.client,
client: self.client,
marker: std::marker::PhantomData,
}
})
}
}
impl<T: Config, Client: OnlineClientAtBlockT<T>> StorageClient<T, Client> {
impl<'atblock, T: Config, Client: OnlineClientAtBlockT<T>> StorageClient<'atblock, T, Client> {
/// This is essentially a shorthand for `client.entry(addr)?.fetch(key_parts)`. See [`StorageEntry::fetch()`].
pub async fn fetch<Addr: Address>(
&self,
+60 -46
View File
@@ -29,13 +29,13 @@ pub use validation_result::{
/// A client for working with transactions.
#[derive(Clone)]
pub struct TransactionsClient<T, Client> {
client: Client,
pub struct TransactionsClient<'atblock, T, Client> {
client: &'atblock Client,
marker: PhantomData<T>,
}
impl<T, Client> TransactionsClient<T, Client> {
pub(crate) fn new(client: Client) -> Self {
impl<'atblock, T, Client> TransactionsClient<'atblock, T, Client> {
pub(crate) fn new(client: &'atblock Client) -> Self {
TransactionsClient {
client,
marker: PhantomData,
@@ -43,7 +43,9 @@ impl<T, Client> TransactionsClient<T, Client> {
}
}
impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client> {
impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>>
TransactionsClient<'atblock, T, Client>
{
/// Run the validation logic against some transaction you'd like to submit. Returns `Ok(())`
/// if the call is valid (or if it's not possible to check since the call has no validation hash).
/// Return an error if the call was not valid or something went wrong trying to validate it (ie
@@ -77,6 +79,20 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
}
}
/// Create a [`SubmittableTransaction`] from some already-signed and prepared
/// transaction bytes, and some client (anything implementing [`OfflineClientAtBlockT`]
/// or [`OnlineClientAtBlockT`]).
pub fn from_bytes(
client: &'atblock Client,
tx_bytes: Vec<u8>,
) -> SubmittableTransaction<'atblock, T, Client> {
SubmittableTransaction {
client,
encoded: tx_bytes,
marker: PhantomData,
}
}
/// Return the SCALE encoded bytes representing the call data of the transaction.
pub fn call_data<Call>(&self, call: &Call) -> Result<Vec<u8>, ExtrinsicError>
where
@@ -94,7 +110,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
pub fn create_unsigned<Call>(
&self,
call: &Call,
) -> Result<SubmittableTransaction<T, Client>, ExtrinsicError>
) -> Result<SubmittableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -110,7 +126,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
pub fn create_v4_unsigned<Call>(
&self,
call: &Call,
) -> Result<SubmittableTransaction<T, Client>, ExtrinsicError>
) -> Result<SubmittableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -121,7 +137,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
pub fn create_v5_unsigned<Call>(
&self,
call: &Call,
) -> Result<SubmittableTransaction<T, Client>, ExtrinsicError>
) -> Result<SubmittableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -138,7 +154,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
&self,
call: &Call,
params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<SignableTransaction<T, Client>, ExtrinsicError>
) -> Result<SignableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -159,7 +175,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
&self,
call: &Call,
params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<SignableTransaction<T, Client>, ExtrinsicError>
) -> Result<SignableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -177,7 +193,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
&self,
call: &Call,
params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<SignableTransaction<T, Client>, ExtrinsicError>
) -> Result<SignableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -209,7 +225,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
&self,
call: &Call,
tx_version: SupportedTransactionVersion,
) -> Result<SubmittableTransaction<T, Client>, ExtrinsicError> {
) -> Result<SubmittableTransaction<'atblock, T, Client>, ExtrinsicError> {
let metadata = self.client.metadata_ref();
// 1. Validate this call against the current node metadata if the call comes
@@ -235,7 +251,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
// Wrap in Encoded to ensure that any more "encode" calls leave it in the right state.
Ok(SubmittableTransaction {
client: self.client.clone(),
client: self.client,
encoded: extrinsic,
marker: PhantomData,
})
@@ -247,7 +263,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
call: &Call,
params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
tx_version: SupportedTransactionVersion,
) -> Result<SignableTransaction<T, Client>, ExtrinsicError>
) -> Result<SignableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -286,7 +302,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
// Return these details, ready to construct a signed extrinsic from.
Ok(SignableTransaction {
client: self.client.clone(),
client: self.client,
call_data,
additional_and_extra_params,
tx_extension_version,
@@ -294,10 +310,10 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> TransactionsClient<T, Client>
}
}
impl<T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<T, Client> {
impl<'atblock, T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<'atblock, T, Client> {
/// Get the account nonce for a given account ID.
pub async fn account_nonce(&self, account_id: &T::AccountId) -> Result<u64, ExtrinsicError> {
account_nonce::get_account_nonce(&self.client, account_id)
account_nonce::get_account_nonce(self.client, account_id)
.await
.map_err(|e| ExtrinsicError::AccountNonceError {
block_hash: self.client.block_hash().into(),
@@ -312,7 +328,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<T, Client> {
call: &Call,
account_id: &T::AccountId,
mut params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<SignableTransaction<T, Client>, ExtrinsicError>
) -> Result<SignableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -330,7 +346,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<T, Client> {
call: &Call,
account_id: &T::AccountId,
mut params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<SignableTransaction<T, Client>, ExtrinsicError>
) -> Result<SignableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -348,7 +364,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<T, Client> {
call: &Call,
account_id: &T::AccountId,
mut params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<SignableTransaction<T, Client>, ExtrinsicError>
) -> Result<SignableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
{
@@ -363,7 +379,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<T, Client> {
call: &Call,
signer: &S,
params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<SubmittableTransaction<T, Client>, ExtrinsicError>
) -> Result<SubmittableTransaction<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
S: Signer<T>,
@@ -384,7 +400,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<T, Client> {
&mut self,
call: &Call,
signer: &S,
) -> Result<TransactionProgress<T, Client>, ExtrinsicError>
) -> Result<TransactionProgress<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
S: Signer<T>,
@@ -403,7 +419,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> TransactionsClient<T, Client> {
call: &Call,
signer: &S,
params: <T::ExtrinsicParams as ExtrinsicParams<T>>::Params,
) -> Result<TransactionProgress<T, Client>, ExtrinsicError>
) -> Result<TransactionProgress<'atblock, T, Client>, ExtrinsicError>
where
Call: Payload,
S: Signer<T>,
@@ -506,15 +522,17 @@ pub enum SupportedTransactionVersion {
}
/// This is a transaction that requires signing before it can be submitted.
pub struct SignableTransaction<T: Config, Client> {
client: Client,
pub struct SignableTransaction<'atblock, T: Config, Client> {
client: &'atblock Client,
call_data: Vec<u8>,
additional_and_extra_params: <T as Config>::ExtrinsicParams,
// For V4 transactions this doesn't exist, and for V5 it does.
tx_extension_version: Option<u8>,
}
impl<T: Config, Client: OfflineClientAtBlockT<T>> SignableTransaction<T, Client> {
impl<'atblock, T: Config, Client: OfflineClientAtBlockT<T>>
SignableTransaction<'atblock, T, Client>
{
/// Return the bytes representing the call data for this partially constructed
/// transaction.
pub fn call_data(&self) -> &[u8] {
@@ -530,7 +548,10 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> SignableTransaction<T, Client>
/// Convert this [`SignableTransaction`] into a [`SubmittableTransaction`], ready to submit.
/// The provided `signer` is responsible for providing the "from" address for the transaction,
/// as well as providing a signature to attach to it.
pub fn sign<S: Signer<T>>(&mut self, signer: &S) -> SubmittableTransaction<T, Client> {
pub fn sign<S: Signer<T>>(
&mut self,
signer: &S,
) -> SubmittableTransaction<'atblock, T, Client> {
// Given our signer, we can sign the payload representing this extrinsic.
let signature = signer.sign(&self.signer_payload());
// Now, use the signature and "from" account to build the extrinsic.
@@ -545,7 +566,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> SignableTransaction<T, Client>
&mut self,
account_id: &T::AccountId,
signature: &T::Signature,
) -> SubmittableTransaction<T, Client> {
) -> SubmittableTransaction<'atblock, T, Client> {
let encoded = if let Some(tx_extensions_version) = self.tx_extension_version {
let mut encoded_inner = Vec::new();
// Pass account and signature to extensions to be added.
@@ -593,7 +614,7 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> SignableTransaction<T, Client>
};
SubmittableTransaction {
client: self.client.clone(),
client: self.client,
encoded,
marker: PhantomData,
}
@@ -627,28 +648,17 @@ impl<T: Config, Client: OfflineClientAtBlockT<T>> SignableTransaction<T, Client>
}
/// This is a transaction that is ready to submit.
pub struct SubmittableTransaction<T, Client> {
client: Client,
pub struct SubmittableTransaction<'atblock, T, Client> {
client: &'atblock Client,
encoded: Vec<u8>,
marker: PhantomData<T>,
}
impl<T, Client> SubmittableTransaction<T, Client>
impl<'atblock, T, Client> SubmittableTransaction<'atblock, T, Client>
where
T: Config,
Client: OfflineClientAtBlockT<T>,
{
/// Create a [`SubmittableTransaction`] from some already-signed and prepared
/// transaction bytes, and some client (anything implementing [`OfflineClientAtBlockT`]
/// or [`OnlineClientAtBlockT`]).
pub fn from_bytes(client: Client, tx_bytes: Vec<u8>) -> Self {
Self {
client,
encoded: tx_bytes,
marker: PhantomData,
}
}
/// Calculate and return the hash of the transaction, based on the configured hasher.
pub fn hash(&self) -> HashFor<T> {
self.client.hasher().hash(&self.encoded)
@@ -666,12 +676,16 @@ where
}
}
impl<T: Config, Client: OnlineClientAtBlockT<T>> SubmittableTransaction<T, Client> {
impl<'atblock, T: Config, Client: OnlineClientAtBlockT<T>>
SubmittableTransaction<'atblock, T, Client>
{
/// Submits the transaction to the chain.
///
/// Returns a [`TransactionProgress`], which can be used to track the status of the transaction
/// and obtain details about it, once it has made it into a block.
pub async fn submit_and_watch(&self) -> Result<TransactionProgress<T, Client>, ExtrinsicError> {
pub async fn submit_and_watch(
&self,
) -> Result<TransactionProgress<'atblock, T, Client>, ExtrinsicError> {
// Get a hash of the transaction (we'll need this later).
let ext_hash = self.hash();
@@ -683,7 +697,7 @@ impl<T: Config, Client: OnlineClientAtBlockT<T>> SubmittableTransaction<T, Clien
.await
.map_err(ExtrinsicError::ErrorSubmittingTransaction)?;
Ok(TransactionProgress::new(sub, self.client.clone(), ext_hash))
Ok(TransactionProgress::new(sub, self.client, ext_hash))
}
/// Submits the transaction to the chain for block inclusion.
+43 -36
View File
@@ -12,22 +12,22 @@ use std::pin::Pin;
use std::task::{Context, Poll};
#[derive(Debug)]
pub struct TransactionProgress<T: Config, C> {
pub struct TransactionProgress<'atblock, T: Config, C> {
sub: Option<StreamOfResults<BackendTransactionStatus<HashFor<T>>>>,
ext_hash: HashFor<T>,
client: C,
client: &'atblock C,
}
// The above type is not `Unpin` by default unless the generic param `T` is,
// so we manually make it clear that Unpin is actually fine regardless of `T`
// (we don't care if this moves around in memory while it's "pinned").
impl<T: Config, C> Unpin for TransactionProgress<T, C> {}
impl<'atblock, T: Config, C> Unpin for TransactionProgress<'atblock, T, C> {}
impl<T: Config, C> TransactionProgress<T, C> {
impl<'atblock, T: Config, C> TransactionProgress<'atblock, T, C> {
/// Instantiate a new [`TransactionProgress`] from a custom subscription.
pub fn new(
sub: StreamOfResults<BackendTransactionStatus<HashFor<T>>>,
client: C,
client: &'atblock C,
ext_hash: HashFor<T>,
) -> Self {
Self {
@@ -43,7 +43,7 @@ impl<T: Config, C> TransactionProgress<T, C> {
}
}
impl<T, C> TransactionProgress<T, C>
impl<'atblock, T, C> TransactionProgress<'atblock, T, C>
where
T: Config,
C: OnlineClientAtBlockT<T>,
@@ -53,7 +53,7 @@ where
/// avoid importing that trait if you don't otherwise need it.
pub async fn next(
&mut self,
) -> Option<Result<TransactionStatus<T, C>, TransactionProgressError>> {
) -> Option<Result<TransactionStatus<'atblock, T, C>, TransactionProgressError>> {
StreamExt::next(self).await
}
@@ -69,7 +69,7 @@ where
/// out if they finally made it into a block or not.
pub async fn wait_for_finalized(
mut self,
) -> Result<TransactionInBlock<T, C>, TransactionProgressError> {
) -> Result<TransactionInBlock<'atblock, T, C>, TransactionProgressError> {
while let Some(status) = self.next().await {
match status? {
// Finalized! Return.
@@ -104,15 +104,15 @@ where
/// out if they finally made it into a block or not.
pub async fn wait_for_finalized_success(
self,
) -> Result<ExtrinsicEvents<T>, TransactionFinalizedSuccessError> {
) -> Result<ExtrinsicEvents<'atblock, T>, TransactionFinalizedSuccessError> {
let evs = self.wait_for_finalized().await?.wait_for_success().await?;
Ok(evs)
}
}
// TransactionProgress is a stream of transaction events
impl<T: Config, C: Clone> Stream for TransactionProgress<T, C> {
type Item = Result<TransactionStatus<T, C>, TransactionProgressError>;
impl<'atblock, T: Config, C: Clone> Stream for TransactionProgress<'atblock, T, C> {
type Item = Result<TransactionStatus<'atblock, T, C>, TransactionProgressError>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let sub = match self.sub.as_mut() {
@@ -133,7 +133,7 @@ impl<T: Config, C: Clone> Stream for TransactionProgress<T, C> {
TransactionStatus::InBestBlock(TransactionInBlock::new(
hash,
self.ext_hash,
self.client.clone(),
self.client,
))
}
// These stream events mean that nothing further will be sent:
@@ -142,7 +142,7 @@ impl<T: Config, C: Clone> Stream for TransactionProgress<T, C> {
TransactionStatus::InFinalizedBlock(TransactionInBlock::new(
hash,
self.ext_hash,
self.client.clone(),
self.client,
))
}
BackendTransactionStatus::Error { message } => {
@@ -164,7 +164,7 @@ impl<T: Config, C: Clone> Stream for TransactionProgress<T, C> {
/// Possible transaction statuses returned from our [`TransactionProgress::next()`] call.
#[derive(Debug)]
pub enum TransactionStatus<T: Config, C> {
pub enum TransactionStatus<'atblock, T: Config, C> {
/// Transaction is part of the future queue.
Validated,
/// The transaction has been broadcast to other nodes.
@@ -172,9 +172,9 @@ pub enum TransactionStatus<T: Config, C> {
/// Transaction is no longer in a best block.
NoLongerInBestBlock,
/// Transaction has been included in block with given hash.
InBestBlock(TransactionInBlock<T, C>),
InBestBlock(TransactionInBlock<'atblock, T, C>),
/// Transaction has been finalized by a finality-gadget, e.g GRANDPA
InFinalizedBlock(TransactionInBlock<T, C>),
InFinalizedBlock(TransactionInBlock<'atblock, T, C>),
/// Something went wrong in the node.
Error {
/// Human readable message; what went wrong.
@@ -192,10 +192,10 @@ pub enum TransactionStatus<T: Config, C> {
},
}
impl<T: Config, C> TransactionStatus<T, C> {
impl<'atblock, T: Config, C> TransactionStatus<'atblock, T, C> {
/// A convenience method to return the finalized details. Returns
/// [`None`] if the enum variant is not [`TxStatus::InFinalizedBlock`].
pub fn as_finalized(&self) -> Option<&TransactionInBlock<T, C>> {
pub fn as_finalized(&self) -> Option<&TransactionInBlock<'atblock, T, C>> {
match self {
Self::InFinalizedBlock(val) => Some(val),
_ => None,
@@ -204,7 +204,7 @@ impl<T: Config, C> TransactionStatus<T, C> {
/// A convenience method to return the best block details. Returns
/// [`None`] if the enum variant is not [`TxStatus::InBestBlock`].
pub fn as_in_block(&self) -> Option<&TransactionInBlock<T, C>> {
pub fn as_in_block(&self) -> Option<&TransactionInBlock<'atblock, T, C>> {
match self {
Self::InBestBlock(val) => Some(val),
_ => None,
@@ -214,14 +214,18 @@ impl<T: Config, C> TransactionStatus<T, C> {
/// This struct represents a transaction that has made it into a block.
#[derive(Debug)]
pub struct TransactionInBlock<T: Config, C> {
pub struct TransactionInBlock<'atblock, T: Config, C> {
block_ref: BlockRef<HashFor<T>>,
ext_hash: HashFor<T>,
client: C,
client: &'atblock C,
}
impl<T: Config, C> TransactionInBlock<T, C> {
pub(crate) fn new(block_ref: BlockRef<HashFor<T>>, ext_hash: HashFor<T>, client: C) -> Self {
impl<'atblock, T: Config, C> TransactionInBlock<'atblock, T, C> {
pub(crate) fn new(
block_ref: BlockRef<HashFor<T>>,
ext_hash: HashFor<T>,
client: &'atblock C,
) -> Self {
Self {
block_ref,
ext_hash,
@@ -240,7 +244,7 @@ impl<T: Config, C> TransactionInBlock<T, C> {
}
}
impl<T: Config, C: OnlineClientAtBlockT<T>> TransactionInBlock<T, C> {
impl<'atblock, T: Config, C: OnlineClientAtBlockT<T>> TransactionInBlock<'atblock, T, C> {
/// Fetch the events associated with this transaction. If the transaction
/// was successful (ie no `ExtrinsicFailed`) events were found, then we return
/// the events associated with it. If the transaction was not successful, or
@@ -254,7 +258,9 @@ impl<T: Config, C: OnlineClientAtBlockT<T>> TransactionInBlock<T, C> {
///
/// **Note:** This has to download block details from the node and decode events
/// from them.
pub async fn wait_for_success(&self) -> Result<ExtrinsicEvents<T>, TransactionEventsError> {
pub async fn wait_for_success(
&self,
) -> Result<ExtrinsicEvents<'atblock, T>, TransactionEventsError> {
let events = self.fetch_events().await?;
// Try to find any errors; return the first one we encounter.
@@ -286,7 +292,9 @@ impl<T: Config, C: OnlineClientAtBlockT<T>> TransactionInBlock<T, C> {
///
/// **Note:** This has to download block details from the node and decode events
/// from them.
pub async fn fetch_events(&self) -> Result<ExtrinsicEvents<T>, TransactionEventsError> {
pub async fn fetch_events(
&self,
) -> Result<ExtrinsicEvents<'atblock, T>, TransactionEventsError> {
let hasher = self.client.hasher();
let block_body = self
@@ -316,16 +324,15 @@ impl<T: Config, C: OnlineClientAtBlockT<T>> TransactionInBlock<T, C> {
transaction_hash: self.ext_hash.into(),
})?;
let events =
ExtrinsicEvents::fetch(self.client.clone(), self.extrinsic_hash(), extrinsic_index)
.await
.map_err(
|e| TransactionEventsError::CannotFetchEventsForTransaction {
block_hash: self.block_hash().into(),
transaction_hash: self.ext_hash.into(),
error: e,
},
)?;
let events = ExtrinsicEvents::fetch(self.client, self.extrinsic_hash(), extrinsic_index)
.await
.map_err(
|e| TransactionEventsError::CannotFetchEventsForTransaction {
block_hash: self.block_hash().into(),
transaction_hash: self.ext_hash.into(),
error: e,
},
)?;
Ok(events)
}
+6 -6
View File
@@ -17,14 +17,14 @@ const CALL_NAME: &str = "RuntimeViewFunction_execute_view_function";
/// Execute View Function calls.
#[derive_where(Clone; Client)]
pub struct ViewFunctionsClient<T: Config, Client> {
client: Client,
pub struct ViewFunctionsClient<'atblock, T: Config, Client> {
client: &'atblock Client,
marker: PhantomData<T>,
}
impl<T: Config, Client> ViewFunctionsClient<T, Client> {
impl<'atblock, T: Config, Client> ViewFunctionsClient<'atblock, T, Client> {
/// Create a new [`ViewFunctionsClient`]
pub(crate) fn new(client: Client) -> Self {
pub(crate) fn new(client: &'atblock Client) -> Self {
Self {
client,
marker: PhantomData,
@@ -32,7 +32,7 @@ impl<T: Config, Client> ViewFunctionsClient<T, Client> {
}
}
impl<T, Client> ViewFunctionsClient<T, Client>
impl<'atblock, T, Client> ViewFunctionsClient<'atblock, T, Client>
where
T: Config,
Client: OfflineClientAtBlockT<T>,
@@ -83,7 +83,7 @@ where
}
}
impl<T, Client> ViewFunctionsClient<T, Client>
impl<'atblock, T, Client> ViewFunctionsClient<'atblock, T, Client>
where
T: Config,
Client: OnlineClientAtBlockT<T>,