From 136bb458278275666fff6ea3f57726a189c799c1 Mon Sep 17 00:00:00 2001 From: ManuelArto Date: Mon, 29 Jun 2026 13:00:21 +0200 Subject: [PATCH 1/3] fix(evm): align insufficient-funds-for-transfer message with Geth --- .../Nethermind.Blockchain.Test/TransactionProcessorTests.cs | 2 +- src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs | 2 +- .../Nethermind.Evm.Test/Tracing/GasEstimationTests.cs | 4 ++-- .../TransactionProcessing/TransactionProcessor.cs | 2 +- .../Nethermind.Facade.Test/BlockchainBridgeTests.cs | 4 ++-- .../Modules/Eth/EthRpcModuleTests.EstimateGas.cs | 2 +- .../Modules/DebugModule/StructLogEnvelopeWriter.cs | 1 - 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs index aaed71b08a77..b5543e731556 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs @@ -286,7 +286,7 @@ public ulong Should_not_estimate_tx_with_high_value(UInt256 txValue) else if (txValue + (UInt256)gasLimit > AccountBalance) { Assert.That(err, Is.Not.Null); // Should have error - Assert.That(err, Is.EqualTo("insufficient sender balance for transfer")); + Assert.That(err, Is.EqualTo("insufficient funds for transfer")); } else { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs index 0a7446dbb4ab..3ce5851faa67 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs @@ -28,7 +28,7 @@ public class GasEstimator( public const string GasExceedsAllowanceMsgPrefix = "gas required exceeds allowance"; /// Message emitted when the sender has insufficient balance. - public const string InsufficientBalance = "insufficient sender balance for transfer"; + public const string InsufficientBalance = "insufficient funds for transfer"; /// Message emitted when the sender cannot cover gas * price + value. public const string InsufficientFundsForGas = "insufficient funds for gas * price + value"; diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index 3cdc83156ccd..90ee8225fe13 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -45,7 +45,7 @@ public void Does_not_take_into_account_precompiles() testEnvironment.tracer.ReportActionEnd(600, Array.Empty()); Assert.That(testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err), Is.EqualTo(0)); - Assert.That(err, Is.EqualTo("insufficient sender balance for transfer")); + Assert.That(err, Is.EqualTo("insufficient funds for transfer")); } [Test] @@ -75,7 +75,7 @@ public void Handles_well_top_level() testEnvironment.tracer.ReportActionEnd(600, Array.Empty()); Assert.That(testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err), Is.EqualTo(0)); - Assert.That(err, Is.EqualTo("insufficient sender balance for transfer")); + Assert.That(err, Is.EqualTo("insufficient funds for transfer")); } [Test] diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index a39bef78b19a..27902e9ac399 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -1749,7 +1749,7 @@ public static TransactionResult EvmException(EvmExceptionType evmExceptionType, public static readonly TransactionResult GasLimitBelowIntrinsicGas = new(ErrorType.GasLimitBelowIntrinsicGas, errorDescription: "intrinsic gas too low"); public static readonly TransactionResult GasLimitBelowFloorGas = new(ErrorType.GasLimitBelowFloorGas, errorDescription: "gas below floor data cost"); public static readonly TransactionResult InsufficientMaxFeePerGasForSenderBalance = new(ErrorType.InsufficientMaxFeePerGasForSenderBalance, errorDescription: "insufficient funds for gas * price + value"); - public static readonly TransactionResult InsufficientSenderBalance = new(ErrorType.InsufficientSenderBalance, errorDescription: "insufficient sender balance for transfer"); + public static readonly TransactionResult InsufficientSenderBalance = new(ErrorType.InsufficientSenderBalance, errorDescription: "insufficient funds for transfer"); public static readonly TransactionResult MalformedTransaction = new(ErrorType.MalformedTransaction, errorDescription: "malformed"); public static readonly TransactionResult MinerPremiumNegative = new(ErrorType.MinerPremiumNegative, errorDescription: "miner premium is negative"); public static readonly TransactionResult NonceOverflow = new(ErrorType.NonceOverflow, errorDescription: "nonce overflow"); diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 43180eb4353f..53f2df92d347 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -429,7 +429,7 @@ public void Call_tx_returns_InsufficientSenderBalanceError() CallOutput callOutput = _blockchainBridge.Call(header, tx); - Assert.That(callOutput.Error, Is.EqualTo("insufficient sender balance for transfer")); + Assert.That(callOutput.Error, Is.EqualTo("insufficient funds for transfer")); } [Test] @@ -443,7 +443,7 @@ public void EstimateGas_tx_returns_InsufficientSenderBalanceError() CallOutput callOutput = _blockchainBridge.EstimateGas(header, tx, 1); - Assert.That(callOutput.Error, Is.EqualTo("insufficient sender balance for transfer")); + Assert.That(callOutput.Error, Is.EqualTo("insufficient funds for transfer")); } [Test] 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 8cb526416be4..ee0ad0019e12 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 sender balance for transfer\"},\"id\":67}")); + serialized, Is.EqualTo("{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"insufficient funds for transfer\"},\"id\":67}")); AssertAccountDoesNotExist(ctx, TestAccount); } diff --git a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs index 623e39121de5..c51c5150e678 100644 --- a/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs +++ b/src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/StructLogEnvelopeWriter.cs @@ -109,7 +109,6 @@ private static string FormatErrorDescription(TransactionResult result) string detail = result.ErrorDescription; return result.Error switch { - ErrorType.InsufficientSenderBalance => ReplacePrefix(detail, "insufficient sender balance for transfer", "insufficient funds for transfer"), ErrorType.InsufficientMaxFeePerGasForSenderBalance => detail, ErrorType.SenderHasDeployedCode => ReplacePrefix(detail, "sender has deployed code", "sender not an eoa"), ErrorType.NonceOverflow => ReplacePrefix(detail, "nonce overflow", "nonce has max value"), From acf61523690a7e7d4892c0871310bde1d3282096 Mon Sep 17 00:00:00 2001 From: ManuelArto Date: Mon, 29 Jun 2026 13:18:00 +0200 Subject: [PATCH 2/3] fix(state): align InsufficientBalanceException message with Geth --- src/Nethermind/Nethermind.State/InsufficientBalanceException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs b/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs index c2442e40beb5..46511ed9de38 100644 --- a/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs +++ b/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs @@ -5,7 +5,7 @@ namespace Nethermind.State { - public class InsufficientBalanceException(Address address) : StateException($"insufficient sender balance for transfer: address {address}") + public class InsufficientBalanceException(Address address) : StateException($"insufficient funds for transfer: address {address}") { } } From 1cf809d5ff09bd9c06f551e52c57ebf111567b2c Mon Sep 17 00:00:00 2001 From: ManuelArto Date: Mon, 29 Jun 2026 23:55:22 +0200 Subject: [PATCH 3/3] fix: standardize insufficient funds error messages across transaction processing --- .../Nethermind.Blockchain.Test/TransactionProcessorTests.cs | 2 +- src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs | 3 ++- src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs | 2 ++ .../Nethermind.Evm.Test/Tracing/GasEstimationTests.cs | 4 ++-- .../TransactionProcessing/TransactionProcessor.cs | 2 +- .../Nethermind.Facade.Test/BlockchainBridgeTests.cs | 5 +++-- .../Nethermind.State/InsufficientBalanceException.cs | 3 ++- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs index b5543e731556..6a63af61e23b 100644 --- a/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs +++ b/src/Nethermind/Nethermind.Blockchain.Test/TransactionProcessorTests.cs @@ -286,7 +286,7 @@ public ulong Should_not_estimate_tx_with_high_value(UInt256 txValue) else if (txValue + (UInt256)gasLimit > AccountBalance) { Assert.That(err, Is.Not.Null); // Should have error - Assert.That(err, Is.EqualTo("insufficient funds for transfer")); + Assert.That(err, Is.EqualTo(GasEstimator.InsufficientBalance)); } else { diff --git a/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs b/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs index 3ce5851faa67..b5bc0b70bddb 100644 --- a/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs +++ b/src/Nethermind/Nethermind.Blockchain/Tracing/GasEstimator.cs @@ -6,6 +6,7 @@ using Nethermind.Config; using Nethermind.Core; using Nethermind.Core.Extensions; +using Nethermind.Core.Messages; using Nethermind.Core.Specs; using Nethermind.Evm; using Nethermind.Evm.TransactionProcessing; @@ -28,7 +29,7 @@ public class GasEstimator( public const string GasExceedsAllowanceMsgPrefix = "gas required exceeds allowance"; /// Message emitted when the sender has insufficient balance. - public const string InsufficientBalance = "insufficient funds for transfer"; + public const string InsufficientBalance = TxErrorMessages.InsufficientFundsForTransfer; /// Message emitted when the sender cannot cover gas * price + value. public const string InsufficientFundsForGas = "insufficient funds for gas * price + value"; diff --git a/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs b/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs index f3eafd69cdde..8e54ef58ccb3 100644 --- a/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs +++ b/src/Nethermind/Nethermind.Core/Messages/TxErrorMessages.cs @@ -11,6 +11,8 @@ public static string InvalidTxType(string name) => "intrinsic gas too low"; public const string GasBelowFloorDataCost = "gas below floor data cost"; + public const string InsufficientFundsForTransfer = + "insufficient funds for transfer"; public const string TxMissingTo = "blob transaction of type create"; diff --git a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs index 90ee8225fe13..e8b1e139212f 100644 --- a/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs +++ b/src/Nethermind/Nethermind.Evm.Test/Tracing/GasEstimationTests.cs @@ -45,7 +45,7 @@ public void Does_not_take_into_account_precompiles() testEnvironment.tracer.ReportActionEnd(600, Array.Empty()); Assert.That(testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err), Is.EqualTo(0)); - Assert.That(err, Is.EqualTo("insufficient funds for transfer")); + Assert.That(err, Is.EqualTo(GasEstimator.InsufficientBalance)); } [Test] @@ -75,7 +75,7 @@ public void Handles_well_top_level() testEnvironment.tracer.ReportActionEnd(600, Array.Empty()); Assert.That(testEnvironment.estimator.Estimate(tx, block.Header, testEnvironment.tracer, out string? err), Is.EqualTo(0)); - Assert.That(err, Is.EqualTo("insufficient funds for transfer")); + Assert.That(err, Is.EqualTo(GasEstimator.InsufficientBalance)); } [Test] diff --git a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs index 27902e9ac399..07dee79d2410 100644 --- a/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs +++ b/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs @@ -1749,7 +1749,7 @@ public static TransactionResult EvmException(EvmExceptionType evmExceptionType, public static readonly TransactionResult GasLimitBelowIntrinsicGas = new(ErrorType.GasLimitBelowIntrinsicGas, errorDescription: "intrinsic gas too low"); public static readonly TransactionResult GasLimitBelowFloorGas = new(ErrorType.GasLimitBelowFloorGas, errorDescription: "gas below floor data cost"); public static readonly TransactionResult InsufficientMaxFeePerGasForSenderBalance = new(ErrorType.InsufficientMaxFeePerGasForSenderBalance, errorDescription: "insufficient funds for gas * price + value"); - public static readonly TransactionResult InsufficientSenderBalance = new(ErrorType.InsufficientSenderBalance, errorDescription: "insufficient funds for transfer"); + public static readonly TransactionResult InsufficientSenderBalance = new(ErrorType.InsufficientSenderBalance, errorDescription: TxErrorMessages.InsufficientFundsForTransfer); public static readonly TransactionResult MalformedTransaction = new(ErrorType.MalformedTransaction, errorDescription: "malformed"); public static readonly TransactionResult MinerPremiumNegative = new(ErrorType.MinerPremiumNegative, errorDescription: "miner premium is negative"); public static readonly TransactionResult NonceOverflow = new(ErrorType.NonceOverflow, errorDescription: "nonce overflow"); diff --git a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs index 53f2df92d347..b0f95ec72035 100644 --- a/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs +++ b/src/Nethermind/Nethermind.Facade.Test/BlockchainBridgeTests.cs @@ -8,6 +8,7 @@ using Autofac; using Nethermind.Blockchain; using Nethermind.Blockchain.Receipts; +using Nethermind.Blockchain.Tracing; using Nethermind.Core; using Nethermind.Core.Crypto; using Nethermind.Core.Extensions; @@ -429,7 +430,7 @@ public void Call_tx_returns_InsufficientSenderBalanceError() CallOutput callOutput = _blockchainBridge.Call(header, tx); - Assert.That(callOutput.Error, Is.EqualTo("insufficient funds for transfer")); + Assert.That(callOutput.Error, Is.EqualTo(GasEstimator.InsufficientBalance)); } [Test] @@ -443,7 +444,7 @@ public void EstimateGas_tx_returns_InsufficientSenderBalanceError() CallOutput callOutput = _blockchainBridge.EstimateGas(header, tx, 1); - Assert.That(callOutput.Error, Is.EqualTo("insufficient funds for transfer")); + Assert.That(callOutput.Error, Is.EqualTo(GasEstimator.InsufficientBalance)); } [Test] diff --git a/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs b/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs index 46511ed9de38..f6168951c5fc 100644 --- a/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs +++ b/src/Nethermind/Nethermind.State/InsufficientBalanceException.cs @@ -2,10 +2,11 @@ // SPDX-License-Identifier: LGPL-3.0-only using Nethermind.Core; +using Nethermind.Core.Messages; namespace Nethermind.State { - public class InsufficientBalanceException(Address address) : StateException($"insufficient funds for transfer: address {address}") + public class InsufficientBalanceException(Address address) : StateException($"{TxErrorMessages.InsufficientFundsForTransfer}: address {address}") { } }