Skip to content

eth_call: leading-zero hex in blockOverrides.number is accepted instead of rejected #12102

Description

@manusw7

Description

When eth_call is invoked with a blockOverrides object whose number field contains a hex string with leading zeros (e.g. "0x0b" instead of "0xb"), NM silently accepts the value and returns a result. Geth correctly rejects it with -32602.

The Execution API spec requires that integer hex strings have no leading zero digits (except "0x0" itself). This rule applies to all QUANTITY fields, including blockOverrides.number.

Steps to Reproduce

{
  "jsonrpc": "2.0",
  "method": "eth_call",
  "params": [
    {
      "from": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
      "to": "0xc100000000000000000000000000000000000000",
      "data": "0x28b5e32b"
    },
    "latest",
    {},
    { "number": "0x0b" }
  ],
  "id": 1
}

Note: "0x0b" has a leading zero — the correct encoding is "0xb".

Expected (Geth)

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "invalid argument 3: json: cannot unmarshal hex number with leading zero digits into Go struct field BlockOverrides.Number of type *hexutil.Big"
  }
}

Actual (Nethermind v1.39.0-rc+c6739713)

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x000000000000000000000000000000000000000000000000000000000000000b"
}

Fix Location

The blockOverrides struct deserializer in the eth_call handler. Search for the BlockOverrides / BlockNumberOverride binding in Nethermind.JsonRpc — the number field should use the same strict hexutil Big-equivalent decoder that rejects leading zeros. The same validation is already applied elsewhere (e.g. block-number parameters); it needs to be applied to the blockOverrides.number field as well.

Notes

  • Fixture: integration/mainnet/eth_call/test_41.json.
  • The stored fixture response matches NM's (lenient) behaviour. Once NM is fixed, the fixture response should be updated to match Geth's -32602 error.
  • Leading-zero rejection is a QUANTITY encoding rule, not specific to blockOverrides; audit other BlockOverrides fields (time, gasLimit, baseFeePerGas, blobBaseFee) for the same gap.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions