| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- // Copyright 2021 The go-ethereum Authors
- // This file is part of the go-ethereum library.
- //
- // The go-ethereum library is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Lesser General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // The go-ethereum library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public License
- // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
- package snap
- import (
- "math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/holiman/uint256"
- )
- // hashRange is a utility to handle ranges of hashes, Split up the
- // hash-space into sections, and 'walk' over the sections
- type hashRange struct {
- current *uint256.Int
- step *uint256.Int
- }
- // newHashRange creates a new hashRange, initiated at the start position,
- // and with the step set to fill the desired 'num' chunks
- func newHashRange(start common.Hash, num uint64) *hashRange {
- left := new(big.Int).Sub(hashSpace, start.Big())
- step := new(big.Int).Div(
- new(big.Int).Add(left, new(big.Int).SetUint64(num-1)),
- new(big.Int).SetUint64(num),
- )
- step256 := new(uint256.Int)
- step256.SetFromBig(step)
- return &hashRange{
- current: uint256.NewInt().SetBytes32(start[:]),
- step: step256,
- }
- }
- // Next pushes the hash range to the next interval.
- func (r *hashRange) Next() bool {
- next := new(uint256.Int)
- if overflow := next.AddOverflow(r.current, r.step); overflow {
- return false
- }
- r.current = next
- return true
- }
- // Start returns the first hash in the current interval.
- func (r *hashRange) Start() common.Hash {
- return r.current.Bytes32()
- }
- // End returns the last hash in the current interval.
- func (r *hashRange) End() common.Hash {
- // If the end overflows (non divisible range), return a shorter interval
- next := new(uint256.Int)
- if overflow := next.AddOverflow(r.current, r.step); overflow {
- return common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
- }
- return new(uint256.Int).Sub(next, uint256.NewInt().SetOne()).Bytes32()
- }
- // incHash returns the next hash, in lexicographical order (a.k.a plus one)
- func incHash(h common.Hash) common.Hash {
- a := uint256.NewInt().SetBytes32(h[:])
- a.Add(a, uint256.NewInt().SetOne())
- return common.Hash(a.Bytes32())
- }
|