Abstract

This Document describes enhancing support of historical blocks related to the work defined in HIP-584.

Motivation

Ongoing user experience work needs EVM execution to enable features such as making queries to historical blocks via eth_call.

Enhancing Mirror Archive Nodes with historical support will enable users to implement dApps for monitoring, analyzing tools and any other use cases that need to use historical data.

Eth_call immediately executes a new message call without creating a transaction. Currently in Hedera, we are supporting its most fundamental use cases which are:

  1. Execute read methods of a smart contract using the current state of the network.
  2. Simulate the result of a transaction before sending the actual transaction using the current state of the network.

However, eth_call has additional capabilities that we may want to enable for developers on Hedera, such as:

  1. Execute read methods of a smart contract using the network state right after a specific block.
  2. Simulate the result of a function call using the network state right after a specific block.

Rationale

The JSON-RPC endpoint eth_call accepts a block number as an input argument. This block number specifies that the execution of eth_call has to be based on the state that is produced after the execution of all transactions into the specified block. In this way, the state would reliably reflect the changes included in the given block. As defined in HIP-415, in Hedera, the block number is the consecutive number of a record file that was streamed from the consensus nodes.

The block number can be specified in a hexadecimal format or with string values - “latest” or “earliest”. The other string values defined in Ethereum will default to “latest”, as Hedera architecture incorporates finality of a block right after a given block is created. These are - “pending”, “safe” and “finalized”. We will throw HTTP code BAD_REQUEST exception for a block that is malformed or has a value above the current latest block.

In order to be possible to query historical blocks, we should meet some requirements:

  1. Use full mirror node, keeping state from the genesis block and having CONTRACT_BYTECODE , CONTRACT_STATE_CHANGE sidecar types enabled.
  2. Implement a mechanism that can map the block height from the request to a specific timestamp and then to a specific value for the contract storage.
  3. Support EVM versioning, so that we use the appropriate EVM version for a specific historical block.
  4. Implement a mechanism that can map the block height from the request to a specific EVM version that was used at that time and to information about System Contracts availability at that point in time.