- Observed behavior
debug_executionWitnessCall treats explicit gas: 0x0 differently from an omitted gas field.
debug_executionWitnessCall already fills a missing gas field from the selected block header gas limit.
The explicit zero form does not follow that same endpoint rule. A request with gas: 0x0 still returns success, but the generated witness can miss the called contract bytecode.
- Local reproduction before the fix
Targeted regression:
Debug_executionWitnessCall_with_zero_gas_still_records_full_witness
Observed failure:
zero gas must still capture called-contract bytecode
Assert.That(witnessWithZeroGas.Codes, Is.Not.Empty)
Expected: not
But was:
- Why this is a real RPC consistency bug
The endpoint already has local gas defaulting in src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs:
callRequest.Gas ??= header.GasLimit;
The omitted-gas regression in src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.ExecutionWitness.cs already expects a complete witness when gas is absent:
Debug_executionWitnessCall_without_gas_field_still_records_full_witness
So omitted gas and explicit gas: 0x0 diverge inside this endpoint. The bug does not show up as a clean RPC error. It returns success with a weaker witness shape.
- Expected behavior
For debug_executionWitnessCall, gas: 0x0 should follow the same endpoint-local fallback as an omitted gas field and use the block header gas limit before witness generation.
This fix should stay local to debug_executionWitnessCall. TransactionForRpc.ToTransaction should keep preserving explicit zero gas for endpoints that intentionally treat it as literal input.
debug_executionWitnessCall treats explicit gas: 0x0 differently from an omitted gas field.
debug_executionWitnessCall already fills a missing gas field from the selected block header gas limit.
The explicit zero form does not follow that same endpoint rule. A request with gas: 0x0 still returns success, but the generated witness can miss the called contract bytecode.
Targeted regression:
Debug_executionWitnessCall_with_zero_gas_still_records_full_witness
Observed failure:
zero gas must still capture called-contract bytecode
Assert.That(witnessWithZeroGas.Codes, Is.Not.Empty)
Expected: not
But was:
The endpoint already has local gas defaulting in src/Nethermind/Nethermind.JsonRpc/Modules/DebugModule/DebugRpcModule.cs:
callRequest.Gas ??= header.GasLimit;
The omitted-gas regression in src/Nethermind/Nethermind.JsonRpc.Test/Modules/DebugRpcModuleTests.ExecutionWitness.cs already expects a complete witness when gas is absent:
Debug_executionWitnessCall_without_gas_field_still_records_full_witness
So omitted gas and explicit gas: 0x0 diverge inside this endpoint. The bug does not show up as a clean RPC error. It returns success with a weaker witness shape.
For debug_executionWitnessCall, gas: 0x0 should follow the same endpoint-local fallback as an omitted gas field and use the block header gas limit before witness generation.
This fix should stay local to debug_executionWitnessCall. TransactionForRpc.ToTransaction should keep preserving explicit zero gas for endpoints that intentionally treat it as literal input.