Skip to content

Commit

Permalink
Temporary CancunEOF fork for EOF testing.
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 committed Jun 19, 2024
1 parent 86b9c38 commit 3761248
Show file tree
Hide file tree
Showing 19 changed files with 252 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1515,6 +1515,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 @@ -178,6 +178,17 @@ public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisCo
miningParameters);
}

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

public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) {
return MainnetProtocolSpecs.pragueDefinition(
chainId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
Expand Down Expand Up @@ -446,13 +447,18 @@ static ProtocolSpecBuilder londonDefinition(
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
final long londonForkBlockNumber =
genesisConfigOptions.getLondonBlockNumber().orElse(Long.MAX_VALUE);
final BaseFeeMarket londonFeeMarket =
genesisConfigOptions.isZeroBaseFee()
? FeeMarket.zeroBaseFee(londonForkBlockNumber)
: genesisConfigOptions.isFixedBaseFee()
? FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningParameters.getMinTransactionGasPrice())
: FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
final BaseFeeMarket londonFeeMarket;
if (genesisConfigOptions.isZeroBaseFee()) {
londonFeeMarket = FeeMarket.zeroBaseFee(londonForkBlockNumber);
} else if (genesisConfigOptions.isFixedBaseFee()) {
londonFeeMarket =
FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningParameters.getMinTransactionGasPrice());
} else {
londonFeeMarket =
FeeMarket.london(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
}

return berlinDefinition(
chainId,
configContractSizeLimit,
Expand Down Expand Up @@ -661,13 +667,17 @@ static ProtocolSpecBuilder cancunDefinition(

final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
final long londonForkBlockNumber = genesisConfigOptions.getLondonBlockNumber().orElse(0L);
final BaseFeeMarket cancunFeeMarket =
genesisConfigOptions.isZeroBaseFee()
? FeeMarket.zeroBaseFee(londonForkBlockNumber)
: genesisConfigOptions.isFixedBaseFee()
? FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningParameters.getMinTransactionGasPrice())
: FeeMarket.cancun(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
final BaseFeeMarket cancunFeeMarket;
if (genesisConfigOptions.isZeroBaseFee()) {
cancunFeeMarket = FeeMarket.zeroBaseFee(londonForkBlockNumber);
} else if (genesisConfigOptions.isFixedBaseFee()) {
cancunFeeMarket =
FeeMarket.fixedBaseFee(
londonForkBlockNumber, miningParameters.getMinTransactionGasPrice());
} else {
cancunFeeMarket =
FeeMarket.cancun(londonForkBlockNumber, genesisConfigOptions.getBaseFeePerGas());
}

return shanghaiDefinition(
chainId,
Expand Down Expand Up @@ -728,6 +738,30 @@ static ProtocolSpecBuilder cancunDefinition(
.name("Cancun");
}

static ProtocolSpecBuilder cancunEOFDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final EvmConfiguration evmConfiguration,
final MiningParameters miningParameters) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);

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

static ProtocolSpecBuilder pragueDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
Expand Down Expand Up @@ -780,14 +814,25 @@ static ProtocolSpecBuilder pragueEOFDefinition(
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);

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

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

static ProtocolSpecBuilder futureEipsDefinition(
Expand Down Expand Up @@ -965,7 +1009,8 @@ private void updateWorldStateForDao(final MutableWorldState worldState) {
final JsonArray json =
new JsonArray(
Resources.toString(
this.getClass().getResource("/daoAddresses.json"), StandardCharsets.UTF_8));
Objects.requireNonNull(this.getClass().getResource("/daoAddresses.json")),
StandardCharsets.UTF_8));
final List<Address> addresses =
IntStream.range(0, json.size())
.mapToObj(json::getString)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,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 @@ -331,6 +332,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 @@ -113,6 +113,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 @@ -81,6 +81,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
Loading

0 comments on commit 3761248

Please sign in to comment.