Skip to content

Commit e8029ed

Browse files
committed
changes on data column sidecar and peerdas
1 parent 791b97e commit e8029ed

File tree

19 files changed

+1314
-176
lines changed

19 files changed

+1314
-176
lines changed

cl/beacon/handler/block_production.go

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,47 +1225,71 @@ func (a *ApiHandler) broadcastBlock(ctx context.Context, blk *cltypes.SignedBeac
12251225
}
12261226
}
12271227

1228-
if blk.Version() >= clparams.FuluVersion && blk.Block.Body.BlobKzgCommitments.Len() > 0 {
1229-
kzgCommitmentsCopy := solid.NewStaticListSSZ[*cltypes.KZGCommitment](cltypes.MaxBlobsCommittmentsPerBlock, length.Bytes48)
1230-
for i := 0; i < blk.Block.Body.BlobKzgCommitments.Len(); i++ {
1231-
kzgCommitmentsCopy.Append(blk.Block.Body.BlobKzgCommitments.Get(i))
1232-
}
1233-
1234-
// Assemble inclusion proof
1235-
inclusionProofRaw, err := blk.Block.Body.KzgCommitmentsInclusionProof()
1236-
if err != nil {
1237-
return err
1238-
}
1239-
commitmentInclusionProof := solid.NewHashVector(cltypes.CommitmentBranchSize)
1240-
for i, h := range inclusionProofRaw {
1241-
commitmentInclusionProof.Set(i, h)
1242-
}
1243-
1244-
cellsAndProofsPerBlob := make([]peerdasutils.CellsAndKZGProofs, 0, kzgCommitmentsCopy.Len())
1245-
for i := 0; i < kzgCommitmentsCopy.Len(); i++ {
1246-
commitment := kzgCommitmentsCopy.Get(i)
1247-
bundle, has := a.blobBundles.Get(common.Bytes48(*commitment))
1248-
if !has {
1249-
return fmt.Errorf("missing blob bundle for commitment %x", commitment)
1250-
}
1251-
cells, err := das.ComputeCells(bundle.Blob)
1252-
if err != nil {
1253-
return err
1228+
// Handle Fulu+ data column sidecars
1229+
if blk.Version() >= clparams.FuluVersion {
1230+
// Get kzgCommitments based on version
1231+
var kzgCommitments *solid.ListSSZ[*cltypes.KZGCommitment]
1232+
isGloas := blk.Version() >= clparams.GloasVersion
1233+
1234+
if isGloas {
1235+
// [New in Gloas:EIP7732] Get from signed_execution_payload_bid
1236+
if bid := blk.Block.Body.GetSignedExecutionPayloadBid(); bid != nil && bid.Message != nil {
1237+
kzgCommitments = &bid.Message.BlobKzgCommitments
12541238
}
1239+
} else {
1240+
// Fulu: Get from BlobKzgCommitments
1241+
kzgCommitments = blk.Block.Body.BlobKzgCommitments
1242+
}
1243+
1244+
if kzgCommitments != nil && kzgCommitments.Len() > 0 {
1245+
// Build cellsAndProofsPerBlob (common logic)
1246+
cellsAndProofsPerBlob := make([]peerdasutils.CellsAndKZGProofs, 0, kzgCommitments.Len())
1247+
for i := 0; i < kzgCommitments.Len(); i++ {
1248+
commitment := kzgCommitments.Get(i)
1249+
bundle, has := a.blobBundles.Get(common.Bytes48(*commitment))
1250+
if !has {
1251+
return fmt.Errorf("missing blob bundle for commitment %x", commitment)
1252+
}
1253+
cells, err := das.ComputeCells(bundle.Blob)
1254+
if err != nil {
1255+
return err
1256+
}
12551257

1256-
cellsAndProof := peerdasutils.CellsAndKZGProofs{}
1257-
for i := 0; i < len(cells); i++ {
1258-
cellsAndProof.Blobs = append(cellsAndProof.Blobs, cells[i])
1258+
cellsAndProof := peerdasutils.CellsAndKZGProofs{}
1259+
for i := 0; i < len(cells); i++ {
1260+
cellsAndProof.Blobs = append(cellsAndProof.Blobs, cells[i])
1261+
}
1262+
for j := 0; j < len(bundle.KzgProofs); j++ {
1263+
cellsAndProof.Proofs = append(cellsAndProof.Proofs, cltypes.KZGProof(bundle.KzgProofs[j]))
1264+
}
1265+
cellsAndProofsPerBlob = append(cellsAndProofsPerBlob, cellsAndProof)
12591266
}
12601267

1261-
for j := 0; j < len(bundle.KzgProofs); j++ {
1262-
cellsAndProof.Proofs = append(cellsAndProof.Proofs, cltypes.KZGProof(bundle.KzgProofs[j]))
1268+
// Create sidecars based on version
1269+
if isGloas {
1270+
blockRoot, err := blk.Block.HashSSZ()
1271+
if err != nil {
1272+
return fmt.Errorf("failed to compute block root: %w", err)
1273+
}
1274+
columnsSidecars, err = peerdasutils.GetDataColumnSidecarsGloas(blk.Block.Slot, blockRoot, cellsAndProofsPerBlob)
1275+
if err != nil {
1276+
return fmt.Errorf("failed to get data column sidecars: %w", err)
1277+
}
1278+
} else {
1279+
// Fulu needs inclusion proof
1280+
inclusionProofRaw, err := blk.Block.Body.KzgCommitmentsInclusionProof()
1281+
if err != nil {
1282+
return err
1283+
}
1284+
commitmentInclusionProof := solid.NewHashVector(cltypes.CommitmentBranchSize)
1285+
for i, h := range inclusionProofRaw {
1286+
commitmentInclusionProof.Set(i, h)
1287+
}
1288+
columnsSidecars, err = peerdasutils.GetDataColumnSidecars(header, kzgCommitments, commitmentInclusionProof, cellsAndProofsPerBlob)
1289+
if err != nil {
1290+
return fmt.Errorf("failed to get data column sidecars: %w", err)
1291+
}
12631292
}
1264-
cellsAndProofsPerBlob = append(cellsAndProofsPerBlob, cellsAndProof)
1265-
}
1266-
columnsSidecars, err = peerdasutils.GetDataColumnSidecars(header, kzgCommitmentsCopy, commitmentInclusionProof, cellsAndProofsPerBlob)
1267-
if err != nil {
1268-
return fmt.Errorf("failed to get data column sidecars: %w", err)
12691293
}
12701294
}
12711295

cl/cltypes/column_sidecar.go

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,16 @@ var (
3333

3434
type DataColumnSidecar struct {
3535
BlockRoot common.Hash `json:"-"`
36-
Slot uint64 `json:"-"`
3736
Index uint64 `json:"index,string"` // index of the column
3837
Column *solid.ListSSZ[*Cell] `json:"column"`
39-
KzgCommitments *solid.ListSSZ[*KZGCommitment] `json:"kzg_commitments"`
4038
KzgProofs *solid.ListSSZ[*KZGProof] `json:"kzg_proofs"`
41-
SignedBlockHeader *SignedBeaconBlockHeader `json:"signed_block_header"`
42-
KzgCommitmentsInclusionProof solid.HashVectorSSZ `json:"kzg_commitments_inclusion_proof"`
39+
Slot uint64 `json:"slot"` // [New in Gloas:EIP7732]
40+
BeaconBlockRoot common.Hash `json:"beacon_block_root"` // [New in Gloas:EIP7732]
41+
KzgCommitments *solid.ListSSZ[*KZGCommitment] `json:"kzg_commitments,omitempty"` // [Removed in Gloas:EIP7732]
42+
SignedBlockHeader *SignedBeaconBlockHeader `json:"signed_block_header,omitempty"` // [Removed in Gloas:EIP7732]
43+
KzgCommitmentsInclusionProof solid.HashVectorSSZ `json:"kzg_commitments_inclusion_proof,omitempty"` // [Removed in Gloas:EIP7732]
44+
45+
version clparams.StateVersion // internal: tracks the version for encoding
4346
}
4447

4548
func NewDataColumnSidecar() *DataColumnSidecar {
@@ -48,56 +51,102 @@ func NewDataColumnSidecar() *DataColumnSidecar {
4851
return d
4952
}
5053

54+
// NewDataColumnSidecarWithVersion creates a new DataColumnSidecar with a specific version.
55+
// Use this when you need version-aware encoding.
56+
func NewDataColumnSidecarWithVersion(version clparams.StateVersion) *DataColumnSidecar {
57+
d := &DataColumnSidecar{version: version}
58+
d.tryInitWithVersion(version)
59+
return d
60+
}
61+
62+
// Version returns the version used for encoding.
63+
func (d *DataColumnSidecar) Version() clparams.StateVersion {
64+
return d.version
65+
}
66+
5167
func (d *DataColumnSidecar) Clone() clonable.Clonable {
5268
newSidecar := &DataColumnSidecar{
53-
BlockRoot: d.BlockRoot,
54-
Slot: d.Slot,
69+
BlockRoot: d.BlockRoot,
70+
Slot: d.Slot,
71+
BeaconBlockRoot: d.BeaconBlockRoot,
72+
version: d.version,
5573
}
56-
newSidecar.tryInit()
74+
newSidecar.tryInitWithVersion(d.version)
5775
return newSidecar
5876
}
5977

6078
func (d *DataColumnSidecar) tryInit() {
79+
d.tryInitWithVersion(d.version)
80+
}
81+
82+
func (d *DataColumnSidecar) tryInitWithVersion(version clparams.StateVersion) {
6183
cfg := clparams.GetBeaconConfig()
6284
if d.Column == nil {
6385
d.Column = solid.NewStaticListSSZ[*Cell](int(cfg.MaxBlobCommittmentsPerBlock), BytesPerCell)
6486
}
65-
if d.KzgCommitments == nil {
66-
d.KzgCommitments = solid.NewStaticListSSZ[*KZGCommitment](int(cfg.MaxBlobCommittmentsPerBlock), 48)
67-
}
6887
if d.KzgProofs == nil {
6988
d.KzgProofs = solid.NewStaticListSSZ[*KZGProof](int(cfg.MaxBlobCommittmentsPerBlock), 48)
7089
}
71-
if d.SignedBlockHeader == nil {
72-
d.SignedBlockHeader = &SignedBeaconBlockHeader{}
73-
d.SignedBlockHeader.Header = &BeaconBlockHeader{}
74-
}
75-
if d.KzgCommitmentsInclusionProof == nil {
76-
d.KzgCommitmentsInclusionProof = solid.NewHashVector(KzgCommitmentsInclusionProofDepth)
90+
// Pre-Gloas fields (Fulu and earlier)
91+
if version < clparams.GloasVersion {
92+
if d.KzgCommitments == nil {
93+
d.KzgCommitments = solid.NewStaticListSSZ[*KZGCommitment](int(cfg.MaxBlobCommittmentsPerBlock), 48)
94+
}
95+
if d.SignedBlockHeader == nil {
96+
d.SignedBlockHeader = &SignedBeaconBlockHeader{}
97+
d.SignedBlockHeader.Header = &BeaconBlockHeader{}
98+
}
99+
if d.KzgCommitmentsInclusionProof == nil {
100+
d.KzgCommitmentsInclusionProof = solid.NewHashVector(KzgCommitmentsInclusionProofDepth)
101+
}
77102
}
78103
}
79104

80105
func (d *DataColumnSidecar) DecodeSSZ(buf []byte, version int) error {
81-
return ssz2.UnmarshalSSZ(buf, version, d.getSchema()...)
106+
d.version = clparams.StateVersion(version)
107+
d.tryInitWithVersion(d.version)
108+
return ssz2.UnmarshalSSZ(buf, version, d.getSchemaForVersion(d.version)...)
82109
}
83110

84111
func (d *DataColumnSidecar) EncodeSSZ(buf []byte) ([]byte, error) {
85-
return ssz2.MarshalSSZ(buf, d.getSchema()...)
112+
return ssz2.MarshalSSZ(buf, d.getSchemaForVersion(d.version)...)
86113
}
87114

88-
func (d *DataColumnSidecar) getSchema() []any {
89-
d.tryInit()
115+
// getSchemaForVersion returns the SSZ schema for the given version.
116+
// Fulu and earlier: Index, Column, KzgCommitments, KzgProofs, SignedBlockHeader, KzgCommitmentsInclusionProof
117+
// Gloas and later: Index, Column, KzgProofs, Slot, BeaconBlockRoot
118+
func (d *DataColumnSidecar) getSchemaForVersion(version clparams.StateVersion) []any {
119+
d.tryInitWithVersion(version)
120+
if version >= clparams.GloasVersion {
121+
return []any{&d.Index, d.Column, d.KzgProofs, &d.Slot, d.BeaconBlockRoot[:]}
122+
}
123+
// Fulu and earlier
90124
return []any{&d.Index, d.Column, d.KzgCommitments, d.KzgProofs, d.SignedBlockHeader, d.KzgCommitmentsInclusionProof}
91125
}
92126

127+
// getSchema returns the SSZ schema using the stored version.
128+
func (d *DataColumnSidecar) getSchema() []any {
129+
return d.getSchemaForVersion(d.version)
130+
}
131+
93132
func (d *DataColumnSidecar) EncodingSizeSSZ() int {
94-
d.tryInit()
133+
return d.EncodingSizeSSZForVersion(d.version)
134+
}
135+
136+
// EncodingSizeSSZForVersion returns the encoding size for the given version.
137+
func (d *DataColumnSidecar) EncodingSizeSSZForVersion(version clparams.StateVersion) int {
138+
d.tryInitWithVersion(version)
139+
if version >= clparams.GloasVersion {
140+
// Index (8) + Column (variable) + KzgProofs (variable) + Slot (8) + BeaconBlockRoot (32)
141+
return 8 + d.Column.EncodingSizeSSZ() + d.KzgProofs.EncodingSizeSSZ() + 8 + 32
142+
}
143+
// Fulu and earlier
95144
return 8 + d.Column.EncodingSizeSSZ() + d.KzgCommitments.EncodingSizeSSZ() + d.KzgProofs.EncodingSizeSSZ() +
96145
d.SignedBlockHeader.EncodingSizeSSZ() + d.KzgCommitmentsInclusionProof.EncodingSizeSSZ()
97146
}
98147

99148
func (d *DataColumnSidecar) HashSSZ() ([32]byte, error) {
100-
return merkle_tree.HashTreeRoot(d.getSchema()...)
149+
return merkle_tree.HashTreeRoot(d.getSchemaForVersion(d.version)...)
101150
}
102151

103152
func (d *DataColumnSidecar) Static() bool {

0 commit comments

Comments
 (0)