Context

This data is gathered replaying ~200k historical blocks around the Shanghai fork. While they do not give a perfect view of how execution will behave once EIP-4762 is active, it still gives a good indication of what to expect, and how the spec should evolve.

This document is still work in progress, and will be updated as more data is collected and processed.

Witnesses

Size

Research has been conducted, in order to determine the best structure for a witness. We tried three methods:

class SuffixStateDiffs(Container):
    suffixes: bytes
    # None means not currently present
    current_values: List[bytes]
    # None means value not updated
    new_values:     List[bytes]
class SuffixStateDiffs(Container):
    updated_suffixes: bytes
    updated_currents: List[Bytes32]
    updated_news: List[Bytes32]

    inserted_suffixes: bytes
    inserted_news: List[Bytes32]

    read_suffixes: bytes
    read_currents: List[Bytes32]

    missing_suffixes: bytes
class UpdateDiff(Container):
    suffix: byte
    current: Bytes32
    new: Bytes32

class ReadDiff(Container):
    suffix: byte
    current: Bytes32

class InsertDiff(Container):
    suffix: byte
    new: Bytes32

class MissingDiff(Container):
    suffix byte

class StemStateDiff(Container):
    stem: Bytes31

    updates: List[UpdateDiff]
    reads: List[ReadStateDiff]
    insert: List[InsertStateDiff]
    # TODO: check if this encodes as well as bytes
    missing: List[MissingStateDiff]

Here are our findings after replaying data for 200k blocks:

image.png

One can see that the spec is much less efficient than the other types. This is due to the inefficiency of storing Optional[T]. As a result, we didn’t include this method in the rest of the analysis.

When only considering the post-transition witnesses, this is what is found:

image.png

The maximum and minimum sizes for each type, are summarized in the following table:

Name Min (KB) Max (KB)
type 1 425 1285
type 2 383 928
type 3 380 928