Skip to content

Commit 2d7b8ee

Browse files
geokneetheochap
authored andcommitted
txmgr: allow blobs to be sent with fusaka-compatible cell proofs (sidecar version 1) by configuration (#17620)
* update batcher * txmgr: log full tx hash to enable debugging * cell proofs OFF by default * thread configurable helper through to test code and add test TODOs * wire up flag * fix test * op-e2e/actions: add EnableCellProofs config * remove TODO * use regular not atomic bool * refactor MakeSidecar * optimize creation of proofs slice
1 parent 6f87ebf commit 2d7b8ee

File tree

6 files changed

+75
-15
lines changed

6 files changed

+75
-15
lines changed

op-chain-ops/cmd/check-ecotone/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ func checkBlobTxDenial(ctx context.Context, env *actionEnv) error {
500500
for i := 0; i < 4096; i++ {
501501
blob[32*i] &= 0b0011_1111
502502
}
503-
sidecar, blobHashes, err := txmgr.MakeSidecar([]*eth.Blob{&blob})
503+
sidecar, blobHashes, err := txmgr.MakeSidecar([]*eth.Blob{&blob}, false)
504504
if err != nil {
505505
return fmt.Errorf("failed to make sidecar: %w", err)
506506
}

op-e2e/actions/helpers/l2_batcher.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ type BatcherCfg struct {
6464

6565
DataAvailabilityType batcherFlags.DataAvailabilityType
6666
AltDA AltDAInputSetter
67+
68+
EnableCellProofs bool
6769
}
6870

6971
func DefaultBatcherCfg(dp *e2eutils.DeployParams) *BatcherCfg {
@@ -72,6 +74,7 @@ func DefaultBatcherCfg(dp *e2eutils.DeployParams) *BatcherCfg {
7274
MaxL1TxSize: 128_000,
7375
BatcherKey: dp.Secrets.Batcher,
7476
DataAvailabilityType: batcherFlags.CalldataType,
77+
EnableCellProofs: false, // TODO change to true when Osaka activates on L1
7578
}
7679
}
7780

@@ -373,7 +376,7 @@ func (s *L2Batcher) ActL2BatchSubmitRaw(t Testing, payload []byte, txOpts ...fun
373376
} else if s.l2BatcherCfg.DataAvailabilityType == batcherFlags.BlobsType {
374377
var b eth.Blob
375378
require.NoError(t, b.FromData(payload), "must turn data into blob")
376-
sidecar, blobHashes, err := txmgr.MakeSidecar([]*eth.Blob{&b})
379+
sidecar, blobHashes, err := txmgr.MakeSidecar([]*eth.Blob{&b}, s.l2BatcherCfg.EnableCellProofs)
377380
require.NoError(t, err)
378381
require.NotNil(t, pendingHeader.ExcessBlobGas, "need L1 header with 4844 properties")
379382
blobBaseFee, err := s.l1.BlobBaseFee(t.Ctx())
@@ -458,7 +461,7 @@ func (s *L2Batcher) ActL2BatchSubmitMultiBlob(t Testing, numBlobs int) {
458461
require.NoError(t, err, "need l1 pending header for gas price estimation")
459462
gasFeeCap := new(big.Int).Add(gasTipCap, new(big.Int).Mul(pendingHeader.BaseFee, big.NewInt(2)))
460463

461-
sidecar, blobHashes, err := txmgr.MakeSidecar(blobs)
464+
sidecar, blobHashes, err := txmgr.MakeSidecar(blobs, s.l2BatcherCfg.EnableCellProofs)
462465
require.NoError(t, err)
463466
blobBaseFee, err := s.l1.BlobBaseFee(t.Ctx())
464467
require.NoError(t, err, "need blob base fee")

op-service/txmgr/cli.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const (
4444
TxNotInMempoolTimeoutFlagName = "txmgr.not-in-mempool-timeout"
4545
ReceiptQueryIntervalFlagName = "txmgr.receipt-query-interval"
4646
AlreadyPublishedCustomErrsFlagName = "txmgr.already-published-custom-errs"
47+
EnableCellProofsFlagName = "txmgr.enable-cell-proofs"
4748
)
4849

4950
var (
@@ -76,6 +77,7 @@ type DefaultFlagValues struct {
7677
TxSendTimeout time.Duration
7778
TxNotInMempoolTimeout time.Duration
7879
ReceiptQueryInterval time.Duration
80+
EnableCellProofs bool
7981
}
8082

8183
var (
@@ -94,6 +96,7 @@ var (
9496
TxSendTimeout: 0, // Try sending txs indefinitely, to preserve tx ordering for Holocene
9597
TxNotInMempoolTimeout: 2 * time.Minute,
9698
ReceiptQueryInterval: 12 * time.Second,
99+
EnableCellProofs: false, // Ater Osaka activates on L1, this should be set to true
97100
}
98101
DefaultChallengerFlagValues = DefaultFlagValues{
99102
NumConfirmations: uint64(3),
@@ -238,6 +241,12 @@ func CLIFlagsWithDefaults(envPrefix string, defaults DefaultFlagValues) []cli.Fl
238241
Usage: "List of custom RPC error messages that indicate that a transaction has already been published.",
239242
EnvVars: prefixEnvVars("TXMGR_ALREADY_PUBLISHED_CUSTOM_ERRS"),
240243
},
244+
&cli.BoolFlag{
245+
Name: EnableCellProofsFlagName,
246+
Usage: "Enable cell proofs in blob transactions for Fusaka (EIP-7742) compatibility",
247+
Value: false,
248+
EnvVars: prefixEnvVars("TXMGR_ENABLE_CELL_PROOFS"),
249+
},
241250
}, opsigner.CLIFlags(envPrefix, "")...)
242251
}
243252

@@ -266,6 +275,7 @@ type CLIConfig struct {
266275
TxSendTimeout time.Duration
267276
TxNotInMempoolTimeout time.Duration
268277
AlreadyPublishedCustomErrs []string
278+
EnableCellProofs bool
269279
}
270280

271281
func NewCLIConfig(l1RPCURL string, defaults DefaultFlagValues) CLIConfig {
@@ -285,6 +295,7 @@ func NewCLIConfig(l1RPCURL string, defaults DefaultFlagValues) CLIConfig {
285295
TxSendTimeout: defaults.TxSendTimeout,
286296
TxNotInMempoolTimeout: defaults.TxNotInMempoolTimeout,
287297
ReceiptQueryInterval: defaults.ReceiptQueryInterval,
298+
EnableCellProofs: defaults.EnableCellProofs,
288299
SignerCLIConfig: opsigner.NewCLIConfig(),
289300
}
290301
}
@@ -367,6 +378,7 @@ func ReadCLIConfig(ctx *cli.Context) CLIConfig {
367378
TxSendTimeout: ctx.Duration(TxSendTimeoutFlagName),
368379
TxNotInMempoolTimeout: ctx.Duration(TxNotInMempoolTimeoutFlagName),
369380
AlreadyPublishedCustomErrs: ctx.StringSlice(AlreadyPublishedCustomErrsFlagName),
381+
EnableCellProofs: ctx.Bool(EnableCellProofsFlagName),
370382
}
371383
}
372384

@@ -460,6 +472,7 @@ func NewConfig(cfg CLIConfig, l log.Logger) (*Config, error) {
460472
res.MinTipCap.Store(minTipCap)
461473
res.MaxTipCap.Store(maxTipCap)
462474
res.MinBlobTxFee.Store(defaultMinBlobTxFee)
475+
res.EnableCellProofs = cfg.EnableCellProofs
463476

464477
return &res, nil
465478
}
@@ -498,6 +511,10 @@ type Config struct {
498511

499512
MinBlobTxFee atomic.Pointer[big.Int]
500513

514+
// EnableCellProofs determines whether to use cell proofs (Version1 sidecars)
515+
// for Fusaka (EIP-7742) compatibility. If false, uses legacy blob proofs (Version0).
516+
EnableCellProofs bool
517+
501518
// ChainID is the chain ID of the L1 chain.
502519
ChainID *big.Int
503520

op-service/txmgr/test_txmgr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (m *TestTxManager) makeStuckTx(ctx context.Context, candidate TxCandidate)
5252
var sidecar *types.BlobTxSidecar
5353
var blobHashes []common.Hash
5454
if len(candidate.Blobs) > 0 {
55-
if sidecar, blobHashes, err = MakeSidecar(candidate.Blobs); err != nil {
55+
if sidecar, blobHashes, err = MakeSidecar(candidate.Blobs, m.cfg.EnableCellProofs); err != nil {
5656
return nil, err
5757
}
5858
}

op-service/txmgr/txmgr.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ func (m *SimpleTxManager) Close() {
209209
}
210210

211211
func (m *SimpleTxManager) txLogger(tx *types.Transaction, logGas bool) log.Logger {
212-
fields := []any{"tx", tx.Hash(), "nonce", tx.Nonce()}
212+
fields := []any{"tx", tx.Hash().Hex(), "nonce", tx.Nonce()}
213213
if logGas {
214214
fields = append(fields, "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap(), "gasLimit", tx.Gas())
215215
}
@@ -364,7 +364,8 @@ func (m *SimpleTxManager) craftTx(ctx context.Context, candidate TxCandidate) (*
364364
if candidate.To == nil {
365365
return nil, errors.New("blob txs cannot deploy contracts")
366366
}
367-
if sidecar, blobHashes, err = MakeSidecar(candidate.Blobs); err != nil {
367+
// Use configuration to determine whether to enable cell proofs
368+
if sidecar, blobHashes, err = MakeSidecar(candidate.Blobs, m.cfg.EnableCellProofs); err != nil {
368369
return nil, fmt.Errorf("failed to make sidecar: %w", err)
369370
}
370371
}
@@ -492,10 +493,23 @@ func (m *SimpleTxManager) SetBumpFeeRetryTime(val time.Duration) {
492493
}
493494

494495
// MakeSidecar builds & returns the BlobTxSidecar and corresponding blob hashes from the raw blob
495-
// data.
496-
func MakeSidecar(blobs []*eth.Blob) (*types.BlobTxSidecar, []common.Hash, error) {
497-
sidecar := &types.BlobTxSidecar{}
496+
// data with configurable cell proof support.
497+
func MakeSidecar(blobs []*eth.Blob, enableCellProofs bool) (*types.BlobTxSidecar, []common.Hash, error) {
498+
var sidecar *types.BlobTxSidecar
499+
if enableCellProofs {
500+
sidecar = &types.BlobTxSidecar{
501+
Proofs: make([]kzg4844.Proof, 0, len(blobs)*kzg4844.CellProofsPerBlob),
502+
Version: types.BlobSidecarVersion1, // Use Version1 for cell proofs (Fusaka compatibility)
503+
}
504+
} else {
505+
sidecar = &types.BlobTxSidecar{
506+
Proofs: make([]kzg4844.Proof, 0, len(blobs)),
507+
Version: types.BlobSidecarVersion0, // Use Version0 for legacy blob proofs
508+
}
509+
}
510+
498511
blobHashes := make([]common.Hash, 0, len(blobs))
512+
499513
for i, blob := range blobs {
500514
rawBlob := blob.KZGBlob()
501515
sidecar.Blobs = append(sidecar.Blobs, *rawBlob)
@@ -504,13 +518,24 @@ func MakeSidecar(blobs []*eth.Blob) (*types.BlobTxSidecar, []common.Hash, error)
504518
return nil, nil, fmt.Errorf("cannot compute KZG commitment of blob %d in tx candidate: %w", i, err)
505519
}
506520
sidecar.Commitments = append(sidecar.Commitments, commitment)
507-
proof, err := kzg4844.ComputeBlobProof(rawBlob, commitment)
508-
if err != nil {
509-
return nil, nil, fmt.Errorf("cannot compute KZG proof for fast commitment verification of blob %d in tx candidate: %w", i, err)
510-
}
511-
sidecar.Proofs = append(sidecar.Proofs, proof)
512521
blobHashes = append(blobHashes, eth.KZGToVersionedHash(commitment))
522+
if enableCellProofs {
523+
// Version1: Use cell proofs for Fusaka compatibility
524+
cellProofs, err := kzg4844.ComputeCellProofs(rawBlob)
525+
if err != nil {
526+
return nil, nil, fmt.Errorf("cannot compute KZG cell proofs for blob %d in tx candidate: %w", i, err)
527+
}
528+
sidecar.Proofs = append(sidecar.Proofs, cellProofs...)
529+
} else {
530+
// Version0: Use legacy blob proofs
531+
proof, err := kzg4844.ComputeBlobProof(rawBlob, sidecar.Commitments[i])
532+
if err != nil {
533+
return nil, nil, fmt.Errorf("cannot compute KZG proof for fast commitment verification of blob %d in tx candidate: %w", i, err)
534+
}
535+
sidecar.Proofs = append(sidecar.Proofs, proof)
536+
}
513537
}
538+
514539
return sidecar, blobHashes, nil
515540
}
516541

op-service/txmgr/txmgr_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1728,7 +1728,9 @@ func TestMakeSidecar(t *testing.T) {
17281728
for i := 0; i < 4096; i++ {
17291729
blob[32*i] &= 0b0011_1111
17301730
}
1731-
sidecar, hashes, err := MakeSidecar([]*eth.Blob{&blob})
1731+
1732+
// Pre Fusaka, blob proof sidecar is Version0
1733+
sidecar, hashes, err := MakeSidecar([]*eth.Blob{&blob}, false)
17321734
require.NoError(t, err)
17331735
require.Equal(t, len(hashes), 1)
17341736
require.Equal(t, len(sidecar.Blobs), len(hashes))
@@ -1739,6 +1741,19 @@ func TestMakeSidecar(t *testing.T) {
17391741
require.NoError(t, eth.VerifyBlobProof((*eth.Blob)(&sidecar.Blobs[i]), commit, sidecar.Proofs[i]), "proof must be valid")
17401742
require.Equal(t, hashes[i], eth.KZGToVersionedHash(commit))
17411743
}
1744+
1745+
// Post Fusaka, blob proof sidecar is Version1
1746+
sidecar, hashes, err = MakeSidecar([]*eth.Blob{&blob}, true)
1747+
require.NoError(t, err)
1748+
require.Equal(t, len(hashes), 1)
1749+
require.Equal(t, len(sidecar.Blobs), len(hashes))
1750+
require.Equal(t, len(sidecar.Proofs), len(hashes)*kzg4844.CellProofsPerBlob)
1751+
require.Equal(t, len(sidecar.Commitments), len(hashes))
1752+
1753+
require.NoError(t, kzg4844.VerifyCellProofs(sidecar.Blobs, sidecar.Commitments, sidecar.Proofs), "cell proof must be valid")
1754+
for i, commit := range sidecar.Commitments {
1755+
require.Equal(t, hashes[i], eth.KZGToVersionedHash(commit))
1756+
}
17421757
}
17431758

17441759
func TestSendAsyncUnbufferedChan(t *testing.T) {

0 commit comments

Comments
 (0)