mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-22 20:48:01 +00:00
Implement BlocksClient for working with blocks (#671)
* rpc: Fill in any missing finalized blocks Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * tests: Move fill blocks test to RPC location Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * events: Remove the fill in strategy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * blocks: Introduce blocks client Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * client: Enable the block API Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * blocks: Simplify `subscribe_finalized_headers` method Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * tests: Add tests for `subscribe_finalized_headers` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * blocks: Implement `subscribe_headers` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * tests: Add tests for `subscribe_headers` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * tests: Move `missing_block_headers_will_be_filled_in` to blocks Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * events: Use the new subscribe to blocks Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * blocks: Change API to return future similar to events Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * events: Use blocks API for subscribing to blocks Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update subxt/src/blocks/blocks_client.rs Co-authored-by: James Wilson <james@jsdw.me> * blocks: Simplify docs for `subscribe_finalized_headers` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * blocks: Use `PhantomDataSendSync` to avoid other bounds on `T: Config` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * blocks: Add docs for best blocks Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * blocks: Avoid one clone for the `client.rpc()` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update testing/integration-tests/src/blocks/mod.rs Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com> * blocks: Improve `subscribe_headers` doc Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: James Wilson <james@jsdw.me> Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
// 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.
|
||||
|
||||
use crate::test_context;
|
||||
use futures::StreamExt;
|
||||
|
||||
// Check that we can subscribe to non-finalized blocks.
|
||||
#[tokio::test]
|
||||
async fn non_finalized_headers_subscription() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let mut sub = api.blocks().subscribe_headers().await?;
|
||||
|
||||
// Wait for the next set of headers, and check that the
|
||||
// associated block hash is the one we just finalized.
|
||||
// (this can be a bit slow as we have to wait for finalization)
|
||||
let header = sub.next().await.unwrap()?;
|
||||
let block_hash = header.hash();
|
||||
let current_block_hash = api.rpc().block_hash(None).await?.unwrap();
|
||||
|
||||
assert_eq!(block_hash, current_block_hash);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Check that we can subscribe to finalized blocks.
|
||||
#[tokio::test]
|
||||
async fn finalized_headers_subscription() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
let mut sub = api.blocks().subscribe_finalized_headers().await?;
|
||||
|
||||
// Wait for the next set of headers, and check that the
|
||||
// associated block hash is the one we just finalized.
|
||||
// (this can be a bit slow as we have to wait for finalization)
|
||||
let header = sub.next().await.unwrap()?;
|
||||
let finalized_hash = api.rpc().finalized_head().await?;
|
||||
|
||||
assert_eq!(header.hash(), finalized_hash);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn missing_block_headers_will_be_filled_in() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
// 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 = api
|
||||
.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 = subxt::blocks::subscribe_to_block_headers_filling_in_gaps(
|
||||
ctx.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);
|
||||
}
|
||||
|
||||
assert!(last_block_number.is_some());
|
||||
Ok(())
|
||||
}
|
||||
@@ -169,57 +169,6 @@ async fn balance_transfer_subscription() -> Result<(), subxt::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn missing_block_headers_will_be_filled_in() -> Result<(), subxt::Error> {
|
||||
let ctx = test_context().await;
|
||||
let api = ctx.client();
|
||||
|
||||
// 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;
|
||||
|
||||
// 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 = api
|
||||
.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.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
|
||||
|
||||
@@ -9,6 +9,8 @@ mod codegen;
|
||||
#[cfg(test)]
|
||||
mod utils;
|
||||
|
||||
#[cfg(test)]
|
||||
mod blocks;
|
||||
#[cfg(test)]
|
||||
mod client;
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user