Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chain_head/tests: Check finalized block event before new block
Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
  • Loading branch information
lexnv committed Mar 22, 2023
commit b8d00c197ea3768680fbd132f45d52fe1d8f05bf
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

88 changes: 87 additions & 1 deletion client/rpc-spec-v2/src/chain_head/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::chain_head::test_utils::ChainHeadMockClient;

use super::*;
use assert_matches::assert_matches;
use codec::{Decode, Encode};
Expand Down Expand Up @@ -33,7 +35,7 @@ const CHILD_STORAGE_KEY: &[u8] = b"child";
const CHILD_VALUE: &[u8] = b"child value";

async fn get_next_event<T: serde::de::DeserializeOwned>(sub: &mut RpcSubscription) -> T {
let (event, _sub_id) = tokio::time::timeout(std::time::Duration::from_secs(1), sub.next())
let (event, _sub_id) = tokio::time::timeout(std::time::Duration::from_secs(5), sub.next())
.await
.unwrap()
.unwrap()
Expand Down Expand Up @@ -1317,3 +1319,87 @@ async fn follow_report_multiple_pruned_block() {
});
assert_eq!(event, expected);
}

#[tokio::test]
async fn follow_finalized_before_new_block() {
let builder = TestClientBuilder::new();
let backend = builder.backend();
let mut client = Arc::new(builder.build());

let client_mock = Arc::new(ChainHeadMockClient::new(client.clone()));

let api = ChainHead::new(
client_mock.clone(),
backend,
Arc::new(TaskExecutor::default()),
CHAIN_GENESIS,
MAX_PINNED_BLOCKS,
)
.into_rpc();

// Make sure the block is imported for it to be pinned.
let block_1 = client.new_block(Default::default()).unwrap().build().unwrap().block;
let block_1_hash = block_1.header.hash();
client.import(BlockOrigin::Own, block_1.clone()).await.unwrap();

let mut sub = api.subscribe("chainHead_unstable_follow", [false]).await.unwrap();

// Trigger the Finalized notification before the NewBlock one.
client_mock.trigger_finality_stream(block_1.header.clone()).await;

// Initialized must always be reported first.
let finalized_hash = client.info().finalized_hash;
let event: FollowEvent<String> = get_next_event(&mut sub).await;
let expected = FollowEvent::Initialized(Initialized {
finalized_block_hash: format!("{:?}", finalized_hash),
finalized_block_runtime: None,
runtime_updates: false,
});
assert_eq!(event, expected);

// Block 1 must be reported because we triggered the finalized notification.
let event: FollowEvent<String> = get_next_event(&mut sub).await;
let expected = FollowEvent::NewBlock(NewBlock {
block_hash: format!("{:?}", block_1_hash),
parent_block_hash: format!("{:?}", finalized_hash),
new_runtime: None,
runtime_updates: false,
});
assert_eq!(event, expected);

let event: FollowEvent<String> = get_next_event(&mut sub).await;
let expected = FollowEvent::BestBlockChanged(BestBlockChanged {
best_block_hash: format!("{:?}", block_1_hash),
});
assert_eq!(event, expected);

let event: FollowEvent<String> = get_next_event(&mut sub).await;
let expected = FollowEvent::Finalized(Finalized {
finalized_block_hashes: vec![format!("{:?}", block_1_hash)],
pruned_block_hashes: vec![],
});
assert_eq!(event, expected);

let block_2 = client.new_block(Default::default()).unwrap().build().unwrap().block;
let block_2_hash = block_2.header.hash();
client.import(BlockOrigin::Own, block_2.clone()).await.unwrap();

// Trigger NewBlock notification for block 1 and block 2.
client_mock.trigger_import_stream(block_1.header).await;
client_mock.trigger_import_stream(block_2.header).await;

let event: FollowEvent<String> = get_next_event(&mut sub).await;
let expected = FollowEvent::NewBlock(NewBlock {
block_hash: format!("{:?}", block_2_hash),
parent_block_hash: format!("{:?}", block_1_hash),
new_runtime: None,
runtime_updates: false,
});
assert_eq!(event, expected);

let event: FollowEvent<String> = get_next_event(&mut sub).await;
let expected = FollowEvent::BestBlockChanged(BestBlockChanged {
best_block_hash: format!("{:?}", block_2_hash),
});
assert_eq!(event, expected);
}