Skip to content

Conversation

@Kukoomomo
Copy link
Contributor

@Kukoomomo Kukoomomo commented Nov 4, 2025

Summary by CodeRabbit

  • Enhancements

    • Blob transaction sidecars now choose version based on chain header and Osaka-era timings, improving compatibility.
    • Fee tip/cap calculations and resubmit/cancel flows use header-aware logic for more accurate fee handling.
    • New blob utilities support hashing, proof and cell-proof generation, and on-the-fly sidecar version conversion.
  • Tests

    • Added extensive tests for blob hashing, KZG proofs, cell proofs, and version/consistency checks.

@Kukoomomo Kukoomomo requested a review from a team as a code owner November 4, 2025 09:03
@Kukoomomo Kukoomomo requested review from Web3Jumb0 and removed request for a team November 4, 2025 09:03
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 4, 2025

Walkthrough

Removes proof generation from the internal blob helper and sidecar construction, adds header-aware blob sidecar versioning by threading a block header through fee/tip retrieval and rollup transaction creation, and adds blob hashing/proof utilities and tests.

Changes

Cohort / File(s) Summary
Node blob helper
node/types/blob.go
Renamed/refactored makeBCP()makeBlobCommitment() to return only Blob and Commitment (removed Proof generation and return); call sites updated; BlobTxSidecar construction no longer populates Proofs.
Rollup fee & version flow
tx-submitter/services/rollup.go
GetGasTipAndCap() now returns head *ethtypes.Header; head threaded through createRollupTx, createBlobTx, ReSubmitTx, CancelTx; added DetermineBlobVersion(head) and dynamic blob sidecar versioning using head.
Rollup tests
tx-submitter/services/rollup_test.go
Tests updated to accept the extra head return from GetGasTipAndCap() (now ignored in tests).
Blob hashing tests
tx-submitter/services/blob_hash_test.go
New tests for blob hash: v0 vs v1 consistency, hasher reuse across calls, and idempotency of CalcBlobHashV1.
Blob utilities & tests
tx-submitter/types/blob.go, tx-submitter/types/blob_test.go, tx-submitter/types/blob_config_test.go, tx-submitter/types/blob_params.go
New utilities: BlobHashes, MakeBlobProof, MakeCellProof, DetermineBlobVersion, BlobSidecarVersionToV1; comprehensive KZG blob/cell proof tests; added Osaka/BPO timing and config fields to chain configs and a small config test.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Rollup.rollup()
    participant Gas as GetGasTipAndCap()
    participant RollupTx as createRollupTx()
    participant BlobTx as createBlobTx()
    participant Version as DetermineBlobVersion()
    participant Sidecar as BlobTxSidecar

    Caller->>Gas: request fees
    Gas-->>Caller: return (tip, gasFeeCap, blobFee, head, err)
    Caller->>RollupTx: create rollup tx (head, fees, calldata)
    RollupTx->>Version: determine blobVersion(head)
    Version-->>RollupTx: blobVersion
    RollupTx->>BlobTx: create blob tx (head, blobVersion, sidecar)
    BlobTx->>Sidecar: build/convert sidecar (versioning, proofs)
    Sidecar-->>BlobTx: versioned sidecar
    BlobTx-->>RollupTx: tx with sidecar
    RollupTx-->>Caller: signed tx ready
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Focus areas:
    • Correct propagation and error handling of the new head return across all call sites.
    • Ensure removal of proofs from makeBlobCommitment aligns with new proof-generation utilities and consumers.
    • Verify DetermineBlobVersion logic against chain config timings (Osaka/BPO*).
    • Review new blob proof/hash utilities and extensive tests for determinism and edge cases.

Possibly related PRs

Suggested reviewers

  • Web3Jumb0
  • r3aker86
  • FletcherMan

Poem

🐰 I hopped through bytes and trimmed a proof,
Threaded a header to guide the roof.
Blobs now choose their version by date,
Tests hum along to validate.
Thump-thump — the rabbit says: nice update!

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary objective of the changeset: introducing blob version checking functionality for blob transactions across the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch submitter/blobVersion

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Kukoomomo and others added 2 commits November 4, 2025 17:05
Co-authored-by: fletcher.fan <fletcher.fan@bitget.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
node/types/blob.go (1)

68-75: Critical inconsistency: Empty blob includes Proofs while non-empty blobs don't.

The empty blob case still populates the Proofs field (line 73), but the non-empty cases (lines 101-104) omit it entirely. This creates an inconsistent BlobTxSidecar structure.

Apply this diff to make the behavior consistent:

 	if len(blobBytes) == 0 {
 		return &eth.BlobTxSidecar{
 			Blobs:       []kzg4844.Blob{*emptyBlob},
 			Commitments: []kzg4844.Commitment{emptyBlobCommit},
-			Proofs:      []kzg4844.Proof{emptyBlobProof},
 		}, nil
 	}
tx-submitter/services/rollup.go (2)

1866-1894: Blob cancellation always uses Version0, potentially causing version mismatch.

The CancelTx function ignores the head parameter (line 1828) and always creates a Version0 blob hash using kZGToVersionedHash (line 1888). If the network has upgraded to support Version1 blobs (Osaka), the cancellation transaction may fail due to version mismatch.

Consider applying this diff to use the correct version:

-	tip, gasFeeCap, blobFeeCap, _, err := r.GetGasTipAndCap()
+	tip, gasFeeCap, blobFeeCap, head, err := r.GetGasTipAndCap()
 	if err != nil {
 		return nil, fmt.Errorf("get gas tip and cap error:%w", err)
 	}
 	
 	// ... existing bump logic ...
 	
 	case ethtypes.BlobTxType:
 		// For blob transactions, we need to keep one empty blob
 		var emptyBlob kzg4844.Blob
 		emptyCommitment, err := kzg4844.BlobToCommitment(&emptyBlob)
 		if err != nil {
 			return nil, fmt.Errorf("failed to create empty blob commitment: %w", err)
 		}
 		emptyProof, err := kzg4844.ComputeBlobProof(&emptyBlob, emptyCommitment)
 		if err != nil {
 			return nil, fmt.Errorf("failed to create empty blob proof: %w", err)
 		}
+		
+		// Determine blob version based on chain state
+		version := r.DetermineBlobVersion(head)
+		var blobHash common.Hash
+		if version == ethtypes.BlobSidecarVersion1 {
+			hasher := sha256.New()
+			blobHash = common.Hash(kzg4844.CalcBlobHashV1(hasher, &emptyCommitment))
+		} else {
+			blobHash = kZGToVersionedHash(emptyCommitment)
+		}
 
 		newTx = ethtypes.NewTx(&ethtypes.BlobTx{
 			ChainID:    uint256.MustFromBig(tx.ChainId()),
 			Nonce:      tx.Nonce(),
 			GasTipCap:  uint256.MustFromBig(tip),
 			GasFeeCap:  uint256.MustFromBig(gasFeeCap),
 			Gas:        tx.Gas(),
 			To:         *tx.To(),
 			Value:      uint256.MustFromBig(tx.Value()),
 			Data:       []byte{}, // Empty calldata for cancellation
 			BlobFeeCap: uint256.MustFromBig(blobFeeCap),
-			BlobHashes: []common.Hash{kZGToVersionedHash(emptyCommitment)},
+			BlobHashes: []common.Hash{blobHash},
 			Sidecar: &ethtypes.BlobTxSidecar{
+				Version:     version,
 				Blobs:       []kzg4844.Blob{emptyBlob},
 				Commitments: []kzg4844.Commitment{emptyCommitment},
 				Proofs:      []kzg4844.Proof{emptyProof},
 			},
 		})

1156-1183: Add nil check for batch.Sidecar before accessing Blobs field.

Line 1150 accesses batch.Sidecar.Blobs without verifying batch.Sidecar is not nil. When batches originate from the oracle path and don't meet the parent copy conditions (line 180 in oracle/oracle/batch.go), batch.Sidecar remains nil, causing a panic. Additionally, verify that batch.Sidecar.Proofs is properly populated for both derivation and oracle paths—the oracle path may leave this field incomplete.

func (r *Rollup) createRollupTx(batch *eth.RPCRollupBatch, nonce, gas uint64, tip, gasFeeCap, blobFee *big.Int, calldata []byte, head *ethtypes.Header) (*ethtypes.Transaction, error) {
	if batch.Sidecar != nil && len(batch.Sidecar.Blobs) > 0 {
		return r.createBlobTx(batch, nonce, gas, tip, gasFeeCap, blobFee, calldata, head)
	}
	return r.createDynamicFeeTx(nonce, gas, tip, gasFeeCap, calldata)
}
🧹 Nitpick comments (1)
tx-submitter/services/rollup_test.go (1)

67-72: Consider verifying the head parameter in successful test cases.

While the current implementation correctly captures the new head return value, the tests should assert that head is not nil when the call succeeds to validate the API contract.

Apply this diff:

-	tip, feecap, blobfee, _, err := r.GetGasTipAndCap()
+	tip, feecap, blobfee, head, err := r.GetGasTipAndCap()
 	require.NoError(t, err)
 	require.NotNil(t, tip)
 	require.NotNil(t, feecap)
 	require.NotNil(t, blobfee)
+	require.NotNil(t, head)
 	require.Equal(t, initTip, tip)

Apply similar changes to line 80.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64a3b43 and 5c34427.

📒 Files selected for processing (4)
  • node/types/blob.go (2 hunks)
  • tx-submitter/services/blob_hash_test.go (1 hunks)
  • tx-submitter/services/rollup.go (14 hunks)
  • tx-submitter/services/rollup_test.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tx-submitter/services/rollup.go (1)
tx-submitter/types/blob_params.go (2)
  • ChainConfigMap (10-14)
  • DefaultBlobConfig (8-8)
node/types/blob.go (1)
node/derivation/blobs.go (1)
  • Blob (9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: check
  • GitHub Check: test
  • GitHub Check: check
  • GitHub Check: test
  • GitHub Check: check
  • GitHub Check: test
  • GitHub Check: check
  • GitHub Check: test
  • GitHub Check: Analyze (rust)
  • GitHub Check: Analyze (go)
🔇 Additional comments (7)
node/types/blob.go (2)

55-66: LGTM: Clean refactor to remove proof generation.

The rename to makeBlobCommitment better reflects the function's purpose, and removing proof generation simplifies the API appropriately.


86-100: LGTM: Call sites correctly updated.

All calls to makeBlobCommitment properly handle the new return signature without the proof value.

tx-submitter/services/rollup.go (4)

845-849: LGTM: Finalize correctly ignores blob-related parameters.

Since finalize() creates a DynamicFeeTx (line 878), it appropriately ignores the head and blobFee return values from GetGasTipAndCap().


1250-1307: LGTM: GetGasTipAndCap correctly returns head parameter.

The function properly retrieves the header (line 1251) and threads it through all return paths, returning it on success (line 1306) or nil on error (lines 1253, 1258, 1264, 1273).


1586-1650: LGTM: ReSubmitTx correctly handles blob version conversion.

The function properly uses the head parameter (line 1586) to determine the blob version (line 1644) and conditionally converts from Version0 to Version1 (lines 1645-1650), ensuring resubmitted blob transactions use the correct version.


1921-1933: LGTM: DetermineBlobVersion has sound versioning logic.

The function safely defaults to Version0 when the head is unavailable (lines 1922-1924), uses chain-specific configuration (lines 1925-1928), and correctly identifies when to use Version1 based on Osaka activation (lines 1929-1931).

tx-submitter/services/blob_hash_test.go (1)

1-126: The review comment is incorrect—kZGToVersionedHash is properly defined and accessible.

The function kZGToVersionedHash is defined at tx-submitter/services/utils.go:27 with a complete implementation. Since both the test file (blob_hash_test.go) and the utility file (utils.go) are in the same services package, the unexported function is accessible to the tests. The function signature matches all three call sites in the test file (lines 58, 99, 124), and the tests will compile and run without issues.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
tx-submitter/services/rollup.go (2)

1156-1192: Compute blob hashes after choosing the sidecar version

createBlobTx grabs the blob hashes before the version switch, so even with the helper fixed we still end up hashing with the wrong version info. For v0 submits this continues to emit Osaka (v1) hashes; for v1 submits we never recompute after BlobSidecarVersionToV1 enriches the proofs. Please derive the hashes after the version branch and pass the final sidecar.Version into BlobHashes so commitments, proofs, and hashes all agree.(eips.ethereum.org)

-	versionedHashes := types.BlobHashes(batch.Sidecar.Blobs, batch.Sidecar.Commitments)
 	sidecar := &ethtypes.BlobTxSidecar{
 		Blobs:       batch.Sidecar.Blobs,
 		Commitments: batch.Sidecar.Commitments,
 	}
 	switch types.DetermineBlobVersion(head, r.chainId.Uint64()) {
@@
 	default:
 		return nil, fmt.Errorf("unsupported blob version")
 	}
+	versionedHashes := types.BlobHashes(sidecar.Blobs, sidecar.Commitments, sidecar.Version)
 
 	return ethtypes.NewTx(&ethtypes.BlobTx{
@@
-		BlobHashes: versionedHashes,
+		BlobHashes: versionedHashes,
 		Sidecar:    sidecar,
 	}), nil

1653-1673: Resubmits upgrade proofs but leave stale blob hashes

When we bump a v0 sidecar to v1 in ReSubmitTx, BlobSidecarVersionToV1 swaps in cell proofs but we still reuse the original blob hashes (0x01 prefix). Osaka validators will reject that payload. After the potential version upgrade, recompute the BlobHashes with the sidecar’s actual version before building the new blob tx.(eips.ethereum.org)

 	case ethtypes.BlobTxType:
 		sidecar := tx.BlobTxSidecar()
 		version := types.DetermineBlobVersion(head, r.chainId.Uint64())
 		if sidecar.Version == ethtypes.BlobSidecarVersion0 && version == ethtypes.BlobSidecarVersion1 {
 			err = types.BlobSidecarVersionToV1(sidecar)
 			if err != nil {
 				return nil, err
 			}
+			blobHashes := types.BlobHashes(sidecar.Blobs, sidecar.Commitments, sidecar.Version)
+			sidecar.Proofs = sidecar.Proofs
+			tx = tx.WithBlobHashes(blobHashes)
 		}
 		newTx = ethtypes.NewTx(&ethtypes.BlobTx{
@@
-			BlobHashes: tx.BlobHashes(),
+			BlobHashes: types.BlobHashes(sidecar.Blobs, sidecar.Commitments, sidecar.Version),
 			Sidecar:    sidecar,
 		})
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c34427 and 30e1961.

📒 Files selected for processing (3)
  • tx-submitter/services/rollup.go (14 hunks)
  • tx-submitter/types/blob.go (1 hunks)
  • tx-submitter/types/blob_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
tx-submitter/types/blob.go (2)
node/derivation/blobs.go (1)
  • Blob (9-9)
tx-submitter/types/blob_params.go (2)
  • ChainConfigMap (10-14)
  • DefaultBlobConfig (8-8)
tx-submitter/types/blob_test.go (3)
node/derivation/blobs.go (1)
  • Blob (9-9)
tx-submitter/types/blob.go (2)
  • MakeBlobProof (21-31)
  • MakeCellProof (33-43)
node/derivation/beacon.go (1)
  • VerifyBlobProof (217-219)
tx-submitter/services/rollup.go (2)
tx-submitter/types/blob.go (5)
  • BlobHashes (12-19)
  • DetermineBlobVersion (45-57)
  • MakeBlobProof (21-31)
  • MakeCellProof (33-43)
  • BlobSidecarVersionToV1 (60-73)
tx-submitter/types/blob_params.go (1)
  • ChainConfigMap (10-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: check
  • GitHub Check: test
  • GitHub Check: check
  • GitHub Check: test
  • GitHub Check: check
  • GitHub Check: check
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (rust)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30e1961 and b8f06ed.

📒 Files selected for processing (2)
  • tx-submitter/types/blob_config_test.go (2 hunks)
  • tx-submitter/types/blob_params.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tx-submitter/types/blob_config_test.go (2)
tx-submitter/types/blob_params.go (1)
  • HoodiChainConfig (40-54)
tx-submitter/types/blob_config.go (1)
  • GetBlobFeeDenominator (92-136)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Analyze (rust)
🔇 Additional comments (1)
tx-submitter/types/blob_params.go (1)

28-35: LGTM! Mainnet fork configurations added correctly.

The Osaka, BPO1, and BPO2 fork times and configurations have been properly added to MainnetChainConfig, bringing it in line with the test network configurations. The timestamps are in chronological order and the configuration structure is consistent.

@Kukoomomo Kukoomomo merged commit 3e02ce8 into main Nov 6, 2025
13 of 15 checks passed
@Kukoomomo Kukoomomo deleted the submitter/blobVersion branch November 6, 2025 03:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants