mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
cmd/devp2p/internal/ethtest: fix header stride in reverse GetHeaders (#35362)
`Chain.GetHeaders` steps by `1 + Skip` in the forward branch but by `1 -
Skip` in the reverse branch. `Skip` is a `uint64`, so the reverse stride
is wrong for every `Skip > 0`:
| Skip | reverse step | result |
| --- | --- | --- |
| 0 | `-= 1` | correct |
| 1 | `-= 0` | block number never moves, the same header is returned
`Amount` times |
| >= 2 | `1 - Skip` underflows | walks *forward* instead of back (`Skip
= 2` on block 100 lands on 101) |
Per the `GetBlockHeadersRequest` definition, `Skip` is "Blocks to skip
between consecutive headers", so the stride is `Skip + 1` in whichever
direction the query runs. Subtracting `1 + Skip` makes the reverse
branch mirror the forward one.
The existing table test covers forward + `Skip: 1` and reverse + `Skip:
0` (which works by accident, since `1 - 0 == 1`). Added the missing
reverse + `Skip: 1` case; it fails on master:
```
--- FAIL: TestChainGetHeaders/3
Test: TestChainGetHeaders/3
FAIL github.com/ethereum/go-ethereum/cmd/devp2p/internal/ethtest
```
and passes with the fix (4/4).
No caller sends a reverse request with `Skip > 0` today, so nothing is
broken in the current suite. The helper computes the expected headers
that responses are checked against, though, so the moment a reverse+skip
case is added it would silently assert the wrong headers rather than
fail loudly.
This commit is contained in:
parent
06b23b4293
commit
80b58f649a
2 changed files with 16 additions and 1 deletions
|
|
@ -231,7 +231,7 @@ func (c *Chain) GetHeaders(req *eth.GetBlockHeadersPacket) ([]*types.Header, err
|
|||
}
|
||||
if req.Reverse {
|
||||
for i := 1; i < int(req.Amount); i++ {
|
||||
blockNumber -= (1 - req.Skip)
|
||||
blockNumber -= (1 + req.Skip)
|
||||
headers[i] = c.blocks[blockNumber].Header()
|
||||
}
|
||||
return headers, nil
|
||||
|
|
|
|||
|
|
@ -186,6 +186,21 @@ func TestChainGetHeaders(t *testing.T) {
|
|||
chain.Head().Header(),
|
||||
},
|
||||
},
|
||||
{
|
||||
req: eth.GetBlockHeadersPacket{
|
||||
GetBlockHeadersRequest: ð.GetBlockHeadersRequest{
|
||||
Origin: eth.HashOrNumber{Number: uint64(10)},
|
||||
Amount: uint64(3),
|
||||
Skip: 1,
|
||||
Reverse: true,
|
||||
},
|
||||
},
|
||||
expected: []*types.Header{
|
||||
chain.blocks[10].Header(),
|
||||
chain.blocks[8].Header(),
|
||||
chain.blocks[6].Header(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
|
|
|
|||
Loading…
Reference in a new issue