Skip to content
BaseHub by wbnns Updated

Migrate to 200ms Blocks

Read this page if your application consumes Flashblocks. The Denim upgrade swaps Flashblocks for canonical 200ms blocks. Once it activates, Flashblocks subscriptions and the pending state behind them stop being available.

Take an inventory before Denim lands. Two things belong on that list: every Flashblocks subscription your application opens, and every RPC request it makes with the "pending" block tag. Work through the table below and pair each one with its replacement.

Flashblocks integrations are not the only thing Denim touches. If you also own contracts, check them for durations expressed as block counts: block.number advances ten times faster afterwards, so timelocks, cooldowns, vesting schedules, and governance windows written that way shrink to a tenth of their intended length. Block-number contract logic has the pattern table.

Flashblocks integrationUpdate for Denim
eth_subscribe("newFlashblocks")Use eth_subscribe("newHeads").
eth_subscribe("pendingLogs")Use eth_subscribe("logs").
eth_subscribe("newFlashblockTransactions")Use eth_subscribe("newHeads"), then fetch transactions for each canonical block.
eth_getBlockByNumber("pending", ...)Use normal RPC calls to read the latest canonical blocks.
eth_getBalance(..., "pending")Use normal RPC calls to read the latest canonical state.
eth_getTransactionCount(..., "pending", ...)Use normal RPC calls to read the latest canonical state.
eth_call(..., "pending")Use normal RPC calls to read the latest canonical state.
eth_estimateGas(..., "pending")Use normal RPC calls to read the latest canonical state.
eth_simulateV1(..., "pending")Use normal RPC calls to read the latest canonical state.
eth_getLogs with a range ending at "pending"Use normal RPC calls to query logs from canonical blocks.
eth_getBlockTransactionCountByNumber("pending")Use normal RPC calls to read the latest canonical block.
A bridge or proof flow that reads historical block hashes or beacon rootsRe-check what it assumes about reach. The number of values kept does not change, but each one covers a tenth as much elapsed time.

The practical difference is one of timing rather than shape. A preconfirmation used to arrive ahead of the block that contained it. A 200ms canonical block arrives at the same cadence but already settled, so the read you make after migrating is a read of committed state.

The last row of that table is the one most likely to be missed, because nothing about it looks like a Flashblocks integration and nothing in the affected code has to change to break.

Onchain history is retained by count, not by duration. The EIP-2935 ring buffer holds 8191 entries, and BLOCKHASH reaches back 256 blocks. Neither figure moves at Denim. What moves is how much time those fixed counts represent, and since blocks arrive ten times more often, each window contracts by the same factor:

WindowBefore DenimAfter Denim
BLOCKHASH, 256 blocksabout 8.5 minutesabout 51 seconds
EIP-2935 history buffer, 8191 blocksabout 4.5 hoursabout 27 minutes

Audit any flow that fetches a historical block hash or beacon root and ask how long it takes end to end, including the parts you do not control: a user signing, an operator batching, a relay waiting on L1 confirmation. A step that took twenty minutes was well inside a four-and-a-half-hour buffer and sits outside a twenty-seven-minute one. Where a flow cannot be made faster, capture the hash or root at the time of use and carry it through, rather than looking it up again once the work completes.

Point your migrated integration at Vibenet and exercise it there. For the protocol design behind the change, along with the RPC behaviour it produces, see Denim 200ms Native Blocks.