engine_getBlobsV4#774
Conversation
- Expand V4 spec from 1 line to 7 detailed specification points mirroring V3 style - Add support for multiple blob versioned hashes in example (3 blobs) - Clarify missing blob handling (return null at corresponding positions) - Add support for partial blobs with null cells and null proofs - Update response schema to allow null entries (oneOf pattern) - Include example with: present blob, partial blob with null cell, missing blob Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds new Engine API capabilities needed for EIP-8070 “sparse blobpools”, enabling the CL to (1) communicate its blob column custody set to the EL and (2) request partial blob cell data (with proofs) from the EL blobpool.
Changes:
- Introduces
engine_blobCustodyUpdatedV1for CL→EL custody-set updates via a 16-byte bitarray. - Introduces
engine_getBlobsV4for fetching requested blob cells + KZG proofs (including partial/missing data semantics). - Adds shared schema types (
bytes16,BlobCellsAndProofsV1) and updates fork documentation/spellcheck wordlist accordingly.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| wordlist.txt | Adds the new versioned schema/method-related token for spellchecking. |
| src/schemas/base-types.yaml | Adds a reusable bytes16 primitive used by the new methods’ bitarray params. |
| src/engine/openrpc/schemas/blob.yaml | Defines BlobCellsAndProofsV1 response object for partial cell/proof returns. |
| src/engine/openrpc/methods/blob.yaml | Adds OpenRPC method entries for engine_blobCustodyUpdatedV1 and engine_getBlobsV4 (with examples). |
| src/engine/amsterdam.md | Documents the new structure and method specs in the Amsterdam fork markdown (including ToC updates). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
we will ship this !! |
| * params: | ||
| 1. `forkchoiceState`: [`ForkchoiceStateV1`](./paris.md#ForkchoiceStateV1). | ||
| 2. `payloadAttributes`: `Object|null` - Instance of [`PayloadAttributesV4`](#payloadattributesv4) or `null`. | ||
| 3. `custodyColumns`: `DATA|null`, 16 Bytes - Interpreted as a bitarray of length `CELLS_PER_EXT_BLOB` indicating which column indices form the CL's custody set, or `null` if the CL does not provide custody services. |
There was a problem hiding this comment.
Are we certain that no network in the future will use CELLS_PER_EXT_BLOB > 128?
There was a problem hiding this comment.
Yes, for the midterm, and we can adjust this length later, right ?
There was a problem hiding this comment.
We could extend this field to Bytes32 with the high part zeroed out, doesn’t seem to be a big overhead. If we stick with Bytes16 for now and this number will be increased in the future we will have to introduce a new version of fcU. I don’t have a strong opinion on that, and would lean on whatever you think is reasonable
|
|
||
| 2. If the custody set has contracted, the Execution client **MAY** prune dropped cells from local storage, but **ONLY AFTER** it has broadcast an updated `NewPooledTransactionHashes` announcement with the reduced available set to avoid peers perceiving an availability fault. | ||
|
|
||
| 4. The Execution client **MUST** treat a request to update the custody set to the current value as a no-op and return Ok. |
There was a problem hiding this comment.
Does “no-op and return OK" mean the forkchoiceUpdate processing MUST NOT be affected by the custodyColumns?
There was a problem hiding this comment.
I would phrase it something like the following then:
- The Execution client MUST run custody set update independently to the fork choice update, i.e. execution time and errors occurred during custody set update MUST NOT affect the main processing flow of this method.
There was a problem hiding this comment.
I think this may be added as additional rule. So we keep 4. and introduce 5. as how you described it
|
|
||
| 1. If the custody set has expanded, the Execution client **SHOULD** issue new sampling requests for the delta. It **MAY** broadcast an updated `NewPooledTransactionHashes` announcement with the newly available set. | ||
|
|
||
| 2. If the custody set has contracted, the Execution client **MAY** prune dropped cells from local storage, but **ONLY AFTER** it has broadcast an updated `NewPooledTransactionHashes` announcement with the reduced available set to avoid peers perceiving an availability fault. |
There was a problem hiding this comment.
What would a reasonable minimal delay between broadcasting updated NewPooledTransactionHashes and pruning? It would be helpful to specify it here to set expectations, like the minimal delay could be a slot duration or something like that.
There was a problem hiding this comment.
We were considering 2 slots, but this number is (IIRC) quite arbitrary and needs to be tested on devnet. We will discuss this and update the PR. Thank you
| schema: | ||
| $ref: '#/components/schemas/PayloadAttributesV4' | ||
| - name: Custody columns | ||
| required: false |
There was a problem hiding this comment.
I think it should be true as it either bytes or null, there is no case when custodyColumns param is completely missing
There was a problem hiding this comment.
it was set to false for consistency with the previous field (payloadAttributes) which also could be null but is not required.
But no big deal making Custody columns required if needed
raulk
left a comment
There was a problem hiding this comment.
Re: optionality of the custody column filter. We have been designing solutions for in-transit reconstruction at the CL. There is a scenario in which we'd want the EL to serve all cells it has buffered, regardless of the CL's custody set. That would include "excess" cells when acting as a sampler, and all cells when acting as a provider.
What filter are you referring to ? This is possible with setting the bitmap array in getBlobsV4 request to all 1, right ? |
| * method: `engine_getBlobsV4` | ||
| * params: | ||
| 1. `versioned_blob_hashes`: `Array of DATA`, 32 Bytes - an array of blob versioned hashes. | ||
| 2. `indices_bitarray`: `DATA`, 16 Bytes - a bitarray denoting the indices of the cells to retrieve. |
There was a problem hiding this comment.
This is already doable with the proposed API.
CL can set indices_bitarray to all ones. That way CL requests EL to provide all cells it has for the requested versioned blob hashes. For the missing cells (e.g. for cells that EL was acting as a sampler) request will contain nulls in the blob_cells field
Co-authored-by: Mikhail Kalinin <noblesse.knight@gmail.com>
Co-authored-by: Mikhail Kalinin <noblesse.knight@gmail.com>
Co-authored-by: Mikhail Kalinin <noblesse.knight@gmail.com>
Companion PR to ethereum/EIPs#11444 . The current PR is expected to be merged first.
To support EIP-8070 (sparse blobpools) :
engine_getBlobsV4: provides the mechanism for the CL to request partial blobs data from the the EL's blobpoolengine_forkchoiceupdatedv4: updated with the column custody field to update EL about CL's custody column set