EIP-2935: Save historical block hashes in state

Can we please use an address close to the bottom of the address space? Anything smaller than 2*32 will be fine.

Before this opcode becomes available, the problem with storing a merkle root of blockhashes up to a certain block number, is that you can’t update the merkle root securely to get the hash of more recent blocks. To combat that, before this EIP is implemented, I wrote a fun little optimistic rollup (based on interactive fraud proofs) to figure out determine historical blockhashes optimistically. It’s super experimental and not tested, but all of the elements are there :slight_smile:.

Are there any plans to implement this proposal please?

2 Likes

Just to mention that this EIP would be very helpfull for L2 bridging.

1 Like

I’m trying to implement this proposal in geth after it appears that it is required for verkle trees.

This raised a couple of questions:

  1. Any thought on how to best adapt this to the timestamp-based forks that we now use?
  2. In particular, why is the activation at block.number > FORK_BLKNUM and not block.number >= FORK_BLKNUM ? It makes things difficult to handle when FORK_BLOCKNUM isn’t readily available.
  3. Given that there is a complete state overall at the boundary, could we simply insert all block hashes in the tree as well, thus ensuring that all historical blocks see their hashes available in the state?
  4. How are the costs of the BLOCKHASH instruction meant to evolve? For instance, in the case of verkle:
  • should only the witness gas costs be charged or not?
  • what extra costs that should be added besides the witness costs?

Clarifying point #2: in stateless mode, having block.time > FORK_BLKTIME forces me to get the parent to check if its timestamp is after the FORK_BLKTIME. Whereas if it’s block.time >= FORK_BLKTIME then all I need is to check if the current block’s time is past the fork time.

1 Like
  1. if 3 then this is irrelevant
  2. I think it may have been an omission
  3. I think it is a good idea
  4. Witness cost and extra processing in case of > 256 (around 100?)

I’m not a fan of storing the entire block hash history in storage, even if it is from a fixed point in time. I’d prefer we adapt what was done for Beacon Roots in EIP-4788 and have a rolling storage set. However instead of TIMESTAMP we would need to use NUMBER and tune the buffer length down. From this we would ensure that at least the last 256 hashes are in storage and that’s all we need for the opcode to work.

I think since it is a new thing anyway, one could store a ZK-friendly Merkle root of the current state and block transactions.