mirror of
https://github.com/luxfi/evmgpu.git
synced 2026-10-30 16:57:11 +00:00
119 lines
3.1 KiB
Go
119 lines
3.1 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package header
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/luxfi/evmgpu/commontype"
|
|
"github.com/luxfi/evmgpu/params/extras"
|
|
"github.com/luxfi/geth/core/types"
|
|
ethparams "github.com/luxfi/geth/params"
|
|
"github.com/luxfi/math"
|
|
)
|
|
|
|
var (
|
|
errInvalidGasUsed = errors.New("invalid gas used")
|
|
errInvalidGasLimit = errors.New("invalid gas limit")
|
|
)
|
|
|
|
type CalculateGasLimitFunc func(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint64
|
|
|
|
// GasLimit takes the previous header and the timestamp of its child block and
|
|
// calculates the gas limit for the child block.
|
|
func GasLimit(
|
|
config *extras.ChainConfig,
|
|
feeConfig commontype.FeeConfig,
|
|
parent *types.Header,
|
|
timestamp uint64,
|
|
) (uint64, error) {
|
|
switch {
|
|
case config.IsEVM(timestamp):
|
|
return feeConfig.GasLimit.Uint64(), nil
|
|
default:
|
|
// since all chains have activated EVM,
|
|
// this code is not used in production. To avoid a dependency on the
|
|
// `core` package, this code is modified to just return the parent gas
|
|
// limit; which was valid to do prior to EVM.
|
|
return parent.GasLimit, nil
|
|
}
|
|
}
|
|
|
|
// VerifyGasUsed verifies that the gas used is less than or equal to the gas
|
|
// limit.
|
|
func VerifyGasUsed(
|
|
config *extras.ChainConfig,
|
|
feeConfig commontype.FeeConfig,
|
|
parent *types.Header,
|
|
header *types.Header,
|
|
) error {
|
|
gasUsed := header.GasUsed
|
|
capacity, err := GasCapacity(config, feeConfig, parent, header.Time)
|
|
if err != nil {
|
|
return fmt.Errorf("calculating gas capacity: %w", err)
|
|
}
|
|
if gasUsed > capacity {
|
|
return fmt.Errorf("%w: have %d, capacity %d",
|
|
errInvalidGasUsed,
|
|
gasUsed,
|
|
capacity,
|
|
)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// VerifyGasLimit verifies that the gas limit for the header is valid.
|
|
func VerifyGasLimit(
|
|
config *extras.ChainConfig,
|
|
feeConfig commontype.FeeConfig,
|
|
parent *types.Header,
|
|
header *types.Header,
|
|
) error {
|
|
switch {
|
|
case config.IsEVM(header.Time):
|
|
expectedGasLimit := feeConfig.GasLimit.Uint64()
|
|
if header.GasLimit != expectedGasLimit {
|
|
return fmt.Errorf("%w: expected to be %d in EVM, but found %d",
|
|
errInvalidGasLimit,
|
|
expectedGasLimit,
|
|
header.GasLimit,
|
|
)
|
|
}
|
|
default:
|
|
if header.GasLimit < ethparams.MinGasLimit || header.GasLimit > ethparams.MaxGasLimit {
|
|
return fmt.Errorf("%w: %d not in range [%d, %d]",
|
|
errInvalidGasLimit,
|
|
header.GasLimit,
|
|
ethparams.MinGasLimit,
|
|
ethparams.MaxGasLimit,
|
|
)
|
|
}
|
|
|
|
// Verify that the gas limit remains within allowed bounds
|
|
diff := math.AbsDiff(parent.GasLimit, header.GasLimit)
|
|
limit := parent.GasLimit / ethparams.GasLimitBoundDivisor
|
|
if diff >= limit {
|
|
return fmt.Errorf("%w: have %d, want %d += %d",
|
|
errInvalidGasLimit,
|
|
header.GasLimit,
|
|
parent.GasLimit,
|
|
limit,
|
|
)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GasCapacity takes the previous header and the timestamp of its child block
|
|
// and calculates the available gas that can be consumed in the child block.
|
|
func GasCapacity(
|
|
config *extras.ChainConfig,
|
|
feeConfig commontype.FeeConfig,
|
|
parent *types.Header,
|
|
timestamp uint64,
|
|
) (uint64, error) {
|
|
return GasLimit(config, feeConfig, parent, timestamp)
|
|
}
|