diff --git a/prdoc/pr_9878.prdoc b/prdoc/pr_9878.prdoc new file mode 100644 index 0000000000000..ddc16ca89ec09 --- /dev/null +++ b/prdoc/pr_9878.prdoc @@ -0,0 +1,9 @@ +title: 'pallet-revive: add custom addr recovery logic in `ReceiptExtractor`' +doc: +- audience: Node Dev + description: |- + 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 + bump: minor diff --git a/substrate/frame/revive/rpc/src/cli.rs b/substrate/frame/revive/rpc/src/cli.rs index 499483c47fea3..c603947e33a95 100644 --- a/substrate/frame/revive/rpc/src/cli.rs +++ b/substrate/frame/revive/rpc/src/cli.rs @@ -127,7 +127,8 @@ fn build_client( let receipt_extractor = ReceiptExtractor::new( api.clone(), - earliest_receipt_block).await?; + earliest_receipt_block, + ).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..5569a1940c109 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 @@ -66,6 +72,24 @@ impl ReceiptExtractor { pub async fn new( api: OnlineClient, earliest_receipt_block: Option, + ) -> Result { + Self::new_with_custom_address_recovery( + api, + 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. + /// + /// 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 async fn new_with_custom_address_recovery( + api: OnlineClient, + earliest_receipt_block: Option, + recover_eth_address_fn: RecoverEthAddressFn, ) -> Result { let native_to_eth_ratio = native_to_eth_ratio(&api).await?; @@ -80,7 +104,12 @@ impl ReceiptExtractor { Box::pin(fut) as Pin> }); - Ok(Self { native_to_eth_ratio, fetch_gas_price, earliest_receipt_block }) + Ok(Self { + native_to_eth_ratio, + fetch_gas_price, + earliest_receipt_block, + recover_eth_address: recover_eth_address_fn, + }) } #[cfg(test)] @@ -88,7 +117,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 +152,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 })?;