From 5df91cedac933402bc28016970394e18e06d2d40 Mon Sep 17 00:00:00 2001 From: linning Date: Sat, 21 Dec 2024 03:42:01 +0800 Subject: [PATCH 1/2] Fine-grained Pending state Signed-off-by: linning --- frame/ethereum/src/lib.rs | 45 +++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index a211f2478e..ff3a9dc07a 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -255,7 +255,8 @@ pub mod pallet { UniqueSaturatedInto::::unique_saturated_into(to_remove), )); } - Pending::::kill(); + // Reset the next transaction index + NextTxIndex::::set(0); } fn on_initialize(_: BlockNumberFor) -> Weight { @@ -348,10 +349,14 @@ pub mod pallet { PreLogExists, } - /// Current building block's transactions and receipts. + /// The next transcation index. + #[pallet::storage] + pub type NextTxIndex = StorageValue<_, u32, ValueQuery>; + + /// Mapping from transaction index to transaction in the current building block. #[pallet::storage] pub type Pending = - StorageValue<_, Vec<(Transaction, TransactionStatus, Receipt)>, ValueQuery>; + StorageMap<_, Identity, u32, (Transaction, TransactionStatus, Receipt), OptionQuery>; /// The current Ethereum block. #[pallet::storage] @@ -441,17 +446,19 @@ impl Pallet { let mut receipts = Vec::new(); let mut logs_bloom = Bloom::default(); let mut cumulative_gas_used = U256::zero(); - for (transaction, status, receipt) in Pending::::get() { - 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); + for tx_index in 0..NextTxIndex::::get() { + if let Some((transaction, status, receipt)) = Pending::::take(tx_index) { + 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); + } } let ommers = Vec::::new(); @@ -597,9 +604,8 @@ impl Pallet { ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { let (to, _, info) = Self::execute(source, &transaction, None)?; - let pending = Pending::::get(); let transaction_hash = transaction.hash(); - let transaction_index = pending.len() as u32; + let transaction_index = NextTxIndex::::get(); let (reason, status, weight_info, used_gas, dest, extra_data) = match info.clone() { CallOrCreateInfo::Call(info) => ( @@ -675,7 +681,9 @@ 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)) = + Pending::::get(transaction_index.saturating_sub(1)) + { match receipt { Receipt::Legacy(d) | Receipt::EIP2930(d) | Receipt::EIP1559(d) => { d.used_gas.saturating_add(used_gas.effective) @@ -706,7 +714,8 @@ impl Pallet { } }; - Pending::::append((transaction, status, receipt)); + Pending::::insert(transaction_index, (transaction, status, receipt)); + NextTxIndex::::set(transaction_index + 1); Self::deposit_event(Event::Executed { from: source, From 45bec2f652202ca626cfc8434c8885649dfa414c Mon Sep 17 00:00:00 2001 From: linning Date: Tue, 14 Jan 2025 04:48:31 +0800 Subject: [PATCH 2/2] Use CountedStorageMap for managing pending transactions Signed-off-by: linning --- frame/ethereum/src/lib.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index ff3a9dc07a..2a4b4d36f9 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -255,8 +255,6 @@ pub mod pallet { UniqueSaturatedInto::::unique_saturated_into(to_remove), )); } - // Reset the next transaction index - NextTxIndex::::set(0); } fn on_initialize(_: BlockNumberFor) -> Weight { @@ -349,14 +347,10 @@ pub mod pallet { PreLogExists, } - /// The next transcation index. - #[pallet::storage] - pub type NextTxIndex = StorageValue<_, u32, ValueQuery>; - /// Mapping from transaction index to transaction in the current building block. #[pallet::storage] pub type Pending = - StorageMap<_, Identity, u32, (Transaction, TransactionStatus, Receipt), OptionQuery>; + CountedStorageMap<_, Identity, u32, (Transaction, TransactionStatus, Receipt), OptionQuery>; /// The current Ethereum block. #[pallet::storage] @@ -441,13 +435,14 @@ impl Pallet { } fn store_block(post_log: Option, block_number: U256) { - let mut transactions = Vec::new(); - let mut statuses = Vec::new(); - let mut receipts = Vec::new(); + let transactions_count = Pending::::count(); + let mut transactions = Vec::with_capacity(transactions_count as usize); + let mut statuses = Vec::with_capacity(transactions_count as usize); + let mut receipts = Vec::with_capacity(transactions_count as usize); let mut logs_bloom = Bloom::default(); let mut cumulative_gas_used = U256::zero(); - for tx_index in 0..NextTxIndex::::get() { - if let Some((transaction, status, receipt)) = Pending::::take(tx_index) { + for transaction_index in 0..transactions_count { + if let Some((transaction, status, receipt)) = Pending::::take(transaction_index) { transactions.push(transaction); statuses.push(status); receipts.push(receipt.clone()); @@ -605,7 +600,7 @@ impl Pallet { let (to, _, info) = Self::execute(source, &transaction, None)?; let transaction_hash = transaction.hash(); - let transaction_index = NextTxIndex::::get(); + let transaction_index = Pending::::count(); let (reason, status, weight_info, used_gas, dest, extra_data) = match info.clone() { CallOrCreateInfo::Call(info) => ( @@ -715,7 +710,6 @@ impl Pallet { }; Pending::::insert(transaction_index, (transaction, status, receipt)); - NextTxIndex::::set(transaction_index + 1); Self::deposit_event(Event::Executed { from: source,