Supported RPC Methods
All modifications done to the existing Ethereum JSON RPC methods are confined to overloading the existing pending tag except a few JSON RPC methods which become inherently aware of the preconfirmation state. Originally, this tag was designed to return block data being processed by the node's internal miner It's fitting that we now use it for a similar purpose: exposing blocks in their preconfirmation stage. When queried with the pending tag, the endpoint uses the preconfirmation state to construct the response. The response might include not only transactions but also block metadata like state root and receipt root.
The tag is currently in a soft-deprecated state due to inconsistent implementations across clients, particularly after The Merge. However, it's worth noting that it's still actively used for certain endpoints, particularly eth_getTransactionCount where it serves the important function of returning the next available nonce for an account (including transactions in the memepool). This presents an opportunity: the tag is well-defined enough to be supported by client libraries, yet loosely defined enough to allow for our preconfirmation use case. While there's a possibility of the tag being removed in the future (see EIP discussions), the design could adapt by introducing a realtime block specific tag if needed.
We repurpose the pending tag in the following RPC calls to enable consuming preconfirmed state:
eth_call
eth_estimateGas
eth_getBlockByNumber
eth_getBalance
eth_getTransactionCount
eth_getCode
eth_getStorageAt
Note: not all RPC methods explicitly require a "pending" tag to tap into the real time state's awareness.
The following RPC methods implicitly incorporate realtime block awareness like that whenever possible:
eth_getTransactionReceipt
eth_getTransactionByHash
eth_getTransactionReceipt
{
"method": "eth_getTransactionReceipt",
"params": ["0x..."],// Transaction hash
"id": 1,
"jsonrpc": "2.0"
}
{
"transactionHash": "0x...",
"blockHash": "0x0", // Empty hash as placeholder
"blockNumber": "0x...", // Current pending block number
"transactionIndex": "0x0",
"from": "0x...",
"to": "0x...",
"gasUsed": "0x...",
"status": "0x1",
"cumulativeGasUsed": "0x...",
"effectiveGasPrice": "0x...",
"contractAddress": "0x...", // For contract creations
"logs": [],
"logsBloom": "0x..."
}
When queried, this endpoint first checks the preconfirmation state for the requested transaction hash before falling back to the standard chain lookup. Some fields in the response cannot be final at the preconfirmation stage and require placeholder values:
blockHash: Uses empty hash as placeholder
blockNumber: Can be set to the current block number being processed
eth_getTransactionsByHash
{
"method": "eth_getTransactionByHash",
"params": ["0x..."], // Transaction hash of the potentially pre-confirmed transaction
"id": 1,
"jsonrpc": "2.0"
}
{
"id": 1,
"result": {
"blockHash": "0x...",
"blockNumber": "0x...",
"hash": "0x...",
"transactionIndex": "0x0",
"type": "0x2",
"nonce": "0x...",
"from": "0x...",
"to": "0x...",
"gas": "0x...",
"value": "0x...",
"gasPrice": "0x...",
"chainId": "0x..."
},
"jsonrpc": "2.0"
}
When queried, this endpoint first checks the preconfirmation state for the requested transaction hash before falling back to the standard chain state lookup. Some fields in the response cannot be final at the preconfirmation stage and require placeholder values:
blockHash: Uses the block hash of the pending blocks at the time the transaction was preconfirmed
blockNumber: Can be set to the curent block number being processed
eth_getBlockByNumber
{
"method": "eth_getBlockByNumber",
"params": ["pending", false], // Second parameter indicates full transaction objects (true) or only hashes (false)
"id": 1,
"jsonrpc": "2.0"
}
{
"hash": "0x0", // Empty hash as placeholder
"parentHash": "0x...",
"stateRoot": "0x...",
"transactionsRoot": "0x...",
"receiptsRoot": "0x...",
"number": "0x...", // Current pending block number
"gasUsed": "0x...",
"gasLimit": "0x...",
"timestamp": "0x...",
"extraData": "0x...",
"mixHash": "0x...",
"nonce": "0x...", // // Used to signal realtime block index
"transactions": [] // Array of transaction hashes or full transaction objects
}
The endpoing implements an append-only pattern - multiple queries during the sam eblock's preconfirmation phase will show an expanding list of transactions as new realtime blocks are processed. Each query reflects the current state of all preconfirmed transactions at that moment.
eth_getBalance
{
"method": "eth_getBalance",
"params": ["0x...", "pending"], // Account address and block parameter
"id": 1,
"jsonrpc": "2.0"
}
"0x..." // Balance in wei When queried with the pending tag, the endpoint uses the preconfirmation state to return the account balance. If the requested account appears in the AccountMetadata of a received realtime block with a non-null balance field, the RPC provider can directly return this value without needing toa ccess the full state. The response reflects all changes from preconfirmed trnasactions that affect the requested account's balance.
eth_call
{
"method": "eth_call",
"params": [{"to": "0x...", "data": "0x..."}, "pending"], // Transaction call object and block parameter
"id": 1,
"jsonrpc": "2.0"
}
"0x..." // Return data from the call When queried with the pending tag, the endpoint uses the preconfirmation state to return the call result. For this endpoint to work, the preconfirmation stream needs to include state differences for both accounts and storage after each realtime block.
Similar to current override functionality in eth_call where EVM transitions are executed on top of modified state, this implementation executes the call on top of the preconfirmation state changes.
eth_estimateGas
Generates and returns an estimate of how much gas is necessary to allow the transaction to complete considering the latest pre-confirmed state.
{
"jsonrpc": "2.0",
"method": "eth_estimateGas",
"params": [{"from":"0x...","to":"0x...","value":"0x..."}, "pending"],
"id": 1
}
{
"jsonrpc": "2.0",
"id": "1",
"result": "0x..." // The estimated amount of gas required for the transaction, as a hexadecimal string.
}
eth_getCode
{
"method": "eth_getCode",
"params": ["0x...", "pending"],// Contract address and block parameter
"id": 1,
"jsonrpc": "2.0"
}
{
"jsonrpc": "2.0",
"id": "1",
"result": "0x..."// Contract bytecode
}
When queried with the pending tag, the endpoint returns the contract bytecode from the preconfirmation state. If the requested account appears in the AccountMetadata of a received realtime block with a non-null code field, the RPC provider can directly return this value without accessing the full state.
eth_getTransactionCount
{
"method": "eth_getTransactionCount",
"params": ["0x...", "pending"],// Account address and block parameter
"id": 1,
"jsonrpc": "2.0"
}
{
"jsonrpc": "2.0",
"id": "1",
"result": "0x..."// Nonce value as a hex string
}
When queried with the pending tag, the endpoint returns the transaction count (nonce) of the account from the preconfirmation state. If the requested account appears in the AccountMetadata of a received realtime block, the RPC provider can directly use the nonce field without additional state access.
eth_getStorageAt
{
"method": "eth_getStorageAt",
"params": ["0x...", "0x...", "pending"],// Contract address, storage position, and block parameter
"id": 1,
"jsonrpc": "2.0"
}
{
"jsonrpc": "2.0",
"id": "1",
"result": "0x..." // Storage value as a hex string
}
When queried with the pending tag, the endpoint returns the value from the specified storage slot using the preconfirmation state. If the requested account appears in the AccountMetadata of a received realtime block, the RPC Provider scans the storage_slots list for the requested key and returns the corresponding value directly
Last updated