From e44a2526d8529da9706ab27bd085ab82b9171edf Mon Sep 17 00:00:00 2001 From: pgherveou Date: Fri, 7 Nov 2025 23:02:03 +0100 Subject: [PATCH 01/11] use finalized == best when auto seal is on --- .../revive/rpc/src/block_info_provider.rs | 6 ++--- substrate/frame/revive/rpc/src/cli.rs | 25 +++++++++++-------- substrate/frame/revive/rpc/src/client.rs | 20 ++++++++++----- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/substrate/frame/revive/rpc/src/block_info_provider.rs b/substrate/frame/revive/rpc/src/block_info_provider.rs index 808cd8c8a16d6..5d18b15f3fe84 100644 --- a/substrate/frame/revive/rpc/src/block_info_provider.rs +++ b/substrate/frame/revive/rpc/src/block_info_provider.rs @@ -30,7 +30,7 @@ use tokio::sync::RwLock; #[async_trait] pub trait BlockInfoProvider: Send + Sync { /// Update the latest block - async fn update_latest(&self, block: SubstrateBlock, subscription_type: SubscriptionType); + async fn update_latest(&self, block: Arc, subscription_type: SubscriptionType); /// Return the latest finalized block. async fn latest_finalized_block(&self) -> Arc; @@ -86,12 +86,12 @@ impl SubxtBlockInfoProvider { #[async_trait] impl BlockInfoProvider for SubxtBlockInfoProvider { - async fn update_latest(&self, block: SubstrateBlock, subscription_type: SubscriptionType) { + async fn update_latest(&self, block: Arc, subscription_type: SubscriptionType) { let mut latest = match subscription_type { SubscriptionType::FinalizedBlocks => self.latest_finalized_block.write().await, SubscriptionType::BestBlocks => self.latest_block.write().await, }; - *latest = Arc::new(block); + *latest = block; } async fn latest_block(&self) -> Arc { diff --git a/substrate/frame/revive/rpc/src/cli.rs b/substrate/frame/revive/rpc/src/cli.rs index 7a077f3eba94a..21b603e4c591e 100644 --- a/substrate/frame/revive/rpc/src/cli.rs +++ b/substrate/frame/revive/rpc/src/cli.rs @@ -22,7 +22,7 @@ use crate::{ LOG_TARGET, }; use clap::Parser; -use futures::{pin_mut, FutureExt}; +use futures::{future::BoxFuture, pin_mut, FutureExt}; use jsonrpsee::server::RpcModule; use sc_cli::{PrometheusParams, RpcParams, SharedParams, Signals}; use sc_service::{ @@ -229,17 +229,22 @@ pub fn run(cmd: CliCommand) -> anyhow::Result<()> { task_manager .spawn_essential_handle() .spawn("block-subscription", None, async move { - let fut1 = client.subscribe_and_cache_new_blocks(SubscriptionType::BestBlocks); - let fut2 = client.subscribe_and_cache_new_blocks(SubscriptionType::FinalizedBlocks); + let mut futures: Vec>> = + vec![Box::pin(client.subscribe_and_cache_new_blocks(SubscriptionType::BestBlocks))]; + + // When the chain has automine turned on, there will be no finalized blocks stream. + // We will define the best block as the finalized block in that case. + if !client.is_automine() { + futures.push(Box::pin( + client.subscribe_and_cache_new_blocks(SubscriptionType::FinalizedBlocks), + )) + } - let res = if let Some(index_last_n_blocks) = index_last_n_blocks { - let fut3 = client.subscribe_and_cache_blocks(index_last_n_blocks); - tokio::try_join!(fut1, fut2, fut3).map(|_| ()) - } else { - tokio::try_join!(fut1, fut2).map(|_| ()) - }; + if let Some(index_last_n_blocks) = index_last_n_blocks { + futures.push(Box::pin(client.subscribe_and_cache_blocks(index_last_n_blocks))); + } - if let Err(err) = res { + if let Err(err) = futures::future::try_join_all(futures).await { panic!("Block subscription task failed: {err:?}",) } }); diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 66d6ae09d47b4..378a013f19bb1 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -365,16 +365,24 @@ impl Client { .into_iter() .unzip(); - self.block_provider.update_latest(block, subscription_type).await; + let block = Arc::new(block); + self.block_provider.update_latest(Arc::clone(&block), subscription_type).await; + + // When automine is enabled, we consider best blocks as finalized blocks as well. + if self.automine { + self.block_provider + .update_latest(block, SubscriptionType::FinalizedBlocks) + .await; + } + self.fee_history_provider.update_fee_history(&evm_block, &receipts).await; - // Only broadcast for best blocks to avoid duplicate notifications. - match (subscription_type, &self.block_notifier) { - (SubscriptionType::BestBlocks, Some(sender)) if sender.receiver_count() > 0 => { + if let Some(sender) = &self.block_notifier { + if sender.receiver_count() > 0 { let _ = sender.send(hash); - }, - _ => {}, + } } + Ok(()) }) .await From 680624ee928615d57d5e8cdf468ff4cd301e53af Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 10:11:03 +0000 Subject: [PATCH 02/11] Update from github-actions[bot] running command 'prdoc --audience runtime_dev --bump patch' --- prdoc/pr_10252.prdoc | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 prdoc/pr_10252.prdoc diff --git a/prdoc/pr_10252.prdoc b/prdoc/pr_10252.prdoc new file mode 100644 index 0000000000000..db6ff8e3e7571 --- /dev/null +++ b/prdoc/pr_10252.prdoc @@ -0,0 +1,7 @@ +title: '[pallet-revive] set finalize = best when automine is on' +doc: +- audience: Runtime Dev + description: Make the finalized block == best block when automine is on +crates: +- name: pallet-revive-eth-rpc + bump: patch From 5cf3cd81c8bf006bf731342da99871699186150e Mon Sep 17 00:00:00 2001 From: pgherveou Date: Mon, 10 Nov 2025 11:42:28 +0100 Subject: [PATCH 03/11] rollback --- substrate/frame/revive/rpc/src/client.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 378a013f19bb1..d13d91eb8c95b 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -377,10 +377,12 @@ impl Client { self.fee_history_provider.update_fee_history(&evm_block, &receipts).await; - if let Some(sender) = &self.block_notifier { - if sender.receiver_count() > 0 { + // Only broadcast for best blocks to avoid duplicate notifications. + match (subscription_type, &self.block_notifier) { + (SubscriptionType::BestBlocks, Some(sender)) if sender.receiver_count() > 0 => { let _ = sender.send(hash); - } + }, + _ => {}, } Ok(()) From 87bd0d0b3b0bb03bbca807c09ced269b7e3fe695 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Mon, 10 Nov 2025 12:46:53 +0100 Subject: [PATCH 04/11] fix --- substrate/frame/revive/rpc/src/cli.rs | 14 ++++---------- substrate/frame/revive/rpc/src/client.rs | 7 ++++++- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/substrate/frame/revive/rpc/src/cli.rs b/substrate/frame/revive/rpc/src/cli.rs index 21b603e4c591e..6016215a32f2d 100644 --- a/substrate/frame/revive/rpc/src/cli.rs +++ b/substrate/frame/revive/rpc/src/cli.rs @@ -229,16 +229,10 @@ pub fn run(cmd: CliCommand) -> anyhow::Result<()> { task_manager .spawn_essential_handle() .spawn("block-subscription", None, async move { - let mut futures: Vec>> = - vec![Box::pin(client.subscribe_and_cache_new_blocks(SubscriptionType::BestBlocks))]; - - // When the chain has automine turned on, there will be no finalized blocks stream. - // We will define the best block as the finalized block in that case. - if !client.is_automine() { - futures.push(Box::pin( - client.subscribe_and_cache_new_blocks(SubscriptionType::FinalizedBlocks), - )) - } + let mut futures: Vec>> = vec![ + Box::pin(client.subscribe_and_cache_new_blocks(SubscriptionType::BestBlocks)), + Box::pin(client.subscribe_and_cache_new_blocks(SubscriptionType::FinalizedBlocks)), + ]; if let Some(index_last_n_blocks) = index_last_n_blocks { futures.push(Box::pin(client.subscribe_and_cache_blocks(index_last_n_blocks))); diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index d13d91eb8c95b..495c6690e9d0a 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -356,6 +356,11 @@ impl Client { ) -> Result<(), ClientError> { log::info!(target: LOG_TARGET, "🔌 Subscribing to new blocks ({subscription_type:?})"); self.subscribe_new_blocks(subscription_type, |block| async { + // Skip finalized block processing when automine is enabled. + if matches!(subscription_type, SubscriptionType::FinalizedBlocks) && self.automine { + return Ok(()) + } + let hash = block.hash(); let evm_block = self.runtime_api(hash).eth_block().await?; let (_, receipts): (Vec<_>, Vec<_>) = self @@ -368,7 +373,7 @@ impl Client { let block = Arc::new(block); self.block_provider.update_latest(Arc::clone(&block), subscription_type).await; - // When automine is enabled, we consider best blocks as finalized blocks as well. + // If automine is enabled, set the finalized block to be the best block. if self.automine { self.block_provider .update_latest(block, SubscriptionType::FinalizedBlocks) From 5665a7611a3781525b2c9045a0ca4070ca8cfe65 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Mon, 10 Nov 2025 13:24:17 +0000 Subject: [PATCH 05/11] fixes --- substrate/frame/revive/rpc/src/block_info_provider.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/revive/rpc/src/block_info_provider.rs b/substrate/frame/revive/rpc/src/block_info_provider.rs index 5d18b15f3fe84..5c0689b84a5d0 100644 --- a/substrate/frame/revive/rpc/src/block_info_provider.rs +++ b/substrate/frame/revive/rpc/src/block_info_provider.rs @@ -172,7 +172,7 @@ pub mod test { impl BlockInfoProvider for MockBlockInfoProvider { async fn update_latest( &self, - _block: SubstrateBlock, + _block: Arc, _subscription_type: SubscriptionType, ) { } From cafaca539d682adaa5949364c61d4d0a856d2e49 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 11 Nov 2025 09:01:23 +0100 Subject: [PATCH 06/11] try suggestion --- substrate/frame/revive/dev-node/node/src/service.rs | 2 +- substrate/frame/revive/rpc/src/client.rs | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/substrate/frame/revive/dev-node/node/src/service.rs b/substrate/frame/revive/dev-node/node/src/service.rs index 3e06fff574bb4..efd578dbea2ef 100644 --- a/substrate/frame/revive/dev-node/node/src/service.rs +++ b/substrate/frame/revive/dev-node/node/src/service.rs @@ -221,7 +221,7 @@ pub fn new_full::Ha create_inherent_data_providers: timestamp_provider, }; - let authorship_future = sc_consensus_manual_seal::run_instant_seal(params); + let authorship_future = sc_consensus_manual_seal::run_instant_seal_and_finalize(params); task_manager.spawn_essential_handle().spawn_blocking( "instant-seal", diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 495c6690e9d0a..7023161338663 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -356,11 +356,6 @@ impl Client { ) -> Result<(), ClientError> { log::info!(target: LOG_TARGET, "🔌 Subscribing to new blocks ({subscription_type:?})"); self.subscribe_new_blocks(subscription_type, |block| async { - // Skip finalized block processing when automine is enabled. - if matches!(subscription_type, SubscriptionType::FinalizedBlocks) && self.automine { - return Ok(()) - } - let hash = block.hash(); let evm_block = self.runtime_api(hash).eth_block().await?; let (_, receipts): (Vec<_>, Vec<_>) = self @@ -372,14 +367,6 @@ impl Client { let block = Arc::new(block); self.block_provider.update_latest(Arc::clone(&block), subscription_type).await; - - // If automine is enabled, set the finalized block to be the best block. - if self.automine { - self.block_provider - .update_latest(block, SubscriptionType::FinalizedBlocks) - .await; - } - self.fee_history_provider.update_fee_history(&evm_block, &receipts).await; // Only broadcast for best blocks to avoid duplicate notifications. From d51784b3319bcfa2f9f70e16be18d2d8c7cdb929 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 11 Nov 2025 09:02:49 +0100 Subject: [PATCH 07/11] change prdoc --- prdoc/pr_10252.prdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prdoc/pr_10252.prdoc b/prdoc/pr_10252.prdoc index db6ff8e3e7571..6343665baadb4 100644 --- a/prdoc/pr_10252.prdoc +++ b/prdoc/pr_10252.prdoc @@ -1,7 +1,7 @@ title: '[pallet-revive] set finalize = best when automine is on' doc: - audience: Runtime Dev - description: Make the finalized block == best block when automine is on + description: Fix finalized block in revive-dev-node with instant-seal crates: - name: pallet-revive-eth-rpc bump: patch From 09a09da789d2fd77f1f9178856fd997f3c0bd396 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Tue, 11 Nov 2025 09:05:45 +0100 Subject: [PATCH 08/11] Apply suggestion from @pgherveou --- substrate/frame/revive/rpc/src/client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 7023161338663..7635e9662c3a2 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -376,7 +376,6 @@ impl Client { }, _ => {}, } - Ok(()) }) .await From ac117a994caa63bfa54face2a340edbd0fb3ba71 Mon Sep 17 00:00:00 2001 From: PG Herveou Date: Tue, 11 Nov 2025 09:08:31 +0100 Subject: [PATCH 09/11] Apply suggestion from @pgherveou --- prdoc/pr_10252.prdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prdoc/pr_10252.prdoc b/prdoc/pr_10252.prdoc index 6343665baadb4..6490d56bcf326 100644 --- a/prdoc/pr_10252.prdoc +++ b/prdoc/pr_10252.prdoc @@ -1,4 +1,4 @@ -title: '[pallet-revive] set finalize = best when automine is on' +title: '[pallet-revive] use run_instant_seal_and_finalize in dev-node' doc: - audience: Runtime Dev description: Fix finalized block in revive-dev-node with instant-seal From bb42ff150448f91bf548263736fca10f62515310 Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 11 Nov 2025 09:09:58 +0100 Subject: [PATCH 10/11] fix --- substrate/frame/revive/rpc/src/client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 7635e9662c3a2..721b514632561 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -365,7 +365,6 @@ impl Client { .into_iter() .unzip(); - let block = Arc::new(block); self.block_provider.update_latest(Arc::clone(&block), subscription_type).await; self.fee_history_provider.update_fee_history(&evm_block, &receipts).await; From 6e6227d3ba630f9e6b720a79fbb8a6438d3cab8d Mon Sep 17 00:00:00 2001 From: pgherveou Date: Tue, 11 Nov 2025 09:33:23 +0100 Subject: [PATCH 11/11] fix build --- substrate/frame/revive/rpc/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs index 721b514632561..2557e9b97d16b 100644 --- a/substrate/frame/revive/rpc/src/client.rs +++ b/substrate/frame/revive/rpc/src/client.rs @@ -365,7 +365,7 @@ impl Client { .into_iter() .unzip(); - self.block_provider.update_latest(Arc::clone(&block), subscription_type).await; + self.block_provider.update_latest(Arc::new(block), subscription_type).await; self.fee_history_provider.update_fee_history(&evm_block, &receipts).await; // Only broadcast for best blocks to avoid duplicate notifications.