Skip to content

Commit

Permalink
Temporary CancunEOF fork for EOF testing. (#7227)
Browse files Browse the repository at this point in the history
Add Genesis ("CancunEOFTime") and reference test ("CancunEOF") support
for a temporary Cancun+EOF fork, in anticipation of potential devnets.

Signed-off-by: Danno Ferrin <[email protected]>
  • Loading branch information
shemnon authored Jun 25, 2024
1 parent cfc3e76 commit 0f2046d
Show file tree
Hide file tree
Showing 19 changed files with 207 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1514,6 +1514,7 @@ private void configureNativeLibs() {
}

if (genesisConfigOptionsSupplier.get().getCancunTime().isPresent()
|| genesisConfigOptionsSupplier.get().getCancunEOFTime().isPresent()
|| genesisConfigOptionsSupplier.get().getPragueTime().isPresent()
|| genesisConfigOptionsSupplier.get().getPragueEOFTime().isPresent()) {
if (kzgTrustedSetupFile != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,13 @@ default boolean isConsensusMigration() {
*/
OptionalLong getCancunTime();

/**
* Gets cancun EOF time.
*
* @return the cancun EOF time
*/
OptionalLong getCancunEOFTime();

/**
* Gets prague time.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ public OptionalLong getShanghaiTime() {
return getOptionalLong("shanghaitime");
}

@Override
public OptionalLong getCancunEOFTime() {
return getOptionalLong("cancuneoftime");
}

@Override
public OptionalLong getCancunTime() {
return getOptionalLong("cancuntime");
Expand Down Expand Up @@ -461,6 +466,7 @@ public Map<String, Object> asMap() {
getMergeNetSplitBlockNumber().ifPresent(l -> builder.put("mergeNetSplitBlock", l));
getShanghaiTime().ifPresent(l -> builder.put("shanghaiTime", l));
getCancunTime().ifPresent(l -> builder.put("cancunTime", l));
getCancunEOFTime().ifPresent(l -> builder.put("cancunEOFTime", l));
getPragueTime().ifPresent(l -> builder.put("pragueTime", l));
getPragueEOFTime().ifPresent(l -> builder.put("pragueEOFTime", l));
getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l));
Expand Down Expand Up @@ -610,6 +616,7 @@ public List<Long> getForkBlockTimestamps() {
Stream.of(
getShanghaiTime(),
getCancunTime(),
getCancunEOFTime(),
getPragueTime(),
getPragueEOFTime(),
getFutureEipsTime(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
private OptionalLong mergeNetSplitBlockNumber = OptionalLong.empty();
private OptionalLong shanghaiTime = OptionalLong.empty();
private OptionalLong cancunTime = OptionalLong.empty();
private OptionalLong cancunEOFTime = OptionalLong.empty();
private OptionalLong pragueTime = OptionalLong.empty();
private OptionalLong pragueEOFTime = OptionalLong.empty();
private OptionalLong futureEipsTime = OptionalLong.empty();
Expand Down Expand Up @@ -82,7 +83,9 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
private boolean fixedBaseFee = false;

/** Default constructor. */
public StubGenesisConfigOptions() {}
public StubGenesisConfigOptions() {
// Explicit default constructor because of JavaDoc linting
}

@Override
public StubGenesisConfigOptions clone() {
Expand Down Expand Up @@ -238,6 +241,11 @@ public OptionalLong getCancunTime() {
return cancunTime;
}

@Override
public OptionalLong getCancunEOFTime() {
return cancunEOFTime;
}

@Override
public OptionalLong getPragueTime() {
return pragueTime;
Expand Down Expand Up @@ -630,6 +638,17 @@ public StubGenesisConfigOptions cancunTime(final long timestamp) {
return this;
}

/**
* Cancun EOF time.
*
* @param timestamp the timestamp
* @return the stub genesis config options
*/
public StubGenesisConfigOptions cancunEOFTime(final long timestamp) {
cancunEOFTime = OptionalLong.of(timestamp);
return this;
}

/**
* Prague time.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ void shouldGetCancunTime() {
assertThat(config.getCancunTime()).hasValue(1670470142);
}

@Test
void shouldGetCancunEOFTime() {
final GenesisConfigOptions config =
fromConfigOptions(singletonMap("cancunEOFTime", 1670470142));
assertThat(config.getCancunEOFTime()).hasValue(1670470142);
}

@Test
void shouldGetPragueTime() {
final GenesisConfigOptions config = fromConfigOptions(singletonMap("pragueTime", 1670470143));
Expand Down Expand Up @@ -238,6 +245,7 @@ void shouldNotReturnEmptyOptionalWhenBlockNumberNotSpecified() {
assertThat(config.getMergeNetSplitBlockNumber()).isEmpty();
assertThat(config.getShanghaiTime()).isEmpty();
assertThat(config.getCancunTime()).isEmpty();
assertThat(config.getCancunEOFTime()).isEmpty();
assertThat(config.getPragueTime()).isEmpty();
assertThat(config.getPragueEOFTime()).isEmpty();
assertThat(config.getFutureEipsTime()).isEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,15 @@ private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) {
if (cancunTimestamp.isPresent()) {
return genesis.getTimestamp() >= cancunTimestamp.getAsLong();
}
return isPragueAtGenesis(genesis);
return isPragueAtGenesis(genesis) || isCancunEOFAtGenesis(genesis);
}

private static boolean isCancunEOFAtGenesis(final GenesisConfigFile genesis) {
final OptionalLong cancunEOFTimestamp = genesis.getConfigOptions().getCancunEOFTime();
if (cancunEOFTimestamp.isPresent()) {
return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong();
}
return isPragueEOFAtGenesis(genesis);
}

private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisCo
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters);
}

public ProtocolSpecBuilder cancunEOFDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.cancunEOFDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters);
}

public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.pragueDefinition(
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,19 @@ static ProtocolSpecBuilder cancunDefinition(
.name("Cancun");
}

static ProtocolSpecBuilder cancunEOFDefinition(
final Optional<BigInteger> chainId,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {

ProtocolSpecBuilder protocolSpecBuilder =
cancunDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters);
return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF");
}

static ProtocolSpecBuilder pragueDefinition(
final Optional<BigInteger> chainId,
final boolean enableRevertReason,
Expand Down Expand Up @@ -657,8 +670,17 @@ static ProtocolSpecBuilder pragueEOFDefinition(
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {

return pragueDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters)
ProtocolSpecBuilder protocolSpecBuilder =
pragueDefinition(
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters);
return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("PragueEOF");
}

private static ProtocolSpecBuilder addEOF(
final Optional<BigInteger> chainId,
final EvmConfiguration evmConfiguration,
final ProtocolSpecBuilder protocolSpecBuilder) {
return protocolSpecBuilder
// EIP-7692 EOF v1 Gas calculator
.gasCalculator(PragueEOFGasCalculator::new)
// EIP-7692 EOF v1 EVM and opcodes
Expand All @@ -674,8 +696,7 @@ static ProtocolSpecBuilder pragueEOFDefinition(
true,
List.of(MaxCodeSizeRule.from(evm), EOFValidationCodeRule.from(evm)),
1,
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES))
.name("PragueEOF");
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES));
}

static ProtocolSpecBuilder futureEipsDefinition(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ private void validateEthereumForkOrdering() {
// Begin timestamp forks
lastForkBlock = validateForkOrder("Shanghai", config.getShanghaiTime(), lastForkBlock);
lastForkBlock = validateForkOrder("Cancun", config.getCancunTime(), lastForkBlock);
lastForkBlock = validateForkOrder("CancunEOF", config.getCancunEOFTime(), lastForkBlock);
lastForkBlock = validateForkOrder("Prague", config.getPragueTime(), lastForkBlock);
lastForkBlock = validateForkOrder("PragueEOF", config.getPragueEOFTime(), lastForkBlock);
lastForkBlock = validateForkOrder("FutureEips", config.getFutureEipsTime(), lastForkBlock);
Expand Down Expand Up @@ -326,6 +327,7 @@ private Stream<Optional<BuilderMapEntry>> createMilestones(
// Timestamp Forks
timestampMilestone(config.getShanghaiTime(), specFactory.shanghaiDefinition(config)),
timestampMilestone(config.getCancunTime(), specFactory.cancunDefinition(config)),
timestampMilestone(config.getCancunEOFTime(), specFactory.cancunEOFDefinition(config)),
timestampMilestone(config.getPragueTime(), specFactory.pragueDefinition(config)),
timestampMilestone(config.getPragueEOFTime(), specFactory.pragueEOFDefinition(config)),
timestampMilestone(config.getFutureEipsTime(), specFactory.futureEipsDefinition(config)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ public static Map<String, Supplier<ProtocolSchedule>> createSchedules() {
Map.entry(
"cancun",
createSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a))),
Map.entry(
"cancuneof",
createSchedule(new StubGenesisConfigOptions().cancunEOFTime(0).baseFeePerGas(0x0a))),
Map.entry(
"prague",
createSchedule(new StubGenesisConfigOptions().pragueTime(0).baseFeePerGas(0x0a))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ protected double runPrecompileBenchmark(final Bytes arg, final PrecompiledContra
}
timer.stop();

if (executions < 1) {
if (executions > 0) {
final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D;
return elapsed / executions;
} else {
return Double.NaN;
}

final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D;
return elapsed / executions;
}

/**
Expand All @@ -143,7 +143,15 @@ public static GasCalculator gasCalculatorForFork(final String fork) {
case SHANGHAI -> new ShanghaiGasCalculator();
case CANCUN -> new CancunGasCalculator();
case PRAGUE -> new PragueGasCalculator();
case PRAGUE_EOF, OSAKA, AMSTERDAM, BOGOTA, POLIS, BANGKOK, FUTURE_EIPS, EXPERIMENTAL_EIPS ->
case CANCUN_EOF,
PRAGUE_EOF,
OSAKA,
AMSTERDAM,
BOGOTA,
POLIS,
BANGKOK,
FUTURE_EIPS,
EXPERIMENTAL_EIPS ->
new PragueEOFGasCalculator();
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
},
"out": "0x",
"post": {
"Prague": [
"CancunEOF": [
{
"hash": "0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3",
"logs": "0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940",
Expand Down Expand Up @@ -79,7 +79,7 @@
{"pc":5,"section":0,"op":95,"gas":"0x793d71","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"},
{"pc":6,"section":0,"op":95,"gas":"0x793d6f","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH0"},
{"pc":7,"section":0,"op":238,"immediate":"0x00","gas":"0x793d6d","gasCost":"0x0","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"RETURNCONTRACT"},
{"output":"","gasUsed":"0xe433","test":"create-eof","fork":"Prague","d":0,"g":0,"v":0,"postHash":"0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3","postLogsHash":"0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940","pass":true},
{"output":"","gasUsed":"0xe433","test":"create-eof","fork":"CancunEOF","d":0,"g":0,"v":0,"postHash":"0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3","postLogsHash":"0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940","pass":true},
{"pc":0,"op":239,"gas":"0x794068","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"INVALID","error":"Bad instruction"},
{"output":"","gasUsed":"0x7a1200","test":"create-eof","fork":"Cancun","d":0,"g":0,"v":0,"postHash":"0xaa80d89bc89f58da8de41d3894bd1a241896ff91f7a5964edaefb39e8e3a4a98","postLogsHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","pass":true,"error":"INVALID_OPERATION"}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"--coinbase",
"4444588443C3A91288C5002483449ABA1054192B",
"--fork",
"pragueeof"
"CancunEOF"
],
"stdin": "",
"stdout": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public static ReferenceTestProtocolSchedules create(final StubGenesisConfigOptio
"ShanghaiToCancunAtTime15k",
createSchedule(genesisStub.clone().shanghaiTime(0).cancunTime(15000)));
builder.put("Cancun", createSchedule(genesisStub.clone().cancunTime(0)));
builder.put("CancunEOF", createSchedule(genesisStub.clone().cancunEOFTime(0)));
// also load KZG file for mainnet
KZGPointEvalPrecompiledContract.init();
builder.put(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public enum EvmSpecVersion {
SHANGHAI(0x6000, 0xc000, 0, true, "Shanghai", "Finalized"),
/** Cancun evm spec version. */
CANCUN(0x6000, 0xc000, 0, true, "Cancun", "Finalized"),
/** Cancun evm spec version. */
CANCUN_EOF(0x6000, 0xc000, 1, false, "CancunEOF", "For Testing"),
/** Prague evm spec version. */
PRAGUE(0x6000, 0xc000, 0, false, "Prague", "In Development"),
/** PragueEOF evm spec version. */
Expand Down Expand Up @@ -201,6 +203,10 @@ public static EvmSpecVersion fromName(final String name) {
if ("prague".equalsIgnoreCase(name)) {
return EvmSpecVersion.PRAGUE_EOF;
}
// TODO remove once PragueEOF settles
if ("cancuneof".equalsIgnoreCase(name)) {
return EvmSpecVersion.CANCUN_EOF;
}
for (var version : EvmSpecVersion.values()) {
if (version.name().equalsIgnoreCase(name)) {
return version;
Expand Down
Loading

0 comments on commit 0f2046d

Please sign in to comment.