From 75d60bb4cc7a0e8dec0ab47d460bc9547a73ff76 Mon Sep 17 00:00:00 2001 From: Iulian Barbu Date: Tue, 30 Sep 2025 08:41:16 +0000 Subject: [PATCH 1/7] pallet-revive: add custom addr recovery... ...in the receipt extractor Signed-off-by: Iulian Barbu --- substrate/frame/revive/rpc/src/cli.rs | 4 ++- .../frame/revive/rpc/src/receipt_extractor.rs | 34 ++++++++++++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/substrate/frame/revive/rpc/src/cli.rs b/substrate/frame/revive/rpc/src/cli.rs index 499483c47fea3..449b0387f168a 100644 --- a/substrate/frame/revive/rpc/src/cli.rs +++ b/substrate/frame/revive/rpc/src/cli.rs @@ -127,7 +127,9 @@ fn build_client( let receipt_extractor = ReceiptExtractor::new( api.clone(), - earliest_receipt_block).await?; + earliest_receipt_block, + None, + ).await?; let receipt_provider = ReceiptProvider::new( pool, diff --git a/substrate/frame/revive/rpc/src/receipt_extractor.rs b/substrate/frame/revive/rpc/src/receipt_extractor.rs index 0e5273d4f7501..1c838fe295666 100644 --- a/substrate/frame/revive/rpc/src/receipt_extractor.rs +++ b/substrate/frame/revive/rpc/src/receipt_extractor.rs @@ -23,7 +23,7 @@ use crate::{ transaction_payment::events::TransactionFeePaid, SrcChainConfig, }, - ClientError, LOG_TARGET, + ClientError, H160, LOG_TARGET, }; use futures::{stream, StreamExt}; use pallet_revive::{ @@ -37,6 +37,9 @@ use subxt::OnlineClient; type FetchGasPriceFn = Arc< dyn Fn(H256) -> Pin> + Send>> + Send + Sync, >; + +type RecoverEthAddressFn = Arc Result + Send + Sync>; + /// Utility to extract receipts from extrinsics. #[derive(Clone)] pub struct ReceiptExtractor { @@ -48,6 +51,9 @@ pub struct ReceiptExtractor { /// Earliest block number to consider when searching for transaction receipts. earliest_receipt_block: Option, + + /// Recover the ethereum address from a transaction signature. + recover_eth_address: RecoverEthAddressFn, } /// Fetch the native_to_eth_ratio @@ -63,9 +69,14 @@ impl ReceiptExtractor { } /// Create a new `ReceiptExtractor` with the given native to eth ratio. + /// + /// The Ethereum address recovery function that can be set as a parameter + /// for the constructor can be set to `None` when the + /// [`TransactionSigned::recover_eth_address()`] logic must be used. pub async fn new( api: OnlineClient, earliest_receipt_block: Option, + recover_eth_address_fn: Option, ) -> Result { let native_to_eth_ratio = native_to_eth_ratio(&api).await?; @@ -80,7 +91,15 @@ impl ReceiptExtractor { Box::pin(fut) as Pin> }); - Ok(Self { native_to_eth_ratio, fetch_gas_price, earliest_receipt_block }) + let recover_eth_address = recover_eth_address_fn.unwrap_or_else(|| { + Arc::new(|signed_tx: &TransactionSigned| signed_tx.recover_eth_address()) + }); + Ok(Self { + native_to_eth_ratio, + fetch_gas_price, + earliest_receipt_block, + recover_eth_address, + }) } #[cfg(test)] @@ -88,7 +107,14 @@ impl ReceiptExtractor { let fetch_gas_price = Arc::new(|_| Box::pin(std::future::ready(Ok(U256::from(1000)))) as Pin>); - Self { native_to_eth_ratio: 1_000_000, fetch_gas_price, earliest_receipt_block: None } + Self { + native_to_eth_ratio: 1_000_000, + fetch_gas_price, + earliest_receipt_block: None, + recover_eth_address: Arc::new(|signed_tx: &TransactionSigned| { + signed_tx.recover_eth_address() + }), + } } /// Extract a [`TransactionSigned`] and a [`ReceiptInfo`] from an extrinsic. @@ -116,7 +142,7 @@ impl ReceiptExtractor { let signed_tx = TransactionSigned::decode(&call.payload).map_err(|_| ClientError::TxDecodingFailed)?; - let from = signed_tx.recover_eth_address().map_err(|_| { + let from = (self.recover_eth_address)(&signed_tx).map_err(|_| { log::error!(target: LOG_TARGET, "Failed to recover eth address from signed tx"); ClientError::RecoverEthAddressFailed })?; From d66afdbeafd5e2fab2bf0d301ad59cdfbe57a38f Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 10:33:42 +0000 Subject: [PATCH 2/7] Update from github-actions[bot] running command 'prdoc' --- prdoc/pr_9878.prdoc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 prdoc/pr_9878.prdoc diff --git a/prdoc/pr_9878.prdoc b/prdoc/pr_9878.prdoc new file mode 100644 index 0000000000000..3c9f208820992 --- /dev/null +++ b/prdoc/pr_9878.prdoc @@ -0,0 +1,18 @@ +title: 'pallet-revive: add custom addr recovery logic in `ReceiptExtractor`' +doc: +- audience: Todo + description: |- + # Description + + `ReceiptExtractor` parses blocks and associated transactions in pallet-revive-eth-rpc and is useful for a range of Ethereum node RPCs. When the transactions are impersonated, they are based on a fake signature, which can't be used with the production eth address recovery logic. The recovery logic must be customised in cases where we impersonate transactions, so this PR adds a custom function on the `ReceiptExtractor` that if set to `None` it defaults to the production eth address recovery. + + ## Integration + + Developers using pallet-revive-eth-rpc as a lib should instantiate the `ReceiptExtractor` in a custom way if impersonation usecases must be supported, otherwhise should set the constructor parameter to `None`. + + ## Review Notes + + Relevant in context of https://github.com/paritytech/foundry-polkadot/issues/242, to implement anvil-polkadot impersonation. +crates: +- name: pallet-revive-eth-rpc + bump: major From 8c54caa369da75c01c62ffd3d887b61c179a63f1 Mon Sep 17 00:00:00 2001 From: Iulian Barbu Date: Tue, 30 Sep 2025 10:35:43 +0000 Subject: [PATCH 3/7] prdoc: update audience & description Signed-off-by: Iulian Barbu --- prdoc/pr_9878.prdoc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/prdoc/pr_9878.prdoc b/prdoc/pr_9878.prdoc index 3c9f208820992..c7286f36ce93f 100644 --- a/prdoc/pr_9878.prdoc +++ b/prdoc/pr_9878.prdoc @@ -1,18 +1,11 @@ title: 'pallet-revive: add custom addr recovery logic in `ReceiptExtractor`' doc: -- audience: Todo +- audience: Node Dev description: |- - # Description - `ReceiptExtractor` parses blocks and associated transactions in pallet-revive-eth-rpc and is useful for a range of Ethereum node RPCs. When the transactions are impersonated, they are based on a fake signature, which can't be used with the production eth address recovery logic. The recovery logic must be customised in cases where we impersonate transactions, so this PR adds a custom function on the `ReceiptExtractor` that if set to `None` it defaults to the production eth address recovery. - ## Integration - Developers using pallet-revive-eth-rpc as a lib should instantiate the `ReceiptExtractor` in a custom way if impersonation usecases must be supported, otherwhise should set the constructor parameter to `None`. - ## Review Notes - - Relevant in context of https://github.com/paritytech/foundry-polkadot/issues/242, to implement anvil-polkadot impersonation. crates: - name: pallet-revive-eth-rpc bump: major From 6dc71ce7b6637c0076d3a4dfc914ad344e8515e2 Mon Sep 17 00:00:00 2001 From: Iulian Barbu Date: Tue, 30 Sep 2025 14:04:18 +0000 Subject: [PATCH 4/7] prdoc: simplify description Signed-off-by: Iulian Barbu --- prdoc/pr_9878.prdoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/prdoc/pr_9878.prdoc b/prdoc/pr_9878.prdoc index c7286f36ce93f..a9ad4978dc386 100644 --- a/prdoc/pr_9878.prdoc +++ b/prdoc/pr_9878.prdoc @@ -2,9 +2,7 @@ title: 'pallet-revive: add custom addr recovery logic in `ReceiptExtractor`' doc: - audience: Node Dev description: |- - `ReceiptExtractor` parses blocks and associated transactions in pallet-revive-eth-rpc and is useful for a range of Ethereum node RPCs. When the transactions are impersonated, they are based on a fake signature, which can't be used with the production eth address recovery logic. The recovery logic must be customised in cases where we impersonate transactions, so this PR adds a custom function on the `ReceiptExtractor` that if set to `None` it defaults to the production eth address recovery. - - Developers using pallet-revive-eth-rpc as a lib should instantiate the `ReceiptExtractor` in a custom way if impersonation usecases must be supported, otherwhise should set the constructor parameter to `None`. + Add ability to customize pallet-revive-eth-rpc's `ReceiptExtractor` ethereum address recovery logic, used when parsing through blocks' transactions. crates: - name: pallet-revive-eth-rpc From 0c770bc3e16508f210695a3690ba43d31fd2f212 Mon Sep 17 00:00:00 2001 From: Iulian Barbu Date: Tue, 30 Sep 2025 14:15:39 +0000 Subject: [PATCH 5/7] pallet-revive: added a new ReceiptExtractor constructor Signed-off-by: Iulian Barbu --- substrate/frame/revive/rpc/src/cli.rs | 1 - .../frame/revive/rpc/src/receipt_extractor.rs | 27 ++++++++++++------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/substrate/frame/revive/rpc/src/cli.rs b/substrate/frame/revive/rpc/src/cli.rs index 449b0387f168a..c603947e33a95 100644 --- a/substrate/frame/revive/rpc/src/cli.rs +++ b/substrate/frame/revive/rpc/src/cli.rs @@ -128,7 +128,6 @@ fn build_client( let receipt_extractor = ReceiptExtractor::new( api.clone(), earliest_receipt_block, - None, ).await?; let receipt_provider = ReceiptProvider::new( diff --git a/substrate/frame/revive/rpc/src/receipt_extractor.rs b/substrate/frame/revive/rpc/src/receipt_extractor.rs index 1c838fe295666..181a44cbc3d6b 100644 --- a/substrate/frame/revive/rpc/src/receipt_extractor.rs +++ b/substrate/frame/revive/rpc/src/receipt_extractor.rs @@ -69,15 +69,27 @@ impl ReceiptExtractor { } /// Create a new `ReceiptExtractor` with the given native to eth ratio. - /// - /// The Ethereum address recovery function that can be set as a parameter - /// for the constructor can be set to `None` when the - /// [`TransactionSigned::recover_eth_address()`] logic must be used. pub async fn new( api: OnlineClient, earliest_receipt_block: Option, - recover_eth_address_fn: Option, ) -> Result { + Self::new_with_custom_address_recovery( + api, + earliest_receipt_block, + Arc::new(|signed_tx: &TransactionSigned| signed_tx.recover_eth_address()), + ) + } + + /// Create a new `ReceiptExtractor` with the given native to eth ratio. + /// + /// Specify also a custom Ethereum address recovery logic. + /// Use `ReceiptExtractor::new` if the default Ethereum address recovery + /// logic ([`TransactionSigned::recover_eth_address`] based) is enough. + pub fn new_with_custom_address_recovery( + api: OnlineClient, + earliest_receipt_block: Option, + recover_eth_address_fn: RecoverEthAddressFn, + ) -> Self { let native_to_eth_ratio = native_to_eth_ratio(&api).await?; let fetch_gas_price = Arc::new(move |block_hash| { @@ -91,14 +103,11 @@ impl ReceiptExtractor { Box::pin(fut) as Pin> }); - let recover_eth_address = recover_eth_address_fn.unwrap_or_else(|| { - Arc::new(|signed_tx: &TransactionSigned| signed_tx.recover_eth_address()) - }); Ok(Self { native_to_eth_ratio, fetch_gas_price, earliest_receipt_block, - recover_eth_address, + recover_eth_address: recover_eth_address_fn, }) } From e05b74c9706304d3eaff4a0c7bb0889dcdd37029 Mon Sep 17 00:00:00 2001 From: Iulian Barbu Date: Tue, 30 Sep 2025 15:13:08 +0000 Subject: [PATCH 6/7] pallet-revive: fix ReceiptExtractor constructor Signed-off-by: Iulian Barbu --- substrate/frame/revive/rpc/src/receipt_extractor.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/substrate/frame/revive/rpc/src/receipt_extractor.rs b/substrate/frame/revive/rpc/src/receipt_extractor.rs index 181a44cbc3d6b..5569a1940c109 100644 --- a/substrate/frame/revive/rpc/src/receipt_extractor.rs +++ b/substrate/frame/revive/rpc/src/receipt_extractor.rs @@ -78,6 +78,7 @@ impl ReceiptExtractor { earliest_receipt_block, Arc::new(|signed_tx: &TransactionSigned| signed_tx.recover_eth_address()), ) + .await } /// Create a new `ReceiptExtractor` with the given native to eth ratio. @@ -85,11 +86,11 @@ impl ReceiptExtractor { /// Specify also a custom Ethereum address recovery logic. /// Use `ReceiptExtractor::new` if the default Ethereum address recovery /// logic ([`TransactionSigned::recover_eth_address`] based) is enough. - pub fn new_with_custom_address_recovery( + pub async fn new_with_custom_address_recovery( api: OnlineClient, earliest_receipt_block: Option, recover_eth_address_fn: RecoverEthAddressFn, - ) -> Self { + ) -> Result { let native_to_eth_ratio = native_to_eth_ratio(&api).await?; let fetch_gas_price = Arc::new(move |block_hash| { From 11fe19272499b25a3856fb6e606401120e3afd55 Mon Sep 17 00:00:00 2001 From: Iulian Barbu <14218860+iulianbarbu@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:15:10 +0300 Subject: [PATCH 7/7] Update prdoc/pr_9878.prdoc --- prdoc/pr_9878.prdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prdoc/pr_9878.prdoc b/prdoc/pr_9878.prdoc index a9ad4978dc386..ddc16ca89ec09 100644 --- a/prdoc/pr_9878.prdoc +++ b/prdoc/pr_9878.prdoc @@ -6,4 +6,4 @@ doc: crates: - name: pallet-revive-eth-rpc - bump: major + bump: minor