diff --git a/params/blob_config.go b/params/blob_config.go index 93a8df80c..0bbc419a8 100644 --- a/params/blob_config.go +++ b/params/blob_config.go @@ -53,6 +53,21 @@ func (bcfg *BlobConfig) MaxBlobGas() uint64 { return uint64(bcfg.Max) * BlobTxBlobGasPerBlob } +// validate checks that a blob config from a chain configuration is sane. +// UpdateFraction must be non-zero because it is used as a division denominator. +func (bcfg *BlobConfig) validate() error { + if bcfg.Max < 0 { + return errors.New("max < 0") + } + if bcfg.Target < 0 { + return errors.New("target < 0") + } + if bcfg.UpdateFraction == 0 { + return errors.New("update fraction must be defined and non-zero") + } + return nil +} + // blobPriceEIP4844 returns the price for EIP-4844 of one blob in Wei. func (bcfg *BlobConfig) BlobPriceEIP4844(excessBlobGas uint64) *big.Int { f := bcfg.BlobBaseFeeEIP4844(excessBlobGas) diff --git a/params/config.go b/params/config.go index fcce26b04..20cc8f9d2 100644 --- a/params/config.go +++ b/params/config.go @@ -449,7 +449,7 @@ func (c *ChainConfig) Copy() *ChainConfig { // BlobConfig returns the blob config associated with the provided fork. func (c *ChainConfig) BlobConfig(head *big.Int) *BlobConfig { - if c.IsOsakaForkEnabled(head) { + if c.IsOsakaForkEnabled(head) && c.BlobScheduleConfig != nil { return c.BlobScheduleConfig.Osaka } return nil @@ -649,6 +649,19 @@ func (c *ChainConfig) CheckConfigForkOrder() error { lastFork = cur } } + + // Check that the fork enabling blobs explicitly defines a valid blob schedule. + var osakaBlobConfig *BlobConfig + if c.BlobScheduleConfig != nil { + osakaBlobConfig = c.BlobScheduleConfig.Osaka + } + if osakaBlobConfig != nil { + if err := osakaBlobConfig.validate(); err != nil { + return fmt.Errorf("invalid chain configuration in blobSchedule for fork %q: %v", "osaka", err) + } + } else if c.OsakaCompatibleBlock != nil { + return fmt.Errorf("invalid chain configuration: missing entry for fork %q in blobSchedule", "osaka") + } return nil }