Return events from blocks skipped over during Finalization, too (#473)

* make subscription stream generic in EventSubscription

* rename to EventSub/FinalizedEventSub

* wip fix some lifetimes so that event sub can depend on client in stream

* Cargo fmt + comment tweaks

* Add another comment

* factor out prev block header fetching into a separate function to tidy

* add a comment

* remove ListOrValue as it's unused

* Into<u128> on BlockNumber to simplify things

* clippy

* Fix an example and clippy

* simplify iterator now we are Into<u128>

* Into<u64> instead because it needs serializing, and test core logic

* Tweak missing block test to fill in >=2 holes

* tweak a comment
This commit is contained in:
James Wilson
2022-03-10 10:24:24 +00:00
committed by GitHub
parent a091d2b756
commit 4144a769d5
9 changed files with 206 additions and 59 deletions
+2 -2
View File
@@ -27849,13 +27849,13 @@ pub mod api {
}
pub async fn subscribe(
&self,
) -> Result<::subxt::events::EventSubscription<'a, T, Event>, ::subxt::BasicError>
) -> Result<::subxt::events::EventSubscription<'a, ::subxt::events::EventSub<T::Header>, T, Event>, ::subxt::BasicError>
{
::subxt::events::subscribe::<T, Event>(self.client).await
}
pub async fn subscribe_finalized(
&self,
) -> Result<::subxt::events::EventSubscription<'a, T, Event>, ::subxt::BasicError>
) -> Result<::subxt::events::EventSubscription<'a, ::subxt::events::FinalizedEventSub<'a, T::Header>, T, Event>, ::subxt::BasicError>
{
::subxt::events::subscribe_finalized::<T, Event>(self.client).await
}
+52
View File
@@ -136,6 +136,58 @@ async fn balance_transfer_subscription() -> Result<(), subxt::BasicError> {
Ok(())
}
#[async_std::test]
async fn missing_block_headers_will_be_filled_in() -> Result<(), subxt::BasicError> {
// This function is not publically available to use, but contains
// the key logic for filling in missing blocks, so we want to test it.
// This is used in `subscribe_finalized` to ensure no block headers are
// missed.
use subxt::events::subscribe_to_block_headers_filling_in_gaps;
let ctx = test_context().await;
// Manually subscribe to the next 6 finalized block headers, but deliberately
// filter out some in the middle so we get back b _ _ b _ b. This guarantees
// that there will be some gaps, even if there aren't any from the subscription.
let some_finalized_blocks = ctx
.api
.client
.rpc()
.subscribe_finalized_blocks()
.await?
.enumerate()
.take(6)
.filter(|(n, _)| {
let n = *n;
async move { n == 0 || n == 3 || n == 5 }
})
.map(|(_, h)| h);
// This should spot any gaps in the middle and fill them back in.
let all_finalized_blocks = subscribe_to_block_headers_filling_in_gaps(
&ctx.api.client,
None,
some_finalized_blocks,
);
futures::pin_mut!(all_finalized_blocks);
// Iterate the block headers, making sure we get them all in order.
let mut last_block_number = None;
while let Some(header) = all_finalized_blocks.next().await {
let header = header?;
use sp_runtime::traits::Header;
let block_number: u128 = (*header.number()).into();
if let Some(last) = last_block_number {
assert_eq!(last + 1, block_number);
}
last_block_number = Some(block_number);
}
Ok(())
}
// This is just a compile-time check that we can subscribe to events in
// a context that requires the event subscription/filtering to be Send-able.
// We test a typical use of EventSubscription and FilterEvents. We don't need