mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 21:21:11 +00:00
make offline event and extrinsic ops possible
This commit is contained in:
+13
-13
@@ -4,9 +4,8 @@ mod online_client;
|
||||
use crate::config::{Config, HashFor};
|
||||
use crate::constants::ConstantsClient;
|
||||
use crate::custom_values::CustomValuesClient;
|
||||
use crate::error::{EventsError, ExtrinsicError};
|
||||
use crate::events::Events;
|
||||
use crate::extrinsics::Extrinsics;
|
||||
use crate::events::EventsClient;
|
||||
use crate::extrinsics::ExtrinsicsClient;
|
||||
use crate::runtime_apis::RuntimeApisClient;
|
||||
use crate::storage::StorageClient;
|
||||
use crate::transactions::TransactionsClient;
|
||||
@@ -54,10 +53,21 @@ where
|
||||
ConstantsClient::new(self.client.clone())
|
||||
}
|
||||
|
||||
/// Access custom values at this block.
|
||||
pub fn custom_values(&self) -> CustomValuesClient<T, Client> {
|
||||
CustomValuesClient::new(self.client.clone())
|
||||
}
|
||||
|
||||
/// Work with the extrinsics in this block.
|
||||
pub fn extrinsics(&self) -> ExtrinsicsClient<T, Client> {
|
||||
ExtrinsicsClient::new(self.client.clone())
|
||||
}
|
||||
|
||||
/// Work with the events at this block.
|
||||
pub fn events(&self) -> EventsClient<T, Client> {
|
||||
EventsClient::new(self.client.clone())
|
||||
}
|
||||
|
||||
/// Access runtime APIs at this block.
|
||||
pub fn runtime_apis(&self) -> RuntimeApisClient<T, Client> {
|
||||
RuntimeApisClient::new(self.client.clone())
|
||||
@@ -83,16 +93,6 @@ where
|
||||
T: Config,
|
||||
Client: OnlineClientAtBlockT<T>,
|
||||
{
|
||||
/// Obtain the extrinsics in this block.
|
||||
pub async fn extrinsics(&self) -> Result<Extrinsics<T, Client>, ExtrinsicError> {
|
||||
Extrinsics::fetch(self.client.clone()).await
|
||||
}
|
||||
|
||||
/// Obtain the extrinsic events at this block.
|
||||
pub async fn events(&self) -> Result<Events<T>, EventsError> {
|
||||
Events::fetch(self.client.clone()).await
|
||||
}
|
||||
|
||||
/// The current block hash.
|
||||
pub fn block_hash(&self) -> HashFor<T> {
|
||||
self.client.block_hash()
|
||||
|
||||
+63
-32
@@ -1,8 +1,9 @@
|
||||
mod decode_as_event;
|
||||
|
||||
use crate::backend::BackendExt;
|
||||
use crate::client::{OfflineClientAtBlockT, OnlineClientAtBlockT};
|
||||
use crate::config::{Config, HashFor};
|
||||
use crate::error::EventsError;
|
||||
use crate::{backend::BackendExt, client::OnlineClientAtBlockT};
|
||||
use codec::{Compact, Decode, Encode};
|
||||
use scale_decode::{DecodeAsFields, DecodeAsType};
|
||||
use std::marker::PhantomData;
|
||||
@@ -11,6 +12,67 @@ use subxt_metadata::Metadata;
|
||||
|
||||
pub use decode_as_event::DecodeAsEvent;
|
||||
|
||||
/// A client for working with events.
|
||||
pub struct EventsClient<T, Client> {
|
||||
client: Client,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T, Client> EventsClient<T, Client> {
|
||||
pub(crate) fn new(client: Client) -> Self {
|
||||
EventsClient {
|
||||
client,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config, Client: OfflineClientAtBlockT<T>> EventsClient<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> {
|
||||
// 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.
|
||||
//
|
||||
// Note: if we get no bytes back, avoid an error reading vec length
|
||||
// and default to 0 events.
|
||||
let cursor = &mut &*event_bytes;
|
||||
let num_events = <Compact<u32>>::decode(cursor).unwrap_or(Compact(0)).0;
|
||||
|
||||
// Start decoding after the compact encoded bytes.
|
||||
let start_idx = event_bytes.len() - cursor.len();
|
||||
|
||||
Events {
|
||||
metadata: self.client.metadata(),
|
||||
event_bytes,
|
||||
start_idx,
|
||||
num_events,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config, Client: OnlineClientAtBlockT<T>> EventsClient<T, Client> {
|
||||
/// Fetch the events at this block.
|
||||
pub async fn fetch(&self) -> Result<Events<T>, EventsError> {
|
||||
let client = &self.client;
|
||||
|
||||
// Fetch the bytes. Ensure things work if we get 0 bytes back.
|
||||
let block_hash = client.block_hash();
|
||||
let event_bytes = client
|
||||
.backend()
|
||||
.storage_fetch_value(system_events_key().to_vec(), block_hash)
|
||||
.await
|
||||
.map_err(EventsError::CannotFetchEventBytes)?
|
||||
.unwrap_or_default();
|
||||
|
||||
Ok(self.from_bytes(event_bytes))
|
||||
}
|
||||
}
|
||||
|
||||
/// The events at some block.
|
||||
#[derive(Debug)]
|
||||
pub struct Events<T> {
|
||||
@@ -25,37 +87,6 @@ pub struct Events<T> {
|
||||
}
|
||||
|
||||
impl<T: Config> Events<T> {
|
||||
pub(crate) async fn fetch(client: impl OnlineClientAtBlockT<T>) -> Result<Self, EventsError> {
|
||||
// Fetch the bytes. Ensure things work if we get 0 bytes back.
|
||||
let block_hash = client.block_hash();
|
||||
let event_bytes = client
|
||||
.backend()
|
||||
.storage_fetch_value(system_events_key().to_vec(), block_hash)
|
||||
.await
|
||||
.map_err(EventsError::CannotFetchEventBytes)?
|
||||
.unwrap_or_default();
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Note: if we get no bytes back, avoid an error reading vec length
|
||||
// and default to 0 events.
|
||||
let cursor = &mut &*event_bytes;
|
||||
let num_events = <Compact<u32>>::decode(cursor).unwrap_or(Compact(0)).0;
|
||||
|
||||
// Start decoding after the compact encoded bytes.
|
||||
let start_idx = event_bytes.len() - cursor.len();
|
||||
|
||||
Ok(Self {
|
||||
metadata: client.metadata(),
|
||||
event_bytes,
|
||||
start_idx,
|
||||
num_events,
|
||||
marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
/// The number of events.
|
||||
pub fn len(&self) -> u32 {
|
||||
self.num_events
|
||||
|
||||
+43
-9
@@ -18,16 +18,39 @@ pub use extrinsic_transaction_extensions::{
|
||||
ExtrinsicTransactionExtension, ExtrinsicTransactionExtensions,
|
||||
};
|
||||
|
||||
/// The extrinsics in a block.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Extrinsics<T, C> {
|
||||
client: C,
|
||||
extrinsics: Arc<Vec<Vec<u8>>>,
|
||||
/// A client for working with extrinsics.
|
||||
pub struct ExtrinsicsClient<T, Client> {
|
||||
client: Client,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Config, C: OnlineClientAtBlockT<T>> Extrinsics<T, C> {
|
||||
pub(crate) async fn fetch(client: C) -> Result<Self, ExtrinsicError> {
|
||||
impl<T, Client> ExtrinsicsClient<T, Client> {
|
||||
pub(crate) fn new(client: Client) -> Self {
|
||||
ExtrinsicsClient {
|
||||
client,
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config, Client: OfflineClientAtBlockT<T>> ExtrinsicsClient<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> {
|
||||
Extrinsics {
|
||||
client: self.client.clone(),
|
||||
extrinsics: Arc::new(extrinsics),
|
||||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config, Client: OnlineClientAtBlockT<T>> ExtrinsicsClient<T, Client> {
|
||||
/// Fetch the extrinsics at this block.
|
||||
pub async fn fetch(&self) -> Result<Extrinsics<T, Client>, ExtrinsicError> {
|
||||
let client = &self.client;
|
||||
let block_hash = client.block_hash();
|
||||
let extrinsics = client
|
||||
.backend()
|
||||
@@ -37,13 +60,21 @@ impl<T: Config, C: OnlineClientAtBlockT<T>> Extrinsics<T, C> {
|
||||
.ok_or_else(|| ExtrinsicError::BlockNotFound(block_hash.into()))?;
|
||||
|
||||
Ok(Extrinsics {
|
||||
client,
|
||||
client: client.clone(),
|
||||
extrinsics: Arc::new(extrinsics),
|
||||
marker: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The extrinsics in a block.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Extrinsics<T, C> {
|
||||
client: C,
|
||||
extrinsics: Arc<Vec<Vec<u8>>>,
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Config, C: OfflineClientAtBlockT<T>> Extrinsics<T, C> {
|
||||
/// The number of extrinsics.
|
||||
pub fn len(&self) -> usize {
|
||||
@@ -334,7 +365,10 @@ impl<T: Config> ExtrinsicEvents<T> {
|
||||
extrinsic_hash: HashFor<T>,
|
||||
extrinsic_index: usize,
|
||||
) -> Result<Self, EventsError> {
|
||||
let events = crate::client::ClientAtBlock::new(client).events().await?;
|
||||
let events = crate::client::ClientAtBlock::new(client)
|
||||
.events()
|
||||
.fetch()
|
||||
.await?;
|
||||
Ok(ExtrinsicEvents {
|
||||
extrinsic_hash,
|
||||
extrinsic_index,
|
||||
|
||||
Reference in New Issue
Block a user