Skip to content

v3.9.x post fusaka blob backports (#4007, #4110, #4111)#4113

Merged
joshuacolvin0 merged 3 commits into
v3.9.x-releasefrom
post-fusaka-blob-ports
Dec 4, 2025
Merged

v3.9.x post fusaka blob backports (#4007, #4110, #4111)#4113
joshuacolvin0 merged 3 commits into
v3.9.x-releasefrom
post-fusaka-blob-ports

Conversation

The Ethereum Fusaka fork introduced /eth/v1/beacon/blobs as a replacement
for the legacy /eth/v1/beacon/blob_sidecars endpoint. Nitro's getBlobs()
function fetches from the new endpoint but was not saving blobs to disk.

The legacy blobSidecars() function saves blobs in "Version 0" format with
full metadata (commitments, proofs, block roots). The new endpoint returns
only blob data, requiring a minimal storage format optimized for hash-based
lookups.

Additionally, there was no ReadBlobsFromDisk() function - blobs could be
saved but not read back. This commit adds the reader for testing and to
enable a future beacon endpoint emulator that we may add.

Storage Format V1 (new):
- Stores blobs as versioned hash -> blob map
- File: {blob-directory}/{slot}
- Format: {"version": 1, "data": {"0xHASH": "0xBLOB", ...}}
- Used by getBlobs() when fetching from /eth/v1/beacon/blobs

Storage Format V0 (legacy, backward compatible):
- Stores blob_sidecars array with full metadata
- Format: {"data": [{"blob": "0x...", "kzg_commitment": "0x...",
  "kzg_proof": "0x...", ...}]}
- Used by blobSidecars() when fetching from legacy endpoint
- Still readable for backward compatibility

ReadBlobsFromDisk() (new):
- Reads blobs from disk, transparently handling V0 or V1 format
- Auto-detects version via presence of "version" field
- Validates blob integrity:
  * V1: Computes commitment -> versioned hash, verifies match to key
  * V0: Computes commitment from blob, verifies match to stored commitment
- No migration needed - both formats coexist

Renamed functions for clarity:
- saveBlobDataToDisk -> saveBlobsV0ToDisk (legacy format)
- Added saveBlobsV1ToDisk (new format)

Testing improvements:
- Updated createTestBlobs() to use production blobs.EncodeBlobs()
- All tests now use real KZG blobs with valid commitments
- Added TestReadBlobsV1ValidationFailure and TestReadBlobsV0ValidationFailure
- Renamed existing tests to indicate format (e.g., TestSaveBlobsV0ToDisk)

(cherry picked from commit 0ea5b8f)
…ched

The Fusaka hard fork introduced the new /eth/v1/beacon/blobs endpoint which
is now universally available. This removes all code related to the legacy
blob_sidecars endpoint including the toggle logic that would switch between
endpoints on errors.

- Remove useLegacyEndpoint config field and --use-legacy-endpoint flag
- Remove blobSidecars() function from blob_client.go
- Simplify GetBlobsBySlot() to always use getBlobs()
- Remove --compare-endpoints flag and compareEndpoints() from blobtool
- Keep saveBlobsV0ToDisk() and V0 reading code for backwards compatibility
  with existing blob files saved to disk

(cherry picked from commit 8299e50)
The Fusaka hard fork made cell proofs (Version1) universally required, so
the legacy single-proof-per-blob (Version0) code path is no longer needed.

- Remove enableCellProofs parameter from ComputeProofs(), always use cell proofs
- Remove EnableCellProofs config field and --enable-cell-proofs flag
- Remove shouldEnableCellProofs() function from data_poster.go
- Remove SupportsCellProofs() function from parent.go
- Remove Version0 tests

(cherry picked from commit 3df0d2e)
@Tristan-Wilson Tristan-Wilson changed the base branch from master to v3.9.x-release December 4, 2025 17:56

@joshuacolvin0 joshuacolvin0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

auto-merge was automatically disabled December 4, 2025 19:56

Pull request was closed

@joshuacolvin0 joshuacolvin0 reopened this Dec 4, 2025
@joshuacolvin0 joshuacolvin0 merged commit 7f582c3 into v3.9.x-release Dec 4, 2025
18 of 21 checks passed
@joshuacolvin0 joshuacolvin0 deleted the post-fusaka-blob-ports branch December 4, 2025 20:06
@github-actions

github-actions Bot commented Dec 4, 2025

Copy link
Copy Markdown
Contributor

❌ 3 Tests Failed:

Tests completed Failed Passed Skipped
2170 3 2167 0
View the top 3 failed tests by shortest run time
TestBatchPosterActuallyPostsBlobsToL1
Stack Traces | 26.720s run time
=== RUN   TestBatchPosterActuallyPostsBlobsToL1
=== PAUSE TestBatchPosterActuallyPostsBlobsToL1
=== CONT  TestBatchPosterActuallyPostsBlobsToL1
    batch_poster_test.go:884: goroutine 52 [running]:
        runtime/debug.Stack()
        	/opt/hostedtoolcache/go/1.25.4/x64/src/runtime/debug/stack.go:26 +0x5e
        github.com/offchainlabs/nitro/util/testhelpers.RequireImpl({0x40c3050, 0xc000482c40}, {0x40804e0, 0x5e97060}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/util/testhelpers/testhelpers.go:29 +0x55
        github.com/offchainlabs/nitro/system_tests.Require(0xc000482c40, {0x40804e0, 0x5e97060}, {0x0, 0x0, 0x0})
        	/home/runner/work/nitro/nitro/system_tests/common_test.go:1790 +0x5d
        github.com/offchainlabs/nitro/system_tests.TestBatchPosterActuallyPostsBlobsToL1(0xc000482c40)
        	/home/runner/work/nitro/nitro/system_tests/batch_poster_test.go:884 +0x388
        testing.tRunner(0xc000482c40, 0x3d08280)
        	/opt/hostedtoolcache/go/1.25.4/x64/src/testing/testing.go:1934 +0xea
        created by testing.(*T).Run in goroutine 1
        	/opt/hostedtoolcache/go/1.25.4/x64/src/testing/testing.go:1997 +0x465
        
    batch_poster_test.go:884: �[31;1m [] context deadline exceeded �[0;0m
--- FAIL: TestBatchPosterActuallyPostsBlobsToL1 (26.72s)
TestEthSyncing
Stack Traces | 27.400s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
DEBUG[12-04|20:11:50.377] Served eth_getBlockByNumber              reqid=2605 duration="98.554µs"
TRACE[12-04|20:11:50.377] Handled RPC response                     reqid=301  duration="1.293µs"
TRACE[12-04|20:11:50.377] Handled RPC response                     reqid=134  duration="2.385µs"
DEBUG[12-04|20:11:50.377] Served eth_getBlockByNumber              reqid=247  duration="100.377µs"
DEBUG[12-04|20:11:50.377] Served eth_maxPriorityFeePerGas          reqid=143  duration="430.572µs"
TRACE[12-04|20:11:50.377] Handled RPC response                     reqid=143  duration="2.004µs"
TRACE[12-04|20:11:50.377] Engine API request received              method=NewPayload                    number=23  hash=151d34..74848a
DEBUG[12-04|20:11:50.376] Served eth_getTransactionReceipt         reqid=300  duration="22.152µs"
TRACE[12-04|20:11:50.378] Inserting block without sethead          hash=151d34..74848a number=23
DEBUG[12-04|20:11:50.378] Served eth_subscribe                     reqid=136  duration="23.634µs"
DEBUG[12-04|20:11:50.376] Finality not supported, not pushing finality data to execution
TRACE[12-04|20:11:50.378] Handled RPC response                     reqid=300  duration="2.234µs"
DEBUG[12-04|20:11:50.376] Pushed sync data from consensus to execution synced=true  maxMessageCount=12  updatedAt=2025-12-04T20:11:50+0000 hasProgressMap=false
DEBUG[12-04|20:11:50.376] Created new diff layer                   id=22                 block=21  nodesize=3.05KiB  statesize=1.13KiB
DEBUG[12-04|20:11:50.378] ExecuteNextMsg failed to send message to execEngine err="createBlock mutex held"              msgIdxToExecute=12
TRACE[12-04|20:11:50.375] Handled RPC response                     reqid=258  duration="1.002µs"
INFO [12-04|20:11:50.376] Chain head was updated                   number=19  hash=5f583b..7bc05e root=77c06b..d9ece2 elapsed="483.129µs"
DEBUG[12-04|20:11:50.376] Served eth_getBlockByNumber              reqid=2604 duration="97.601µs"
TRACE[12-04|20:11:50.376] Handled RPC response                     reqid=1260 duration="2.214µs"
--- FAIL: TestEthSyncing (27.40s)
TestBatchPosterActuallyPostsBlobsToL1
Stack Traces | 59.160s run time
... [CONTENT TRUNCATED: Keeping last 20 lines]
DEBUG[12-04|20:12:55.322] Executing EVM call finished              runtime="307.713µs"
TRACE[12-04|20:12:55.322] Handled RPC response                     reqid=1691  duration="2.324µs"
DEBUG[12-04|20:12:55.322] Served eth_call                          reqid=1483  duration="348.268µs"
DEBUG[12-04|20:12:55.322] Served eth_getTransactionCount           reqid=4511  duration="39.333µs"
TRACE[12-04|20:12:55.322] Handled RPC response                     reqid=1483  duration="2.504µs"
TRACE[12-04|20:12:55.322] Handled RPC response                     reqid=4510  duration="1.763µs"
TRACE[12-04|20:12:55.322] Handled RPC response                     reqid=4511  duration="1.372µs"
DEBUG[12-04|20:12:55.322] Served eth_getBlockByNumber              reqid=14040 duration="88.214µs"
DEBUG[12-04|20:12:55.322] Served eth_getBlockByNumber              reqid=4888  duration="118.891µs"
TRACE[12-04|20:12:55.322] Handled RPC response                     reqid=14040 duration="2.224µs"
INFO [12-04|20:12:55.322] Initialising Ethereum protocol           network=412,346 dbversion=<nil>
INFO [12-04|20:12:55.322] Load database journal from disk
TRACE[12-04|20:12:55.322] Handled RPC response                     reqid=4888  duration="2.064µs"
DEBUG[12-04|20:12:55.322] Executing EVM call finished              runtime="179.975µs"
DEBUG[12-04|20:12:55.322] Served eth_call                          reqid=4512  duration="225.881µs"
TRACE[12-04|20:12:55.322] Handled RPC response                     reqid=4512  duration="1.954µs"
DEBUG[12-04|20:12:55.323] Executing EVM call finished              runtime="186.968µs"
DEBUG[12-04|20:12:55.323] Served eth_call                          reqid=4889  duration="232.483µs"
TRACE[12-04|20:12:55.323] Handled RPC response                     reqid=4889  duration="1.804µs"
DEBUG[12-04|20:12:55.323] Executing EVM call finished              runtime="158.536µs"

📣 Thoughts on this report? Let Codecov know! | Powered by Codecov

@joshuacolvin0 joshuacolvin0 changed the title v3.9.x post fusaka blob backports v3.9.x post fusaka blob backports (#4007, #4110, #4111) Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants