diff --git a/scripts/known-failing-hive-tests.txt b/scripts/known-failing-hive-tests.txt index fb01ffafd8c2..2e002d854eb4 100644 --- a/scripts/known-failing-hive-tests.txt +++ b/scripts/known-failing-hive-tests.txt @@ -7,20 +7,11 @@ eth_simulateV1/ethSimulate-empty-with-block-num-set-plus1 (nethermind) eth_simulateV1/ethSimulate-eth-send-should-not-produce-logs-on-revert (nethermind) eth_simulateV1/ethSimulate-eth-send-should-produce-no-logs-on-forward-revert (nethermind) eth_simulateV1/ethSimulate-fee-recipient-receiving-funds (nethermind) -eth_simulateV1/ethSimulate-gas-fees-and-value-error-38014 (nethermind) eth_simulateV1/ethSimulate-instrict-gas-38013 (nethermind) eth_simulateV1/ethSimulate-make-call-with-future-block (nethermind) -eth_simulateV1/ethSimulate-move-to-address-itself-reference-38022 (nethermind) -eth_simulateV1/ethSimulate-move-two-non-precompiles-accounts-to-same (nethermind) -eth_simulateV1/ethSimulate-overflow-nonce-validation (nethermind) -eth_simulateV1/ethSimulate-override-address-twice (nethermind) eth_simulateV1/ethSimulate-run-gas-spending (nethermind) eth_simulateV1/ethSimulate-run-out-of-gas-in-block-38015 (nethermind) eth_simulateV1/ethSimulate-simple-more-params-validate (nethermind) -eth_simulateV1/ethSimulate-simple-no-funds (nethermind) -eth_simulateV1/ethSimulate-simple-no-funds-with-balance-querying (nethermind) -eth_simulateV1/ethSimulate-simple-send-from-contract-no-balance (nethermind) -eth_simulateV1/ethSimulate-try-to-move-non-precompile (nethermind) eth_simulateV1/ethSimulate-two-blocks-with-complete-eth-sends (nethermind) eth_simulateV1/ethSimulate-use-as-many-features-as-possible (nethermind) diff --git a/src/Nethermind/Nethermind.Blockchain/InvalidTransactionException.cs b/src/Nethermind/Nethermind.Blockchain/InvalidTransactionException.cs new file mode 100644 index 000000000000..afa267ad792d --- /dev/null +++ b/src/Nethermind/Nethermind.Blockchain/InvalidTransactionException.cs @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited +// SPDX-License-Identifier: LGPL-3.0-only + +using System; +using Nethermind.Core; +using Nethermind.Evm.TransactionProcessing; + +namespace Nethermind.Blockchain; + +public class InvalidTransactionException : InvalidBlockException +{ + public InvalidTransactionException(BlockHeader header, string message, TransactionResult result, Exception? innerException = null) + : base(header, message, innerException) => Reason = result; + + public TransactionResult Reason; +} diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs index d06684f97b2c..b1ff6fdd855e 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionPicker.cs @@ -78,7 +78,7 @@ public virtual AddingTxEventArgs CanAddTransaction(Block block, Transaction curr IReleaseSpec spec = _specProvider.GetSpec(block.Header); if (currentTx.IsAboveInitCode(spec)) { - return args.Set(TxAction.Skip, TransactionResult.TransactionSizeOverMaxInitCodeSize.Error); + return args.Set(TxAction.Skip, TransactionResult.TransactionSizeOverMaxInitCodeSize.ErrorDescription); } if (!_ignoreEip3607 && stateProvider.IsInvalidContractSender(spec, currentTx.SenderAddress)) diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs index 478c9e6a0f25..1418fe284017 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockProductionTransactionsExecutor.cs @@ -112,7 +112,7 @@ private TxAction ProcessTransaction( } else { - args.Set(TxAction.Skip, result.Error!); + args.Set(TxAction.Skip, result.ErrorDescription!); } } diff --git a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs index 0f1dc661c729..f33be3a63766 100644 --- a/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs +++ b/src/Nethermind/Nethermind.Consensus/Processing/BlockProcessor.BlockValidationTransactionsExecutor.cs @@ -45,14 +45,14 @@ public TxReceipt[] ProcessTransactions(Block block, ProcessingOptions processing protected virtual void ProcessTransaction(Block block, Transaction currentTx, int index, BlockReceiptsTracer receiptsTracer, ProcessingOptions processingOptions) { TransactionResult result = transactionProcessor.ProcessTransaction(currentTx, receiptsTracer, processingOptions, stateProvider); - if (!result) ThrowInvalidBlockException(result, block.Header, currentTx, index); + if (!result) ThrowInvalidTransactionException(result, block.Header, currentTx, index); transactionProcessedEventHandler?.OnTransactionProcessed(new TxProcessedEventArgs(index, currentTx, block.Header, receiptsTracer.TxReceipts[index])); } [DoesNotReturn, StackTraceHidden] - private void ThrowInvalidBlockException(TransactionResult result, BlockHeader header, Transaction currentTx, int index) + private void ThrowInvalidTransactionException(TransactionResult result, BlockHeader header, Transaction currentTx, int index) { - throw new InvalidBlockException(header, $"Transaction {currentTx.Hash} at index {index} failed with error {result.Error}"); + throw new InvalidTransactionException(header, $"Transaction {currentTx.Hash} at index {index} failed with error {result.Error}", result); } /// diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 566bef746a68..438dd62c6cd6 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -922,14 +922,33 @@ protected virtual long CalculateClaimableRefund(long spentGas, long totalRefund, private static void ThrowInvalidDataException(string message) => throw new InvalidDataException(message); } - public readonly struct TransactionResult(string? error, EvmExceptionType evmException = EvmExceptionType.None) : IEquatable + public readonly struct TransactionResult : IEquatable { - [MemberNotNullWhen(false, nameof(TransactionExecuted))] - public string? Error { get; } = error; - public bool TransactionExecuted => Error is null; - public EvmExceptionType EvmExceptionType { get; } = evmException; + private TransactionResult(ErrorType error = ErrorType.None, EvmExceptionType evmException = EvmExceptionType.None) + { + Error = error; + EvmExceptionType = evmException; + } + public ErrorType Error { get; } + public bool TransactionExecuted => Error is ErrorType.None; + public EvmExceptionType EvmExceptionType { get; } - public static implicit operator TransactionResult(string? error) => new(error); + public string ErrorDescription => Error switch + { + ErrorType.BlockGasLimitExceeded => "Block gas limit exceeded", + ErrorType.GasLimitBelowIntrinsicGas => "gas limit below intrinsic gas", + ErrorType.InsufficientMaxFeePerGasForSenderBalance => "insufficient MaxFeePerGas for sender balance", + ErrorType.InsufficientSenderBalance => "insufficient sender balance", + ErrorType.MalformedTransaction => "malformed", + ErrorType.MinerPremiumNegative => "miner premium is negative", + ErrorType.NonceOverflow => "nonce overflow", + ErrorType.SenderHasDeployedCode => "sender has deployed code", + ErrorType.SenderNotSpecified => "sender not specified", + ErrorType.TransactionSizeOverMaxInitCodeSize => "EIP-3860 - transaction size over max init code size", + ErrorType.WrongTransactionNonce => "wrong transaction nonce", + _ => "" + }; + public static implicit operator TransactionResult(ErrorType error) => new(error); public static implicit operator bool(TransactionResult result) => result.TransactionExecuted; public bool Equals(TransactionResult other) => (TransactionExecuted && other.TransactionExecuted) || (Error == other.Error); public static bool operator ==(TransactionResult obj1, TransactionResult obj2) => obj1.Equals(obj2); @@ -937,25 +956,41 @@ public readonly struct TransactionResult(string? error, EvmExceptionType evmExce public override bool Equals(object? obj) => obj is TransactionResult result && Equals(result); public override int GetHashCode() => TransactionExecuted ? 1 : Error.GetHashCode(); - public override string ToString() => Error is not null ? $"Fail : {Error}" : "Success"; + public override string ToString() => Error is not ErrorType.None ? $"Fail : {ErrorDescription}" : "Success"; public static TransactionResult EvmException(EvmExceptionType evmExceptionType) { - return new TransactionResult(null, evmExceptionType); + return new TransactionResult(ErrorType.None, evmExceptionType); } public static readonly TransactionResult Ok = new(); - public static readonly TransactionResult BlockGasLimitExceeded = "Block gas limit exceeded"; - public static readonly TransactionResult GasLimitBelowIntrinsicGas = "gas limit below intrinsic gas"; - public static readonly TransactionResult InsufficientMaxFeePerGasForSenderBalance = "insufficient MaxFeePerGas for sender balance"; - public static readonly TransactionResult InsufficientSenderBalance = "insufficient sender balance"; - public static readonly TransactionResult MalformedTransaction = "malformed"; - public static readonly TransactionResult MinerPremiumNegative = "miner premium is negative"; - public static readonly TransactionResult NonceOverflow = "nonce overflow"; - public static readonly TransactionResult SenderHasDeployedCode = "sender has deployed code"; - public static readonly TransactionResult SenderNotSpecified = "sender not specified"; - public static readonly TransactionResult TransactionSizeOverMaxInitCodeSize = "EIP-3860 - transaction size over max init code size"; - public static readonly TransactionResult WrongTransactionNonce = "wrong transaction nonce"; + public static readonly TransactionResult BlockGasLimitExceeded = ErrorType.BlockGasLimitExceeded; + public static readonly TransactionResult GasLimitBelowIntrinsicGas = ErrorType.GasLimitBelowIntrinsicGas; + public static readonly TransactionResult InsufficientMaxFeePerGasForSenderBalance = ErrorType.InsufficientMaxFeePerGasForSenderBalance; + public static readonly TransactionResult InsufficientSenderBalance = ErrorType.InsufficientSenderBalance; + public static readonly TransactionResult MalformedTransaction = ErrorType.MalformedTransaction; + public static readonly TransactionResult MinerPremiumNegative = ErrorType.MinerPremiumNegative; + public static readonly TransactionResult NonceOverflow = ErrorType.NonceOverflow; + public static readonly TransactionResult SenderHasDeployedCode = ErrorType.SenderHasDeployedCode; + public static readonly TransactionResult SenderNotSpecified = ErrorType.SenderNotSpecified; + public static readonly TransactionResult TransactionSizeOverMaxInitCodeSize = ErrorType.TransactionSizeOverMaxInitCodeSize; + public static readonly TransactionResult WrongTransactionNonce = ErrorType.WrongTransactionNonce; + + public enum ErrorType + { + None, + BlockGasLimitExceeded, + GasLimitBelowIntrinsicGas, + InsufficientMaxFeePerGasForSenderBalance, + InsufficientSenderBalance, + MalformedTransaction, + MinerPremiumNegative, + NonceOverflow, + SenderHasDeployedCode, + SenderNotSpecified, + TransactionSizeOverMaxInitCodeSize, + WrongTransactionNonce, + } } } diff --git a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs index 0a79495ff345..f9f2d10556f1 100644 --- a/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs +++ b/src/Nethermind/Nethermind.Facade/BlockchainBridge.cs @@ -214,9 +214,9 @@ private TransactionResult TryCallAndRestore( { return CallAndRestore(blockHeader, transaction, treatBlockHeaderAsParentBlock, tracer, components); } - catch (InsufficientBalanceException ex) + catch (InsufficientBalanceException) { - return new TransactionResult(ex.Message); + return TransactionResult.InsufficientSenderBalance; } } @@ -404,7 +404,7 @@ public IEnumerable FindLogs(LogFilter filter, CancellationToken cance { { TransactionExecuted: true } when txResult.EvmExceptionType is not (EvmExceptionType.None or EvmExceptionType.Revert) => txResult.EvmExceptionType.GetEvmExceptionDescription(), { TransactionExecuted: true } when tracerError is not null => tracerError, - { TransactionExecuted: false, Error: not null } => txResult.Error, + { TransactionExecuted: false, Error: not TransactionResult.ErrorType.None } => txResult.ErrorDescription, _ => null }; diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs index 5dbf398f73a8..feb2722394d3 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateBridgeHelper.cs @@ -19,9 +19,8 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading; -using Nethermind.Consensus; using Nethermind.Evm.State; -using Nethermind.Logging; +using Nethermind.Evm.TransactionProcessing; using Transaction = Nethermind.Core.Transaction; namespace Nethermind.Facade.Simulate; @@ -70,31 +69,38 @@ public SimulateOutput TrySimulate( try { - if (!TrySimulate(parent, payload, tracer, env, list, gasCapLimit, cancellationToken, out string? error)) - { - result.Error = error; - } + Simulate(parent, payload, tracer, env, list, gasCapLimit, cancellationToken); + } + catch (ArgumentException ex) + { + result.Error = ex.Message; + result.IsInvalidOutput = true; + } + catch (InvalidTransactionException ex) + { + result.Error = ex.Reason.ErrorDescription; + result.TransactionResult = ex.Reason; } catch (InsufficientBalanceException ex) { result.Error = ex.Message; + result.TransactionResult = TransactionResult.InsufficientSenderBalance; } catch (Exception ex) { - result.Error = ex.ToString(); + result.Error = ex.Message; } return result; } - private bool TrySimulate(BlockHeader parent, + private void Simulate(BlockHeader parent, SimulatePayload payload, IBlockTracer tracer, SimulateReadOnlyBlocksProcessingScope env, List> output, long gasCapLimit, - CancellationToken cancellationToken, - [NotNullWhen(false)] out string? error) + CancellationToken cancellationToken) { IBlockTree blockTree = env.BlockTree; IWorldState stateProvider = env.WorldState; @@ -157,9 +163,6 @@ private bool TrySimulate(BlockHeader parent, parent = processedBlock.Header; } } - - error = null; - return true; } private BlockBody AssembleBody( diff --git a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs index 04cd2d539674..98f5f5d6449a 100644 --- a/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs +++ b/src/Nethermind/Nethermind.Facade/Simulate/SimulateOutput.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only using System.Collections.Generic; +using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade.Proxy.Models.Simulate; namespace Nethermind.Facade.Simulate; @@ -9,7 +10,8 @@ namespace Nethermind.Facade.Simulate; public class SimulateOutput { public string? Error { get; set; } - public int? ErrorCode { get; set; } + public bool IsInvalidOutput { get; set; } + public TransactionResult TransactionResult { get; set; } public IReadOnlyList> Items { get; init; } } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs index 4566561182f6..379c644d9e3c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EstimateGas.cs @@ -38,7 +38,7 @@ public async Task Eth_estimateGas_web3_should_return_insufficient_balance_error( string serialized = await ctx.Test.TestEthRpc("eth_estimateGas", transaction); Assert.That( - serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"insufficient funds for transfer: address 0x0001020304050607080910111213141516171819\"},\"id\":67}")); + serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"insufficient sender balance\"},\"id\":67}")); ctx.Test.ReadOnlyState.AccountExists(someAccount).Should().BeFalse(); } diff --git a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs index 891d1b2dbb71..6fcbea5cd21c 100644 --- a/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs +++ b/src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.EthCall.cs @@ -70,7 +70,7 @@ public async Task Eth_call_web3_should_return_insufficient_balance_error() "{\"from\":\"0x0001020304050607080910111213141516171819\",\"gasPrice\":\"0x100000\", \"data\": \"0x70a082310000000000000000000000006c1f09f6271fbe133db38db9c9280307f5d22160\", \"to\": \"0x0d8775f648430679a709e98d2b0cb6250d2887ef\", \"value\": 500, \"gas\": 100000000}"); string serialized = await ctx.Test.TestEthRpc("eth_call", transaction); Assert.That( - serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"insufficient funds for transfer: address 0x0001020304050607080910111213141516171819\"},\"id\":67}")); + serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"insufficient sender balance\"},\"id\":67}")); ctx.Test.ReadOnlyState.AccountExists(someAccount).Should().BeFalse(); } diff --git a/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs b/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs index a1233d4d5922..75a58bb63892 100644 --- a/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs +++ b/src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs @@ -126,5 +126,67 @@ public static class ErrorCodes /// Block is not available due to history expirty policy /// public const int PrunedHistoryUnavailable = 4444; + + /// + /// Default error code + /// + public const int Default = -32000; + + /// + /// Transaction.Nonce is bigger than expected nonce + /// + public const int NonceTooHigh = -38011; + + /// + /// Transaction.Nonce is smaller than expected nonce + /// + public const int NonceTooLow = -38010; + + /// + /// Invalid intrinsic gas. Miner premium is negative + /// + public const int IntrinsicGas = -38013; + + /// + /// Not enough value to cover transaction costs + /// + public const int InsufficientFunds = -38014; + + /// + /// Gas limit reached + /// + public const int BlockGasLimitReached = -38015; + + /// + /// Invalid block number + /// + public const int BlockNumberInvalid = -38020; + + /// + /// Invalid block timestamp + /// + public const int BlockTimestampInvalid = -38021; + + /// + /// Transaction.Sender is not an EOA + /// + public const int SenderIsNotEOA = -38024; + + /// + /// EIP-3860. Code size is to big + /// + public const int MaxInitCodeSizeExceeded = -38025; + + /// + /// Transaction reverted. Geth sets it to -32000 in simulate but suppose to 3. We kepp it as geth for now + /// + public const int RevertedSimulate = -32000; + + /// + /// Error during EVM execution + /// + public const int VMError = -32015; + public const int TxSyncTimeout = 4; + public const int ClientLimitExceeded = -38026; } } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs index 3ca5335b986f..3330a296897f 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs @@ -10,6 +10,7 @@ using Nethermind.Core; using Nethermind.Core.Collections; using Nethermind.Evm; +using Nethermind.Evm.TransactionProcessing; using Nethermind.Facade; using Nethermind.Facade.Eth.RpcTransaction; using Nethermind.Facade.Proxy.Models.Simulate; @@ -216,22 +217,42 @@ protected override ResultWrapper>> Exe } } - if (results.Error is not null) + int? errorCode = results.TransactionResult.TransactionExecuted + ? null + : (int)MapSimulateErrorCode(results.TransactionResult); + if (results.IsInvalidOutput) errorCode = ErrorCodes.Default; + return results.Error is null + ? ResultWrapper>>.Success([.. results.Items]) + : errorCode is not null + ? ResultWrapper>>.Fail(results.Error!, errorCode.Value) + : ResultWrapper>>.Fail(results.Error); + } + + private int MapSimulateErrorCode(TransactionResult txResult) + { + if (txResult.Error != TransactionResult.ErrorType.None) { - results.ErrorCode = results.Error switch + return txResult.Error switch { - var e when e.Contains("invalid transaction", StringComparison.OrdinalIgnoreCase) => ErrorCodes.InvalidTransaction, - var e when e.Contains("InsufficientBalanceException", StringComparison.OrdinalIgnoreCase) => ErrorCodes.InvalidTransaction, - var e when e.Contains("InvalidBlockException", StringComparison.OrdinalIgnoreCase) => ErrorCodes.InvalidParams, - var e when e.Contains("below intrinsic gas", StringComparison.OrdinalIgnoreCase) => ErrorCodes.InsufficientIntrinsicGas, - _ => results.ErrorCode + TransactionResult.ErrorType.BlockGasLimitExceeded => ErrorCodes.BlockGasLimitReached, + TransactionResult.ErrorType.GasLimitBelowIntrinsicGas => ErrorCodes.IntrinsicGas, + TransactionResult.ErrorType.InsufficientMaxFeePerGasForSenderBalance + or TransactionResult.ErrorType.InsufficientSenderBalance => ErrorCodes.InsufficientFunds, + TransactionResult.ErrorType.MalformedTransaction => ErrorCodes.InternalError, + TransactionResult.ErrorType.MinerPremiumNegative => ErrorCodes.InvalidParams, + TransactionResult.ErrorType.NonceOverflow => ErrorCodes.InternalError, + TransactionResult.ErrorType.SenderHasDeployedCode => ErrorCodes.InvalidParams, + TransactionResult.ErrorType.SenderNotSpecified => ErrorCodes.InternalError, + TransactionResult.ErrorType.TransactionSizeOverMaxInitCodeSize => ErrorCodes.MaxInitCodeSizeExceeded, + TransactionResult.ErrorType.WrongTransactionNonce => ErrorCodes.InternalError, + _ => ErrorCodes.InternalError }; } - return results.Error is null - ? ResultWrapper>>.Success([.. results.Items]) - : results.ErrorCode is not null - ? ResultWrapper>>.Fail(results.Error!, results.ErrorCode!.Value) - : ResultWrapper>>.Fail(results.Error); + return txResult.EvmExceptionType switch + { + EvmExceptionType.Revert => ErrorCodes.RevertedSimulate, + _ => ErrorCodes.VMError + }; } } diff --git a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs index 5108f8492620..3976b0c9919b 100644 --- a/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Optimism/OptimismTransactionProcessor.cs @@ -45,7 +45,7 @@ protected override TransactionResult Execute(Transaction tx, ITxTracer tracer, E TransactionResult result = base.Execute(tx, tracer, opts); - if (!result && tx.IsDeposit() && result.Error != "block gas limit exceeded") + if (!result && tx.IsDeposit() && result.Error != TransactionResult.ErrorType.BlockGasLimitExceeded) { // deposit tx should be included WorldState.Restore(snapshot); diff --git a/tools/Evm/T8n/T8nExecutor.cs b/tools/Evm/T8n/T8nExecutor.cs index fb27cbe1ca21..72935f0e7674 100644 --- a/tools/Evm/T8n/T8nExecutor.cs +++ b/tools/Evm/T8n/T8nExecutor.cs @@ -116,9 +116,9 @@ public static T8nExecutionResult Execute(T8nCommandArguments arguments) blockReceiptsTracer.LastReceipt.BlockNumber = 0; transactionExecutionReport.SuccessfulTransactionReceipts.Add(blockReceiptsTracer.LastReceipt); } - else if (transactionResult.Error is not null && transaction.SenderAddress is not null) + else if (!transactionResult.TransactionExecuted && transaction.SenderAddress is not null) { - var error = GethErrorMappings.GetErrorMapping(transactionResult.Error, + var error = GethErrorMappings.GetErrorMapping(transactionResult.ErrorDescription, transaction.SenderAddress.ToString(true), transaction.Nonce, stateProvider.GetNonce(transaction.SenderAddress));