diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index c5358f2a3c..e87054b562 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] @@ -222,7 +224,7 @@ pub mod pallet { UniqueSaturatedInto::::unique_saturated_into(to_remove), )); } - Pending::::kill(); + // Pending::::kill(); } fn on_initialize(_: T::BlockNumber) -> Weight { @@ -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(info) => Ok(info), + 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) + }, + } } } @@ -324,6 +330,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 +419,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 +439,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 +633,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 +713,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 +744,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, @@ -1089,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