Filter one or multiple events by type from an EventSubscription (#461)

* Split events.rs into multiple files and start work on FilterEvents

* First pass filtering event(s)

* Tweak event examples to show filter_events

* cargo clippy + fmt

* consistify and tidy

* cargo fmt

* Tweak a couple of comments

* Expose phase and block_hash of filtered events, too

* cargo fmt

* expose FilteredEventDetails

* Add docs

* cargo clippy

* remove FilterEvents knowledge of EventSubscription so it's easier to unit test

* unit test filter_events

* tweak an integration test to use filter_events

* cargo fmt

* cargo clippy

* Tweak a comment

Co-authored-by: David <dvdplm@gmail.com>

Co-authored-by: David <dvdplm@gmail.com>
This commit is contained in:
James Wilson
2022-03-01 10:42:05 +00:00
committed by GitHub
parent 70d83feaba
commit 13347362d5
14 changed files with 1343 additions and 655 deletions
+8 -10
View File
@@ -78,7 +78,7 @@ async fn subscription_produces_events_each_block() -> Result<(), subxt::BasicErr
.await
.expect("events expected each block")?;
let success_event = events
.find_first_event::<system::events::ExtrinsicSuccess>()
.find_first::<system::events::ExtrinsicSuccess>()
.expect("decode error");
// Every now and then I get no bytes back for the first block events;
// I assume that this might be the case for the genesis block, so don't
@@ -100,14 +100,12 @@ async fn balance_transfer_subscription() -> Result<(), subxt::BasicError> {
let ctx = test_context().await;
// Subscribe to balance transfer events, ignoring all else.
let event_sub = ctx.api.events().subscribe().await?.filter_map(|events| {
async move {
let events = events.ok()?;
events
.find_first_event::<balances::events::Transfer>()
.ok()?
}
});
let event_sub = ctx
.api
.events()
.subscribe()
.await?
.filter_events::<(balances::events::Transfer,)>();
// Calling `.next()` on the above borrows it, and the `filter_map`
// means it's no longer `Unpin`, so we pin it on the stack:
@@ -125,7 +123,7 @@ async fn balance_transfer_subscription() -> Result<(), subxt::BasicError> {
// Wait for the next balance transfer event in our subscription stream
// and check that it lines up:
let event = event_sub.next().await.unwrap();
let event = event_sub.next().await.unwrap().unwrap().event;
assert_eq!(
event,
balances::events::Transfer {
+4 -4
View File
@@ -63,11 +63,11 @@ async fn tx_basic_transfer() -> Result<(), subxt::Error<DispatchError>> {
.wait_for_finalized_success()
.await?;
let event = events
.find_first_event::<balances::events::Transfer>()
.find_first::<balances::events::Transfer>()
.expect("Failed to decode balances::events::Transfer")
.expect("Failed to find balances::events::Transfer");
let _extrinsic_success = events
.find_first_event::<system::events::ExtrinsicSuccess>()
.find_first::<system::events::ExtrinsicSuccess>()
.expect("Failed to decode ExtrinisicSuccess")
.expect("Failed to find ExtrinisicSuccess");
@@ -125,7 +125,7 @@ async fn storage_balance_lock() -> Result<(), subxt::Error<DispatchError>> {
.await?
.wait_for_finalized_success()
.await?
.find_first_event::<system::events::ExtrinsicSuccess>()?
.find_first::<system::events::ExtrinsicSuccess>()?
.expect("No ExtrinsicSuccess Event found");
let locks = cxt
@@ -205,7 +205,7 @@ async fn transfer_implicit_subscription() {
.wait_for_finalized_success()
.await
.unwrap()
.find_first_event::<balances::events::Transfer>()
.find_first::<balances::events::Transfer>()
.expect("Can decode events")
.expect("Can find balance transfer event");
+4 -4
View File
@@ -100,13 +100,13 @@ impl ContractsTestContext {
.await?;
let code_stored = events
.find_first_event::<events::CodeStored>()?
.find_first::<events::CodeStored>()?
.ok_or_else(|| Error::Other("Failed to find a CodeStored event".into()))?;
let instantiated = events
.find_first_event::<events::Instantiated>()?
.find_first::<events::Instantiated>()?
.ok_or_else(|| Error::Other("Failed to find a Instantiated event".into()))?;
let _extrinsic_success = events
.find_first_event::<system::events::ExtrinsicSuccess>()?
.find_first::<system::events::ExtrinsicSuccess>()?
.ok_or_else(|| {
Error::Other("Failed to find a ExtrinsicSuccess event".into())
})?;
@@ -141,7 +141,7 @@ impl ContractsTestContext {
log::info!("Instantiate result: {:?}", result);
let instantiated = result
.find_first_event::<events::Instantiated>()?
.find_first::<events::Instantiated>()?
.ok_or_else(|| Error::Other("Failed to find a Instantiated event".into()))?;
Ok(instantiated.contract)
+3 -1
View File
@@ -28,7 +28,9 @@ use sp_keyring::AccountKeyring;
async fn storage_plain_lookup() -> Result<(), subxt::Error<DispatchError>> {
let ctx = test_context().await;
// Look up a plain value
// Look up a plain value. Wait long enough that we don't get the genesis block data,
// because it may have no storage associated with it.
async_std::task::sleep(std::time::Duration::from_secs(6)).await;
let entry = ctx.api.storage().timestamp().now(None).await?;
assert!(entry > 0);