From f5950c9cfc28d96d23f91fe45a1d7f6b7e9dc787 Mon Sep 17 00:00:00 2001 From: Ljiacheng Date: Mon, 8 Sep 2025 11:10:40 +0800 Subject: [PATCH 1/3] use StorageMap for Pending transactions --- frame/ethereum/src/lib.rs | 46 +++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index c5358f2a3c..88004ce7d2 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -222,7 +222,7 @@ pub mod pallet { UniqueSaturatedInto::::unique_saturated_into(to_remove), )); } - Pending::::kill(); + // Pending::::kill(); } fn on_initialize(_: T::BlockNumber) -> Weight { @@ -324,6 +324,13 @@ pub mod pallet { pub(super) type Pending = StorageValue<_, Vec<(Transaction, TransactionStatus, Receipt)>, ValueQuery>; + #[pallet::storage] + pub(super) type PendingIndex = StorageValue<_, u32, ValueQuery>; + + #[pallet::storage] + pub(super) type PendingMap = + StorageMap<_, Twox64Concat, u32, (Transaction, TransactionStatus, Receipt)>; + /// The current Ethereum block. #[pallet::storage] pub type CurrentBlock = StorageValue<_, ethereum::BlockV2>; @@ -406,14 +413,15 @@ impl Pallet { let total_timer = std::time::Instant::now(); #[cfg(feature = "std")] let tx_timer = std::time::Instant::now(); - let pending_transactions = Pending::::take(); - let mut transactions = Vec::with_capacity(pending_transactions.len()); - let mut statuses = Vec::with_capacity(pending_transactions.len()); - let mut receipts = Vec::with_capacity(pending_transactions.len()); + let pending_index = PendingIndex::::take(); + // let pending_transactions = Pending::::take(); + let mut transactions = Vec::with_capacity(pending_index as usize); + let mut statuses = Vec::with_capacity(pending_index as usize); + let mut receipts = Vec::with_capacity(pending_index as usize); let mut logs_bloom = Bloom::default(); let mut cumulative_gas_used = U256::zero(); - for transaction in pending_transactions { - let (transaction, status, receipt) = transaction; + for i in 0..pending_index { + let (transaction, status, receipt) = PendingMap::::take(i).unwrap(); transactions.push(transaction); statuses.push(status); receipts.push(receipt.clone()); @@ -425,6 +433,19 @@ impl Pallet { cumulative_gas_used = used_gas; Self::logs_bloom(logs, &mut logs_bloom); } + // for transaction in pending_transactions { + // let (transaction, status, receipt) = transaction; + // transactions.push(transaction); + // statuses.push(status); + // receipts.push(receipt.clone()); + // let (logs, used_gas) = match receipt { + // Receipt::Legacy(d) | Receipt::EIP2930(d) | Receipt::EIP1559(d) => { + // (d.logs.clone(), d.used_gas) + // } + // }; + // cumulative_gas_used = used_gas; + // Self::logs_bloom(logs, &mut logs_bloom); + // } #[cfg(feature = "std")] let tx_time = tx_timer.elapsed().as_micros(); @@ -606,9 +627,10 @@ impl Pallet { ) -> DispatchResultWithPostInfo { let (to, _, info) = Self::execute(source, fee_source, &transaction, None)?; - let pending = Pending::::get(); + let pending_index = PendingIndex::::get(); + // let pending = Pending::::get(); let transaction_hash = transaction.hash(); - let transaction_index = pending.len() as u32; + let transaction_index = pending_index; let (reason, status, weight_info, used_gas, dest, extra_data) = match info { CallOrCreateInfo::Call(info) => ( @@ -685,7 +707,7 @@ impl Pallet { }; let logs_bloom = status.logs_bloom; let logs = status.clone().logs; - let cumulative_gas_used = if let Some((_, _, receipt)) = pending.last() { + let cumulative_gas_used = if let Some((_, _, receipt)) = PendingMap::::get(pending_index.saturating_sub(1)) { match receipt { Receipt::Legacy(d) | Receipt::EIP2930(d) | Receipt::EIP1559(d) => { d.used_gas.saturating_add(used_gas.effective) @@ -716,7 +738,9 @@ impl Pallet { } }; - Pending::::append((transaction, status, receipt)); + PendingMap::::insert(pending_index, (transaction, status, receipt)); + PendingIndex::::put(pending_index + 1); + // Pending::::append((transaction, status, receipt)); Self::deposit_event(Event::Executed { from: source, From 864045b933536105fab0f9d98d222d9d6f903000 Mon Sep 17 00:00:00 2001 From: helin6 <577522102@qq.com> Date: Tue, 9 Sep 2025 14:48:15 +0800 Subject: [PATCH 2/3] feature DispatchPrecompile --- frame/ethereum/src/lib.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index 88004ce7d2..2e29f3dc3f 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -197,6 +197,8 @@ pub mod pallet { type PostLogContent: Get; /// The maximum length of the extra data in the Executed event. type ExtraDataLength: Get; + /// Dispatch precompile call directly. + type DispatchPrecompile: DispatchPrecompile; } #[pallet::hooks] @@ -288,13 +290,17 @@ pub mod pallet { source: H160, ) -> DispatchResultWithPostInfo { // let source = ensure_ethereum_transaction(origin)?; - // Disable transact functionality if PreLog exist. - assert!( - fp_consensus::find_pre_log(&frame_system::Pallet::::digest()).is_err(), - "pre log already exists; block is invalid", - ); - - Self::apply_validated_transaction(source.clone(), source, transaction, false) + match T::DispatchPrecompile::dispatch_precompile_call(&transaction, &source)? { + Some(_) => Ok(().into()), + None => { + // Disable transact functionality if PreLog exist. + assert!( + fp_consensus::find_pre_log(&frame_system::Pallet::::digest()).is_err(), + "pre log already exists; block is invalid", + ); + Self::apply_validated_transaction(source.clone(), source, transaction, false) + }, + } } } @@ -1113,3 +1119,7 @@ impl From for InvalidTransactionWrapper { } } } + +pub trait DispatchPrecompile { + fn dispatch_precompile_call(transaction: &Transaction, source: &H160) -> Result, sp_runtime::DispatchError>; +} \ No newline at end of file From 342c8feb4706e357d5a9d71d184aa911c7e9b1d4 Mon Sep 17 00:00:00 2001 From: helin6 <577522102@qq.com> Date: Tue, 9 Sep 2025 16:47:34 +0800 Subject: [PATCH 3/3] update DispatchPrecompile return type --- frame/ethereum/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index 2e29f3dc3f..e87054b562 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -291,7 +291,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { // let source = ensure_ethereum_transaction(origin)?; match T::DispatchPrecompile::dispatch_precompile_call(&transaction, &source)? { - Some(_) => Ok(().into()), + Some(info) => Ok(info), None => { // Disable transact functionality if PreLog exist. assert!( @@ -1121,5 +1121,5 @@ impl From for InvalidTransactionWrapper { } pub trait DispatchPrecompile { - fn dispatch_precompile_call(transaction: &Transaction, source: &H160) -> Result, sp_runtime::DispatchError>; + fn dispatch_precompile_call(transaction: &Transaction, source: &H160) -> Result, sp_runtime::DispatchError>; } \ No newline at end of file