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.