mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
params: move blob count functions to eip4844
This commit is contained in:
parent
28496b0180
commit
fa73a5e424
10 changed files with 80 additions and 76 deletions
|
|
@ -242,7 +242,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
txBlobGas := uint64(0)
|
txBlobGas := uint64(0)
|
||||||
if tx.Type() == types.BlobTxType {
|
if tx.Type() == types.BlobTxType {
|
||||||
txBlobGas = uint64(params.BlobTxBlobGasPerBlob * len(tx.BlobHashes()))
|
txBlobGas = uint64(params.BlobTxBlobGasPerBlob * len(tx.BlobHashes()))
|
||||||
max := chainConfig.MaxBlobGasPerBlock(pre.Env.Timestamp)
|
max := eip4844.MaxBlobGasPerBlock(chainConfig, pre.Env.Timestamp)
|
||||||
if used := blobGasUsed + txBlobGas; used > max {
|
if used := blobGasUsed + txBlobGas; used > max {
|
||||||
err := fmt.Errorf("blob gas (%d) would exceed maximum allowance %d", used, max)
|
err := fmt.Errorf("blob gas (%d) would exceed maximum allowance %d", used, max)
|
||||||
log.Warn("rejected tx", "index", i, "err", err)
|
log.Warn("rejected tx", "index", i, "err", err)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade
|
||||||
return errors.New("header is missing blobGasUsed")
|
return errors.New("header is missing blobGasUsed")
|
||||||
}
|
}
|
||||||
// Verify that the blob gas used remains within reasonable limits.
|
// Verify that the blob gas used remains within reasonable limits.
|
||||||
maxBlobGas := config.MaxBlobGasPerBlock(header.Time)
|
maxBlobGas := MaxBlobGasPerBlock(config, header.Time)
|
||||||
if *header.BlobGasUsed > maxBlobGas {
|
if *header.BlobGasUsed > maxBlobGas {
|
||||||
return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", *header.BlobGasUsed, maxBlobGas)
|
return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", *header.BlobGasUsed, maxBlobGas)
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +61,7 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade
|
||||||
// blobs on top of the excess blob gas.
|
// blobs on top of the excess blob gas.
|
||||||
func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header) uint64 {
|
func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header) uint64 {
|
||||||
var (
|
var (
|
||||||
targetGas = uint64(config.TargetBlobsPerBlock(parent.Time)) * params.BlobTxBlobGasPerBlob
|
targetGas = uint64(TargetBlobsPerBlock(config, parent.Time)) * params.BlobTxBlobGasPerBlob
|
||||||
parentExcessBlobGas uint64
|
parentExcessBlobGas uint64
|
||||||
parentBlobGasUsed uint64
|
parentBlobGasUsed uint64
|
||||||
)
|
)
|
||||||
|
|
@ -88,6 +88,67 @@ func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TargetBlobsPerBlock returns the target blobs per block associated with
|
||||||
|
// requested time.
|
||||||
|
func TargetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
|
||||||
|
if cfg.BlobScheduleConfig == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
london = cfg.LondonBlock
|
||||||
|
s = cfg.BlobScheduleConfig
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case cfg.IsPrague(london, time) && s.Prague != nil:
|
||||||
|
return s.Prague.Target
|
||||||
|
case cfg.IsCancun(london, time) && s.Cancun != nil:
|
||||||
|
return s.Cancun.Target
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp.
|
||||||
|
func MaxBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
|
||||||
|
if cfg.BlobScheduleConfig == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
london = cfg.LondonBlock
|
||||||
|
s = cfg.BlobScheduleConfig
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case cfg.IsPrague(london, time) && s.Prague != nil:
|
||||||
|
return s.Prague.Max
|
||||||
|
case cfg.IsCancun(london, time) && s.Cancun != nil:
|
||||||
|
return s.Cancun.Max
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxBlobsPerBlock returns the maximum blob gas that can be spent in a block at the given timestamp.
|
||||||
|
func MaxBlobGasPerBlock(cfg *params.ChainConfig, time uint64) uint64 {
|
||||||
|
return uint64(MaxBlobsPerBlock(cfg, time)) * params.BlobTxBlobGasPerBlob
|
||||||
|
}
|
||||||
|
|
||||||
|
// LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the
|
||||||
|
// configuration, regardless of the currently active fork.
|
||||||
|
func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int {
|
||||||
|
s := cfg.BlobScheduleConfig
|
||||||
|
if s == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case s.Prague != nil:
|
||||||
|
return s.Prague.Max
|
||||||
|
case s.Cancun != nil:
|
||||||
|
return s.Cancun.Max
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// fakeExponential approximates factor * e ** (numerator / denominator) using
|
// fakeExponential approximates factor * e ** (numerator / denominator) using
|
||||||
// Taylor expansion.
|
// Taylor expansion.
|
||||||
func fakeExponential(factor, numerator, denominator *big.Int) *big.Int {
|
func fakeExponential(factor, numerator, denominator *big.Int) *big.Int {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import (
|
||||||
func TestCalcExcessBlobGas(t *testing.T) {
|
func TestCalcExcessBlobGas(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
config = params.MainnetChainConfig
|
config = params.MainnetChainConfig
|
||||||
targetBlobs = config.TargetBlobsPerBlock(*config.CancunTime)
|
targetBlobs = TargetBlobsPerBlock(config, *config.CancunTime)
|
||||||
targetBlobGas = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob
|
targetBlobGas = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob
|
||||||
)
|
)
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
|
|
|
||||||
|
|
@ -387,7 +387,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres
|
||||||
fails = append(fails, id)
|
fails = append(fails, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
slotter := newSlotter(p.chain.Config().LatestMaxBlobsPerBlock())
|
slotter := newSlotter(eip4844.LatestMaxBlobsPerBlock(p.chain.Config()))
|
||||||
store, err := billy.Open(billy.Options{Path: queuedir, Repair: true}, slotter, index)
|
store, err := billy.Open(billy.Options{Path: queuedir, Repair: true}, slotter, index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -421,7 +421,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres
|
||||||
|
|
||||||
// Pool initialized, attach the blob limbo to it to track blobs included
|
// Pool initialized, attach the blob limbo to it to track blobs included
|
||||||
// recently but not yet finalized
|
// recently but not yet finalized
|
||||||
p.limbo, err = newLimbo(limbodir, p.chain.Config().LatestMaxBlobsPerBlock())
|
p.limbo, err = newLimbo(limbodir, eip4844.LatestMaxBlobsPerBlock(p.chain.Config()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.Close()
|
p.Close()
|
||||||
return err
|
return err
|
||||||
|
|
@ -1599,7 +1599,8 @@ func (p *BlobPool) updateStorageMetrics() {
|
||||||
metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotusedGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.FilledSlots))
|
metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotusedGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.FilledSlots))
|
||||||
metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotgapsGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.GappedSlots))
|
metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotgapsGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.GappedSlots))
|
||||||
|
|
||||||
if shelf.SlotSize/blobSize > uint32(p.chain.Config().LatestMaxBlobsPerBlock()) {
|
maxBlobs := eip4844.LatestMaxBlobsPerBlock(p.chain.Config())
|
||||||
|
if shelf.SlotSize/blobSize > uint32(maxBlobs) {
|
||||||
oversizedDataused += slotDataused
|
oversizedDataused += slotDataused
|
||||||
oversizedDatagaps += slotDatagaps
|
oversizedDatagaps += slotDatagaps
|
||||||
oversizedSlotused += shelf.FilledSlots
|
oversizedSlotused += shelf.FilledSlots
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -134,8 +135,9 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
if len(hashes) == 0 {
|
if len(hashes) == 0 {
|
||||||
return errors.New("blobless blob transaction")
|
return errors.New("blobless blob transaction")
|
||||||
}
|
}
|
||||||
if max := opts.Config.MaxBlobsPerBlock(head.Time); len(hashes) > max {
|
maxBlobs := eip4844.MaxBlobsPerBlock(opts.Config, head.Time)
|
||||||
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), max)
|
if len(hashes) > maxBlobs {
|
||||||
|
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), maxBlobs)
|
||||||
}
|
}
|
||||||
// Ensure commitments, proofs and hashes are valid
|
// Ensure commitments, proofs and hashes are valid
|
||||||
if err := validateBlobSidecar(hashes, sidecar); err != nil {
|
if err := validateBlobSidecar(hashes, sidecar); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,8 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
|
||||||
// Compute gas used ratio for normal and blob gas.
|
// Compute gas used ratio for normal and blob gas.
|
||||||
bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
|
bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
|
||||||
if blobGasUsed := bf.header.BlobGasUsed; blobGasUsed != nil {
|
if blobGasUsed := bf.header.BlobGasUsed; blobGasUsed != nil {
|
||||||
bf.results.blobGasUsedRatio = float64(*blobGasUsed) / float64(config.MaxBlobsPerBlock(bf.header.Time))
|
maxBlobs := eip4844.MaxBlobsPerBlock(config, bf.header.Time)
|
||||||
|
bf.results.blobGasUsedRatio = float64(*blobGasUsed) / float64(maxBlobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(percentiles) == 0 {
|
if len(percentiles) == 0 {
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
|
||||||
if args.BlobHashes != nil && len(args.BlobHashes) == 0 {
|
if args.BlobHashes != nil && len(args.BlobHashes) == 0 {
|
||||||
return errors.New(`need at least 1 blob for a blob transaction`)
|
return errors.New(`need at least 1 blob for a blob transaction`)
|
||||||
}
|
}
|
||||||
maxBlobs := b.ChainConfig().MaxBlobsPerBlock(b.CurrentHeader().Time)
|
maxBlobs := eip4844.MaxBlobsPerBlock(b.ChainConfig(), b.CurrentHeader().Time)
|
||||||
if args.BlobHashes != nil && len(args.BlobHashes) > maxBlobs {
|
if args.BlobHashes != nil && len(args.BlobHashes) > maxBlobs {
|
||||||
return fmt.Errorf(`too many blobs in transaction (have=%d, max=%d)`, len(args.BlobHashes), maxBlobs)
|
return fmt.Errorf(`too many blobs in transaction (have=%d, max=%d)`, len(args.BlobHashes), maxBlobs)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio
|
||||||
// isn't really a better place right now. The blob gas limit is checked at block validation time
|
// isn't really a better place right now. The blob gas limit is checked at block validation time
|
||||||
// and not during execution. This means core.ApplyTransaction will not return an error if the
|
// and not during execution. This means core.ApplyTransaction will not return an error if the
|
||||||
// tx has too many blobs. So we have to explicitly check it here.
|
// tx has too many blobs. So we have to explicitly check it here.
|
||||||
maxBlobs := miner.chainConfig.MaxBlobsPerBlock(env.header.Time)
|
maxBlobs := eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time)
|
||||||
if env.blobs+len(sc.Blobs) > maxBlobs {
|
if env.blobs+len(sc.Blobs) > maxBlobs {
|
||||||
return errors.New("max data blobs reached")
|
return errors.New("max data blobs reached")
|
||||||
}
|
}
|
||||||
|
|
@ -331,7 +331,7 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran
|
||||||
}
|
}
|
||||||
// If we don't have enough blob space for any further blob transactions,
|
// If we don't have enough blob space for any further blob transactions,
|
||||||
// skip that list altogether
|
// skip that list altogether
|
||||||
if !blobTxs.Empty() && env.blobs >= miner.chainConfig.MaxBlobsPerBlock(env.header.Time) {
|
if !blobTxs.Empty() && env.blobs >= eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) {
|
||||||
log.Trace("Not enough blob space for further blob transactions")
|
log.Trace("Not enough blob space for further blob transactions")
|
||||||
blobTxs.Clear()
|
blobTxs.Clear()
|
||||||
// Fall though to pick up any plain txs
|
// Fall though to pick up any plain txs
|
||||||
|
|
@ -370,7 +370,7 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran
|
||||||
// blobs or not, however the max check panics when called on a chain without
|
// blobs or not, however the max check panics when called on a chain without
|
||||||
// a defined schedule, so we need to verify it's safe to call.
|
// a defined schedule, so we need to verify it's safe to call.
|
||||||
if miner.chainConfig.IsCancun(env.header.Number, env.header.Time) {
|
if miner.chainConfig.IsCancun(env.header.Number, env.header.Time) {
|
||||||
left := miner.chainConfig.MaxBlobsPerBlock(env.header.Time) - env.blobs
|
left := eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) - env.blobs
|
||||||
if left < int(ltx.BlobGas/params.BlobTxBlobGasPerBlob) {
|
if left < int(ltx.BlobGas/params.BlobTxBlobGasPerBlob) {
|
||||||
log.Trace("Not enough blob space left for transaction", "hash", ltx.Hash, "left", left, "needed", ltx.BlobGas/params.BlobTxBlobGasPerBlob)
|
log.Trace("Not enough blob space left for transaction", "hash", ltx.Hash, "left", left, "needed", ltx.BlobGas/params.BlobTxBlobGasPerBlob)
|
||||||
txs.Pop()
|
txs.Pop()
|
||||||
|
|
|
||||||
|
|
@ -491,67 +491,6 @@ type BlobScheduleConfig struct {
|
||||||
Verkle *BlobConfig `json:"verkle,omitempty"`
|
Verkle *BlobConfig `json:"verkle,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TargetBlobsPerBlock returns the target blobs per block associated with
|
|
||||||
// requested time.
|
|
||||||
func (c *ChainConfig) TargetBlobsPerBlock(time uint64) int {
|
|
||||||
if c.BlobScheduleConfig == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
london = c.LondonBlock
|
|
||||||
s = c.BlobScheduleConfig
|
|
||||||
)
|
|
||||||
switch {
|
|
||||||
case c.IsPrague(london, time) && s.Prague != nil:
|
|
||||||
return s.Prague.Target
|
|
||||||
case c.IsCancun(london, time) && s.Cancun != nil:
|
|
||||||
return s.Cancun.Target
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp.
|
|
||||||
func (c *ChainConfig) MaxBlobsPerBlock(time uint64) int {
|
|
||||||
if c.BlobScheduleConfig == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
london = c.LondonBlock
|
|
||||||
s = c.BlobScheduleConfig
|
|
||||||
)
|
|
||||||
switch {
|
|
||||||
case c.IsPrague(london, time) && s.Prague != nil:
|
|
||||||
return s.Prague.Max
|
|
||||||
case c.IsCancun(london, time) && s.Cancun != nil:
|
|
||||||
return s.Cancun.Max
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MaxBlobsPerBlock returns the maximum blob gas that can be spent in a block at the given timestamp.
|
|
||||||
func (c *ChainConfig) MaxBlobGasPerBlock(time uint64) uint64 {
|
|
||||||
return uint64(c.MaxBlobsPerBlock(time)) * BlobTxBlobGasPerBlob
|
|
||||||
}
|
|
||||||
|
|
||||||
// LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the
|
|
||||||
// configuration, regardless of the currently active fork.
|
|
||||||
func (c *ChainConfig) LatestMaxBlobsPerBlock() int {
|
|
||||||
s := c.BlobScheduleConfig
|
|
||||||
if s == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case s.Prague != nil:
|
|
||||||
return s.Prague.Max
|
|
||||||
case s.Cancun != nil:
|
|
||||||
return s.Cancun.Max
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsHomestead returns whether num is either equal to the homestead block or greater.
|
// IsHomestead returns whether num is either equal to the homestead block or greater.
|
||||||
func (c *ChainConfig) IsHomestead(num *big.Int) bool {
|
func (c *ChainConfig) IsHomestead(num *big.Int) bool {
|
||||||
return isBlockForked(c.HomesteadBlock, num)
|
return isBlockForked(c.HomesteadBlock, num)
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
||||||
// Here, we just do this shortcut smaller fix, since state tests do not
|
// Here, we just do this shortcut smaller fix, since state tests do not
|
||||||
// utilize those codepaths.
|
// utilize those codepaths.
|
||||||
if config.IsCancun(new(big.Int), block.Time()) {
|
if config.IsCancun(new(big.Int), block.Time()) {
|
||||||
if len(msg.BlobHashes) > config.MaxBlobsPerBlock(block.Time()) {
|
if len(msg.BlobHashes) > eip4844.MaxBlobsPerBlock(config, block.Time()) {
|
||||||
return st, common.Hash{}, 0, errors.New("blob gas exceeds maximum")
|
return st, common.Hash{}, 0, errors.New("blob gas exceeds maximum")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue