# `eth_sendBlobs` and `eth_getBlobsStatus` ## Abstract This EIP proposes two new JSON-RPC methods, `eth_sendBlobs` and `eth_getBlobsStatus`. The `eth_sendBlobs` method allows originators to submit a bundle of candidate EIP-4844 Type 3 transactions that share the same `sender` address and `nonce`. The receiving RPC node, often connected to specialized block-building infrastructure, can select the most advantageous transaction from the bundle based on available blob capacity in a block (per EIP-4844 limits) and other mempool conditions. This maximizes the probability of the sender's blob data being included without requiring the originator to guess the optimal number of blobs. A successful submission returns a unique `bundleId`. The `eth_getBlobsStatus` method allows originators to query the status of a previously submitted bundle using its `bundleId`. It provides information on whether the bundle is pending, included in a block (and which transaction/block), expired, or not found. ## Motivation EIP-4844 introduced Shard Blob Transactions but imposed a strict limit on the number of blobs per block (initially 6). This creates uncertainty for blob transaction originators: 1. **Competition:** Other blob transactions, potentially with higher fees, might consume available blob slots. 2. **Fixed Submission:** Standard methods like `eth_sendRawTransaction` handle only one transaction per `sender`/`nonce`, forcing the originator to commit to a specific blob count. 3. **Inefficiency & Exclusion:** A transaction with N blobs might be excluded if fewer than N slots are available, even if a variant with fewer blobs could have fit. Originators must guess the optimal count, risking under-utilization or complete exclusion. `eth_sendBlobs` addresses this by allowing submission of multiple variants (e.g., transactions with 1 to 6 blobs) for the same `sender`/`nonce`. The receiving infrastructure, having a better view of block construction, selects the best-fitting variant, increasing inclusion probability. However, tracking these submissions poses challenges: 1. **Uncertainty:** The originator doesn't know which specific transaction hash (if any) from the bundle will be included. 2. **Visibility:** Bundles reside in specialized, potentially off-chain pools, invisible to standard mempool explorers. 3. **Lifecycle:** Bundles can expire based on `maxBlockNumber` or provider policy. `eth_getBlobsStatus` provides a standard way to query the bundle's state using the `bundleId` obtained from `eth_sendBlobs`, addressing these tracking needs. ## Specification ### Method: `eth_sendBlobs` Allows submitting a bundle of alternative blob transactions for a single nonce. #### Parameters The method accepts a single `Array` parameter containing one `Object` with the following fields: 1. `txs`: `Array[DATA]` * An array of hex-encoded, RLP-serialized signed EIP-4844 Type 3 transactions. * **Constraint:** All transactions within this array *MUST* originate from the same `sender` address. * **Constraint:** All transactions within this array *MUST* use the identical `nonce`. * **Constraint:** Each transaction string `DATA` must represent a valid, signed EIP-4844 transaction. * **Recommendation:** Transactions should ideally differ primarily in the number of blobs (`blobVersionedHashes`) to represent inclusion options. * **Recommendation:** Transactions should have consistent fee parameters (`maxFeePerGas`, `maxPriorityFeePerGas`, `maxFeePerBlobGas`) to allow for predictable selection based on blob count. 2. `maxBlockNumber`: `QUANTITY | TAG` (Optional) * A hex-encoded block number (`0x...`) or a tag (`"latest"`, `"pending"`). * If provided, the bundle should not be considered for inclusion in any block *after* this block number. Provides an expiry hint. * If omitted, lifespan is determined by the receiving node's policy. #### Returns * `result`: `DATA | Null` * On success: A unique identifier (`DATA`, e.g., hex-encoded string) for the submitted bundle, generated by the receiving node. This `bundleId` is used for `eth_getBlobsStatus`. * On failure: `null`. * `error`: `Object | Null` * If an error occurs (validation, processing), contains a JSON-RPC 2.0 error object. `result` will be `null`. * Potential error codes: * `-32602: Invalid params` (Invalid structure, type mismatches, non-hex `DATA`, txs violate constraints). * `-32000` (or other server-defined errors): Internal server error, invalid signature, non-EIP-4844 transaction, etc. * If successful, `error` is `null`. #### Example Request (`eth_sendBlobs`) ```json { "jsonrpc": "2.0", "id": 1, "method": "eth_sendBlobs", "params": [{ "txs": [ "0xf8eabc...", // Signed Tx, 1 blob, nonce N, Addr A "0xf8eade...", // Signed Tx, 2 blobs, nonce N, Addr A "0xf8eaf0...", // Signed Tx, 3 blobs, nonce N, Addr A "0xf8eb12...", // Signed Tx, 4 blobs, nonce N, Addr A "0xf8eb34...", // Signed Tx, 5 blobs, nonce N, Addr A "0xf8eb56..." // Signed Tx, 6 blobs, nonce N, Addr A ], "maxBlockNumber": "0xAFEBE1" // Optional: Expire after block 11529953 }] } ``` #### Example Response (Success) (`eth_sendBlobs`) ```json { "jsonrpc": "2.0", "id": 1, "result": "0x7b9d8f61a3f1f6d9b8e0c2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3", // Unique Bundle ID "error": null } ``` #### Expected Node Behavior (`eth_sendBlobs`) Nodes implementing this method (likely specialized endpoints) *MUST*: 1. **Validate Request:** Check JSON-RPC structure and parameter types. 2. **Validate Transactions:** For each `DATA` string in `txs`: * Decode RLP. * Verify it's a valid signed EIP-4844 Type 3 transaction. * Extract `sender` and `nonce`. 3. **Enforce Constraints:** * Verify all transactions share the *exact same* `sender` address. * Verify all transactions share the *exact same* `nonce`. * Fail the request (`Invalid params` error) if constraints are violated. 4. **Validate `maxBlockNumber`:** If present, check if it's a valid hex quantity or tag. 5. **Generate ID & Store:** If validation passes: * Generate a unique `bundleId`. * Store the bundle (associated transactions, sender, nonce, `maxBlockNumber`, initial status `PENDING`) indexed by the `bundleId`. * Accept the bundle into a specialized pool that allows multiple transactions per `sender`/`nonce`. 6. **Return ID:** Respond with the generated `bundleId`. The node (or associated block builder) *SHOULD* implement selection logic: * During block construction, consider bundles from the specialized pool. * For a given `sender`/`nonce`, select *at most one* transaction from the corresponding bundle. * Selection *SHOULD* prioritize fitting the maximum number of blobs possible within block limits, potentially using fees as a factor. * Once one transaction from a bundle is included canonically, invalidate all other variants of that bundle (same `sender`/`nonce`). * Discard bundles if `maxBlockNumber` is passed or per internal timeout policy, updating the status to `EXPIRED`. ### Method: `eth_getBlobsStatus` Allows querying the status of a bundle submitted via `eth_sendBlobs`. #### Parameters 1. `bundleId`: `DATA` * The unique bundle identifier received from a successful `eth_sendBlobs` call. #### Returns * `result`: `Object | Null` * An object describing the bundle status, or `null` if `bundleId` is not found (alternative: object with `status: "NOT_FOUND"`). Contains: * `status`: `String` - The current status: * `"PENDING"`: Accepted, eligible for inclusion. * `"INCLUDED"`: One transaction from the bundle is included on-chain. * `"EXPIRED"`: No longer eligible for inclusion (deadline passed or timed out). * `"NOT_FOUND"`: The `bundleId` is unknown or invalid. * `includedTxHash`: `DATA` (Only if `status` is `"INCLUDED"`) - The hash of the included transaction. * `inclusionBlockNumber`: `QUANTITY` (Only if `status` is `"INCLUDED"`) - Hex block number of inclusion. * `inclusionBlockHash`: `DATA` (Only if `status` is `"INCLUDED"`) - Hash of the block containing the inclusion. * `expiryReason`: `String` (Optional, if `status` is `"EXPIRED"`) - Reason for expiration (e.g., `"Max block number reached"`, `"Node timeout policy"`). * `error`: `Object | Null` * If an error occurs (e.g., invalid `bundleId` format), contains a JSON-RPC 2.0 error object. `result` will be `null`. * If successful, `error` is `null`. #### Example Request (`eth_getBlobsStatus`) ```json { "jsonrpc": "2.0", "id": 2, "method": "eth_getBlobsStatus", "params": [ "0x7b9d8f61a3f1f6d9b8e0c2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3" // Bundle ID from eth_sendBlobs ] } ``` #### Example Responses (`eth_getBlobsStatus`) ##### Pending ```json { "jsonrpc": "2.0", "id": 2, "result": { "status": "PENDING" }, "error": null } ``` ##### Included ```json { "jsonrpc": "2.0", "id": 2, "result": { "status": "INCLUDED", "includedTxHash": "0xf8eb56...", // Hash of the actual included TX (e.g., the 6-blob one) "inclusionBlockNumber": "0xAFF001", // e.g., 11531393 "inclusionBlockHash": "0xabc123..." }, "error": null } ``` ##### Expired ```json { "jsonrpc": "2.0", "id": 2, "result": { "status": "EXPIRED", "expiryReason": "Max block number reached" }, "error": null } ``` ##### Not Found ```json { "jsonrpc": "2.0", "id": 2, "result": { "status": "NOT_FOUND" }, // Alternatively: "result": null "error": null } ``` #### Expected Node Behavior (`eth_getBlobsStatus`) Nodes implementing this method *MUST*: 1. **Validate Request:** Check JSON-RPC structure and `bundleId` format (`DATA`). 2. **Lookup Bundle:** Attempt to retrieve the bundle state associated with the provided `bundleId` from its specialized storage. 3. **Determine Status:** * If no bundle is found: Return `NOT_FOUND` status (or `null` result). * If found, check internal state: * Has an associated transaction been included in the canonical chain? -> Return `INCLUDED` with details. * Has the bundle been marked expired (deadline/policy)? -> Return `EXPIRED` with optional reason. * Otherwise -> Return `PENDING`. 4. **Format Response:** Construct the JSON response according to the specification for the determined status. ## Sublets The pending pool for these transactions is a subection of a private mempool, called a *sublet*. This subdivision is not strictly necessary. ## Rationale 1. **Necessity of New Methods:** Standard RPC methods (`eth_sendRawTransaction`, `eth_getTransactionReceipt`) and public mempools do not support the concept of bundled alternative transactions for a single nonce or the required specialized status tracking. `eth_sendBlobs` and `eth_getBlobsStatus` provide a dedicated interface. 2. **Bundle Submission (`txs` array):** Efficiently submits all variants at once, signaling their relationship clearly. 3. **Shared Nonce Constraint:** Essential for safety. Ensures only one transaction from the bundle can ever be executed on-chain, preventing unintended replays or state conflicts, leveraging the core Ethereum nonce mechanism. 4. **`maxBlockNumber` Parameter:** Gives originators control over the time-sensitivity of blob data inclusion, a common requirement for time-critical data or avoiding stale submissions in volatile fee markets. 5. **`bundleId` Return (`eth_sendBlobs`):** Provides a necessary, unique handle specific to the submitted bundle, enabling reliable status tracking via `eth_getBlobsStatus`. It decouples tracking from potentially reusable `sender`/`nonce` pairs. 6. **`eth_getBlobsStatus` Method:** Offers a standardized way to poll the outcome of a bundle submission, covering its lifecycle from acceptance to final state (inclusion or expiry), which is crucial given the off-chain nature of the initial pool. 7. **Specialized Infrastructure:** Acknowledges that these methods primarily target specialized RPC endpoints (e.g., builder relays, dedicated node services) capable of managing the required off-chain pool and selection logic, rather than all standard Ethereum clients. ## Backwards Compatibility This EIP introduces two new JSON-RPC methods. It does not modify or deprecate any existing methods or alter Ethereum's consensus rules. ## Security Considerations 1. **Nonce Integrity:** The system's safety relies heavily on the Ethereum protocol's nonce enforcement. The specialized pool and selection logic *MUST NOT* allow more than one transaction from a bundle (sharing the same `sender`/`nonce`) to be included in the canonical chain. Implementers must ensure their off-chain logic respects this. 2. **Centralization and Trust:** Users implicitly trust the RPC provider/builder implementing these methods to: * Faithfully execute the selection logic (e.g., not unfairly discard bundles, select optimally). * Accurately report bundle status via `eth_getBlobsStatus`. * Not censor submissions unduly. * Handle transactions securely. This introduces a reliance similar to using private transaction relays. 3. **Resource Consumption / DoS:** * `eth_sendBlobs`: Receiving large bundles frequently can consume significant bandwidth and processing power. Endpoints *MUST* implement protective measures like rate limiting, limits on the `txs` array size/count, and potentially authentication or stake-based access. * `eth_getBlobsStatus`: While primarily read-only, frequent polling could strain the status tracking database. Rate limiting *SHOULD* be applied. 4. **Transaction Confidentiality:** Transactions submitted via `eth_sendBlobs` might be visible to the RPC provider and associated infrastructure (e.g., builders) before potential on-chain inclusion. Users requiring strong pre-execution privacy should be aware of this. Querying status might also leak information about submission activity. 5. **Fee Consistency:** Inconsistent fee parameters across transactions within a bundle could lead to unpredictable or undesirable selection outcomes. The specification recommends consistency. Implementations *SHOULD* document their selection behavior if fees differ. 6. **`maxBlockNumber` Reliability:** Enforcement of `maxBlockNumber` depends entirely on the implementing service. Users rely on the provider to honor this and correctly report expiry status. 7. **`bundleId` Management:** Service providers must ensure the uniqueness and proper lifecycle management (storage, lookup, garbage collection) of `bundleId`s. The scope of uniqueness (e.g., globally unique, unique per provider, time-limited) *SHOULD* be documented. 8. **Status Accuracy:** The status reported by `eth_getBlobsStatus` depends on the provider's view of the chain and internal state updates. There might be delays in detecting inclusion or processing expiry, leading to temporarily stale status information. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
{"title":"`eth_sendBlobs` and `eth_getBlobsStatus`","description":"JSON-RPC Methods for Optimal Blob Inclusion and Status Tracking","image":"https://hackmd.io/_uploads/SJlHK_Iayg.jpg","contributors":"[{\"id\":\"61692723-37e2-4aaf-9583-0d68d223ae70\",\"add\":15560,\"del\":0}]"}
Expand menu