diff --git a/Cargo.lock b/Cargo.lock index 40b5214338..8675a98e0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1683,6 +1683,7 @@ dependencies = [ "evm", "fc-db", "fc-rpc-core", + "fp-ethereum", "fp-evm", "fp-rpc", "fp-storage", @@ -1873,6 +1874,7 @@ dependencies = [ "ethereum-types", "fp-evm", "frame-support", + "num_enum", "parity-scale-codec", "sp-core", "sp-std", @@ -4315,6 +4317,27 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "object" version = "0.27.1" diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index d2297b2345..69aa9993d0 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -49,6 +49,7 @@ sp-storage = { version = "6.0.0", git = "https://github.com/paritytech/substrate # Frontier fc-db = { version = "2.0.0-dev", path = "../db" } fc-rpc-core = { version = "1.1.0-dev", path = "../rpc-core" } +fp-ethereum = { version = "1.0.0-dev", path = "../../primitives/ethereum" } fp-evm = { version = "3.0.0-dev", path = "../../primitives/evm" } fp-rpc = { version = "3.0.0-dev", path = "../../primitives/rpc" } fp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } diff --git a/client/rpc/src/eth/format.rs b/client/rpc/src/eth/format.rs index 19df69e2a2..4d110196dd 100644 --- a/client/rpc/src/eth/format.rs +++ b/client/rpc/src/eth/format.rs @@ -20,7 +20,7 @@ use sc_transaction_pool_api::error::{Error as PError, IntoPoolError}; use sp_runtime::transaction_validity::InvalidTransaction; // Frontier -use fp_evm::InvalidEvmTransactionError as VError; +use fp_ethereum::TransactionValidationError as VError; // Formats the same way Geth node formats responses. pub struct Geth; @@ -31,23 +31,23 @@ impl Geth { // https://github.com/ethereum/go-ethereum/blob/794c6133efa2c7e8376d9d141c900ea541790bce/core/error.go match err.into_pool_error() { Ok(PError::AlreadyImported(_)) => "already known".to_string(), - // In Frontier the only case there is a `TemporarilyBanned` is because - // the same transaction was received before and returned - // `InvalidTransaction::Stale`. Thus we return the same error. - Ok(PError::TemporarilyBanned) => "nonce too low".into(), + Ok(PError::TemporarilyBanned) => "already known".into(), Ok(PError::TooLowPriority { .. }) => "replacement transaction underpriced".into(), - Ok(ref outer @ PError::InvalidTransaction(inner)) => match inner { + Ok(PError::InvalidTransaction(inner)) => match inner { InvalidTransaction::Stale => "nonce too low".into(), InvalidTransaction::Payment => "insufficient funds for gas * price + value".into(), - InvalidTransaction::ExhaustsResources => "gas limit reached".into(), - InvalidTransaction::Custom(inner) => match inner { - a if a == VError::InvalidChainId as u8 => "invalid chain id".into(), - // VError::InvalidSignature => "invalid sender".into(), - a if a == VError::GasLimitTooLow as u8 => "intrinsic gas too low".into(), - a if a == VError::GasLimitTooHigh as u8 => "exceeds block gas limit".into(), - _ => format!("submit transaction to pool failed: {:?}", outer), + InvalidTransaction::ExhaustsResources => "exceeds block gas limit".into(), + InvalidTransaction::Custom(inner) => match inner.into() { + VError::UnknownError => "unknown error".into(), + VError::InvalidChainId => "invalid chain id".into(), + VError::InvalidSignature => "invalid sender".into(), + VError::GasLimitTooLow => "intrinsic gas too low".into(), + VError::GasLimitTooHigh => "exceeds block gas limit".into(), + VError::MaxFeePerGasTooLow => { + "max priority fee per gas higher than max fee per gas".into() + } }, - _ => format!("submit transaction to pool failed: {:?}", outer), + _ => "unknown error".into(), }, err => format!("submit transaction to pool failed: {:?}", err), } diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index 4ab4cebf39..0152136248 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -32,7 +32,9 @@ mod tests; use ethereum_types::{Bloom, BloomInput, H160, H256, H64, U256}; use evm::ExitReason; use fp_consensus::{PostLog, PreLog, FRONTIER_ENGINE_ID}; -use fp_ethereum::{TransactionData, ValidatedTransaction as ValidatedTransactionT}; +use fp_ethereum::{ + TransactionData, TransactionValidationError, ValidatedTransaction as ValidatedTransactionT, +}; use fp_evm::{ CallOrCreateInfo, CheckEvmTransaction, CheckEvmTransactionConfig, InvalidEvmTransactionError, }; @@ -872,26 +874,16 @@ impl BlockHashMapping for EthereumBlockHashMapping { } } -#[repr(u8)] -enum TransactionValidationError { - #[allow(dead_code)] - UnknownError, - InvalidChainId, - InvalidSignature, - InvalidGasLimit, - MaxFeePerGasTooLow, -} - pub struct InvalidTransactionWrapper(InvalidTransaction); impl From for InvalidTransactionWrapper { fn from(validation_error: InvalidEvmTransactionError) -> Self { match validation_error { InvalidEvmTransactionError::GasLimitTooLow => InvalidTransactionWrapper( - InvalidTransaction::Custom(TransactionValidationError::InvalidGasLimit as u8), + InvalidTransaction::Custom(TransactionValidationError::GasLimitTooLow as u8), ), InvalidEvmTransactionError::GasLimitTooHigh => InvalidTransactionWrapper( - InvalidTransaction::Custom(TransactionValidationError::InvalidGasLimit as u8), + InvalidTransaction::Custom(TransactionValidationError::GasLimitTooHigh as u8), ), InvalidEvmTransactionError::GasPriceTooLow => { InvalidTransactionWrapper(InvalidTransaction::Payment) diff --git a/frame/ethereum/src/tests/eip1559.rs b/frame/ethereum/src/tests/eip1559.rs index a059cf3672..689801fe87 100644 --- a/frame/ethereum/src/tests/eip1559.rs +++ b/frame/ethereum/src/tests/eip1559.rs @@ -252,7 +252,7 @@ fn transaction_with_invalid_chain_id_should_fail_in_block() { assert_err!( extrinsic.apply::(&dispatch_info, 0), TransactionValidityError::Invalid(InvalidTransaction::Custom( - crate::TransactionValidationError::InvalidChainId as u8, + fp_ethereum::TransactionValidationError::InvalidChainId as u8, )) ); }); diff --git a/frame/ethereum/src/tests/eip2930.rs b/frame/ethereum/src/tests/eip2930.rs index 49b9c66c18..fbdac95590 100644 --- a/frame/ethereum/src/tests/eip2930.rs +++ b/frame/ethereum/src/tests/eip2930.rs @@ -178,7 +178,7 @@ fn transaction_with_invalid_chain_id_should_fail_in_block() { assert_err!( extrinsic.apply::(&dispatch_info, 0), TransactionValidityError::Invalid(InvalidTransaction::Custom( - crate::TransactionValidationError::InvalidChainId as u8, + fp_ethereum::TransactionValidationError::InvalidChainId as u8, )) ); }); diff --git a/frame/ethereum/src/tests/legacy.rs b/frame/ethereum/src/tests/legacy.rs index 0996b1d8da..84acb27d94 100644 --- a/frame/ethereum/src/tests/legacy.rs +++ b/frame/ethereum/src/tests/legacy.rs @@ -178,7 +178,7 @@ fn transaction_with_invalid_chain_id_should_fail_in_block() { assert_err!( extrinsic.apply::(&dispatch_info, 0), TransactionValidityError::Invalid(InvalidTransaction::Custom( - crate::TransactionValidationError::InvalidChainId as u8, + fp_ethereum::TransactionValidationError::InvalidChainId as u8, )) ); }); diff --git a/primitives/ethereum/Cargo.toml b/primitives/ethereum/Cargo.toml index 61c9fd9eb4..27fb62187c 100644 --- a/primitives/ethereum/Cargo.toml +++ b/primitives/ethereum/Cargo.toml @@ -14,6 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] ethereum = { version = "0.12.0", default-features = false, features = ["with-codec"] } ethereum-types = { version = "0.13.1", default-features = false } fp-evm = { version = "3.0.0-dev", path = "../evm", default-features = false } +num_enum = { version = "0.5.4", default-features = false } # Parity codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } @@ -29,6 +30,7 @@ default = ["std"] std = [ "ethereum/std", "ethereum-types/std", + "num_enum/std", # Parity "codec/std", # Substrate diff --git a/primitives/ethereum/src/lib.rs b/primitives/ethereum/src/lib.rs index 931a6dbb3e..abf4b36260 100644 --- a/primitives/ethereum/src/lib.rs +++ b/primitives/ethereum/src/lib.rs @@ -26,6 +26,19 @@ use ethereum_types::{H160, H256, U256}; use fp_evm::CheckEvmTransactionInput; use sp_std::vec::Vec; +#[repr(u8)] +#[derive(num_enum::FromPrimitive, num_enum::IntoPrimitive)] +pub enum TransactionValidationError { + #[allow(dead_code)] + #[num_enum(default)] + UnknownError, + InvalidChainId, + InvalidSignature, + GasLimitTooLow, + GasLimitTooHigh, + MaxFeePerGasTooLow, +} + pub trait ValidatedTransaction { fn apply( source: H160, diff --git a/ts-tests/tests/test-gas.ts b/ts-tests/tests/test-gas.ts index 0f4e1191e1..a05d0b636e 100644 --- a/ts-tests/tests/test-gas.ts +++ b/ts-tests/tests/test-gas.ts @@ -185,7 +185,7 @@ describeWithFrontier("Frontier RPC (Gas)", (context) => { ); const createReceipt = await customRequest(context.web3, "eth_sendRawTransaction", [tx.rawTransaction]); await createAndFinalizeBlock(context.web3); - expect((createReceipt as any).error.message).to.equal("gas limit reached"); + expect((createReceipt as any).error.message).to.equal("exceeds block gas limit"); }); }); diff --git a/ts-tests/tests/test-transaction-cost.ts b/ts-tests/tests/test-transaction-cost.ts index cbdafaeaa2..bcde9388ef 100644 --- a/ts-tests/tests/test-transaction-cost.ts +++ b/ts-tests/tests/test-transaction-cost.ts @@ -11,7 +11,7 @@ describeWithFrontier("Frontier RPC (Transaction cost)", (context) => { d4afd7aefb4a34b373314fff470bb9db743a84d674a0aa06e5994f2d07eafe1c37b4ce5471caecec29011f6f5b\ f0b1a552c55ea348df35f", ]); - let msg = "submit transaction to pool failed: InvalidTransaction(InvalidTransaction::Custom(3))"; + let msg = "intrinsic gas too low"; expect(tx.error).to.include({ message: msg, });