3

I'm having trouble using subxt to query for an historical event. Not sure what manipulation is necessary to filter for the specific events I want.

In my case, I want to query for a BasicOutboundChannel.Committed event at block X.

None of the examples in the subxt repo show how to do this, as they only read events emitted by subscriptions (a different code path).

My client code so far:

#[subxt::subxt(runtime_metadata_path = "metadata.scale")]
pub mod runtime { }

use subxt::{ClientBuilder, DefaultConfig, SubstrateExtrinsicParams};
use subxt::sp_core::H256;
use hex_literal::hex;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api = ClientBuilder::new()
    .set_url("ws://localhost:11144")
    .build()
    .await?
    .to_runtime_api::<runtime::RuntimeApi<DefaultConfig, SubstrateExtrinsicParams<DefaultConfig>>>();

    let hash: Option<H256> = Some(hex!("4f1a8ead12dc09b449e8a4b37fb1de21b3a2b1841a1df037194bf0e1bc156285").into());

    let events = api.storage().system().events(hash).await?;

    // NOTE: This fails to compile. How can I test that events[0] is a 'Committed' event?
    let event: runtime::basic_outbound_channel::events::Committed = events[0].event.try_into()?;

    println!("{:?}", event);

    Ok(())
}

error message:

the trait bound `basic_outbound_channel::events::Committed: From<snowbase_runtime::Event>` is not satisfied
required because of the requirements on the impl of `Into<basic_outbound_channel::events::Committed>` for `snowbase_runtime::Event`
required because of the requirements on the impl of `TryFrom<snowbase_runtime::Event>` for `basic_outbound_channel::events::Committed`
required because of the requirements on the impl of `TryInto<basic_outbound_channel::events::Committed>` for `snowbase_runtime::Event`rustcE0277

1 Answer 1

3

Eventually found the right incantation for querying whether a historical event was emitted:

#[subxt::subxt(runtime_metadata_path = "metadata.scale")]
pub mod runtime { }

use subxt::{ClientBuilder, DefaultConfig, SubstrateExtrinsicParams};
use subxt::sp_core::H256;
use hex_literal::hex;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api = ClientBuilder::new()
    .set_url("ws://localhost:11144")
    .build()
    .await?
    .to_runtime_api::<runtime::RuntimeApi<DefaultConfig, SubstrateExtrinsicParams<DefaultConfig>>>();

    let hash: Option<H256> = Some(hex!("4f1a8ead12dc09b449e8a4b37fb1de21b3a2b1841a1df037194bf0e1bc156285").into());

    let events = api.storage().system().events(hash).await?;

    if let runtime::runtime_types::snowbase_runtime::Event::BasicOutboundChannel(ev) = &events[0].event {
        if let runtime::runtime_types::snowbridge_basic_channel::outbound::pallet::Event::Committed { .. }  = ev {
            println!("found Committed event");
        }
    }

    Ok(())
}
2
  • I've done the same for now but just to note that we probably should not be hardcoding the key as hex but getting subxt to generate the key.
    – Squirrel
    May 26, 2022 at 8:19
  • Two things to mention here briefly: 1) The interface has changed a fair bit in "modern" Subxt, and on master you can roughly call api.blocks().at(block_hash).await?.events() to get all events on some "historic" block. 2) Subxt doesn't support asking for blocks that pre-date the latest node runtime (or more accurately, it might work or might not depending on the runtime changes). Just something to keep in mind :)
    – jsdw
    Nov 5, 2022 at 22:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.