Skip to content

Commit 815868e

Browse files
committed
Add blob schedule support
1 parent 93a5fdd commit 815868e

File tree

10 files changed

+69
-81
lines changed

10 files changed

+69
-81
lines changed

api/client/builder/client.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func (c *Client) GetHeader(ctx context.Context, slot primitives.Slot, parentHash
241241
return nil, errors.Wrap(err, "error getting header from builder server")
242242
}
243243

244-
bid, err := c.parseHeaderResponse(data, header)
244+
bid, err := c.parseHeaderResponse(data, header, slot)
245245
if err != nil {
246246
return nil, errors.Wrapf(
247247
err,
@@ -254,7 +254,7 @@ func (c *Client) GetHeader(ctx context.Context, slot primitives.Slot, parentHash
254254
return bid, nil
255255
}
256256

257-
func (c *Client) parseHeaderResponse(data []byte, header http.Header) (SignedBid, error) {
257+
func (c *Client) parseHeaderResponse(data []byte, header http.Header, slot primitives.Slot) (SignedBid, error) {
258258
var versionHeader string
259259
if c.sszEnabled || header.Get(api.VersionHeader) != "" {
260260
versionHeader = header.Get(api.VersionHeader)
@@ -276,7 +276,7 @@ func (c *Client) parseHeaderResponse(data []byte, header http.Header) (SignedBid
276276
}
277277

278278
if ver >= version.Electra {
279-
return c.parseHeaderElectra(data)
279+
return c.parseHeaderElectra(data, slot)
280280
}
281281
if ver >= version.Deneb {
282282
return c.parseHeaderDeneb(data)
@@ -291,7 +291,7 @@ func (c *Client) parseHeaderResponse(data []byte, header http.Header) (SignedBid
291291
return nil, fmt.Errorf("unsupported header version %s", versionHeader)
292292
}
293293

294-
func (c *Client) parseHeaderElectra(data []byte) (SignedBid, error) {
294+
func (c *Client) parseHeaderElectra(data []byte, slot primitives.Slot) (SignedBid, error) {
295295
if c.sszEnabled {
296296
sb := &ethpb.SignedBuilderBidElectra{}
297297
if err := sb.UnmarshalSSZ(data); err != nil {
@@ -303,7 +303,7 @@ func (c *Client) parseHeaderElectra(data []byte) (SignedBid, error) {
303303
if err := json.Unmarshal(data, hr); err != nil {
304304
return nil, errors.Wrap(err, "could not unmarshal ExecHeaderResponseElectra JSON")
305305
}
306-
p, err := hr.ToProto()
306+
p, err := hr.ToProto(slot)
307307
if err != nil {
308308
return nil, errors.Wrap(err, "could not convert ExecHeaderResponseElectra to proto")
309309
}

api/client/builder/client_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ func TestClient_GetHeader(t *testing.T) {
532532
require.Equal(t, expectedPath, r.URL.Path)
533533
epr := &ExecHeaderResponseElectra{}
534534
require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponseElectra), epr))
535-
pro, err := epr.ToProto()
535+
pro, err := epr.ToProto(100)
536536
require.NoError(t, err)
537537
ssz, err := pro.MarshalSSZ()
538538
require.NoError(t, err)

api/client/builder/types.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,8 +1284,8 @@ type ExecHeaderResponseElectra struct {
12841284
}
12851285

12861286
// ToProto creates a SignedBuilderBidElectra Proto from ExecHeaderResponseElectra.
1287-
func (ehr *ExecHeaderResponseElectra) ToProto() (*eth.SignedBuilderBidElectra, error) {
1288-
bb, err := ehr.Data.Message.ToProto()
1287+
func (ehr *ExecHeaderResponseElectra) ToProto(slot types.Slot) (*eth.SignedBuilderBidElectra, error) {
1288+
bb, err := ehr.Data.Message.ToProto(slot)
12891289
if err != nil {
12901290
return nil, err
12911291
}
@@ -1296,13 +1296,13 @@ func (ehr *ExecHeaderResponseElectra) ToProto() (*eth.SignedBuilderBidElectra, e
12961296
}
12971297

12981298
// ToProto creates a BuilderBidElectra Proto from BuilderBidElectra.
1299-
func (bb *BuilderBidElectra) ToProto() (*eth.BuilderBidElectra, error) {
1299+
func (bb *BuilderBidElectra) ToProto(slot types.Slot) (*eth.BuilderBidElectra, error) {
13001300
header, err := bb.Header.ToProto()
13011301
if err != nil {
13021302
return nil, err
13031303
}
1304-
if len(bb.BlobKzgCommitments) > params.BeaconConfig().MaxBlobsPerBlockByVersion(version.Electra) {
1305-
return nil, fmt.Errorf("blob commitment count %d exceeds the maximum %d", len(bb.BlobKzgCommitments), params.BeaconConfig().MaxBlobsPerBlockByVersion(version.Electra))
1304+
if len(bb.BlobKzgCommitments) > params.BeaconConfig().MaxBlobsPerBlock(slot) {
1305+
return nil, fmt.Errorf("blob commitment count %d exceeds the maximum %d", len(bb.BlobKzgCommitments), params.BeaconConfig().MaxBlobsPerBlock(slot))
13061306
}
13071307
kzgCommitments := make([][]byte, len(bb.BlobKzgCommitments))
13081308
for i, commit := range bb.BlobKzgCommitments {

beacon-chain/rpc/eth/blob/handlers_test.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ func TestBlobs(t *testing.T) {
265265
require.Equal(t, false, resp.Finalized)
266266
})
267267
t.Run("blob index over max", func(t *testing.T) {
268-
overLimit := params.BeaconConfig().MaxBlobsPerBlockByVersion(version.Deneb)
268+
overLimit := maxBlobsPerBlockByVersion(version.Deneb)
269269
u := fmt.Sprintf("http://foo.example/123?indices=%d", overLimit)
270270
request := httptest.NewRequest("GET", u, nil)
271271
writer := httptest.NewRecorder()
@@ -415,7 +415,7 @@ func TestBlobs_Electra(t *testing.T) {
415415
params.OverrideBeaconConfig(cfg)
416416

417417
db := testDB.SetupDB(t)
418-
electraBlock, blobs := util.GenerateTestElectraBlockWithSidecar(t, [32]byte{}, 123, params.BeaconConfig().MaxBlobsPerBlockByVersion(version.Electra))
418+
electraBlock, blobs := util.GenerateTestElectraBlockWithSidecar(t, [32]byte{}, 123, maxBlobsPerBlockByVersion(version.Electra))
419419
require.NoError(t, db.SaveBlock(context.Background(), electraBlock))
420420
bs := filesystem.NewEphemeralBlobStorage(t)
421421
testSidecars := verification.FakeVerifySliceForTest(t, blobs)
@@ -451,7 +451,7 @@ func TestBlobs_Electra(t *testing.T) {
451451
assert.Equal(t, http.StatusOK, writer.Code)
452452
resp := &structs.SidecarsResponse{}
453453
require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
454-
require.Equal(t, params.BeaconConfig().MaxBlobsPerBlockByVersion(version.Electra), len(resp.Data))
454+
require.Equal(t, maxBlobsPerBlockByVersion(version.Electra), len(resp.Data))
455455
sidecar := resp.Data[0]
456456
require.NotNil(t, sidecar)
457457
assert.Equal(t, "0", sidecar.Index)
@@ -464,7 +464,7 @@ func TestBlobs_Electra(t *testing.T) {
464464
require.Equal(t, false, resp.Finalized)
465465
})
466466
t.Run("requested blob index at max", func(t *testing.T) {
467-
limit := params.BeaconConfig().MaxBlobsPerBlockByVersion(version.Electra) - 1
467+
limit := maxBlobsPerBlockByVersion(version.Electra) - 1
468468
u := fmt.Sprintf("http://foo.example/123?indices=%d", limit)
469469
request := httptest.NewRequest("GET", u, nil)
470470
writer := httptest.NewRecorder()
@@ -496,7 +496,7 @@ func TestBlobs_Electra(t *testing.T) {
496496
require.Equal(t, false, resp.Finalized)
497497
})
498498
t.Run("blob index over max", func(t *testing.T) {
499-
overLimit := params.BeaconConfig().MaxBlobsPerBlockByVersion(version.Electra)
499+
overLimit := maxBlobsPerBlockByVersion(version.Electra)
500500
u := fmt.Sprintf("http://foo.example/123?indices=%d", overLimit)
501501
request := httptest.NewRequest("GET", u, nil)
502502
writer := httptest.NewRecorder()
@@ -554,3 +554,11 @@ func Test_parseIndices(t *testing.T) {
554554
})
555555
}
556556
}
557+
558+
func maxBlobsPerBlockByVersion(v int) int {
559+
if v >= version.Electra {
560+
return params.BeaconConfig().DeprecatedMaxBlobsPerBlockElectra
561+
}
562+
563+
return params.BeaconConfig().DeprecatedMaxBlobsPerBlock
564+
}

changelog/tt_corn.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Added
2+
3+
- Add blob schedule support from https://github.com/ethereum/consensus-specs/pull/4277

config/params/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ go_test(
7373
"//consensus-types/primitives:go_default_library",
7474
"//encoding/bytesutil:go_default_library",
7575
"//io/file:go_default_library",
76-
"//runtime/version:go_default_library",
7776
"//testing/assert:go_default_library",
7877
"//testing/require:go_default_library",
7978
"@com_github_sirupsen_logrus//:go_default_library",

config/params/config.go

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ type BeaconChainConfig struct {
295295
NodeIdBits uint64 `yaml:"NODE_ID_BITS" spec:"true"` // NodeIdBits defines the bit length of a node id.
296296

297297
// Blobs Values
298+
BlobSchedule []BlobScheduleEntry `yaml:"BLOB_SCHEDULE"`
298299

299300
// Deprecated_MaxBlobsPerBlock defines the max blobs that could exist in a block.
300301
// Deprecated: This field is no longer supported. Avoid using it.
@@ -313,6 +314,11 @@ type BeaconChainConfig struct {
313314
DeprecatedMaxBlobsPerBlockFulu int `yaml:"MAX_BLOBS_PER_BLOCK_FULU" spec:"true"`
314315
}
315316

317+
type BlobScheduleEntry struct {
318+
Epoch primitives.Epoch `yaml:"EPOCH"`
319+
MaxBlobsPerBlock uint64 `yaml:"MAX_BLOBS_PER_BLOCK"`
320+
}
321+
316322
// InitializeForkSchedule initializes the schedules forks baked into the config.
317323
func (b *BeaconChainConfig) InitializeForkSchedule() {
318324
// Reset Fork Version Schedule.
@@ -400,46 +406,47 @@ func (b *BeaconChainConfig) TargetBlobsPerBlock(slot primitives.Slot) int {
400406
return b.DeprecatedMaxBlobsPerBlock / 2
401407
}
402408

403-
// MaxBlobsPerBlock returns the maximum number of blobs per block for the given slot.
404409
func (b *BeaconChainConfig) MaxBlobsPerBlock(slot primitives.Slot) int {
405410
epoch := primitives.Epoch(slot.DivSlot(b.SlotsPerEpoch))
406411

407-
if epoch >= b.FuluForkEpoch {
408-
return b.DeprecatedMaxBlobsPerBlockFulu
412+
if len(b.BlobSchedule) > 0 {
413+
// Assume BlobSchedule is already sorted ascending by Epoch
414+
for i := len(b.BlobSchedule) - 1; i >= 0; i-- {
415+
if epoch >= b.BlobSchedule[i].Epoch {
416+
return int(b.BlobSchedule[i].MaxBlobsPerBlock)
417+
}
418+
}
409419
}
410420

411-
if epoch >= b.ElectraForkEpoch {
412-
return b.DeprecatedMaxBlobsPerBlockElectra
413-
}
414-
415-
return b.DeprecatedMaxBlobsPerBlock
416-
}
417-
418-
// MaxBlobsPerBlockByVersion returns the maximum number of blobs per block for the given fork version
419-
func (b *BeaconChainConfig) MaxBlobsPerBlockByVersion(v int) int {
420-
if v >= version.Fulu {
421+
switch {
422+
case epoch >= b.FuluForkEpoch:
421423
return b.DeprecatedMaxBlobsPerBlockFulu
422-
}
423-
424-
if v >= version.Electra {
424+
case epoch >= b.ElectraForkEpoch:
425425
return b.DeprecatedMaxBlobsPerBlockElectra
426+
default:
427+
return b.DeprecatedMaxBlobsPerBlock
426428
}
427-
428-
return b.DeprecatedMaxBlobsPerBlock
429429
}
430430

431-
// MaxBlobsPerBlockByEpoch returns the maximum number of blobs per block for the given epoch,
432-
// adjusting for the Electra fork.
431+
// MaxBlobsPerBlockAtEpoch returns the maximum number of blobs per block for the given epoch
433432
func (b *BeaconChainConfig) MaxBlobsPerBlockAtEpoch(epoch primitives.Epoch) int {
434-
if epoch >= b.FuluForkEpoch {
435-
return b.DeprecatedMaxBlobsPerBlockFulu
433+
if len(b.BlobSchedule) > 0 {
434+
// Assume BlobSchedule is already sorted ascending by Epoch
435+
for i := len(b.BlobSchedule) - 1; i >= 0; i-- {
436+
if epoch >= b.BlobSchedule[i].Epoch {
437+
return int(b.BlobSchedule[i].MaxBlobsPerBlock)
438+
}
439+
}
436440
}
437441

438-
if epoch >= b.ElectraForkEpoch {
442+
switch {
443+
case epoch >= b.FuluForkEpoch:
444+
return b.DeprecatedMaxBlobsPerBlockFulu
445+
case epoch >= b.ElectraForkEpoch:
439446
return b.DeprecatedMaxBlobsPerBlockElectra
447+
default:
448+
return b.DeprecatedMaxBlobsPerBlock
440449
}
441-
442-
return b.DeprecatedMaxBlobsPerBlock
443450
}
444451

445452
// DenebEnabled centralizes the check to determine if code paths

config/params/config_test.go

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"github.com/OffchainLabs/prysm/v6/beacon-chain/state/genesis"
1010
"github.com/OffchainLabs/prysm/v6/config/params"
1111
"github.com/OffchainLabs/prysm/v6/consensus-types/primitives"
12-
"github.com/OffchainLabs/prysm/v6/runtime/version"
1312
"github.com/OffchainLabs/prysm/v6/testing/require"
1413
)
1514

@@ -123,41 +122,3 @@ func Test_TargetBlobCount(t *testing.T) {
123122
require.Equal(t, cfg.TargetBlobsPerBlock(primitives.Slot(cfg.ElectraForkEpoch)*cfg.SlotsPerEpoch), 6)
124123
cfg.ElectraForkEpoch = math.MaxUint64
125124
}
126-
127-
func TestMaxBlobsPerBlockByVersion(t *testing.T) {
128-
tests := []struct {
129-
name string
130-
v int
131-
want int
132-
}{
133-
{
134-
name: "Version below Electra",
135-
v: version.Electra - 1,
136-
want: params.BeaconConfig().DeprecatedMaxBlobsPerBlock,
137-
},
138-
{
139-
name: "Version equal to Electra",
140-
v: version.Electra,
141-
want: params.BeaconConfig().DeprecatedMaxBlobsPerBlockElectra,
142-
},
143-
{
144-
name: "Version equal to Fulu",
145-
v: version.Fulu,
146-
want: params.BeaconConfig().DeprecatedMaxBlobsPerBlockFulu,
147-
},
148-
{
149-
name: "Version above Fulu",
150-
v: version.Fulu + 1,
151-
want: params.BeaconConfig().DeprecatedMaxBlobsPerBlockFulu,
152-
},
153-
}
154-
155-
for _, tt := range tests {
156-
t.Run(tt.name, func(t *testing.T) {
157-
got := params.BeaconConfig().MaxBlobsPerBlockByVersion(tt.v)
158-
if got != tt.want {
159-
t.Errorf("MaxBlobsPerBlockByVersion(%d) = %d, want %d", tt.v, got, tt.want)
160-
}
161-
})
162-
}
163-
}

config/params/mainnet_config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,11 @@ var mainnetBeaconConfig = &BeaconChainConfig{
339339
AttestationSubnetPrefixBits: 6,
340340
SubnetsPerNode: 2,
341341
NodeIdBits: 256,
342+
343+
BlobSchedule: []BlobScheduleEntry{
344+
{Epoch: 269568, MaxBlobsPerBlock: 6},
345+
{Epoch: 364032, MaxBlobsPerBlock: 9},
346+
},
342347
}
343348

344349
// MainnetTestConfig provides a version of the mainnet config that has a different name

config/params/minimal_config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ func MinimalSpecConfig() *BeaconChainConfig {
127127
minimalConfig.ConfigName = MinimalName
128128
minimalConfig.PresetBase = "minimal"
129129

130+
minimalConfig.BlobSchedule = []BlobScheduleEntry{
131+
{Epoch: 18446744073709551615, MaxBlobsPerBlock: 6},
132+
{Epoch: 18446744073709551615, MaxBlobsPerBlock: 9},
133+
}
134+
130135
minimalConfig.InitializeForkSchedule()
131136
return minimalConfig
132137
}

0 commit comments

Comments
 (0)