Skip to content

Commit 3b3cea8

Browse files
committed
remove blinded block dependency in peerdas
1 parent faa4891 commit 3b3cea8

File tree

7 files changed

+106
-41
lines changed

7 files changed

+106
-41
lines changed

cl/cltypes/beacon_block.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ var (
4040
_ ssz2.SizedObjectSSZ = (*DenebSignedBeaconBlock)(nil)
4141
)
4242

43+
// ErrGloasCannotBlind is returned when Blinded() is called on a GLOAS block.
44+
// In GLOAS (EIP-7732/ePBS), the execution payload is delivered via a separate
45+
// SignedExecutionPayloadEnvelope, so the blinded block concept doesn't apply.
46+
// Callers should check the block version before calling Blinded() or handle this error.
47+
var ErrGloasCannotBlind = errors.New("blinded beacon block not supported for GLOAS blocks")
48+
4349
const (
4450
MaxAttesterSlashings = 2
4551
MaxProposerSlashings = 16
@@ -129,6 +135,25 @@ func (b *SignedBeaconBlock) Static() bool {
129135
return false
130136
}
131137

138+
// GetSlot returns the slot of the inner block.
139+
// Implements ColumnSyncableSignedBlock interface.
140+
func (b *SignedBeaconBlock) GetSlot() uint64 {
141+
return b.Block.Slot
142+
}
143+
144+
// BlockHashSSZ returns the hash of the inner block (not the signed block).
145+
// Implements ColumnSyncableSignedBlock interface.
146+
func (b *SignedBeaconBlock) BlockHashSSZ() ([32]byte, error) {
147+
return b.Block.HashSSZ()
148+
}
149+
150+
// GetBlobKzgCommitments returns blob KZG commitments from the block body.
151+
// Implements ColumnSyncableSignedBlock interface.
152+
// [Modified in Gloas:EIP7732] For GLOAS, commitments are in SignedExecutionPayloadBid.
153+
func (b *SignedBeaconBlock) GetBlobKzgCommitments() *solid.ListSSZ[*KZGCommitment] {
154+
return b.Block.Body.GetBlobKzgCommitments()
155+
}
156+
132157
// Definition of BeaconBlock
133158
type BeaconBlock struct {
134159
Slot uint64 `json:"slot,string"`
@@ -398,7 +423,7 @@ func (b *BeaconBody) Blinded() (*BlindedBeaconBody, error) {
398423
// [Modified in Gloas:EIP7732] Blinded concept not applicable to GLOAS blocks
399424
// In GLOAS, execution payload is delivered via SignedExecutionPayloadEnvelope
400425
if b.Version >= clparams.GloasVersion {
401-
return nil, errors.New("blinded beacon body not supported for GLOAS blocks")
426+
return nil, ErrGloasCannotBlind
402427
}
403428

404429
header, err := b.ExecutionPayload.PayloadHeader()

cl/cltypes/beacon_block_blinded.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,26 @@ func (b *SignedBlindedBeaconBlock) Full(txs *solid.TransactionsSSZ, withdrawals
119119
}
120120
}
121121

122+
// GetSlot returns the slot of the inner block.
123+
// Implements ColumnSyncableSignedBlock interface.
124+
func (b *SignedBlindedBeaconBlock) GetSlot() uint64 {
125+
return b.Block.Slot
126+
}
127+
128+
// BlockHashSSZ returns the hash of the inner block (not the signed block).
129+
// Implements ColumnSyncableSignedBlock interface.
130+
func (b *SignedBlindedBeaconBlock) BlockHashSSZ() ([32]byte, error) {
131+
return b.Block.HashSSZ()
132+
}
133+
134+
// GetBlobKzgCommitments returns blob KZG commitments from the block body.
135+
// Implements ColumnSyncableSignedBlock interface.
136+
// Note: BlindedBeaconBlock cannot exist for GLOAS (Blinded() returns error),
137+
// so this always returns the pre-GLOAS commitments.
138+
func (b *SignedBlindedBeaconBlock) GetBlobKzgCommitments() *solid.ListSSZ[*KZGCommitment] {
139+
return b.Block.Body.GetBlobKzgCommitments()
140+
}
141+
122142
// Definitions of BlindedBeaconBlock
123143
type BlindedBeaconBlock struct {
124144
Slot uint64 `json:"slot,string"`

cl/cltypes/beacon_block_interface.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ import (
66
"github.com/erigontech/erigon/common"
77
)
88

9+
// ColumnSyncableSignedBlock is implemented by both SignedBeaconBlock and SignedBlindedBeaconBlock
10+
// for PeerDAS column synchronization operations.
11+
// [New in Gloas:EIP7732] This interface allows PeerDAS to work with both block types
12+
// without needing to call Blinded() which fails for GLOAS blocks.
13+
type ColumnSyncableSignedBlock interface {
14+
Version() clparams.StateVersion
15+
GetSlot() uint64
16+
BlockHashSSZ() ([32]byte, error)
17+
GetBlobKzgCommitments() *solid.ListSSZ[*KZGCommitment]
18+
}
19+
920
type GenericBeaconBlock interface {
1021
Version() clparams.StateVersion
1122
GetSlot() uint64

cl/das/mock_services/peer_das_mock.go

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cl/das/peer_das.go

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ type gloasBlockData struct {
4747

4848
//go:generate mockgen -typed=true -destination=mock_services/peer_das_mock.go -package=mock_services . PeerDas
4949
type PeerDas interface {
50-
DownloadColumnsAndRecoverBlobs(ctx context.Context, blocks []*cltypes.SignedBlindedBeaconBlock) error
51-
DownloadOnlyCustodyColumns(ctx context.Context, blocks []*cltypes.SignedBlindedBeaconBlock) error
50+
// [Modified in Gloas:EIP7732] Changed from []*SignedBlindedBeaconBlock to []ColumnSyncableSignedBlock
51+
// to support both pre-GLOAS (blinded) and GLOAS (non-blinded) blocks
52+
DownloadColumnsAndRecoverBlobs(ctx context.Context, blocks []cltypes.ColumnSyncableSignedBlock) error
53+
DownloadOnlyCustodyColumns(ctx context.Context, blocks []cltypes.ColumnSyncableSignedBlock) error
5254
IsDataAvailable(slot uint64, blockRoot common.Hash) (bool, error)
5355
Prune(keepSlotDistance uint64) error
5456
UpdateValidatorsCustody(cgc uint64)
@@ -80,7 +82,7 @@ type peerdas struct {
8082

8183
recoveringMutex sync.Mutex
8284
isRecovering map[common.Hash]bool
83-
blocksToCheckSync sync.Map // blockRoot -> blindedBlock
85+
blocksToCheckSync sync.Map // blockRoot -> ColumnSyncableSignedBlock (SignedBeaconBlock or SignedBlindedBeaconBlock)
8486

8587
// [New in Gloas:EIP7732] For fetching blocks to get kzg_commitments
8688
forkChoice BlockGetter
@@ -648,7 +650,7 @@ var (
648650
)
649651

650652
// DownloadMissingColumns downloads the missing columns for the given blocks but not recover the blobs
651-
func (d *peerdas) DownloadOnlyCustodyColumns(ctx context.Context, blocks []*cltypes.SignedBlindedBeaconBlock) error {
653+
func (d *peerdas) DownloadOnlyCustodyColumns(ctx context.Context, blocks []cltypes.ColumnSyncableSignedBlock) error {
652654
custodyColumns, err := d.state.GetMyCustodyColumns()
653655
if err != nil {
654656
return err
@@ -673,23 +675,24 @@ func (d *peerdas) DownloadOnlyCustodyColumns(ctx context.Context, blocks []*clty
673675
return nil
674676
}
675677

676-
func (d *peerdas) DownloadColumnsAndRecoverBlobs(ctx context.Context, blocks []*cltypes.SignedBlindedBeaconBlock) error {
678+
func (d *peerdas) DownloadColumnsAndRecoverBlobs(ctx context.Context, blocks []cltypes.ColumnSyncableSignedBlock) error {
677679
// filter out blocks that don't need to be processed
678-
blocksToProcess := []*cltypes.SignedBlindedBeaconBlock{}
680+
blocksToProcess := []cltypes.ColumnSyncableSignedBlock{}
679681
for _, block := range blocks {
682+
kzgCommitments := block.GetBlobKzgCommitments()
680683
if block.Version() < clparams.FuluVersion ||
681-
block.Block.Body.BlobKzgCommitments == nil ||
682-
block.Block.Body.BlobKzgCommitments.Len() == 0 {
684+
kzgCommitments == nil ||
685+
kzgCommitments.Len() == 0 {
683686
continue
684687
}
685-
root, err := block.Block.HashSSZ()
688+
root, err := block.BlockHashSSZ()
686689
if err != nil {
687690
log.Warn("failed to get block root", "err", err)
688691
continue
689692
}
690693

691-
if d.IsColumnOverHalf(block.Block.Slot, root) || d.IsBlobAlreadyRecovered(root) {
692-
if err := d.TryScheduleRecover(block.Block.Slot, root); err != nil {
694+
if d.IsColumnOverHalf(block.GetSlot(), root) || d.IsBlobAlreadyRecovered(root) {
695+
if err := d.TryScheduleRecover(block.GetSlot(), root); err != nil {
693696
log.Debug("failed to schedule recover", "err", err)
694697
}
695698
continue
@@ -705,7 +708,7 @@ func (d *peerdas) DownloadColumnsAndRecoverBlobs(ctx context.Context, blocks []*
705708
defer func() {
706709
slots := make([]uint64, 0, len(blocks))
707710
for _, block := range blocks {
708-
slots = append(slots, block.Block.Slot)
711+
slots = append(slots, block.GetSlot())
709712
}
710713
log.Debug("DownloadColumnsAndRecoverBlobs", "elapsed time", time.Since(begin), "slots", slots)
711714
}()
@@ -950,30 +953,32 @@ type downloadRequest struct {
950953
downloadTable map[downloadTableEntry]map[uint64]bool
951954
}
952955

956+
// [Modified in Gloas:EIP7732] Changed from []*SignedBlindedBeaconBlock to []ColumnSyncableSignedBlock
953957
func initializeDownloadRequest(
954-
blocks []*cltypes.SignedBlindedBeaconBlock,
958+
blocks []cltypes.ColumnSyncableSignedBlock,
955959
beaconConfig *clparams.BeaconChainConfig,
956960
columnStorage blob_storage.DataColumnStorage,
957961
expectedColumns map[cltypes.CustodyIndex]bool,
958962
) (*downloadRequest, error) {
959963
downloadTable := make(map[downloadTableEntry]map[uint64]bool)
960-
blockRootToBeaconBlock := make(map[common.Hash]*cltypes.SignedBlindedBeaconBlock)
964+
blockRootToBeaconBlock := make(map[common.Hash]cltypes.ColumnSyncableSignedBlock)
961965
for _, block := range blocks {
962966
if block.Version() < clparams.FuluVersion {
963967
continue
964968
}
965-
if block.Block.Body.BlobKzgCommitments == nil || block.Block.Body.BlobKzgCommitments.Len() == 0 {
969+
kzgCommitments := block.GetBlobKzgCommitments()
970+
if kzgCommitments == nil || kzgCommitments.Len() == 0 {
966971
continue
967972
}
968973

969-
blockRoot, err := block.Block.HashSSZ()
974+
blockRoot, err := block.BlockHashSSZ()
970975
if err != nil {
971976
return nil, err
972977
}
973978
blockRootToBeaconBlock[blockRoot] = block
974979

975980
// get the existing columns from the column storage
976-
existingColumns, err := columnStorage.GetSavedColumnIndex(context.Background(), block.Block.Slot, blockRoot)
981+
existingColumns, err := columnStorage.GetSavedColumnIndex(context.Background(), block.GetSlot(), blockRoot)
977982
if err != nil {
978983
return nil, err
979984
}
@@ -984,7 +989,7 @@ func initializeDownloadRequest(
984989

985990
if _, ok := downloadTable[downloadTableEntry{
986991
blockRoot: blockRoot,
987-
slot: block.Block.Slot,
992+
slot: block.GetSlot(),
988993
}]; !ok {
989994
table := make(map[uint64]bool)
990995
for column := range expectedColumns {
@@ -995,7 +1000,7 @@ func initializeDownloadRequest(
9951000
if len(table) > 0 {
9961001
downloadTable[downloadTableEntry{
9971002
blockRoot: blockRoot,
998-
slot: block.Block.Slot,
1003+
slot: block.GetSlot(),
9991004
}] = table
10001005
}
10011006
}
@@ -1068,18 +1073,19 @@ func (d *peerdas) SyncColumnDataLater(block *cltypes.SignedBeaconBlock) error {
10681073
if block.Version() < clparams.FuluVersion {
10691074
return nil
10701075
}
1071-
if block.Block.Body.BlobKzgCommitments == nil || block.Block.Body.BlobKzgCommitments.Len() == 0 {
1076+
// [Modified in Gloas:EIP7732] Use GetBlobKzgCommitments() which is version-aware
1077+
// For GLOAS, commitments are in SignedExecutionPayloadBid.Message
1078+
kzgCommitments := block.GetBlobKzgCommitments()
1079+
if kzgCommitments == nil || kzgCommitments.Len() == 0 {
10721080
return nil
10731081
}
1074-
blockRoot, err := block.Block.HashSSZ()
1082+
blockRoot, err := block.BlockHashSSZ()
10751083
if err != nil {
10761084
return err
10771085
}
1078-
blindedBlock, err := block.Blinded()
1079-
if err != nil {
1080-
return err
1081-
}
1082-
d.blocksToCheckSync.Store(common.Hash(blockRoot), blindedBlock)
1086+
// [Modified in Gloas:EIP7732] Store SignedBeaconBlock directly via ColumnSyncableSignedBlock interface
1087+
// instead of calling Blinded() which fails for GLOAS blocks
1088+
d.blocksToCheckSync.Store(common.Hash(blockRoot), block)
10831089
return nil
10841090
}
10851091

@@ -1102,21 +1108,22 @@ func (d *peerdas) syncColumnDataWorker(ctx context.Context) {
11021108
}
11031109
}
11041110

1105-
blocks := []*cltypes.SignedBlindedBeaconBlock{}
1111+
// [Modified in Gloas:EIP7732] Use ColumnSyncableSignedBlock interface
1112+
blocks := []cltypes.ColumnSyncableSignedBlock{}
11061113
roots := []common.Hash{}
11071114
d.blocksToCheckSync.Range(func(key, value any) bool {
11081115
root := key.(common.Hash)
1109-
block := value.(*cltypes.SignedBlindedBeaconBlock)
1116+
block := value.(cltypes.ColumnSyncableSignedBlock)
11101117
curSlot := d.ethClock.GetCurrentSlot()
1111-
if curSlot-block.Block.Slot < 5 { // wait slow data from peers
1118+
if curSlot-block.GetSlot() < 5 { // wait slow data from peers
11121119
// skip blocks that are too close to the current slot
11131120
return true
11141121
}
1115-
available, err := d.IsDataAvailable(block.Block.Slot, root)
1122+
available, err := d.IsDataAvailable(block.GetSlot(), root)
11161123
if err != nil {
11171124
log.Warn("failed to check if data is available", "err", err)
11181125
} else if available {
1119-
log.Trace("[syncColumnDataWorker] column data is already available, removing from sync queue", "slot", block.Block.Slot, "blockRoot", root)
1126+
log.Trace("[syncColumnDataWorker] column data is already available, removing from sync queue", "slot", block.GetSlot(), "blockRoot", root)
11201127
d.blocksToCheckSync.Delete(root)
11211128
} else {
11221129
blocks = append(blocks, block)
@@ -1141,7 +1148,7 @@ func (d *peerdas) syncColumnDataWorker(ctx context.Context) {
11411148
}
11421149
for i, root := range roots {
11431150
d.blocksToCheckSync.Delete(root)
1144-
log.Debug("[syncColumnDataWorker] column data is synced, removing from sync queue", "slot", blocks[i].Block.Slot, "blockRoot", root)
1151+
log.Debug("[syncColumnDataWorker] column data is synced, removing from sync queue", "slot", blocks[i].GetSlot(), "blockRoot", root)
11451152
}
11461153
}
11471154
}

cl/phase1/network/blob_downloader.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,9 @@ func (b *BlobHistoryDownloader) downloadOnce(shouldLog bool) error {
345345
if len(fuluBlocks) > 0 {
346346
peerDas := b.peerDasGetter.GetPeerDas()
347347
for _, block := range fuluBlocks {
348-
if err := peerDas.DownloadColumnsAndRecoverBlobs(b.ctx, []*cltypes.SignedBlindedBeaconBlock{block}); err != nil {
349-
b.logger.Warn("[BlobHistoryDownloader] Error recovering blobs from block", "err", err, "slot", block.Block.Slot)
348+
// [Modified in Gloas:EIP7732] Use ColumnSyncableSignedBlock interface
349+
if err := peerDas.DownloadColumnsAndRecoverBlobs(b.ctx, []cltypes.ColumnSyncableSignedBlock{block}); err != nil {
350+
b.logger.Warn("[BlobHistoryDownloader] Error recovering blobs from block", "err", err, "slot", block.GetSlot())
350351
}
351352
}
352353
}

cl/phase1/network/services/data_column_sidecar_service_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ func createMockGloasBlock(slot uint64, blockRoot common.Hash) *cltypes.SignedBea
496496
Block: &cltypes.BeaconBlock{
497497
Slot: slot,
498498
Body: &cltypes.BeaconBody{
499+
Version: clparams.GloasVersion, // Required for GetBlobKzgCommitments() to work correctly
499500
SignedExecutionPayloadBid: &cltypes.SignedExecutionPayloadBid{
500501
Message: &cltypes.ExecutionPayloadBid{
501502
BlobKzgCommitments: *solid.NewStaticListSSZ[*cltypes.KZGCommitment](4, 48),

0 commit comments

Comments
 (0)