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)
|
||||
if tx.Type() == types.BlobTxType {
|
||||
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 {
|
||||
err := fmt.Errorf("blob gas (%d) would exceed maximum allowance %d", used, max)
|
||||
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")
|
||||
}
|
||||
// Verify that the blob gas used remains within reasonable limits.
|
||||
maxBlobGas := config.MaxBlobGasPerBlock(header.Time)
|
||||
maxBlobGas := MaxBlobGasPerBlock(config, header.Time)
|
||||
if *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.
|
||||
func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header) uint64 {
|
||||
var (
|
||||
targetGas = uint64(config.TargetBlobsPerBlock(parent.Time)) * params.BlobTxBlobGasPerBlob
|
||||
targetGas = uint64(TargetBlobsPerBlock(config, parent.Time)) * params.BlobTxBlobGasPerBlob
|
||||
parentExcessBlobGas 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
|
||||
// Taylor expansion.
|
||||
func fakeExponential(factor, numerator, denominator *big.Int) *big.Int {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import (
|
|||
func TestCalcExcessBlobGas(t *testing.T) {
|
||||
var (
|
||||
config = params.MainnetChainConfig
|
||||
targetBlobs = config.TargetBlobsPerBlock(*config.CancunTime)
|
||||
targetBlobs = TargetBlobsPerBlock(config, *config.CancunTime)
|
||||
targetBlobGas = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob
|
||||
)
|
||||
var tests = []struct {
|
||||
|
|
|
|||
|
|
@ -387,7 +387,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres
|
|||
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)
|
||||
if err != nil {
|
||||
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
|
||||
// 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 {
|
||||
p.Close()
|
||||
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(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
|
||||
oversizedDatagaps += slotDatagaps
|
||||
oversizedSlotused += shelf.FilledSlots
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"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/state"
|
||||
"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 {
|
||||
return errors.New("blobless blob transaction")
|
||||
}
|
||||
if max := opts.Config.MaxBlobsPerBlock(head.Time); len(hashes) > max {
|
||||
return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), max)
|
||||
maxBlobs := eip4844.MaxBlobsPerBlock(opts.Config, head.Time)
|
||||
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
|
||||
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.
|
||||
bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
|
|||
if args.BlobHashes != nil && len(args.BlobHashes) == 0 {
|
||||
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 {
|
||||
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
|
||||
// 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.
|
||||
maxBlobs := miner.chainConfig.MaxBlobsPerBlock(env.header.Time)
|
||||
maxBlobs := eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time)
|
||||
if env.blobs+len(sc.Blobs) > maxBlobs {
|
||||
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,
|
||||
// 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")
|
||||
blobTxs.Clear()
|
||||
// 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
|
||||
// a defined schedule, so we need to verify it's safe to call.
|
||||
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) {
|
||||
log.Trace("Not enough blob space left for transaction", "hash", ltx.Hash, "left", left, "needed", ltx.BlobGas/params.BlobTxBlobGasPerBlob)
|
||||
txs.Pop()
|
||||
|
|
|
|||
|
|
@ -491,67 +491,6 @@ type BlobScheduleConfig struct {
|
|||
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.
|
||||
func (c *ChainConfig) IsHomestead(num *big.Int) bool {
|
||||
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
|
||||
// utilize those codepaths.
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue