EEVM.StateRoot (eevm v0.1.0)

Copy Markdown View Source

Computes Ethereum storage roots and state roots from the current EEVM.Database.

The first state root of a database enumerates the backend through EEVM.Database.accounts/1 and EEVM.Database.storage_slots/2, so the backend must support them. update/1 keeps the hashed tries in the database it returns, and every database derived from that one by writes and EEVM.Database.commit/1 carries them along with the addresses and slots written since. The next state root rehashes only those paths, so a block costs Keccak work in proportion to what it wrote, not to the size of the state (#203). EEVM.Block.execute/4 and EEVM.Block.build/4 use it, so the databases in their results, committed or not, carry the tries to the next block.

Summary

Types

Hashed tries for some earlier state, and what changed since: for each address, the slots written, or :all when its storage was cleared. Kept in EEVM.Database's :tries field.

Functions

Returns the world-state trie root of db, overlay included.

Returns the storage trie root of address.

Returns the world-state trie root of db, overlay included, and db with its hashed tries updated, so the next state root of it, or of a database written or committed from it, rehashes only what changed.

Types

tries()

@opaque tries()

Hashed tries for some earlier state, and what changed since: for each address, the slots written, or :all when its storage was cleared. Kept in EEVM.Database's :tries field.

Functions

compute_state_root(db)

@spec compute_state_root(EEVM.Database.t()) :: binary()

Returns the world-state trie root of db, overlay included.

compute_storage_root(db, address)

@spec compute_storage_root(EEVM.Database.t(), non_neg_integer()) :: binary()

Returns the storage trie root of address.

update(db)

@spec update(EEVM.Database.t()) :: {binary(), EEVM.Database.t()}

Returns the world-state trie root of db, overlay included, and db with its hashed tries updated, so the next state root of it, or of a database written or committed from it, rehashes only what changed.

Example

iex> alias EEVM.Database
iex> {_root, db} = EEVM.StateRoot.update(Database.InMemory.new(accounts: %{1 => %{balance: 5}}))
iex> {:ok, db} = db |> Database.set_balance(2, 7) |> Database.commit()
iex> {root, _db} = EEVM.StateRoot.update(db)
iex> fresh = Database.InMemory.new(accounts: %{1 => %{balance: 5}, 2 => %{balance: 7}})
iex> root == EEVM.StateRoot.compute_state_root(fresh)
true