@@ -70,9 +70,6 @@ type TransactionArgs struct {
70
70
71
71
// For SetCodeTxType
72
72
AuthorizationList []types.SetCodeAuthorization `json:"authorizationList"`
73
-
74
- // This configures whether blobs are allowed to be passed.
75
- blobSidecarAllowed bool
76
73
}
77
74
78
75
// from retrieves the transaction sender address.
@@ -94,9 +91,22 @@ func (args *TransactionArgs) data() []byte {
94
91
return nil
95
92
}
96
93
94
+ // setDefaultConfig defines the options for deriving missing fields of transactions.
95
+ type setDefaultConfig struct {
96
+ // This configures whether blobs are allowed to be passed and
97
+ // the associated sidecar version should be attached.
98
+ blobSidecarAllowed bool
99
+ blobSidecarVersion byte
100
+
101
+ // skipGasEstimation is the flag whether the gas estimation is skipped.
102
+ // this flag should only be used in the scenarios that a precise gas limit
103
+ // is not critical, e.g., in non-transaction calls.
104
+ skipGasEstimation bool
105
+ }
106
+
97
107
// setDefaults fills in default values for unspecified tx fields.
98
- func (args * TransactionArgs ) setDefaults (ctx context.Context , b Backend , skipGasEstimation bool ) error {
99
- if err := args .setBlobTxSidecar (ctx ); err != nil {
108
+ func (args * TransactionArgs ) setDefaults (ctx context.Context , b Backend , config setDefaultConfig ) error {
109
+ if err := args .setBlobTxSidecar (ctx , config ); err != nil {
100
110
return err
101
111
}
102
112
if err := args .setFeeDefaults (ctx , b , b .CurrentHeader ()); err != nil {
@@ -119,11 +129,10 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
119
129
120
130
// BlobTx fields
121
131
if args .BlobHashes != nil && len (args .BlobHashes ) == 0 {
122
- return errors .New (` need at least 1 blob for a blob transaction` )
132
+ return errors .New (" need at least 1 blob for a blob transaction" )
123
133
}
124
- maxBlobs := eip4844 .MaxBlobsPerBlock (b .ChainConfig (), b .CurrentHeader ().Time )
125
- if args .BlobHashes != nil && len (args .BlobHashes ) > maxBlobs {
126
- return fmt .Errorf (`too many blobs in transaction (have=%d, max=%d)` , len (args .BlobHashes ), maxBlobs )
134
+ if args .BlobHashes != nil && len (args .BlobHashes ) > params .BlobTxMaxBlobs {
135
+ return fmt .Errorf ("too many blobs in transaction (have=%d, max=%d)" , len (args .BlobHashes ), params .BlobTxMaxBlobs )
127
136
}
128
137
129
138
// create check
@@ -137,13 +146,13 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas
137
146
}
138
147
139
148
if args .Gas == nil {
140
- if skipGasEstimation { // Skip gas usage estimation if a precise gas limit is not critical, e.g., in non-transaction calls.
149
+ if config . skipGasEstimation {
141
150
gas := hexutil .Uint64 (b .RPCGasCap ())
142
151
if gas == 0 {
143
152
gas = hexutil .Uint64 (math .MaxUint64 / 2 )
144
153
}
145
154
args .Gas = & gas
146
- } else { // Estimate the gas usage otherwise.
155
+ } else {
147
156
// These fields are immutable during the estimation, safe to
148
157
// pass the pointer directly.
149
158
data := args .data ()
@@ -283,18 +292,17 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ
283
292
}
284
293
285
294
// setBlobTxSidecar adds the blob tx
286
- func (args * TransactionArgs ) setBlobTxSidecar (ctx context.Context ) error {
295
+ func (args * TransactionArgs ) setBlobTxSidecar (ctx context.Context , config setDefaultConfig ) error {
287
296
// No blobs, we're done.
288
297
if args .Blobs == nil {
289
298
return nil
290
299
}
291
300
292
301
// Passing blobs is not allowed in all contexts, only in specific methods.
293
- if ! args .blobSidecarAllowed {
302
+ if ! config .blobSidecarAllowed {
294
303
return errors .New (`"blobs" is not supported for this RPC method` )
295
304
}
296
305
297
- n := len (args .Blobs )
298
306
// Assume user provides either only blobs (w/o hashes), or
299
307
// blobs together with commitments and proofs.
300
308
if args .Commitments == nil && args .Proofs != nil {
@@ -304,42 +312,73 @@ func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context) error {
304
312
}
305
313
306
314
// len(blobs) == len(commitments) == len(proofs) == len(hashes)
315
+ n := len (args .Blobs )
316
+ if args .BlobHashes != nil && len (args .BlobHashes ) != n {
317
+ return fmt .Errorf ("number of blobs and hashes mismatch (have=%d, want=%d)" , len (args .BlobHashes ), n )
318
+ }
307
319
if args .Commitments != nil && len (args .Commitments ) != n {
308
320
return fmt .Errorf ("number of blobs and commitments mismatch (have=%d, want=%d)" , len (args .Commitments ), n )
309
321
}
310
- if args .Proofs != nil && len (args .Proofs ) != n {
311
- return fmt .Errorf ("number of blobs and proofs mismatch (have=%d, want=%d)" , len (args .Proofs ), n )
322
+ proofLen := n
323
+ if config .blobSidecarVersion == types .BlobSidecarVersion1 {
324
+ proofLen = n * kzg4844 .CellProofsPerBlob
312
325
}
313
- if args .BlobHashes != nil && len (args .BlobHashes ) != n {
314
- return fmt .Errorf ("number of blobs and hashes mismatch (have=%d, want=%d)" , len (args .BlobHashes ), n )
326
+ if args .Proofs != nil && len (args .Proofs ) != proofLen {
327
+ if len (args .Proofs ) != n {
328
+ return fmt .Errorf ("number of blobs and proofs mismatch (have=%d, want=%d)" , len (args .Proofs ), proofLen )
329
+ }
330
+ // Unset the commitments and proofs, as they may be submitted in the legacy format
331
+ log .Debug ("Unset legacy commitments and proofs" , "blobs" , n , "proofs" , len (args .Proofs ))
332
+ args .Commitments , args .Proofs = nil , nil
315
333
}
316
334
335
+ // Generate commitments and proofs if they are missing, or validate them if they
336
+ // are provided.
317
337
if args .Commitments == nil {
318
- // Generate commitment and proof.
319
- commitments := make ([]kzg4844.Commitment , n )
320
- proofs := make ([]kzg4844.Proof , n )
338
+ var (
339
+ commitments = make ([]kzg4844.Commitment , n )
340
+ proofs = make ([]kzg4844.Proof , proofLen )
341
+ )
321
342
for i , b := range args .Blobs {
322
343
c , err := kzg4844 .BlobToCommitment (& b )
323
344
if err != nil {
324
345
return fmt .Errorf ("blobs[%d]: error computing commitment: %v" , i , err )
325
346
}
326
347
commitments [i ] = c
327
- p , err := kzg4844 .ComputeBlobProof (& b , c )
328
- if err != nil {
329
- return fmt .Errorf ("blobs[%d]: error computing proof: %v" , i , err )
348
+
349
+ switch config .blobSidecarVersion {
350
+ case types .BlobSidecarVersion0 :
351
+ p , err := kzg4844 .ComputeBlobProof (& b , c )
352
+ if err != nil {
353
+ return fmt .Errorf ("blobs[%d]: error computing proof: %v" , i , err )
354
+ }
355
+ proofs [i ] = p
356
+ case types .BlobSidecarVersion1 :
357
+ ps , err := kzg4844 .ComputeCellProofs (& b )
358
+ if err != nil {
359
+ return fmt .Errorf ("blobs[%d]: error computing cell proof: %v" , i , err )
360
+ }
361
+ proofs = append (proofs , ps ... )
330
362
}
331
- proofs [i ] = p
332
363
}
333
364
args .Commitments = commitments
334
365
args .Proofs = proofs
335
366
} else {
336
- for i , b := range args .Blobs {
337
- if err := kzg4844 .VerifyBlobProof (& b , args .Commitments [i ], args .Proofs [i ]); err != nil {
338
- return fmt .Errorf ("failed to verify blob proof: %v" , err )
367
+ switch config .blobSidecarVersion {
368
+ case types .BlobSidecarVersion0 :
369
+ for i , b := range args .Blobs {
370
+ if err := kzg4844 .VerifyBlobProof (& b , args .Commitments [i ], args .Proofs [i ]); err != nil {
371
+ return fmt .Errorf ("failed to verify blob proof: %v" , err )
372
+ }
373
+ }
374
+ case types .BlobSidecarVersion1 :
375
+ if err := kzg4844 .VerifyCellProofs (args .Blobs , args .Commitments , args .Proofs ); err != nil {
376
+ return fmt .Errorf ("failed to verify blob cell proof: %v" , err )
339
377
}
340
378
}
341
379
}
342
380
381
+ // Generate blob hashes if they are missing, or validate them if they are provided.
343
382
hashes := make ([]common.Hash , n )
344
383
hasher := sha256 .New ()
345
384
for i , c := range args .Commitments {
@@ -527,8 +566,11 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction {
527
566
BlobFeeCap : uint256 .MustFromBig ((* big .Int )(args .BlobFeeCap )),
528
567
}
529
568
if args .Blobs != nil {
530
- // TODO(rjl493456442, marius) support V1
531
- data .(* types.BlobTx ).Sidecar = types .NewBlobTxSidecar (types .BlobSidecarVersion0 , args .Blobs , args .Commitments , args .Proofs )
569
+ version := types .BlobSidecarVersion0
570
+ if len (args .Proofs ) == len (args .Blobs )* kzg4844 .CellProofsPerBlob {
571
+ version = types .BlobSidecarVersion1
572
+ }
573
+ data .(* types.BlobTx ).Sidecar = types .NewBlobTxSidecar (version , args .Blobs , args .Commitments , args .Proofs )
532
574
}
533
575
534
576
case types .DynamicFeeTxType :
0 commit comments