Skip to content

Commit 0f2046d

Browse files
authored
Temporary CancunEOF fork for EOF testing. (#7227)
Add Genesis ("CancunEOFTime") and reference test ("CancunEOF") support for a temporary Cancun+EOF fork, in anticipation of potential devnets. Signed-off-by: Danno Ferrin <danno@numisight.com>
1 parent cfc3e76 commit 0f2046d

File tree

19 files changed

+207
-16
lines changed

19 files changed

+207
-16
lines changed

besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java

+1
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,7 @@ private void configureNativeLibs() {
15141514
}
15151515

15161516
if (genesisConfigOptionsSupplier.get().getCancunTime().isPresent()
1517+
|| genesisConfigOptionsSupplier.get().getCancunEOFTime().isPresent()
15171518
|| genesisConfigOptionsSupplier.get().getPragueTime().isPresent()
15181519
|| genesisConfigOptionsSupplier.get().getPragueEOFTime().isPresent()) {
15191520
if (kzgTrustedSetupFile != null) {

config/src/main/java/org/hyperledger/besu/config/GenesisConfigOptions.java

+7
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ default boolean isConsensusMigration() {
242242
*/
243243
OptionalLong getCancunTime();
244244

245+
/**
246+
* Gets cancun EOF time.
247+
*
248+
* @return the cancun EOF time
249+
*/
250+
OptionalLong getCancunEOFTime();
251+
245252
/**
246253
* Gets prague time.
247254
*

config/src/main/java/org/hyperledger/besu/config/JsonGenesisConfigOptions.java

+7
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ public OptionalLong getShanghaiTime() {
288288
return getOptionalLong("shanghaitime");
289289
}
290290

291+
@Override
292+
public OptionalLong getCancunEOFTime() {
293+
return getOptionalLong("cancuneoftime");
294+
}
295+
291296
@Override
292297
public OptionalLong getCancunTime() {
293298
return getOptionalLong("cancuntime");
@@ -461,6 +466,7 @@ public Map<String, Object> asMap() {
461466
getMergeNetSplitBlockNumber().ifPresent(l -> builder.put("mergeNetSplitBlock", l));
462467
getShanghaiTime().ifPresent(l -> builder.put("shanghaiTime", l));
463468
getCancunTime().ifPresent(l -> builder.put("cancunTime", l));
469+
getCancunEOFTime().ifPresent(l -> builder.put("cancunEOFTime", l));
464470
getPragueTime().ifPresent(l -> builder.put("pragueTime", l));
465471
getPragueEOFTime().ifPresent(l -> builder.put("pragueEOFTime", l));
466472
getTerminalBlockNumber().ifPresent(l -> builder.put("terminalBlockNumber", l));
@@ -610,6 +616,7 @@ public List<Long> getForkBlockTimestamps() {
610616
Stream.of(
611617
getShanghaiTime(),
612618
getCancunTime(),
619+
getCancunEOFTime(),
613620
getPragueTime(),
614621
getPragueEOFTime(),
615622
getFutureEipsTime(),

config/src/main/java/org/hyperledger/besu/config/StubGenesisConfigOptions.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
4848
private OptionalLong mergeNetSplitBlockNumber = OptionalLong.empty();
4949
private OptionalLong shanghaiTime = OptionalLong.empty();
5050
private OptionalLong cancunTime = OptionalLong.empty();
51+
private OptionalLong cancunEOFTime = OptionalLong.empty();
5152
private OptionalLong pragueTime = OptionalLong.empty();
5253
private OptionalLong pragueEOFTime = OptionalLong.empty();
5354
private OptionalLong futureEipsTime = OptionalLong.empty();
@@ -82,7 +83,9 @@ public class StubGenesisConfigOptions implements GenesisConfigOptions, Cloneable
8283
private boolean fixedBaseFee = false;
8384

8485
/** Default constructor. */
85-
public StubGenesisConfigOptions() {}
86+
public StubGenesisConfigOptions() {
87+
// Explicit default constructor because of JavaDoc linting
88+
}
8689

8790
@Override
8891
public StubGenesisConfigOptions clone() {
@@ -238,6 +241,11 @@ public OptionalLong getCancunTime() {
238241
return cancunTime;
239242
}
240243

244+
@Override
245+
public OptionalLong getCancunEOFTime() {
246+
return cancunEOFTime;
247+
}
248+
241249
@Override
242250
public OptionalLong getPragueTime() {
243251
return pragueTime;
@@ -630,6 +638,17 @@ public StubGenesisConfigOptions cancunTime(final long timestamp) {
630638
return this;
631639
}
632640

641+
/**
642+
* Cancun EOF time.
643+
*
644+
* @param timestamp the timestamp
645+
* @return the stub genesis config options
646+
*/
647+
public StubGenesisConfigOptions cancunEOFTime(final long timestamp) {
648+
cancunEOFTime = OptionalLong.of(timestamp);
649+
return this;
650+
}
651+
633652
/**
634653
* Prague time.
635654
*

config/src/test/java/org/hyperledger/besu/config/GenesisConfigOptionsTest.java

+8
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,13 @@ void shouldGetCancunTime() {
193193
assertThat(config.getCancunTime()).hasValue(1670470142);
194194
}
195195

196+
@Test
197+
void shouldGetCancunEOFTime() {
198+
final GenesisConfigOptions config =
199+
fromConfigOptions(singletonMap("cancunEOFTime", 1670470142));
200+
assertThat(config.getCancunEOFTime()).hasValue(1670470142);
201+
}
202+
196203
@Test
197204
void shouldGetPragueTime() {
198205
final GenesisConfigOptions config = fromConfigOptions(singletonMap("pragueTime", 1670470143));
@@ -238,6 +245,7 @@ void shouldNotReturnEmptyOptionalWhenBlockNumberNotSpecified() {
238245
assertThat(config.getMergeNetSplitBlockNumber()).isEmpty();
239246
assertThat(config.getShanghaiTime()).isEmpty();
240247
assertThat(config.getCancunTime()).isEmpty();
248+
assertThat(config.getCancunEOFTime()).isEmpty();
241249
assertThat(config.getPragueTime()).isEmpty();
242250
assertThat(config.getPragueEOFTime()).isEmpty();
243251
assertThat(config.getFutureEipsTime()).isEmpty();

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/chain/GenesisState.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,15 @@ private static boolean isCancunAtGenesis(final GenesisConfigFile genesis) {
304304
if (cancunTimestamp.isPresent()) {
305305
return genesis.getTimestamp() >= cancunTimestamp.getAsLong();
306306
}
307-
return isPragueAtGenesis(genesis);
307+
return isPragueAtGenesis(genesis) || isCancunEOFAtGenesis(genesis);
308+
}
309+
310+
private static boolean isCancunEOFAtGenesis(final GenesisConfigFile genesis) {
311+
final OptionalLong cancunEOFTimestamp = genesis.getConfigOptions().getCancunEOFTime();
312+
if (cancunEOFTimestamp.isPresent()) {
313+
return genesis.getTimestamp() >= cancunEOFTimestamp.getAsLong();
314+
}
315+
return isPragueEOFAtGenesis(genesis);
308316
}
309317

310318
private static boolean isPragueAtGenesis(final GenesisConfigFile genesis) {

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecFactory.java

+5
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ public ProtocolSpecBuilder cancunDefinition(final GenesisConfigOptions genesisCo
128128
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters);
129129
}
130130

131+
public ProtocolSpecBuilder cancunEOFDefinition(final GenesisConfigOptions genesisConfigOptions) {
132+
return MainnetProtocolSpecs.cancunEOFDefinition(
133+
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters);
134+
}
135+
131136
public ProtocolSpecBuilder pragueDefinition(final GenesisConfigOptions genesisConfigOptions) {
132137
return MainnetProtocolSpecs.pragueDefinition(
133138
chainId, isRevertReasonEnabled, genesisConfigOptions, evmConfiguration, miningParameters);

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java

+25-4
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,19 @@ static ProtocolSpecBuilder cancunDefinition(
617617
.name("Cancun");
618618
}
619619

620+
static ProtocolSpecBuilder cancunEOFDefinition(
621+
final Optional<BigInteger> chainId,
622+
final boolean enableRevertReason,
623+
final GenesisConfigOptions genesisConfigOptions,
624+
final EvmConfiguration evmConfiguration,
625+
final MiningParameters miningParameters) {
626+
627+
ProtocolSpecBuilder protocolSpecBuilder =
628+
cancunDefinition(
629+
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters);
630+
return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("CancunEOF");
631+
}
632+
620633
static ProtocolSpecBuilder pragueDefinition(
621634
final Optional<BigInteger> chainId,
622635
final boolean enableRevertReason,
@@ -657,8 +670,17 @@ static ProtocolSpecBuilder pragueEOFDefinition(
657670
final EvmConfiguration evmConfiguration,
658671
final MiningParameters miningParameters) {
659672

660-
return pragueDefinition(
661-
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters)
673+
ProtocolSpecBuilder protocolSpecBuilder =
674+
pragueDefinition(
675+
chainId, enableRevertReason, genesisConfigOptions, evmConfiguration, miningParameters);
676+
return addEOF(chainId, evmConfiguration, protocolSpecBuilder).name("PragueEOF");
677+
}
678+
679+
private static ProtocolSpecBuilder addEOF(
680+
final Optional<BigInteger> chainId,
681+
final EvmConfiguration evmConfiguration,
682+
final ProtocolSpecBuilder protocolSpecBuilder) {
683+
return protocolSpecBuilder
662684
// EIP-7692 EOF v1 Gas calculator
663685
.gasCalculator(PragueEOFGasCalculator::new)
664686
// EIP-7692 EOF v1 EVM and opcodes
@@ -674,8 +696,7 @@ static ProtocolSpecBuilder pragueEOFDefinition(
674696
true,
675697
List.of(MaxCodeSizeRule.from(evm), EOFValidationCodeRule.from(evm)),
676698
1,
677-
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES))
678-
.name("PragueEOF");
699+
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES));
679700
}
680701

681702
static ProtocolSpecBuilder futureEipsDefinition(

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/ProtocolScheduleBuilder.java

+2
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ private void validateEthereumForkOrdering() {
246246
// Begin timestamp forks
247247
lastForkBlock = validateForkOrder("Shanghai", config.getShanghaiTime(), lastForkBlock);
248248
lastForkBlock = validateForkOrder("Cancun", config.getCancunTime(), lastForkBlock);
249+
lastForkBlock = validateForkOrder("CancunEOF", config.getCancunEOFTime(), lastForkBlock);
249250
lastForkBlock = validateForkOrder("Prague", config.getPragueTime(), lastForkBlock);
250251
lastForkBlock = validateForkOrder("PragueEOF", config.getPragueEOFTime(), lastForkBlock);
251252
lastForkBlock = validateForkOrder("FutureEips", config.getFutureEipsTime(), lastForkBlock);
@@ -326,6 +327,7 @@ private Stream<Optional<BuilderMapEntry>> createMilestones(
326327
// Timestamp Forks
327328
timestampMilestone(config.getShanghaiTime(), specFactory.shanghaiDefinition(config)),
328329
timestampMilestone(config.getCancunTime(), specFactory.cancunDefinition(config)),
330+
timestampMilestone(config.getCancunEOFTime(), specFactory.cancunEOFDefinition(config)),
329331
timestampMilestone(config.getPragueTime(), specFactory.pragueDefinition(config)),
330332
timestampMilestone(config.getPragueEOFTime(), specFactory.pragueEOFDefinition(config)),
331333
timestampMilestone(config.getFutureEipsTime(), specFactory.futureEipsDefinition(config)),

ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/MainnetGenesisFileModule.java

+3
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ public static Map<String, Supplier<ProtocolSchedule>> createSchedules() {
117117
Map.entry(
118118
"cancun",
119119
createSchedule(new StubGenesisConfigOptions().cancunTime(0).baseFeePerGas(0x0a))),
120+
Map.entry(
121+
"cancuneof",
122+
createSchedule(new StubGenesisConfigOptions().cancunEOFTime(0).baseFeePerGas(0x0a))),
120123
Map.entry(
121124
"prague",
122125
createSchedule(new StubGenesisConfigOptions().pragueTime(0).baseFeePerGas(0x0a))),

ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java

+13-5
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ protected double runPrecompileBenchmark(final Bytes arg, final PrecompiledContra
113113
}
114114
timer.stop();
115115

116-
if (executions < 1) {
116+
if (executions > 0) {
117+
final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D;
118+
return elapsed / executions;
119+
} else {
117120
return Double.NaN;
118121
}
119-
120-
final double elapsed = timer.elapsed(TimeUnit.NANOSECONDS) / 1.0e9D;
121-
return elapsed / executions;
122122
}
123123

124124
/**
@@ -143,7 +143,15 @@ public static GasCalculator gasCalculatorForFork(final String fork) {
143143
case SHANGHAI -> new ShanghaiGasCalculator();
144144
case CANCUN -> new CancunGasCalculator();
145145
case PRAGUE -> new PragueGasCalculator();
146-
case PRAGUE_EOF, OSAKA, AMSTERDAM, BOGOTA, POLIS, BANGKOK, FUTURE_EIPS, EXPERIMENTAL_EIPS ->
146+
case CANCUN_EOF,
147+
PRAGUE_EOF,
148+
OSAKA,
149+
AMSTERDAM,
150+
BOGOTA,
151+
POLIS,
152+
BANGKOK,
153+
FUTURE_EIPS,
154+
EXPERIMENTAL_EIPS ->
147155
new PragueEOFGasCalculator();
148156
};
149157
}

ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/create-eof.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
},
4646
"out": "0x",
4747
"post": {
48-
"Prague": [
48+
"CancunEOF": [
4949
{
5050
"hash": "0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3",
5151
"logs": "0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940",
@@ -79,7 +79,7 @@
7979
{"pc":5,"section":0,"op":95,"gas":"0x793d71","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH0"},
8080
{"pc":6,"section":0,"op":95,"gas":"0x793d6f","gasCost":"0x2","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"PUSH0"},
8181
{"pc":7,"section":0,"op":238,"immediate":"0x00","gas":"0x793d6d","gasCost":"0x0","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"RETURNCONTRACT"},
82-
{"output":"","gasUsed":"0xe433","test":"create-eof","fork":"Prague","d":0,"g":0,"v":0,"postHash":"0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3","postLogsHash":"0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940","pass":true},
82+
{"output":"","gasUsed":"0xe433","test":"create-eof","fork":"CancunEOF","d":0,"g":0,"v":0,"postHash":"0x1a8642a04dae90535f00f53d3a30284c4db051d508a653db89eb100ba9aecbf3","postLogsHash":"0xf48b954a6a6f4ce6b28e4950b7027413f4bdc8f459df6003b6e8d7a1567c8940","pass":true},
8383
{"pc":0,"op":239,"gas":"0x794068","gasCost":"0x0","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"INVALID","error":"Bad instruction"},
8484
{"output":"","gasUsed":"0x7a1200","test":"create-eof","fork":"Cancun","d":0,"g":0,"v":0,"postHash":"0xaa80d89bc89f58da8de41d3894bd1a241896ff91f7a5964edaefb39e8e3a4a98","postLogsHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","pass":true,"error":"INVALID_OPERATION"}
8585
]

ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/create-eof.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"--coinbase",
99
"4444588443C3A91288C5002483449ABA1054192B",
1010
"--fork",
11-
"pragueeof"
11+
"CancunEOF"
1212
],
1313
"stdin": "",
1414
"stdout": [

ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/ReferenceTestProtocolSchedules.java

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public static ReferenceTestProtocolSchedules create(final StubGenesisConfigOptio
8484
"ShanghaiToCancunAtTime15k",
8585
createSchedule(genesisStub.clone().shanghaiTime(0).cancunTime(15000)));
8686
builder.put("Cancun", createSchedule(genesisStub.clone().cancunTime(0)));
87+
builder.put("CancunEOF", createSchedule(genesisStub.clone().cancunEOFTime(0)));
8788
// also load KZG file for mainnet
8889
KZGPointEvalPrecompiledContract.init();
8990
builder.put(

evm/src/main/java/org/hyperledger/besu/evm/EvmSpecVersion.java

+6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public enum EvmSpecVersion {
5555
SHANGHAI(0x6000, 0xc000, 0, true, "Shanghai", "Finalized"),
5656
/** Cancun evm spec version. */
5757
CANCUN(0x6000, 0xc000, 0, true, "Cancun", "Finalized"),
58+
/** Cancun evm spec version. */
59+
CANCUN_EOF(0x6000, 0xc000, 1, false, "CancunEOF", "For Testing"),
5860
/** Prague evm spec version. */
5961
PRAGUE(0x6000, 0xc000, 0, false, "Prague", "In Development"),
6062
/** PragueEOF evm spec version. */
@@ -201,6 +203,10 @@ public static EvmSpecVersion fromName(final String name) {
201203
if ("prague".equalsIgnoreCase(name)) {
202204
return EvmSpecVersion.PRAGUE_EOF;
203205
}
206+
// TODO remove once PragueEOF settles
207+
if ("cancuneof".equalsIgnoreCase(name)) {
208+
return EvmSpecVersion.CANCUN_EOF;
209+
}
204210
for (var version : EvmSpecVersion.values()) {
205211
if (version.name().equalsIgnoreCase(name)) {
206212
return version;

0 commit comments

Comments
 (0)