diff --git a/Cargo.lock b/Cargo.lock
index fa27c09f1c12b..0cea3091e4d3f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4276,6 +4276,7 @@ dependencies = [
"cumulus-client-pov-recovery",
"cumulus-primitives-core",
"cumulus-relay-chain-interface",
+ "cumulus-relay-chain-streams",
"cumulus-test-client",
"cumulus-test-relay-sproof-builder",
"dyn-clone",
@@ -4399,6 +4400,7 @@ dependencies = [
"async-trait",
"cumulus-primitives-core",
"cumulus-relay-chain-interface",
+ "cumulus-relay-chain-streams",
"cumulus-test-client",
"futures",
"futures-timer",
@@ -4439,8 +4441,10 @@ dependencies = [
"cumulus-relay-chain-inprocess-interface",
"cumulus-relay-chain-interface",
"cumulus-relay-chain-minimal-node",
+ "cumulus-relay-chain-streams",
"futures",
"polkadot-primitives",
+ "prometheus",
"sc-client-api",
"sc-consensus",
"sc-network",
@@ -4890,6 +4894,19 @@ dependencies = [
"url",
]
+[[package]]
+name = "cumulus-relay-chain-streams"
+version = "0.7.0"
+dependencies = [
+ "cumulus-relay-chain-interface",
+ "futures",
+ "polkadot-node-subsystem",
+ "polkadot-primitives",
+ "sp-api 26.0.0",
+ "sp-consensus",
+ "tracing",
+]
+
[[package]]
name = "cumulus-test-client"
version = "0.1.0"
@@ -15816,6 +15833,7 @@ dependencies = [
"cumulus-relay-chain-interface",
"cumulus-relay-chain-minimal-node",
"cumulus-relay-chain-rpc-interface",
+ "cumulus-relay-chain-streams",
"cumulus-test-relay-sproof-builder",
"emulated-integration-tests-common",
"fork-tree",
diff --git a/Cargo.toml b/Cargo.toml
index 4f0e13418f3d2..bdb74565eb07c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -76,6 +76,7 @@ members = [
"cumulus/client/relay-chain-interface",
"cumulus/client/relay-chain-minimal-node",
"cumulus/client/relay-chain-rpc-interface",
+ "cumulus/client/relay-chain-streams",
"cumulus/client/service",
"cumulus/pallets/aura-ext",
"cumulus/pallets/collator-selection",
@@ -753,6 +754,7 @@ cumulus-relay-chain-inprocess-interface = { path = "cumulus/client/relay-chain-i
cumulus-relay-chain-interface = { path = "cumulus/client/relay-chain-interface", default-features = false }
cumulus-relay-chain-minimal-node = { path = "cumulus/client/relay-chain-minimal-node", default-features = false }
cumulus-relay-chain-rpc-interface = { path = "cumulus/client/relay-chain-rpc-interface", default-features = false }
+cumulus-relay-chain-streams = { path = "cumulus/client/relay-chain-streams", default-features = false }
cumulus-test-client = { path = "cumulus/test/client" }
cumulus-test-relay-sproof-builder = { path = "cumulus/test/relay-sproof-builder", default-features = false }
cumulus-test-runtime = { path = "cumulus/test/runtime" }
diff --git a/cumulus/client/consensus/common/Cargo.toml b/cumulus/client/consensus/common/Cargo.toml
index ae2c23c2e7295..1615215abfa73 100644
--- a/cumulus/client/consensus/common/Cargo.toml
+++ b/cumulus/client/consensus/common/Cargo.toml
@@ -41,6 +41,7 @@ polkadot-primitives = { workspace = true, default-features = true }
cumulus-client-pov-recovery = { workspace = true, default-features = true }
cumulus-primitives-core = { workspace = true, default-features = true }
cumulus-relay-chain-interface = { workspace = true, default-features = true }
+cumulus-relay-chain-streams = { workspace = true, default-features = true }
schnellru = { workspace = true }
[dev-dependencies]
diff --git a/cumulus/client/consensus/common/src/lib.rs b/cumulus/client/consensus/common/src/lib.rs
index 86d5803ad5416..20e38989c256e 100644
--- a/cumulus/client/consensus/common/src/lib.rs
+++ b/cumulus/client/consensus/common/src/lib.rs
@@ -40,6 +40,7 @@ mod tests;
pub use parent_search::*;
+pub use cumulus_relay_chain_streams::finalized_heads;
pub use parachain_consensus::run_parachain_consensus;
use level_monitor::LevelMonitor;
diff --git a/cumulus/client/consensus/common/src/parachain_consensus.rs b/cumulus/client/consensus/common/src/parachain_consensus.rs
index 8af8e1ef2bc7a..3d959aa9948d2 100644
--- a/cumulus/client/consensus/common/src/parachain_consensus.rs
+++ b/cumulus/client/consensus/common/src/parachain_consensus.rs
@@ -15,6 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see .
+use cumulus_relay_chain_streams::{finalized_heads, new_best_heads};
use sc_client_api::{
Backend, BlockBackend, BlockImportNotification, BlockchainEvents, Finalizer, UsageProvider,
};
@@ -25,12 +26,12 @@ use sp_consensus::{BlockOrigin, BlockStatus};
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
use cumulus_client_pov_recovery::{RecoveryKind, RecoveryRequest};
-use cumulus_relay_chain_interface::{RelayChainInterface, RelayChainResult};
+use cumulus_relay_chain_interface::RelayChainInterface;
-use polkadot_primitives::{Hash as PHash, Id as ParaId, OccupiedCoreAssumption};
+use polkadot_primitives::Id as ParaId;
use codec::Decode;
-use futures::{channel::mpsc::Sender, pin_mut, select, FutureExt, Stream, StreamExt};
+use futures::{channel::mpsc::Sender, pin_mut, select, FutureExt, StreamExt};
use std::sync::Arc;
@@ -120,7 +121,7 @@ where
select! {
fin = finalized_heads.next() => {
match fin {
- Some(finalized_head) =>
+ Some((finalized_head, _)) =>
handle_new_finalized_head(¶chain, finalized_head, &mut last_seen_finalized_hashes),
None => {
tracing::debug!(target: LOG_TARGET, "Stopping following finalized head.");
@@ -466,43 +467,3 @@ where
);
}
}
-
-/// Returns a stream that will yield best heads for the given `para_id`.
-async fn new_best_heads(
- relay_chain: impl RelayChainInterface + Clone,
- para_id: ParaId,
-) -> RelayChainResult>> {
- let new_best_notification_stream =
- relay_chain.new_best_notification_stream().await?.filter_map(move |n| {
- let relay_chain = relay_chain.clone();
- async move { parachain_head_at(&relay_chain, n.hash(), para_id).await.ok().flatten() }
- });
-
- Ok(new_best_notification_stream)
-}
-
-/// Returns a stream that will yield finalized heads for the given `para_id`.
-async fn finalized_heads(
- relay_chain: impl RelayChainInterface + Clone,
- para_id: ParaId,
-) -> RelayChainResult>> {
- let finality_notification_stream =
- relay_chain.finality_notification_stream().await?.filter_map(move |n| {
- let relay_chain = relay_chain.clone();
- async move { parachain_head_at(&relay_chain, n.hash(), para_id).await.ok().flatten() }
- });
-
- Ok(finality_notification_stream)
-}
-
-/// Returns head of the parachain at the given relay chain block.
-async fn parachain_head_at(
- relay_chain: &impl RelayChainInterface,
- at: PHash,
- para_id: ParaId,
-) -> RelayChainResult