Skip to content

Commit 1d1173d

Browse files
committed
consensus/misc/eip4844: make it work
It's not great to call scheduleAtTime so many times. The function is much more expensive now since it has to establish the fork order every time. A later refactoring needs to turn it around to compute the order only once.
1 parent 99ad22f commit 1d1173d

File tree

2 files changed

+41
-23
lines changed

2 files changed

+41
-23
lines changed

consensus/misc/eip4844/eip4844.go

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ package eip4844
1919
import (
2020
"errors"
2121
"fmt"
22+
"math"
2223
"math/big"
23-
"slices"
2424

2525
"github.com/ethereum/go-ethereum/core/types"
2626
"github.com/ethereum/go-ethereum/params"
@@ -38,15 +38,22 @@ func VerifyEIP4844Header(config *params.Config2, parent, header *types.Header) e
3838
if header.Number.Uint64() != parent.Number.Uint64()+1 {
3939
panic("bad header pair")
4040
}
41+
4142
// Verify the header is not malformed
4243
if header.ExcessBlobGas == nil {
4344
return errors.New("header is missing excessBlobGas")
4445
}
4546
if header.BlobGasUsed == nil {
4647
return errors.New("header is missing blobGasUsed")
4748
}
49+
50+
blobcfg := scheduleAtTime(config, header.Time)
51+
if blobcfg == nil {
52+
return fmt.Errorf("blob schedule is undefined at time %d", header.Time)
53+
}
54+
4855
// Verify that the blob gas used remains within reasonable limits.
49-
maxBlobGas := MaxBlobGasPerBlock(config, header.Time)
56+
maxBlobGas := uint64(blobcfg.Max) * params.BlobTxBlobGasPerBlob
5057
if *header.BlobGasUsed > maxBlobGas {
5158
return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", *header.BlobGasUsed, maxBlobGas)
5259
}
@@ -101,18 +108,21 @@ func CalcExcessBlobGas(config *params.Config2, parent *types.Header, headTimesta
101108

102109
// CalcBlobFee calculates the blobfee from the header's excess blob gas field.
103110
func CalcBlobFee(config *params.Config2, header *types.Header) *big.Int {
104-
schedule := params.BlobSchedule.Get(config)
105-
if schedule == nil {
111+
blobcfg := scheduleAtTime(config, header.Time)
112+
if blobcfg == nil {
106113
return new(big.Int)
107114
}
108-
f := config.LatestFork(header.Time)
109-
frac := schedule[f].UpdateFraction
115+
frac := blobcfg.UpdateFraction
110116
return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(*header.ExcessBlobGas), new(big.Int).SetUint64(frac))
111117
}
112118

113119
// MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp.
114120
func MaxBlobsPerBlock(cfg *params.Config2, time uint64) int {
115-
return scheduleAtTime(cfg, time).Max
121+
blobcfg := scheduleAtTime(cfg, time)
122+
if blobcfg == nil {
123+
return 0
124+
}
125+
return blobcfg.Max
116126
}
117127

118128
// MaxBlobsPerBlock returns the maximum blob gas that can be spent in a block at the given timestamp.
@@ -123,30 +133,38 @@ func MaxBlobGasPerBlock(cfg *params.Config2, time uint64) uint64 {
123133
// LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the
124134
// configuration, regardless of the currently active fork.
125135
func LatestMaxBlobsPerBlock(cfg *params.Config2) int {
126-
schedule := params.BlobSchedule.Get(cfg)
127-
if schedule == nil {
128-
return 0
129-
}
130-
for _, f := range slices.Backward(forks.CanonOrder) {
131-
if f.HasBlobs() && cfg.Scheduled(f) {
132-
return schedule[f].Max
133-
}
134-
}
135-
return 0
136+
blobcfg := scheduleAtTime(cfg, math.MaxUint64)
137+
return blobcfg.Max
136138
}
137139

138140
// targetBlobsPerBlock returns the target number of blobs in a block at the given timestamp.
139141
func targetBlobsPerBlock(cfg *params.Config2, time uint64) int {
140142
return scheduleAtTime(cfg, time).Target
141143
}
142144

143-
func scheduleAtTime(cfg *params.Config2, time uint64) params.BlobConfig {
145+
// scheduleAtTime resolves the blob schedule at the given timestamp.
146+
func scheduleAtTime(cfg *params.Config2, time uint64) *params.BlobConfig {
144147
schedule := params.BlobSchedule.Get(cfg)
145148
if schedule == nil {
146-
return params.BlobConfig{}
149+
return nil
150+
}
151+
152+
// Find the latest fork defined by the schedule.
153+
forkList := make([]forks.Fork, 0, len(schedule))
154+
for f := range schedule {
155+
act, ok := cfg.Activation(f)
156+
if ok && act <= time {
157+
forkList = append(forkList, f)
158+
}
159+
}
160+
forkList = forks.DependencyOrder(forkList)
161+
162+
// Return the blob config of the last available fork.
163+
if len(forkList) == 0 {
164+
return nil
147165
}
148-
f := cfg.LatestFork(time)
149-
return schedule[f]
166+
blobcfg := schedule[forkList[len(forkList)-1]]
167+
return &blobcfg
150168
}
151169

152170
// fakeExponential approximates factor * e ** (numerator / denominator) using

consensus/misc/eip4844/eip4844_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ func TestCalcBlobFee(t *testing.T) {
8888
forks.London: 0,
8989
forks.Cancun: 0,
9090
},
91-
params.BlobSchedule{
91+
params.BlobSchedule.V(map[forks.Fork]params.BlobConfig{
9292
forks.Cancun: *params.DefaultCancunBlobConfig,
93-
},
93+
}),
9494
)
9595
header := &types.Header{ExcessBlobGas: &tt.excessBlobGas}
9696
have := CalcBlobFee(config, header)

0 commit comments

Comments
 (0)