Skip to content

Commit 15752d0

Browse files
committed
Implement PeerDAS related helper methods
1 parent 608fac6 commit 15752d0

File tree

6 files changed

+73
-43
lines changed

6 files changed

+73
-43
lines changed

beacon-chain/core/peerdas/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ go_library(
99
"p2p_interface.go",
1010
"peer_sampling.go",
1111
"reconstruction.go",
12+
"util.go",
1213
],
1314
importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/peerdas",
1415
visibility = ["//visibility:public"],
@@ -24,6 +25,7 @@ go_library(
2425
"//crypto/hash:go_default_library",
2526
"//encoding/bytesutil:go_default_library",
2627
"//proto/prysm/v1alpha1:go_default_library",
28+
"//runtime/version:go_default_library",
2729
"@com_github_ethereum_go_ethereum//p2p/enode:go_default_library",
2830
"@com_github_ethereum_go_ethereum//p2p/enr:go_default_library",
2931
"@com_github_hashicorp_golang_lru//:go_default_library",

beacon-chain/core/peerdas/das_core.go

+15-39
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package peerdas
22

33
import (
4-
"context"
54
"encoding/binary"
65
"math"
76
"slices"
@@ -20,7 +19,6 @@ import (
2019
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
2120
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
2221
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
23-
"golang.org/x/sync/errgroup"
2422
)
2523

2624
var (
@@ -107,57 +105,34 @@ func ComputeColumnsForCustodyGroup(custodyGroup uint64) ([]uint64, error) {
107105

108106
// DataColumnSidecars computes the data column sidecars from the signed block and blobs.
109107
// https://github.com/ethereum/consensus-specs/blob/dev/specs/fulu/das-core.md#get_data_column_sidecars
110-
func DataColumnSidecars(signedBlock interfaces.ReadOnlySignedBeaconBlock, blobs []kzg.Blob) ([]*ethpb.DataColumnSidecar, error) {
111-
startTime := time.Now()
112-
blobsCount := len(blobs)
113-
if blobsCount == 0 {
108+
func DataColumnSidecars(signedBlock interfaces.ReadOnlySignedBeaconBlock, cellsAndProofs []kzg.CellsAndProofs) ([]*ethpb.DataColumnSidecar, error) {
109+
if signedBlock == nil || len(cellsAndProofs) == 0 {
114110
return nil, nil
115111
}
116112

117-
// Get the signed block header.
118-
signedBlockHeader, err := signedBlock.Header()
119-
if err != nil {
120-
return nil, errors.Wrap(err, "signed block header")
121-
}
122-
123-
// Get the block body.
113+
start := time.Now()
124114
block := signedBlock.Block()
125115
blockBody := block.Body()
126-
127-
// Get the blob KZG commitments.
128116
blobKzgCommitments, err := blockBody.BlobKzgCommitments()
129117
if err != nil {
130118
return nil, errors.Wrap(err, "blob KZG commitments")
131119
}
132120

133-
// Compute the KZG commitments inclusion proof.
134-
kzgCommitmentsInclusionProof, err := blocks.MerkleProofKZGCommitments(blockBody)
135-
if err != nil {
136-
return nil, errors.Wrap(err, "merkle proof ZKG commitments")
121+
if len(blobKzgCommitments) != len(cellsAndProofs) {
122+
return nil, errors.New("mismatch in the number of blob KZG commitments and cellsAndProofs")
137123
}
138124

139-
// Compute cells and proofs.
140-
cellsAndProofs := make([]kzg.CellsAndProofs, blobsCount)
141-
142-
eg, _ := errgroup.WithContext(context.Background())
143-
for i := range blobs {
144-
blobIndex := i
145-
eg.Go(func() error {
146-
blob := &blobs[blobIndex]
147-
blobCellsAndProofs, err := kzg.ComputeCellsAndKZGProofs(blob)
148-
if err != nil {
149-
return errors.Wrap(err, "compute cells and KZG proofs")
150-
}
151-
152-
cellsAndProofs[blobIndex] = blobCellsAndProofs
153-
return nil
154-
})
125+
signedBlockHeader, err := signedBlock.Header()
126+
if err != nil {
127+
return nil, errors.Wrap(err, "signed block header")
155128
}
156-
if err := eg.Wait(); err != nil {
157-
return nil, err
129+
130+
kzgCommitmentsInclusionProof, err := blocks.MerkleProofKZGCommitments(blockBody)
131+
if err != nil {
132+
return nil, errors.Wrap(err, "merkle proof ZKG commitments")
158133
}
159134

160-
// Get the column sidecars.
135+
blobsCount := len(cellsAndProofs)
161136
sidecars := make([]*ethpb.DataColumnSidecar, 0, fieldparams.NumberOfColumns)
162137
for columnIndex := uint64(0); columnIndex < fieldparams.NumberOfColumns; columnIndex++ {
163138
column := make([]kzg.Cell, 0, blobsCount)
@@ -196,7 +171,8 @@ func DataColumnSidecars(signedBlock interfaces.ReadOnlySignedBeaconBlock, blobs
196171

197172
sidecars = append(sidecars, sidecar)
198173
}
199-
dataColumnComputationTime.Observe(float64(time.Since(startTime).Milliseconds()))
174+
175+
dataColumnComputationTime.Observe(float64(time.Since(start).Milliseconds()))
200176
return sidecars, nil
201177
}
202178

beacon-chain/core/peerdas/das_core_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717

1818
func TestDataColumnSidecars(t *testing.T) {
1919
var expected []*ethpb.DataColumnSidecar = nil
20-
actual, err := peerdas.DataColumnSidecars(nil, []kzg.Blob{})
20+
actual, err := peerdas.DataColumnSidecars(nil, []kzg.CellsAndProofs{})
2121
require.NoError(t, err)
2222

2323
require.DeepSSZEqual(t, expected, actual)
@@ -139,7 +139,8 @@ func TestDataColumnsSidecarsBlobsRoundtrip(t *testing.T) {
139139
}
140140

141141
// Compute data columns sidecars from the signed beacon block and from the blobs.
142-
dataColumnsSidecar, err := peerdas.DataColumnSidecars(signedBeaconBlock, blobs)
142+
cellsAndProofs := util.GenerateCellsAndProofs(t, blobs)
143+
dataColumnsSidecar, err := peerdas.DataColumnSidecars(signedBeaconBlock, cellsAndProofs)
143144
require.NoError(t, err)
144145

145146
// Compute the blobs from the data columns sidecar.

beacon-chain/core/peerdas/p2p_interface_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ func TestVerifyDataColumnSidecarKZGProofs(t *testing.T) {
3131
dbBlock.Block.Body.BlobKzgCommitments = comms
3232
sBlock, err := blocks.NewSignedBeaconBlock(dbBlock)
3333
require.NoError(t, err)
34-
sCars, err := peerdas.DataColumnSidecars(sBlock, blobs)
34+
cellsAndProofs := util.GenerateCellsAndProofs(t, blobs)
35+
sCars, err := peerdas.DataColumnSidecars(sBlock, cellsAndProofs)
3536
require.NoError(t, err)
3637

3738
for i, sidecar := range sCars {

beacon-chain/core/peerdas/reconstruction_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ func TestReconstructionRoundTrip(t *testing.T) {
9595
require.NoError(t, err)
9696

9797
// Convert data columns sidecars from signed block and blobs.
98-
dataColumnSidecars, err := peerdas.DataColumnSidecars(signedBeaconBlock, blobs)
98+
cellsAndProofs := util.GenerateCellsAndProofs(t, blobs)
99+
dataColumnSidecars, err := peerdas.DataColumnSidecars(signedBeaconBlock, cellsAndProofs)
99100
require.NoError(t, err)
100101

101102
// Create verified RO data columns.

beacon-chain/core/peerdas/util.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package peerdas
2+
3+
import (
4+
"github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain/kzg"
5+
"github.com/prysmaticlabs/prysm/v5/config/params"
6+
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
7+
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
8+
"github.com/prysmaticlabs/prysm/v5/runtime/version"
9+
)
10+
11+
// Helper function to unblind data column sidecars from a block and a blobs bundle v2.
12+
func ConstructDataColumnSidecars(block interfaces.SignedBeaconBlock, blobs [][]byte, proofs [][]byte) ([]*ethpb.DataColumnSidecar, error) {
13+
// Check if the block is at least a Fulu block.
14+
if block.Version() < version.Fulu {
15+
return nil, nil
16+
}
17+
18+
cellsAndProofs, err := ConstructCellsAndProofs(blobs, proofs)
19+
if err != nil {
20+
return nil, err
21+
}
22+
23+
return DataColumnSidecars(block, cellsAndProofs)
24+
}
25+
26+
func ConstructCellsAndProofs(blobs [][]byte, cellProofs [][]byte) ([]kzg.CellsAndProofs, error) {
27+
cellsAndProofs := make([]kzg.CellsAndProofs, 0, len(blobs))
28+
numColumns := int(params.BeaconConfig().NumberOfColumns)
29+
30+
for i, blob := range blobs {
31+
var b kzg.Blob
32+
copy(b[:], blob)
33+
cells, err := kzg.ComputeCells(&b)
34+
if err != nil {
35+
return nil, err
36+
}
37+
38+
var proofs []kzg.Proof
39+
for idx := i * numColumns; idx < (i+1)*numColumns; idx++ {
40+
proofs = append(proofs, kzg.Proof(cellProofs[idx]))
41+
}
42+
cellsAndProofs[i] = kzg.CellsAndProofs{
43+
Cells: cells,
44+
Proofs: proofs,
45+
}
46+
}
47+
48+
return cellsAndProofs, nil
49+
}

0 commit comments

Comments
 (0)