Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 26 additions & 27 deletions subxt/src/events/events_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,19 @@ where
async move {
// If block hash is not provided, get the hash
// for the latest block and use that.
let (block_hash, metadata) = match block_hash {
Some(hash) => {
// If the block hash is provided, the hash can be of an older
// block where the metadata was different. Fetch the metadata
// at the specific block to ensure proper dynamic decoding of
// events.
(hash, client.rpc().metadata(Some(hash)).await?)
}
let block_hash = match block_hash {
Some(hash) => hash,
None => {
// If the block hash was not provided, the metadata is
// extracted from the client and is presumed to be up to
// date (ie client should subscribe to the runtime upgrades).
(
client
.rpc()
.block_hash(None)
.await?
.expect("didn't pass a block number; qed"),
client.metadata(),
)
client
.rpc()
.block_hash(None)
.await?
.expect("didn't pass a block number; qed")
}
};

let event_bytes = client
.rpc()
.storage(&system_events_key().0, Some(block_hash))
.await?
.map(|e| e.0)
.unwrap_or_else(Vec::new);

Ok(Events::new(metadata, block_hash, event_bytes))
let event_bytes = get_event_bytes(&client, Some(block_hash)).await?;
Ok(Events::new(client.metadata(), block_hash, event_bytes))
}
}
}
Expand All @@ -96,3 +78,20 @@ fn system_events_key() -> StorageKey {
storage_key.extend(twox_128(b"Events").to_vec());
StorageKey(storage_key)
}

// Get the event bytes from the provided client, at the provided block hash.
pub(crate) async fn get_event_bytes<T, Client>(
client: &Client,
block_hash: Option<T::Hash>,
) -> Result<Vec<u8>, Error>
where
T: Config,
Client: OnlineClientT<T>,
{
Ok(client
.rpc()
.storage(&system_events_key().0, block_hash)
.await?
.map(|e| e.0)
.unwrap_or_else(Vec::new))
}
46 changes: 46 additions & 0 deletions subxt/src/events/events_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use super::{
StaticEvent,
};
use crate::{
client::OnlineClientT,
error::Error,
events::events_client::get_event_bytes,
metadata::EventMetadata,
Config,
Metadata,
Expand Down Expand Up @@ -64,6 +66,50 @@ impl<T: Config> Events<T> {
}
}

/// Obtain the events from a block hash, custom metadata and provided client.
///
/// This method gives users the ability to inspect the events of older blocks,
/// where the metadata changed. For those cases, the user is responsible for
/// providing a valid metadata.
///
/// # Example
///
/// ```no_run
/// # #[tokio::main]
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
/// use subxt::{ OnlineClient, PolkadotConfig, events::Events };
///
/// let client = OnlineClient::<PolkadotConfig>::new().await.unwrap();
///
/// // Get the hash of an older block.
/// let block_hash = client
/// .rpc()
/// .block_hash(Some(1u32.into()))
/// .await?
/// .expect("didn't pass a block number; qed");
/// // Fetch the metadata of the given block.
/// let metadata = client.rpc().metadata(Some(block_hash)).await?;
/// // Fetch the events from the client.
/// let events = Events::new_from_client(metadata, block_hash, client);
/// # Ok(())
/// # }
/// ```
///
/// # Note
///
/// Prefer to use [`crate::events::EventsClient::at`] to obtain the events.
pub async fn new_from_client<Client>(
metadata: Metadata,
block_hash: T::Hash,
client: Client,
) -> Result<Self, Error>
where
Client: OnlineClientT<T>,
{
let event_bytes = get_event_bytes(&client, Some(block_hash)).await?;
Ok(Events::new(metadata, block_hash, event_bytes))
}

/// The number of events.
pub fn len(&self) -> u32 {
self.num_events
Expand Down