Skip to content

Corrected error codes for eth simulate #11430

Merged
svlachakis merged 8 commits into
masterfrom
error_code_fix
May 4, 2026
Merged

Corrected error codes for eth simulate #11430
svlachakis merged 8 commits into
masterfrom
error_code_fix

Conversation

@DarkLord017
Copy link
Copy Markdown
Contributor

@DarkLord017 DarkLord017 commented Apr 30, 2026

Fixes Closes Resolves #11220 , #11221 & #11222

Changes

  • Add newer error codes and map them in Eth simulate

Types of changes

What types of changes does your code introduce?

  • Bugfix (a non-breaking change that fixes an issue)
  • New feature (a non-breaking change that adds functionality)
  • Breaking change (a change that causes existing functionality not to work as expected)
  • Optimization
  • Refactoring
  • Documentation update
  • Build-related changes
  • Other: Description

Testing

Requires testing

  • Yes
  • No

If yes, did you write tests?

  • Yes
  • No

Documentation

Requires documentation update

  • Yes
  • No

If yes, link the PR to the docs update or the issue with the details labeled docs. Remove if not applicable.

Requires explanation in Release Notes

  • Yes
  • No

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 30, 2026

Claude finished @DarkLord017's task in 2m 31s —— View job


PR Review: added eth_simulate_error_code

Tasks

  • Gather context and read changed files
  • Read relevant rules files
  • Review ErrorCodes.cs changes
  • Review SimulateTxExecutor.cs changes
  • Check for tests and spec correctness
  • Post inline comments and final verdict

Summary

The change is directionally correct — -38010 (NonceTooLow), -38011 (NonceTooHigh), and -38024 (SenderIsNotEoa) are the values mandated by the eth_simulateV1 spec, and the three switch-arm remappings in SimulateTxExecutor.cs replace incorrect catch-all codes (InternalError / InvalidParams) with those spec-compliant values.


Findings

Medium

Missing regression tests (SimulateTxExecutor.cs, line 261)
AGENTS.md requires a regression test whenever a bug is fixed. None of the three changed error-code paths have a test that asserts the specific error code:

  • TransactionNonceTooLow → -38010: the existing hive test multicall-transaction-too-low-nonce-38010 only checks ResultType.Success, not the numeric code.
  • TransactionNonceTooHigh → -38011: no test at all.
  • SenderHasDeployedCode → -38024: no test at all.

Tests similar to the existing error-code assertions in EthSimulateTestsBlocksAndTransactions.cs (which verify result.Result.Error and result.Result.ResultType) are needed for each path.

Low

  1. Numeric ordering out of sequence (ErrorCodes.cs, line 148) — NonceTooLow = -38010 and NonceTooHigh = -38011 are inserted after -38015, and SenderIsNotEoa = -38024 is inserted after -38025. Place constants in ascending numeric-magnitude order so the file is easy to scan. See inline suggestion.

  2. Trailing whitespace (ErrorCodes.cs, line 153) — NonceTooHigh doc comment has a trailing space.


Verdict

Not yet mergeable — the Medium finding (missing regression tests) must be addressed per the repository's own AGENTS.md guidelines before merging.

@DarkLord017
Copy link
Copy Markdown
Contributor Author

@claude review

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 30, 2026

Claude finished @DarkLord017's task in 3m 10s —— View job


Code Review: added eth_simulate_error_code

  • Read changed files and gathered context
  • Read repo rules and guidelines
  • Analyzed changes for correctness, security, performance
  • Post review feedback

Summary

The change correctly maps three eth_simulateV1 error conditions to their spec-mandated error codes instead of the generic fallbacks they had before:

Condition Old New
TransactionNonceTooLow -32603 (InternalError) -38010 (NonceTooLow)
TransactionNonceTooHigh -32603 (InternalError) -38011 (NonceTooHigh)
SenderHasDeployedCode -32602 (InvalidParams) -38024 (SenderIsNotEoa)

The error code values themselves are correct per the eth_simulateV1 specification.


Findings

Medium — Missing regression tests

AGENTS.md explicitly requires: "When fixing a bug, always add a regression test." The PR checks "No testing required," but all three changes are observable API behaviour fixes.

The test infrastructure for this pattern already exists — EthSimulateTestsBlocksAndTransactions.cs contains tests that assert result.ErrorCode against specific ErrorCodes.* values (e.g. lines 274, 608, 656, 701). Three analogous tests are missing:

  1. NonceTooLow — call with "validation": true and a nonce below the account nonce → assert ErrorCode == ErrorCodes.NonceTooLow (-38010)
  2. NonceTooHigh — call with "validation": true and an explicit nonce above the current nonce → assert ErrorCode == ErrorCodes.NonceTooHigh (-38011)
  3. SenderIsNotEoa — call whose from address has deployed code (EIP-3607) with "validation": true → assert ErrorCode == ErrorCodes.SenderIsNotEoa (-38024)

Without these tests, a future refactor could silently regress the fix. Fix this →


Low — Trailing whitespace in XML doc comment

ErrorCodes.cs line 152 has a trailing space:

/// Transaction nonce is higher than the account's current nonce·

Should be trimmed. Fix this →


Low — Out-of-order error code placement

The new constants break the loose numeric ordering of the eth_simulate error code block:

  • -38010 (NonceTooLow) and -38011 (NonceTooHigh) are declared after -38015 (BlockGasLimitReached)
  • -38024 (SenderIsNotEoa) is declared after -38025 (MaxInitCodeSizeExceeded)

Not a functional issue, but makes the file harder to navigate. Prefer inserting constants in ascending numeric order within the group.


Verdict

The core logic is correct and the error codes match the spec. The one medium finding (missing regression tests) is a repo requirement violation per AGENTS.md. Please add tests for all three error code paths before merging.

Comment thread src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs
Comment thread src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs Outdated
Comment thread src/Nethermind/Nethermind.JsonRpc/Modules/Eth/SimulateTxExecutor.cs
Comment thread src/Nethermind/Nethermind.JsonRpc/ErrorCodes.cs
@DarkLord017
Copy link
Copy Markdown
Contributor Author

@claude re-review

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 30, 2026

Claude finished @DarkLord017's task in 2m 2s —— View job


Re-review: added eth_simulate_error_code

Tasks

  • Read changed files
  • Check if previous findings were addressed (tests, ordering, trailing whitespace)
  • Verify correctness of error code mappings
  • Post final verdict

Summary

All three findings from the previous review have been resolved. The PR is now in good shape.


Previous Findings — Status

Medium (previously blocking) — Regression tests ✅ Fixed

Three regression tests were added to EthSimulateTestsBlocksAndTransactions.cs, each asserting the specific error code:

Test Error path Expected code
eth_simulateV1_nonce_too_low_returns_spec_error_code TransactionNonceTooLow -38010
eth_simulateV1_nonce_too_high_returns_spec_error_code TransactionNonceTooHigh -38011
eth_simulateV1_sender_is_not_eoa_returns_spec_error_code SenderHasDeployedCode -38024

The sender_is_not_eoa test correctly uses TestSpecProvider { AllowTestChainOverride = false } with IsEip3607Enabled = true — this is the right pattern (confirmed by TestBlockchain.cs:274).

Low — Numeric ordering ✅ Fixed

NonceTooLow = -38010 and NonceTooHigh = -38011 are now declared before FeeCapBelowBaseFee = -38012 through BlockGasLimitReached = -38015. SenderIsNotEoa = -38024 is correctly placed before MaxInitCodeSizeExceeded = -38025.

Low — Trailing whitespace ✅ Fixed

The trailing space on the NonceTooHigh doc comment has been removed.


Core Logic

The three switch-arm changes in SimulateTxExecutor.cs are correct:

  • SenderHasDeployedCodeErrorCodes.InvalidParams (-32602) ErrorCodes.SenderIsNotEoa (-38024) ✓
  • TransactionNonceTooHighErrorCodes.InternalError (-32603) ErrorCodes.NonceTooHigh (-38011) ✓
  • TransactionNonceTooLowErrorCodes.InternalError (-32603) ErrorCodes.NonceTooLow (-38010) ✓

All values match the eth_simulateV1 specification.


Verdict

Mergeable ✅ — No remaining findings. All three error code remappings are spec-correct, regression tests cover each changed path, and the ErrorCodes.cs constant ordering is clean.

@DarkLord017 DarkLord017 changed the title added eth_simulate_error_code Corrected error codes for eth simulate Apr 30, 2026
@DarkLord017 DarkLord017 marked this pull request as ready for review April 30, 2026 10:06
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 30, 2026

Claude finished @DarkLord017's task in 3m 48s —— View job


PR Review: error_code_fix — eth_simulateV1 error codes

Tasks

  • Gather context from prior reviews
  • Read changed files and relevant rules
  • Analyze error code correctness against spec
  • Review regression tests
  • Post final verdict

Summary

This PR fixes three eth_simulateV1 error paths that were returning generic JSON-RPC codes instead of the spec-mandated eth_simulateV1-specific codes:

Condition Before After
TransactionNonceTooLow -32603 (InternalError) -38010 (NonceTooLow) ✅
TransactionNonceTooHigh -32603 (InternalError) -38011 (NonceTooHigh) ✅
SenderHasDeployedCode -32602 (InvalidParams) -38024 (SenderIsNotEoa) ✅

All values match the eth_simulateV1 specification. Prior review findings (numeric ordering, trailing whitespace, missing regression tests) have all been addressed.


Core Logic — SimulateTxExecutor.cs

The three switch arm changes at lines 258–262 are correct. The validation order in TransactionProcessor is:

  1. ValidateSenderSenderHasDeployedCode (EIP-3607)
  2. BuyGas → fee validation
  3. IncrementNonce → nonce validation

All three conditions are on distinct code paths, so the changes are orthogonal and cannot interfere with each other.


Constants — ErrorCodes.cs

NonceTooLow = -38010 and NonceTooHigh = -38011 are correctly inserted before FeeCapBelowBaseFee = -38012. SenderIsNotEoa = -38024 is correctly placed before MaxInitCodeSizeExceeded = -38025. Numeric ordering within the eth_simulateV1 group is clean.


Regression Tests — EthSimulateTestsBlocksAndTransactions.cs

Three tests added, each asserting result.ErrorCode against the specific constant:

  • eth_simulateV1_nonce_too_low_returns_spec_error_code — sets account nonce to 10 via state override, sends tx with nonce 0 → expects -38010
  • eth_simulateV1_nonce_too_high_returns_spec_error_code — sends tx with explicit nonce 100 against account nonce 0 → expects -38011
  • eth_simulateV1_sender_is_not_eoa_returns_spec_error_code — overrides sender with deployed code under IsEip3607Enabled = true → expects -38024

Low — Tests omit error message assertion

The IntrinsicGas and FeeCapBelowBaseFee regression tests (same file) assert both result.ErrorCode and result.Result!.Error. The new nonce/EOA tests only assert the error code, not the message. There is no spec-mandated message for these three error types (unlike -38013/-38012 which have defined messages), so this is acceptable. No action required.

Low — No explicit BaseFeePerGas = 0 block override

eth_simulateV1_intrinsic_gas_returns_spec_error_code_and_message sets BlockOverrides = new BlockOverride { BaseFeePerGas = UInt256.Zero } explicitly. The new nonce tests omit this and rely on the chain's genesis block having BaseFeePerGas = 0 (which it does — TestBlockchain builds genesis without an explicit base fee, defaulting to UInt256.Zero, and London base fee propagation keeps it at zero). The existing InsufficientFunds regression test follows the same omission and works. Not blocking, but adding explicit BaseFeePerGas = UInt256.Zero would make intent clearer and prevent future brittleness if genesis defaults change.


Verdict

Mergeable ✅ — All previous findings resolved. The error code mappings are spec-correct, regression tests cover each changed path, and ErrorCodes.cs constants are in proper numeric order.

@LukaszRozmej
Copy link
Copy Markdown
Member

Duplicating with #11434

@LukaszRozmej
Copy link
Copy Markdown
Member

@claude suggest test deduplication if possible

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Apr 30, 2026

Claude finished @LukaszRozmej's task in 1m 37s —— View job


Tasks

  • Gather context from prior reviews
  • Read the new test methods
  • Analyze duplication patterns
  • Post deduplication suggestions

Test Deduplication Analysis

The two nonce tests are good candidates for merging

eth_simulateV1_nonce_too_low_returns_spec_error_code and eth_simulateV1_nonce_too_high_returns_spec_error_code are structurally identical — same chain setup, same BlockStateCalls shape, same sender/receiver addresses, same Validation = true. The only differences are the account nonce in the state override, the transaction nonce, and the expected error code.

They can be collapsed into a single [TestCase] test:

[TestCase(10ul, 0ul,   ErrorCodes.NonceTooLow,  TestName = "NonceTooLow")]
[TestCase(0ul,  100ul, ErrorCodes.NonceTooHigh, TestName = "NonceTooHigh")]
public async Task eth_simulateV1_nonce_validation_returns_spec_error_code(
    ulong accountNonce, ulong txNonce, int expectedErrorCode)
{
    TestRpcBlockchain chain = await EthRpcSimulateTestsBase.CreateChain();

    SimulatePayload<TransactionForRpc> payload = new()
    {
        BlockStateCalls =
        [
            new()
            {
                StateOverrides = new Dictionary<Address, AccountOverride>
                {
                    { TestItem.AddressA, new AccountOverride { Balance = 1.Ether, Nonce = accountNonce } }
                },
                Calls =
                [
                    new LegacyTransactionForRpc
                    {
                        From    = TestItem.AddressA,
                        To      = TestItem.AddressB,
                        Value   = UInt256.Zero,
                        Nonce   = txNonce,
                        GasPrice = UInt256.Zero,
                        Gas     = 21_000
                    }
                ]
            }
        ],
        Validation = true
    };

    ResultWrapper<IReadOnlyList<SimulateBlockResult<SimulateCallResult>>> result =
        chain.EthRpcModule.eth_simulateV1(payload, BlockParameter.Latest);

    Assert.That(result.ErrorCode, Is.EqualTo(expectedErrorCode));
}

Note: the original NonceTooHigh test omits Nonce from AccountOverride (leaving it null, which keeps the account at its genesis nonce of 0). Setting Nonce = 0ul explicitly is equivalent and allows the two cases to share the same body. ErrorCodes.NonceTooLow and NonceTooHigh are const int, so they can appear directly in TestCase attribute arguments.


SenderIsNotEoa — keep separate

This test is structurally different: it requires a bespoke TestSpecProvider with IsEip3607Enabled = true and AllowTestChainOverride = false, it injects contract bytecode into the state override, and it uses a different sender address (AddressC). Merging it with the nonce tests would hurt readability without saving much. Leave it as-is.


Summary: one [TestCase] method replaces two separate test methods. No change to SenderIsNotEoa.

@svlachakis
Copy link
Copy Markdown
Contributor

@DarkLord017 have you run hive tests? do we need to append to #11412 and known failures?

@DarkLord017
Copy link
Copy Markdown
Contributor Author

@DarkLord017 have you run hive tests? do we need to append to #11412 and known failures?

https://github.com/NethermindEth/nethermind/actions/runs/25162663667/job/73760828927 yep they are failing but not due to this pr

@svlachakis
Copy link
Copy Markdown
Contributor

svlachakis commented Apr 30, 2026

@DarkLord017 have you run hive tests? do we need to append to #11412 and known failures?

https://github.com/NethermindEth/nethermind/actions/runs/25162663667/job/73760828927 yep they are failing but not due to this pr

@DarkLord017 no, master should be fine - I've added exclusions to it, merged again latest master in your PR, try again

@DarkLord017
Copy link
Copy Markdown
Contributor Author

@DarkLord017 have you run hive tests? do we need to append to #11412 and known failures?

https://github.com/NethermindEth/nethermind/actions/runs/25162663667/job/73760828927 yep they are failing but not due to this pr

@DarkLord017 no, master should be fine - I've added exclusions to it, merged again latest master in your PR, try again

One is failing
eth_simulateV1/ethSimulate-simple-send-from-contract-with-validation
Our response: Error response handling JsonRpc Id:1 Method:eth_simulateV1 | Code: -38024 Message: sender has deployed code
hive expects -32602 (InvalidParams)

@DarkLord017 DarkLord017 requested a review from rubo as a code owner May 4, 2026 18:04
@svlachakis svlachakis merged commit fbc1508 into master May 4, 2026
572 of 574 checks passed
@svlachakis svlachakis deleted the error_code_fix branch May 4, 2026 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

eth_simulateV1 wrong error code for nonce too low (-32603 instead of -38010)

3 participants