@@ -2,7 +2,6 @@ package fibre
22
33import (
44 "encoding/binary"
5- "encoding/hex"
65 "errors"
76 "fmt"
87 "runtime"
1918 ErrBlobCommitmentMismatch = errors .New ("commitment mismatch: reconstructed data doesn't match expected commitment" )
2019)
2120
22- // Commitment is a commitment to a blob.
23- // TODO(@Wondertan): merge with rsema1d.Commitment once it has these methods.
24- type Commitment rsema1d.Commitment
25-
26- // UnmarshalBinary decodes a [Commitment] from bytes.
27- func (c * Commitment ) UnmarshalBinary (data []byte ) error {
28- if len (data ) != 32 {
29- return fmt .Errorf ("commitment must be 32 bytes, got %d" , len (data ))
30- }
31- copy (c [:], data )
32- return nil
33- }
34-
35- // String returns the hex-encoded string representation of the commitment.
36- func (c Commitment ) String () string {
37- return hex .EncodeToString (c [:])
38- }
39-
40- // CommitmentFromString decodes a [Commitment] from a hex-encoded string.
41- func CommitmentFromString (s string ) (Commitment , error ) {
42- data , err := hex .DecodeString (s )
43- if err != nil {
44- return Commitment {}, fmt .Errorf ("decoding hex: %w" , err )
45- }
46- var c Commitment
47- if err := c .UnmarshalBinary (data ); err != nil {
48- return Commitment {}, err
49- }
50- return c , nil
51- }
52-
53- // Equals returns true if the two commitments are equal.
54- func (c Commitment ) Equals (other Commitment ) bool {
55- return c == other
56- }
57-
5821// BlobConfig contains configuration parameters for blob encoding and decoding.
5922type BlobConfig struct {
6023 // BlobVersion is the version of the row format.
@@ -77,6 +40,17 @@ func DefaultBlobConfigV0() BlobConfig {
7740 return NewBlobConfigFromParams (0 , DefaultProtocolParams )
7841}
7942
43+ // BlobConfigForVersion returns the [BlobConfig] for the given blob version.
44+ // Returns an error if the version is not supported.
45+ func BlobConfigForVersion (version uint8 ) (BlobConfig , error ) {
46+ switch version {
47+ case 0 :
48+ return DefaultBlobConfigV0 (), nil
49+ default :
50+ return BlobConfig {}, fmt .Errorf ("unsupported blob version: %d" , version )
51+ }
52+ }
53+
8054// NewBlobConfigFromParams creates a [BlobConfig] with values derived from the given [ProtocolParams].
8155// Use this when you need a config with non-default protocol parameters (e.g., for testing).
8256func NewBlobConfigFromParams (blobVersion uint8 , p ProtocolParams ) BlobConfig {
@@ -115,7 +89,7 @@ type Blob struct {
11589 cfg BlobConfig
11690
11791 extendedData * rsema1d.ExtendedData
118- commitment Commitment
92+ id BlobID
11993 rlcCoeffs []field.GF128
12094
12195 // holds meta fields about the blob
@@ -146,7 +120,8 @@ func NewBlob(data []byte, cfg BlobConfig) (d *Blob, err error) {
146120 }
147121
148122 rows := d .header .encodeToRows (data , cfg )
149- d .extendedData , d .commitment , d .rlcCoeffs , err = rsema1d .Encode (rows , & rsema1d.Config {
123+ var rsemaCommitment rsema1d.Commitment
124+ d .extendedData , rsemaCommitment , d .rlcCoeffs , err = rsema1d .Encode (rows , & rsema1d.Config {
150125 K : cfg .OriginalRows ,
151126 N : cfg .ParityRows ,
152127 RowSize : len (rows [0 ]),
@@ -155,23 +130,32 @@ func NewBlob(data []byte, cfg BlobConfig) (d *Blob, err error) {
155130 if err != nil {
156131 return nil , fmt .Errorf ("encoding data: %w" , err )
157132 }
133+ d .id = NewBlobID (cfg .BlobVersion , rsemaCommitment )
158134
159135 return d , nil
160136}
161137
162138// NewEmptyBlob creates a new [Blob] instance for receiving and reconstructing data.
163- func NewEmptyBlob (cfg BlobConfig , commitment Commitment ) * Blob {
139+ // Returns an error if the BlobID is invalid or the blob version is not supported.
140+ func NewEmptyBlob (id BlobID ) (* Blob , error ) {
141+ if err := id .Validate (); err != nil {
142+ return nil , fmt .Errorf ("invalid blob ID: %w" , err )
143+ }
144+ cfg , err := BlobConfigForVersion (id .Version ())
145+ if err != nil {
146+ return nil , err
147+ }
164148 totalRows := cfg .OriginalRows + cfg .ParityRows
165149 return & Blob {
166- cfg : cfg ,
167- commitment : commitment ,
168- rows : make ([][]byte , totalRows ),
169- }
150+ cfg : cfg ,
151+ id : id ,
152+ rows : make ([][]byte , totalRows ),
153+ }, nil
170154}
171155
172- // Commitment returns the commitment to the blob.
173- func (d * Blob ) Commitment () Commitment {
174- return d .commitment
156+ // ID returns the BlobID of this blob.
157+ func (d * Blob ) ID () BlobID {
158+ return d .id
175159}
176160
177161// Config returns the blob's configuration.
@@ -220,14 +204,13 @@ func (d *Blob) Row(index int) (*rsema1d.RowInclusionProof, error) {
220204// SetRow adds and verifies [*rsema1d.RowInclusionProof] to the blob.
221205// It is safe to call this method concurrently only for disjoint indices.
222206func (d * Blob ) SetRow (row * rsema1d.RowInclusionProof ) error {
223- // verify the inclusion proof
224207 config := & rsema1d.Config {
225208 K : d .cfg .OriginalRows ,
226209 N : d .cfg .ParityRows ,
227210 RowSize : len (row .Row ),
228211 WorkerCount : d .cfg .CodingWorkers ,
229212 }
230- err := rsema1d .VerifyRowInclusionProof (row , rsema1d . Commitment (d . commitment ), config )
213+ err := rsema1d .VerifyRowInclusionProof (row , d . id . Commitment (), config )
231214 if err != nil {
232215 return fmt .Errorf ("verifying row %d: %w" , row .Index , err )
233216 }
@@ -271,9 +254,9 @@ func (d *Blob) Reconstruct() error {
271254 }
272255
273256 // verify commitment matches
274- if ! d . commitment . Equals ( Commitment (reconstructedCommitment )) {
275- return fmt .Errorf ("%w: expected %s , got %s " ,
276- ErrBlobCommitmentMismatch , d .commitment . String (), Commitment ( reconstructedCommitment ). String () )
257+ if d . id . Commitment () != reconstructedCommitment {
258+ return fmt .Errorf ("%w: expected %x , got %x " ,
259+ ErrBlobCommitmentMismatch , d .id . Commitment (), reconstructedCommitment [:] )
277260 }
278261
279262 // decode header and extract original data from the first K rows, then cache it
0 commit comments