---
# System prepended metadata

title: '`eth_sendBlobs` and `eth_getBlobsStatus`'

---

---
eip: 
title: Optional RPC Methods `eth_sendBlobs`  and `eth_getBlobsStatus`
description: JSON-RPC Methods for Optimal Blob Inclusion and Status Tracking 
author: Sam Bacha (@sambacha)
discussions-to:
status: Draft
type: Standards Track
category: Core
created: 2025-03-26
---

# `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/).
