diff --git a/.github/workflows/cancel.yml b/.github/workflows/cancel.yml index 50a09e0b8b..662dfbea1d 100644 --- a/.github/workflows/cancel.yml +++ b/.github/workflows/cancel.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 3 steps: - - uses: styfle/cancel-workflow-action@0.11.0 + - uses: styfle/cancel-workflow-action@0.12.0 with: workflow_id: 1303397 access_token: ${{ github.token }} diff --git a/client/rpc/src/eth/block.rs b/client/rpc/src/eth/block.rs index c9a1f88017..5956829abb 100644 --- a/client/rpc/src/eth/block.rs +++ b/client/rpc/src/eth/block.rs @@ -33,7 +33,7 @@ use fc_rpc_core::types::*; use fp_rpc::EthereumRuntimeRPCApi; use crate::{ - eth::{rich_block_build, Eth, EthConfig}, + eth::{empty_block_from, rich_block_build, Eth, EthConfig}, frontier_backend_client, internal_err, }; @@ -198,7 +198,23 @@ where _ => Ok(None), } } - None => Ok(None), + None => { + if let BlockNumber::Num(block_number) = number { + let eth_block = empty_block_from(block_number.into()); + let eth_hash = + H256::from_slice(keccak_256(&rlp::encode(ð_block.header)).as_slice()); + Ok(Some(rich_block_build( + eth_block, + Default::default(), + Some(eth_hash), + full, + None, + false, + ))) + } else { + Ok(None) + } + } } } diff --git a/client/rpc/src/eth/mod.rs b/client/rpc/src/eth/mod.rs index ed7a1491a1..43097d3c00 100644 --- a/client/rpc/src/eth/mod.rs +++ b/client/rpc/src/eth/mod.rs @@ -473,6 +473,31 @@ fn rich_block_build( } } +fn empty_block_from(number: U256) -> ethereum::BlockV2 { + let ommers = Vec::::new(); + let receipts = Vec::::new(); + let receipts_root = ethereum::util::ordered_trie_root( + receipts.iter().map(ethereum::EnvelopedEncodable::encode), + ); + let logs_bloom = ethereum_types::Bloom::default(); + let partial_header = ethereum::PartialHeader { + parent_hash: H256::default(), + beneficiary: Default::default(), + state_root: Default::default(), + receipts_root, + logs_bloom, + difficulty: U256::zero(), + number, + gas_limit: U256::from(4_000_000), + gas_used: U256::zero(), + timestamp: Default::default(), + extra_data: Vec::new(), + mix_hash: H256::default(), + nonce: H64::default(), + }; + ethereum::Block::new(partial_header, Default::default(), ommers) +} + fn transaction_build( ethereum_transaction: EthereumTransaction, block: Option, diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index e667341c92..859be26891 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -42,7 +42,9 @@ use fp_evm::{ use fp_storage::{EthereumStorageSchema, PALLET_ETHEREUM_SCHEMA}; use frame_support::{ codec::{Decode, Encode, MaxEncodedLen}, - dispatch::{DispatchInfo, DispatchResultWithPostInfo, Pays, PostDispatchInfo}, + dispatch::{ + DispatchErrorWithPostInfo, DispatchInfo, DispatchResultWithPostInfo, Pays, PostDispatchInfo, + }, scale_info::TypeInfo, traits::{EnsureOrigin, Get, PalletInfoAccess, Time}, weights::Weight, @@ -55,7 +57,7 @@ use sp_runtime::{ transaction_validity::{ InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransactionBuilder, }, - DispatchErrorWithPostInfo, RuntimeDebug, SaturatedConversion, + RuntimeDebug, SaturatedConversion, }; use sp_std::{marker::PhantomData, prelude::*}; @@ -241,7 +243,7 @@ pub mod pallet { Self::validate_transaction_in_block(source, &transaction).expect( "pre-block transaction verification failed; the block cannot be built", ); - let r = Self::apply_validated_transaction(source, transaction) + let (r, _) = Self::apply_validated_transaction(source, transaction) .expect("pre-block apply transaction failed; the block cannot be built"); weight = weight.saturating_add(r.actual_weight.unwrap_or_default()); @@ -290,7 +292,7 @@ pub mod pallet { "pre log already exists; block is invalid", ); - Self::apply_validated_transaction(source, transaction) + Self::apply_validated_transaction(source, transaction).map(|(post_info, _)| post_info) } } @@ -317,7 +319,7 @@ pub mod pallet { /// Current building block's transactions and receipts. #[pallet::storage] - pub(super) type Pending = + pub type Pending = StorageValue<_, Vec<(Transaction, TransactionStatus, Receipt)>, ValueQuery>; /// The current Ethereum block. @@ -558,14 +560,14 @@ impl Pallet { fn apply_validated_transaction( source: H160, transaction: Transaction, - ) -> DispatchResultWithPostInfo { + ) -> 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 (reason, status, weight_info, used_gas, dest, extra_data) = match info { + let (reason, status, weight_info, used_gas, dest, extra_data) = match info.clone() { CallOrCreateInfo::Call(info) => ( info.exit_reason.clone(), TransactionStatus { @@ -680,21 +682,24 @@ impl Pallet { extra_data, }); - Ok(PostDispatchInfo { - actual_weight: { - let mut gas_to_weight = T::GasWeightMapping::gas_to_weight( - used_gas.standard.unique_saturated_into(), - true, - ); - if let Some(weight_info) = weight_info { - if let Some(proof_size_usage) = weight_info.proof_size_usage { - *gas_to_weight.proof_size_mut() = proof_size_usage; + Ok(( + (PostDispatchInfo { + actual_weight: { + let mut gas_to_weight = T::GasWeightMapping::gas_to_weight( + used_gas.standard.unique_saturated_into(), + true, + ); + if let Some(weight_info) = weight_info { + if let Some(proof_size_usage) = weight_info.proof_size_usage { + *gas_to_weight.proof_size_mut() = proof_size_usage; + } } - } - Some(gas_to_weight) - }, - pays_fee: Pays::No, - }) + Some(gas_to_weight) + }, + pays_fee: Pays::No, + }), + info, + )) } /// Get current block hash @@ -707,10 +712,7 @@ impl Pallet { from: H160, transaction: &Transaction, config: Option, - ) -> Result< - (Option, Option, CallOrCreateInfo), - DispatchErrorWithPostInfo, - > { + ) -> Result<(Option, Option, CallOrCreateInfo), DispatchErrorWithPostInfo> { let ( input, value, @@ -963,7 +965,10 @@ impl Pallet { pub struct ValidatedTransaction(PhantomData); impl ValidatedTransactionT for ValidatedTransaction { - fn apply(source: H160, transaction: Transaction) -> DispatchResultWithPostInfo { + fn apply( + source: H160, + transaction: Transaction, + ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { Pallet::::apply_validated_transaction(source, transaction) } } diff --git a/primitives/consensus/src/lib.rs b/primitives/consensus/src/lib.rs index e9643d8eee..98c9a47217 100644 --- a/primitives/consensus/src/lib.rs +++ b/primitives/consensus/src/lib.rs @@ -130,5 +130,8 @@ pub fn find_log(digest: &Digest) -> Result { } pub fn ensure_log(digest: &Digest) -> Result<(), FindLogError> { - find_log(digest).map(|_log| ()) + match find_log(digest) { + Err(FindLogError::MultipleLogs) => Err(FindLogError::MultipleLogs), + _ => Ok(()), + } } diff --git a/primitives/ethereum/src/lib.rs b/primitives/ethereum/src/lib.rs index 03d7092ea3..69bcec62bc 100644 --- a/primitives/ethereum/src/lib.rs +++ b/primitives/ethereum/src/lib.rs @@ -23,9 +23,10 @@ pub use ethereum::{ TransactionAction, TransactionV2 as Transaction, }; use ethereum_types::{H160, H256, U256}; -use fp_evm::CheckEvmTransactionInput; +use fp_evm::{CallOrCreateInfo, CheckEvmTransactionInput}; +use frame_support::dispatch::{DispatchErrorWithPostInfo, PostDispatchInfo}; use scale_codec::{Decode, Encode}; -use sp_std::vec::Vec; +use sp_std::prelude::*; #[repr(u8)] #[derive(num_enum::FromPrimitive, num_enum::IntoPrimitive)] @@ -44,7 +45,7 @@ pub trait ValidatedTransaction { fn apply( source: H160, transaction: Transaction, - ) -> frame_support::dispatch::DispatchResultWithPostInfo; + ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo>; } #[derive(Clone, Debug, Eq, PartialEq, Encode, Decode)]