mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 17:01:09 +00:00
Extend the new api.blocks() to be the primary way to subscribe and fetch blocks/extrinsics/events (#691)
* First pass adding functions to get blocks and extrinsics * cargo fmt and cache block events * prefix block hash with 0x * pin streams for better ergonomics and add an example of subscribing to blocks * remove unused var * standardise on _all, _best and _finalized for different block header subs * WIP center subscribing around blocks * Remove the event filtering/subscribing stuff * clippy * we need tokio, silly clippy * add extrinsic_index() call * Update subxt/src/blocks/block_types.rs Co-authored-by: Andrew Jones <ascjones@gmail.com> Co-authored-by: Andrew Jones <ascjones@gmail.com>
This commit is contained in:
@@ -39,7 +39,6 @@ impl Config for MyConfig {
|
||||
type Address = <SubstrateConfig as Config>::Address;
|
||||
type Header = <SubstrateConfig as Config>::Header;
|
||||
type Signature = <SubstrateConfig as Config>::Signature;
|
||||
type Extrinsic = <SubstrateConfig as Config>::Extrinsic;
|
||||
// ExtrinsicParams makes use of the index type, so we need to adjust it
|
||||
// too to align with our modified index type, above:
|
||||
type ExtrinsicParams = SubstrateExtrinsicParams<Self>;
|
||||
|
||||
@@ -29,7 +29,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
// For non-finalised blocks use `.subscribe_blocks()`
|
||||
let mut blocks: Subscription<Header<u32, BlakeTwo256>> =
|
||||
api.rpc().subscribe_finalized_blocks().await?;
|
||||
api.rpc().subscribe_finalized_block_headers().await?;
|
||||
|
||||
while let Some(Ok(block)) = blocks.next().await {
|
||||
println!(
|
||||
|
||||
+10
-6
@@ -31,8 +31,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to any events that occur:
|
||||
let mut event_sub = api.events().subscribe().await?;
|
||||
// Subscribe to (in this case, finalized) blocks.
|
||||
let mut block_sub = api.blocks().subscribe_finalized().await?;
|
||||
|
||||
// While this subscription is active, balance transfers are made somewhere:
|
||||
tokio::task::spawn({
|
||||
@@ -58,10 +58,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
});
|
||||
|
||||
// Our subscription will see the events emitted as a result of this:
|
||||
while let Some(events) = event_sub.next().await {
|
||||
let events = events?;
|
||||
let block_hash = events.block_hash();
|
||||
// Get each finalized block as it arrives.
|
||||
while let Some(block) = block_sub.next().await {
|
||||
let block = block?;
|
||||
|
||||
// Ask for the events for this block.
|
||||
let events = block.events().await?;
|
||||
|
||||
let block_hash = block.hash();
|
||||
|
||||
// We can dynamically decode events:
|
||||
println!(" Dynamic event details: {block_hash:?}:");
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot 0.9.29-41a9d84b152.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.29/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use futures::StreamExt;
|
||||
use subxt::{
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to all finalized blocks:
|
||||
let mut blocks_sub = api.blocks().subscribe_finalized().await?;
|
||||
|
||||
while let Some(block) = blocks_sub.next().await {
|
||||
let block = block?;
|
||||
|
||||
let block_number = block.header().number;
|
||||
let block_hash = block.hash();
|
||||
|
||||
println!("Block #{block_number}:");
|
||||
println!(" Hash: {block_hash}");
|
||||
println!(" Extrinsics:");
|
||||
|
||||
let body = block.body().await?;
|
||||
for ext in body.extrinsics() {
|
||||
let idx = ext.index();
|
||||
let events = ext.events().await?;
|
||||
let bytes_hex = format!("0x{}", hex::encode(ext.bytes()));
|
||||
|
||||
println!(" Extrinsic #{idx}:");
|
||||
println!(" Bytes: {bytes_hex}");
|
||||
println!(" Events:");
|
||||
|
||||
for evt in events.iter() {
|
||||
let evt = evt?;
|
||||
|
||||
let pallet_name = evt.pallet_name();
|
||||
let event_name = evt.variant_name();
|
||||
|
||||
println!(" {pallet_name}_{event_name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot v0.9.28-9ffe6e9e3da.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.28/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use futures::StreamExt;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use std::time::Duration;
|
||||
use subxt::{
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
/// Subscribe to all events, and then manually look through them and
|
||||
/// pluck out the events that we care about.
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to just balance transfer events, making use of `filter_events`
|
||||
// to select a single event type (note the 1-tuple) to filter out and return.
|
||||
let mut transfer_events = api
|
||||
.events()
|
||||
.subscribe()
|
||||
.await?
|
||||
.filter_events::<(polkadot::balances::events::Transfer,)>();
|
||||
|
||||
// While this subscription is active, balance transfers are made somewhere:
|
||||
tokio::task::spawn({
|
||||
let api = api.clone();
|
||||
async move {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let mut transfer_amount = 1_000_000_000;
|
||||
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
let transfer_tx = polkadot::tx().balances().transfer(
|
||||
AccountKeyring::Bob.to_account_id().into(),
|
||||
transfer_amount,
|
||||
);
|
||||
api.tx()
|
||||
.sign_and_submit_default(&transfer_tx, &signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
transfer_amount += 100_000_000;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Our subscription will see all of the transfer events emitted as a result of this:
|
||||
while let Some(transfer_event) = transfer_events.next().await {
|
||||
println!("Balance transfer event: {transfer_event:?}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright 2019-2022 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot v0.9.28-9ffe6e9e3da.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.28/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use futures::StreamExt;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use std::time::Duration;
|
||||
use subxt::{
|
||||
tx::PairSigner,
|
||||
OnlineClient,
|
||||
PolkadotConfig,
|
||||
};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
/// Subscribe to all events, and then manually look through them and
|
||||
/// pluck out the events that we care about.
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to several balance related events. If we ask for more than one event,
|
||||
// we'll be given a correpsonding tuple of `Option`'s, with exactly one
|
||||
// variant populated each time.
|
||||
let mut balance_events = api.events().subscribe().await?.filter_events::<(
|
||||
polkadot::balances::events::Withdraw,
|
||||
polkadot::balances::events::Transfer,
|
||||
polkadot::balances::events::Deposit,
|
||||
)>();
|
||||
|
||||
// While this subscription is active, balance transfers are made somewhere:
|
||||
tokio::task::spawn({
|
||||
let api = api.clone();
|
||||
async move {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let mut transfer_amount = 1_000_000_000;
|
||||
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
let transfer_tx = polkadot::tx().balances().transfer(
|
||||
AccountKeyring::Bob.to_account_id().into(),
|
||||
transfer_amount,
|
||||
);
|
||||
api.tx()
|
||||
.sign_and_submit_default(&transfer_tx, &signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
transfer_amount += 100_000_000;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Our subscription will see all of the balance events we're filtering on:
|
||||
while let Some(ev) = balance_events.next().await {
|
||||
let event_details = ev?;
|
||||
|
||||
let block_hash = event_details.block_hash;
|
||||
let event = event_details.event;
|
||||
println!("Event at {:?}:", block_hash);
|
||||
|
||||
if let (Some(withdraw), _, _) = &event {
|
||||
println!(" Withdraw event: {withdraw:?}");
|
||||
}
|
||||
if let (_, Some(transfer), _) = &event {
|
||||
println!(" Transfer event: {transfer:?}");
|
||||
}
|
||||
if let (_, _, Some(deposit)) = &event {
|
||||
println!(" Deposit event: {deposit:?}");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user