From 3c01193e3f8dca6cbc10e0de13667b63c7a9d97d Mon Sep 17 00:00:00 2001 From: roethke Date: Thu, 19 Mar 2026 13:09:21 -0700 Subject: [PATCH 1/5] document eth_call pending limitation on Flashblocks nodes --- docs/base-chain/flashblocks/api-reference.mdx | 2 +- docs/base-chain/flashblocks/faq.mdx | 12 +++++++++++- docs/base-chain/reference/json-rpc-api.mdx | 4 ++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/base-chain/flashblocks/api-reference.mdx b/docs/base-chain/flashblocks/api-reference.mdx index fae7ddad2..aa1a6b2ce 100644 --- a/docs/base-chain/flashblocks/api-reference.mdx +++ b/docs/base-chain/flashblocks/api-reference.mdx @@ -6,7 +6,7 @@ description: 'Reference for Flashblocks-specific RPC methods, WebSocket subscrip This page covers what is unique to Flashblocks: the preconf endpoints, Flashblocks-only methods, real-time WebSocket subscriptions, and the infrastructure stream schema. -All [standard JSON-RPC methods](/base-chain/reference/json-rpc-api) work as-is against a Flashblocks endpoint — use the `"pending"` block tag to read preconfirmed state. +Most [standard JSON-RPC methods](/base-chain/reference/json-rpc-api) work as-is against a Flashblocks endpoint — use the `"pending"` block tag to read preconfirmed state. **Exception:** `eth_call "pending"` executes against stale state (3–5 blocks behind tip), not the live Flashblock. Use [`eth_simulateV1`](#eth_simulatev1) to simulate against preconfirmed state. ## Endpoints diff --git a/docs/base-chain/flashblocks/faq.mdx b/docs/base-chain/flashblocks/faq.mdx index 951d68e93..13d6bf46d 100644 --- a/docs/base-chain/flashblocks/faq.mdx +++ b/docs/base-chain/flashblocks/faq.mdx @@ -125,6 +125,16 @@ For a comprehensive introduction to how Flashblocks work, see the [Flashblocks O - Run your own [Flashblocks-aware RPC node](/base-chain/node-operators/run-a-base-node#enable-flashblocks) + + This is a known limitation of Flashblocks-aware nodes. When you call `eth_call` with the `"pending"` block tag, the call executes against a block that may be 3–5 blocks behind the current chain tip — not against the preconfirmed Flashblock state. + + This happens because `eth_call "pending"` internally resolves the block context from a different code path than `eth_getBlockByNumber "pending"`. The two are not synchronized: `eth_getBlockByNumber "pending"` correctly returns the current Flashblock state at N+1, while `eth_call "pending"` falls back to an older sealed block. + + **If you need to simulate a call against actual preconfirmed state, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1) instead.** It executes against the live Flashblock state and supports state overrides, multi-block simulation, and transfer tracing. + + For reading finalized on-chain state (not preconfirmed), `eth_call "latest"` behaves as expected. + + The following methods are Flashblocks-enabled: @@ -135,7 +145,7 @@ For a comprehensive introduction to how Flashblocks work, see the [Flashblocks O | `eth_getTransactionReceipt` | Returns preconfirmed receipts | | `eth_getTransactionByHash` | Use `pending` tag | | `eth_getTransactionCount` | Use `pending` tag | - | `eth_call` | Use `pending` tag | + | `eth_call` | Use `pending` tag — note: executes against old state, not live Flashblock state. Use `eth_simulateV1` to simulate against preconfirmed state. | | `eth_simulateV1` | Use `pending` tag | | `eth_estimateGas` | Use `pending` tag | | `eth_getLogs` | Use `pending` for `toBlock` | diff --git a/docs/base-chain/reference/json-rpc-api.mdx b/docs/base-chain/reference/json-rpc-api.mdx index c1b2db601..370b29d8d 100644 --- a/docs/base-chain/reference/json-rpc-api.mdx +++ b/docs/base-chain/reference/json-rpc-api.mdx @@ -279,6 +279,10 @@ Returns the raw value stored at a specific storage slot of a contract address. Executes a message call against the current chain state without broadcasting a transaction. No gas is consumed on-chain. Used to read contract state or simulate calls. + +**`eth_call "pending"` does not execute against preconfirmed Flashblock state.** On Flashblocks-enabled nodes, `eth_call "pending"` may resolve against a block 3–5 behind the current tip rather than the live preconfirmed state. To simulate against actual Flashblock state, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1) instead. See the [Flashblocks FAQ](/base-chain/flashblocks/faq#why-does-eth_call-pending-execute-against-old-state-instead-of-the-current-flashblock) for more details. + + **Parameters** From 5e19f6730d3e840c3abb57f9dd46c3de4b13bfb6 Mon Sep 17 00:00:00 2001 From: roethke Date: Fri, 20 Mar 2026 10:14:05 -0700 Subject: [PATCH 2/5] update language --- docs/base-chain/flashblocks/api-reference.mdx | 2 +- docs/base-chain/flashblocks/faq.mdx | 12 +++++------- docs/base-chain/reference/json-rpc-api.mdx | 6 +++--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/base-chain/flashblocks/api-reference.mdx b/docs/base-chain/flashblocks/api-reference.mdx index aa1a6b2ce..2e467a1e2 100644 --- a/docs/base-chain/flashblocks/api-reference.mdx +++ b/docs/base-chain/flashblocks/api-reference.mdx @@ -6,7 +6,7 @@ description: 'Reference for Flashblocks-specific RPC methods, WebSocket subscrip This page covers what is unique to Flashblocks: the preconf endpoints, Flashblocks-only methods, real-time WebSocket subscriptions, and the infrastructure stream schema. -Most [standard JSON-RPC methods](/base-chain/reference/json-rpc-api) work as-is against a Flashblocks endpoint — use the `"pending"` block tag to read preconfirmed state. **Exception:** `eth_call "pending"` executes against stale state (3–5 blocks behind tip), not the live Flashblock. Use [`eth_simulateV1`](#eth_simulatev1) to simulate against preconfirmed state. +Most [standard JSON-RPC methods](/base-chain/reference/json-rpc-api) work as-is against a Flashblocks endpoint — use the `"pending"` block tag to read preconfirmed state. **Note:** `eth_call "pending"` returns a correct result but the block number in the call context may appear a few blocks behind tip. Use [`eth_simulateV1`](#eth_simulatev1) if you need the call context to reflect the exact current Flashblock number. ## Endpoints diff --git a/docs/base-chain/flashblocks/faq.mdx b/docs/base-chain/flashblocks/faq.mdx index 13d6bf46d..5e2cbbbf2 100644 --- a/docs/base-chain/flashblocks/faq.mdx +++ b/docs/base-chain/flashblocks/faq.mdx @@ -125,14 +125,12 @@ For a comprehensive introduction to how Flashblocks work, see the [Flashblocks O - Run your own [Flashblocks-aware RPC node](/base-chain/node-operators/run-a-base-node#enable-flashblocks) - - This is a known limitation of Flashblocks-aware nodes. When you call `eth_call` with the `"pending"` block tag, the call executes against a block that may be 3–5 blocks behind the current chain tip — not against the preconfirmed Flashblock state. + + This is expected behavior. Flashblocks-aware nodes store up to 5 historical blocks worth of Flashblocks state to prevent race conditions. When `eth_call "pending"` is called, it operates on top of that historical base, so the block number visible in the call context (e.g. `block.number`) may appear to be N-5. - This happens because `eth_call "pending"` internally resolves the block context from a different code path than `eth_getBlockByNumber "pending"`. The two are not synchronized: `eth_getBlockByNumber "pending"` correctly returns the current Flashblock state at N+1, while `eth_call "pending"` falls back to an older sealed block. + Importantly, **the result of the call is correct** — it reflects the latest sealed block plus all received Flashblocks at the time of the call. The reported block number is an artifact of how the pending state is constructed internally, not a sign that the call used stale data. - **If you need to simulate a call against actual preconfirmed state, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1) instead.** It executes against the live Flashblock state and supports state overrides, multi-block simulation, and transfer tracing. - - For reading finalized on-chain state (not preconfirmed), `eth_call "latest"` behaves as expected. + If you need the call context to explicitly reflect the most recent preconfirmed block number, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1) instead, which supports full state overrides and executes against the live Flashblock state. @@ -145,7 +143,7 @@ For a comprehensive introduction to how Flashblocks work, see the [Flashblocks O | `eth_getTransactionReceipt` | Returns preconfirmed receipts | | `eth_getTransactionByHash` | Use `pending` tag | | `eth_getTransactionCount` | Use `pending` tag | - | `eth_call` | Use `pending` tag — note: executes against old state, not live Flashblock state. Use `eth_simulateV1` to simulate against preconfirmed state. | + | `eth_call` | Use `pending` tag — the call result is correct, but `block.number` in context may appear a few blocks behind tip. See [FAQ](/base-chain/flashblocks/faq#why-does-eth_call-pending-report-a-block-number-several-blocks-behind-tip) for details. | | `eth_simulateV1` | Use `pending` tag | | `eth_estimateGas` | Use `pending` tag | | `eth_getLogs` | Use `pending` for `toBlock` | diff --git a/docs/base-chain/reference/json-rpc-api.mdx b/docs/base-chain/reference/json-rpc-api.mdx index 370b29d8d..bfe9ab780 100644 --- a/docs/base-chain/reference/json-rpc-api.mdx +++ b/docs/base-chain/reference/json-rpc-api.mdx @@ -279,9 +279,9 @@ Returns the raw value stored at a specific storage slot of a contract address. Executes a message call against the current chain state without broadcasting a transaction. No gas is consumed on-chain. Used to read contract state or simulate calls. - -**`eth_call "pending"` does not execute against preconfirmed Flashblock state.** On Flashblocks-enabled nodes, `eth_call "pending"` may resolve against a block 3–5 behind the current tip rather than the live preconfirmed state. To simulate against actual Flashblock state, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1) instead. See the [Flashblocks FAQ](/base-chain/flashblocks/faq#why-does-eth_call-pending-execute-against-old-state-instead-of-the-current-flashblock) for more details. - + +**`eth_call "pending"` on Flashblocks nodes:** The call result is correct and reflects the latest sealed block plus all received Flashblocks state. However, the block number visible in the call context (e.g. `block.number`) may appear a few blocks behind tip. This is expected — nodes store up to 5 historical blocks of Flashblocks state to prevent race conditions, which affects the reported block number but not the accuracy of the result. If you need the call context to reflect the exact current Flashblock number, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1). See the [Flashblocks FAQ](/base-chain/flashblocks/faq#why-does-eth_call-pending-report-a-block-number-several-blocks-behind-tip) for more details. + **Parameters** From dbd03d998df7babb9f9b29794d3b5a9529808c14 Mon Sep 17 00:00:00 2001 From: roethke Date: Fri, 20 Mar 2026 10:16:17 -0700 Subject: [PATCH 3/5] update language --- docs/base-chain/flashblocks/faq.mdx | 2 +- docs/base-chain/reference/json-rpc-api.mdx | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/base-chain/flashblocks/faq.mdx b/docs/base-chain/flashblocks/faq.mdx index 5e2cbbbf2..b38949da5 100644 --- a/docs/base-chain/flashblocks/faq.mdx +++ b/docs/base-chain/flashblocks/faq.mdx @@ -143,7 +143,7 @@ For a comprehensive introduction to how Flashblocks work, see the [Flashblocks O | `eth_getTransactionReceipt` | Returns preconfirmed receipts | | `eth_getTransactionByHash` | Use `pending` tag | | `eth_getTransactionCount` | Use `pending` tag | - | `eth_call` | Use `pending` tag — the call result is correct, but `block.number` in context may appear a few blocks behind tip. See [FAQ](/base-chain/flashblocks/faq#why-does-eth_call-pending-report-a-block-number-several-blocks-behind-tip) for details. | + | `eth_call` | Use `pending` tag | | `eth_simulateV1` | Use `pending` tag | | `eth_estimateGas` | Use `pending` tag | | `eth_getLogs` | Use `pending` for `toBlock` | diff --git a/docs/base-chain/reference/json-rpc-api.mdx b/docs/base-chain/reference/json-rpc-api.mdx index bfe9ab780..c1b2db601 100644 --- a/docs/base-chain/reference/json-rpc-api.mdx +++ b/docs/base-chain/reference/json-rpc-api.mdx @@ -279,10 +279,6 @@ Returns the raw value stored at a specific storage slot of a contract address. Executes a message call against the current chain state without broadcasting a transaction. No gas is consumed on-chain. Used to read contract state or simulate calls. - -**`eth_call "pending"` on Flashblocks nodes:** The call result is correct and reflects the latest sealed block plus all received Flashblocks state. However, the block number visible in the call context (e.g. `block.number`) may appear a few blocks behind tip. This is expected — nodes store up to 5 historical blocks of Flashblocks state to prevent race conditions, which affects the reported block number but not the accuracy of the result. If you need the call context to reflect the exact current Flashblock number, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1). See the [Flashblocks FAQ](/base-chain/flashblocks/faq#why-does-eth_call-pending-report-a-block-number-several-blocks-behind-tip) for more details. - - **Parameters** From f85190560e47f3827b5f52167e496d276acf8687 Mon Sep 17 00:00:00 2001 From: roethke Date: Fri, 20 Mar 2026 10:17:07 -0700 Subject: [PATCH 4/5] update language --- docs/base-chain/flashblocks/api-reference.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/base-chain/flashblocks/api-reference.mdx b/docs/base-chain/flashblocks/api-reference.mdx index 2e467a1e2..fae7ddad2 100644 --- a/docs/base-chain/flashblocks/api-reference.mdx +++ b/docs/base-chain/flashblocks/api-reference.mdx @@ -6,7 +6,7 @@ description: 'Reference for Flashblocks-specific RPC methods, WebSocket subscrip This page covers what is unique to Flashblocks: the preconf endpoints, Flashblocks-only methods, real-time WebSocket subscriptions, and the infrastructure stream schema. -Most [standard JSON-RPC methods](/base-chain/reference/json-rpc-api) work as-is against a Flashblocks endpoint — use the `"pending"` block tag to read preconfirmed state. **Note:** `eth_call "pending"` returns a correct result but the block number in the call context may appear a few blocks behind tip. Use [`eth_simulateV1`](#eth_simulatev1) if you need the call context to reflect the exact current Flashblock number. +All [standard JSON-RPC methods](/base-chain/reference/json-rpc-api) work as-is against a Flashblocks endpoint — use the `"pending"` block tag to read preconfirmed state. ## Endpoints From 962161477b26cfb3453c31fda792bd4f2efb7919 Mon Sep 17 00:00:00 2001 From: roethke Date: Fri, 20 Mar 2026 10:35:10 -0700 Subject: [PATCH 5/5] add latency and configurable param context --- docs/base-chain/flashblocks/faq.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/base-chain/flashblocks/faq.mdx b/docs/base-chain/flashblocks/faq.mdx index b38949da5..83000917a 100644 --- a/docs/base-chain/flashblocks/faq.mdx +++ b/docs/base-chain/flashblocks/faq.mdx @@ -128,9 +128,9 @@ For a comprehensive introduction to how Flashblocks work, see the [Flashblocks O This is expected behavior. Flashblocks-aware nodes store up to 5 historical blocks worth of Flashblocks state to prevent race conditions. When `eth_call "pending"` is called, it operates on top of that historical base, so the block number visible in the call context (e.g. `block.number`) may appear to be N-5. - Importantly, **the result of the call is correct** — it reflects the latest sealed block plus all received Flashblocks at the time of the call. The reported block number is an artifact of how the pending state is constructed internally, not a sign that the call used stale data. + When `eth_call "pending"` executes, the entire block context — `block.number`, `block.timestamp`, `block.basefee`, and all other block properties — corresponds to that historical base block (potentially N-5), not the current chain tip. **The call result is correct** in that it reflects all received Flashblocks state applied on top, but contracts that rely on block context properties should be aware that those values may be several blocks behind. - If you need the call context to explicitly reflect the most recent preconfirmed block number, use [`eth_simulateV1`](/base-chain/flashblocks/api-reference#eth_simulatev1) instead, which supports full state overrides and executes against the live Flashblock state. + If you operate a node in a geographic region where your P2P latency is not significantly higher than the WebSocket stream latency, you can reduce this difference by lowering the `MAX_PENDING_BLOCKS_DEPTH` configuration value. This controls the maximum number of historical blocks worth of Flashblocks your node stores, so a lower value will make the block context closer to tip at the cost of reduced tolerance for P2P latency spikes.