paritytech/subxt

`FollowStreamFinalizedHeads` doesn't work properly for non-reconnecting backend

Closed this issue · 0 comments

FollowStreamFinalizedHeads is used both for reconnecting and non-reconnecting rpc clients currently which doesn't work properly for non-reconnecting because this stream assumes that after the stop event it will continue/be restarted.

This is not true for non reconnecting backend when the stop event is fired the backend is closed. Thus, if one subscribes to finalized blocks and the backend is stopped then the stream will never return and wait forever.

So in order fix this we would need to inject a flag here whether the backend is reconnecting or not, or alternatively make FollowStreamDriverSubscription aware of this in some way.

Example to reproduce this:

Open terminal 1

substrate-node --dev
# Wait for the node to start

Open terminal 2

Run the following code

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    tracing_subscriber::fmt::init();

    let rpc = RpcClient::from_url("ws://localhost:9944".to_string()).await?;
    let backend: ChainHeadBackend<PolkadotConfig> =
        ChainHeadBackendBuilder::default().build_with_background_driver(rpc.clone());
    let api = OnlineClient::from_backend(std::sync::Arc::new(backend)).await?;

    let mut blocks_sub = api.blocks().subscribe_finalized().await?.take(100);

    while let Some(block) = blocks_sub.next().await {
        let block = block?;

        let block_number = block.number();
        let block_hash = block.hash();

        println!("Block #{block_number} ({block_hash})");
    }

    Ok(())
}

Open terminal 3

pkill substrate-node

At this point (when substrate-node is stopped) then the finalized head stream should be terminated but it isn't....