mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-17 13:36:37 +00:00
eth/protocols/eth: improve over/underflow handling in GetBlockHeaders (#31522)
This commit is contained in:
parent
e6098437a6
commit
22c0605b68
2 changed files with 40 additions and 5 deletions
|
|
@ -297,6 +297,34 @@ func testGetBlockHeaders(t *testing.T, protocol uint) {
|
||||||
backend.chain.GetBlockByNumber(0).Hash(),
|
backend.chain.GetBlockByNumber(0).Hash(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// Check a corner case where skipping causes overflow with reverse=false
|
||||||
|
{
|
||||||
|
&GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1},
|
||||||
|
[]common.Hash{
|
||||||
|
backend.chain.GetBlockByNumber(1).Hash(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Check a corner case where skipping causes overflow with reverse=true
|
||||||
|
{
|
||||||
|
&GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: true, Skip: math.MaxUint64 - 1},
|
||||||
|
[]common.Hash{
|
||||||
|
backend.chain.GetBlockByNumber(1).Hash(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Check another corner case where skipping causes overflow with reverse=false
|
||||||
|
{
|
||||||
|
&GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: false, Skip: math.MaxUint64},
|
||||||
|
[]common.Hash{
|
||||||
|
backend.chain.GetBlockByNumber(1).Hash(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Check another corner case where skipping causes overflow with reverse=true
|
||||||
|
{
|
||||||
|
&GetBlockHeadersRequest{Origin: HashOrNumber{Number: 1}, Amount: 2, Reverse: true, Skip: math.MaxUint64},
|
||||||
|
[]common.Hash{
|
||||||
|
backend.chain.GetBlockByNumber(1).Hash(),
|
||||||
|
},
|
||||||
|
},
|
||||||
// Check a corner case where skipping overflow loops back into the chain start
|
// Check a corner case where skipping overflow loops back into the chain start
|
||||||
{
|
{
|
||||||
&GetBlockHeadersRequest{Origin: HashOrNumber{Hash: backend.chain.GetBlockByNumber(3).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1},
|
&GetBlockHeadersRequest{Origin: HashOrNumber{Hash: backend.chain.GetBlockByNumber(3).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1},
|
||||||
|
|
|
||||||
|
|
@ -128,15 +128,22 @@ func serviceNonContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBloc
|
||||||
}
|
}
|
||||||
case query.Reverse:
|
case query.Reverse:
|
||||||
// Number based traversal towards the genesis block
|
// Number based traversal towards the genesis block
|
||||||
if query.Origin.Number >= query.Skip+1 {
|
current := query.Origin.Number
|
||||||
query.Origin.Number -= query.Skip + 1
|
ancestor := current - (query.Skip + 1)
|
||||||
} else {
|
if ancestor >= current { // check for underflow
|
||||||
unknown = true
|
unknown = true
|
||||||
|
} else {
|
||||||
|
query.Origin.Number = ancestor
|
||||||
}
|
}
|
||||||
|
|
||||||
case !query.Reverse:
|
case !query.Reverse:
|
||||||
// Number based traversal towards the leaf block
|
current := query.Origin.Number
|
||||||
query.Origin.Number += query.Skip + 1
|
next := current + query.Skip + 1
|
||||||
|
if next <= current { // check for overflow
|
||||||
|
unknown = true
|
||||||
|
} else {
|
||||||
|
query.Origin.Number = next
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return headers
|
return headers
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue