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));