- Observed behavior
eth_getProof still treats the block parameter as optional.
The interface signature still makes the third argument optional:
src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs
eth_getProof(Address accountAddress, HashSet storageKeys, BlockParameter? blockParameter = null)
The implementation also accepts a nullable block parameter:
src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs
eth_getProof(Address accountAddress, HashSet storageKeys, BlockParameter? blockParameter)
- Root cause
That call then flows into the shared header lookup helper:
src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs
SearchForHeader(this IBlockFinder blockFinder, BlockParameter? blockParameter, bool allowNulls = false)
Inside that helper, Nethermind does:
blockParameter ??= BlockParameter.Latest;
That is why omitting the third argument currently succeeds and silently falls back to the default block selection path instead of failing at binding time.
- Existing behavior around it
There is currently no omission regression in the module tests:
src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs
Eth_get_proof
Eth_get_proof_withTrimmedAndDuplicatedStorageKey
Eth_get_proof_withTooManyKeys
The shared JsonRpc binding path already has the behavior we want for required non-nullable trailing arguments:
src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs
missing value for required argument N
Existing examples already covered in JsonRpcServiceTests:
eth_getBlockByNumber with no args -> missing value for required argument 0
eth_feeHistory with the last arg omitted -> missing value for required argument 2
- Local reproduction on current upstream/master
eth_getProof with the block argument omitted currently succeeds and returns a proof payload instead of invalid params.
Observed response:
{"jsonrpc":"2.0","result":{"accountProof":["0xf8718080808080a0f7a112e339924a29fabe666fb92006d9b2491337a6102cdf4f886256e3fb666980808080a0b052f6653b289835c5c23d2c0b43082bd0b3124aad55ee026e1f9bf57ffa7c84a053692ab7cdc9bb02a28b1f45afe7be86cb27041ea98586e6ff05d98c9b0667138080808080","0xf8518080808080a028ebc35d38a29eefeaea4371f4f151823afdff8aa70ee2616afcd1ca5051f9a48080808080808080a03abd59d564074a5dc032708949ee83f0eb961eea7bbcc5b432b66d0ac4c3eb638080","0xf872a020227dead52ea912e013e7641ccd6b3b174498e55066b0c174a09c8c3cc4bf5eb84ff84d03893635c9adc5de9f09e5a0475ae75f323761db271e75cbdae41aede237e48bc04127fb6611f0f33298f72ba0dbe576b4818846aa77e82f4ed5fa78f92766b141f282d36703886d196df39322"],"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","balance":"0x3635c9adc5de9f09e5","codeHash":"0xdbe576b4818846aa77e82f4ed5fa78f92766b141f282d36703886d196df39322","nonce":"0x3","storageHash":"0x475ae75f323761db271e75cbdae41aede237e48bc04127fb6611f0f33298f72b","storageProof":[]},"id":67}
After changing the method signature to require BlockParameter instead of BlockParameter?, the method moves onto the existing binding-time required-argument path:
omitted block argument -> missing value for required argument 2
explicit null block argument -> missing value for required argument 2
- Validation from a local patch on current upstream/master
dotnet test src\Nethermind\Nethermind.JsonRpc.Test\Nethermind.JsonRpc.Test.csproj --filter "Name=Eth_get_proof|Name=Eth_get_proof_withTrimmedAndDuplicatedStorageKey|Name=Eth_get_proof_withTooManyKeys|Name=Eth_get_proof_no_block_argument_returns_invalid_params|Name=Eth_get_proof_explicit_null_block_argument_returns_invalid_params|Name=ExplicitMissingGetProofBlockArgumentToken"
Result:
6 total, 6 passed
- Suggested fix
Require the third parameter in eth_getProof by signature and add regressions for both omitted and explicit null block arguments.
eth_getProof still treats the block parameter as optional.
The interface signature still makes the third argument optional:
src/Nethermind/Nethermind.JsonRpc/Modules/Eth/IEthRpcModule.cs
eth_getProof(Address accountAddress, HashSet storageKeys, BlockParameter? blockParameter = null)
The implementation also accepts a nullable block parameter:
src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs
eth_getProof(Address accountAddress, HashSet storageKeys, BlockParameter? blockParameter)
That call then flows into the shared header lookup helper:
src/Nethermind/Nethermind.JsonRpc/Modules/BlockFinderExtensions.cs
SearchForHeader(this IBlockFinder blockFinder, BlockParameter? blockParameter, bool allowNulls = false)
Inside that helper, Nethermind does:
blockParameter ??= BlockParameter.Latest;
That is why omitting the third argument currently succeeds and silently falls back to the default block selection path instead of failing at binding time.
There is currently no omission regression in the module tests:
src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs
Eth_get_proof
Eth_get_proof_withTrimmedAndDuplicatedStorageKey
Eth_get_proof_withTooManyKeys
The shared JsonRpc binding path already has the behavior we want for required non-nullable trailing arguments:
src/Nethermind/Nethermind.JsonRpc/JsonRpcService.cs
missing value for required argument N
Existing examples already covered in JsonRpcServiceTests:
eth_getBlockByNumber with no args -> missing value for required argument 0
eth_feeHistory with the last arg omitted -> missing value for required argument 2
eth_getProof with the block argument omitted currently succeeds and returns a proof payload instead of invalid params.
Observed response:
{"jsonrpc":"2.0","result":{"accountProof":["0xf8718080808080a0f7a112e339924a29fabe666fb92006d9b2491337a6102cdf4f886256e3fb666980808080a0b052f6653b289835c5c23d2c0b43082bd0b3124aad55ee026e1f9bf57ffa7c84a053692ab7cdc9bb02a28b1f45afe7be86cb27041ea98586e6ff05d98c9b0667138080808080","0xf8518080808080a028ebc35d38a29eefeaea4371f4f151823afdff8aa70ee2616afcd1ca5051f9a48080808080808080a03abd59d564074a5dc032708949ee83f0eb961eea7bbcc5b432b66d0ac4c3eb638080","0xf872a020227dead52ea912e013e7641ccd6b3b174498e55066b0c174a09c8c3cc4bf5eb84ff84d03893635c9adc5de9f09e5a0475ae75f323761db271e75cbdae41aede237e48bc04127fb6611f0f33298f72ba0dbe576b4818846aa77e82f4ed5fa78f92766b141f282d36703886d196df39322"],"address":"0xb7705ae4c6f81b66cdb323c65f4e8133690fc099","balance":"0x3635c9adc5de9f09e5","codeHash":"0xdbe576b4818846aa77e82f4ed5fa78f92766b141f282d36703886d196df39322","nonce":"0x3","storageHash":"0x475ae75f323761db271e75cbdae41aede237e48bc04127fb6611f0f33298f72b","storageProof":[]},"id":67}
After changing the method signature to require BlockParameter instead of BlockParameter?, the method moves onto the existing binding-time required-argument path:
omitted block argument -> missing value for required argument 2
explicit null block argument -> missing value for required argument 2
dotnet test src\Nethermind\Nethermind.JsonRpc.Test\Nethermind.JsonRpc.Test.csproj --filter "Name=Eth_get_proof|Name=Eth_get_proof_withTrimmedAndDuplicatedStorageKey|Name=Eth_get_proof_withTooManyKeys|Name=Eth_get_proof_no_block_argument_returns_invalid_params|Name=Eth_get_proof_explicit_null_block_argument_returns_invalid_params|Name=ExplicitMissingGetProofBlockArgumentToken"
Result:
6 total, 6 passed
Require the third parameter in eth_getProof by signature and add regressions for both omitted and explicit null block arguments.