cuckoo

Concepts

The clock

Which block number the contract reads, and why it matters on Robinhood Chain.

On Arbitrum-family chains, block.number inside a contract is the parent chain's block number, which moves about once every 12 seconds. The chain's own blocks, a tenth of a second apart, are counted by a precompile, ArbSys.arbBlockNumber().

Measured on the real chain

chain 4663, client nitro/v3.12.1-rc.2
block.number seen by a contract : 26,170,542   (the Ethereum number)
ArbSys.arbBlockNumber()         : 85,989,226
eth_blockNumber                 : 85,989,216
the chain advanced 10 blocks in 1,380 ms through a public RPC

A contract that used block.number would count 12-second blocks, so a window of "3 blocks" would be 36 seconds. Cuckoo.clock() asks ArbSys; where ArbSys does not answer (a local node, Ethereum) it falls back to block.number.

Which block does a transaction see?

The block number a transaction sees is the block it is included in. A simulation (eth_call) runs in the context of the latest block, one block earlier than the block your real transaction will land in. Keep this in mind when you compare a dry run with a real result: the window check can differ by one block.

Numbers in an egg

Always use the chain's own counter (cuckoo block prints it). eth_blockNumber and ArbSys agree within a block or two.