-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Summary
eth_getFinalizedHeader and eth_getFinalizedBlock fail when called with negative integer parameters (e.g., -1, -2, -3) because the verified_validator_num parameter is typed as u64 instead of i64.
Reproduce
curl -X POST http://localhost:8545 \
-H "Content-Type: application/json" \
-d '[{"jsonrpc":"2.0","id":1,"method":"eth_getFinalizedHeader","params":[-1]}]'Reth response:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "Invalid params",
"data": "invalid value: integer `-1`, expected u64 at line 1 column 2"
}
}Geth (BSC) response: Returns the finalized header correctly.
Root cause
The parameter type is defined as u64 in three locations:
crates/rpc/rpc-eth-api/src/core.rs—EthApiServertrait definition and blanket implcrates/rpc/rpc-eth-api/src/helpers/block.rs—rpc_finalized_header/rpc_finalized_blockhelper functions
In BSC geth (internal/ethapi/api.go), the equivalent parameter is int64 (signed), and negative values carry special semantics:
| Value | Meaning |
|---|---|
-1 |
At least ceil(validatorCount / 2) validators |
-2 |
At least ceil(validatorCount * 2 / 3) validators |
-3 |
All validators |
1..N |
Exact validator count (where N = len(currentValidators)) |
Fix
Change u64 to i64 in all 6 occurrences across the two files:
crates/rpc/rpc-eth-api/src/core.rs — trait definition
- async fn finalized_header(&self, verified_validator_num: u64) -> RpcResult<Option<H>>;
+ async fn finalized_header(&self, verified_validator_num: i64) -> RpcResult<Option<H>>;
- async fn finalized_block(&self, verified_validator_num: u64, full: bool) -> RpcResult<Option<B>>;
+ async fn finalized_block(&self, verified_validator_num: i64, full: bool) -> RpcResult<Option<B>>;crates/rpc/rpc-eth-api/src/core.rs — impl block
- async fn finalized_header(&self, verified_validator_num: u64) -> ...
+ async fn finalized_header(&self, verified_validator_num: i64) -> ...
- async fn finalized_block(&self, verified_validator_num: u64, full: bool) -> ...
+ async fn finalized_block(&self, verified_validator_num: i64, full: bool) -> ...crates/rpc/rpc-eth-api/src/helpers/block.rs
- fn rpc_finalized_header(&self, _verified_validator_num: u64, ...) -> ...
+ fn rpc_finalized_header(&self, _verified_validator_num: i64, ...) -> ...
- fn rpc_finalized_block(&self, _verified_validator_num: u64, full: bool, ...) -> ...
+ fn rpc_finalized_block(&self, _verified_validator_num: i64, full: bool, ...) -> ...Note
The current implementation ignores verified_validator_num entirely and delegates to BlockNumberOrTag::Finalized. Implementing the actual probabilistic finality logic (walking headers backward, counting distinct coinbases per the geth behavior) is a separate concern.