Skip to content

Commit 2158a68

Browse files
Fix protocol schedule for devnets (#7429)
* add `ProtocolSchedule::milestoneFor` to retrieve milestones for every hardfork in the genesis file * add `setMilestones` and `milestoneFor` to TransitionProtocolSchedule * refactored all checks for hardforks in the engine API to use hard fork ids * added tests to test that the engine API v2 endpoints return UNSUPPORTED_FORK past Cancun Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net> --------- Signed-off-by: Daniel Lehrner <daniel.lehrner@consensys.net> Signed-off-by: Sally MacFarlane <macfarla.github@gmail.com> Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
1 parent fab2393 commit 2158a68

File tree

23 files changed

+566
-201
lines changed

23 files changed

+566
-201
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
### Bug fixes
2020
- Correct entrypoint in Docker evmtool [#7430](https://github.com/hyperledger/besu/pull/7430)
21+
- Fix protocol schedule check for devnets [#7429](https://github.com/hyperledger/besu/pull/7429)
2122
- Fix behaviour when starting in a pre-merge network [#7431](https://github.com/hyperledger/besu/pull/7431)
2223

2324
## 24.7.1

consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/TransitionProtocolSchedule.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.hyperledger.besu.ethereum.core.MiningParameters;
2323
import org.hyperledger.besu.ethereum.core.PermissionTransactionFilter;
2424
import org.hyperledger.besu.ethereum.core.ProcessableBlockHeader;
25+
import org.hyperledger.besu.ethereum.mainnet.HardforkId;
2526
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule;
2627
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
2728
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec;
@@ -241,6 +242,13 @@ public String listMilestones() {
241242
return transitionUtils.dispatchFunctionAccordingToMergeState(ProtocolSchedule::listMilestones);
242243
}
243244

245+
@Override
246+
public Optional<Long> milestoneFor(final HardforkId hardforkId) {
247+
return mergeContext.isPostMerge()
248+
? transitionUtils.getPostMergeObject().milestoneFor(hardforkId)
249+
: transitionUtils.getPreMergeObject().milestoneFor(hardforkId);
250+
}
251+
244252
/**
245253
* Sets transaction filter.
246254
*

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/AbstractEngineForkchoiceUpdated.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.SYNCING;
2020
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.ExecutionEngineJsonRpcMethod.EngineStatus.VALID;
2121
import static org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine.WithdrawalsValidatorProvider.getWithdrawalsValidator;
22+
import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN;
2223

2324
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
2425
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator.ForkchoiceResult;
@@ -38,7 +39,6 @@
3839
import org.hyperledger.besu.ethereum.core.BlockHeader;
3940
import org.hyperledger.besu.ethereum.core.Withdrawal;
4041
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
41-
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
4242
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
4343

4444
import java.util.List;
@@ -54,7 +54,7 @@
5454
public abstract class AbstractEngineForkchoiceUpdated extends ExecutionEngineJsonRpcMethod {
5555
private static final Logger LOG = LoggerFactory.getLogger(AbstractEngineForkchoiceUpdated.class);
5656
private final MergeMiningCoordinator mergeCoordinator;
57-
protected final Long cancunTimestamp;
57+
protected final Optional<Long> cancunMilestone;
5858

5959
public AbstractEngineForkchoiceUpdated(
6060
final Vertx vertx,
@@ -65,9 +65,7 @@ public AbstractEngineForkchoiceUpdated(
6565
super(vertx, protocolSchedule, protocolContext, engineCallListener);
6666

6767
this.mergeCoordinator = mergeCoordinator;
68-
Optional<ScheduledProtocolSpec.Hardfork> cancun =
69-
protocolSchedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun"));
70-
cancunTimestamp = cancun.map(ScheduledProtocolSpec.Hardfork::milestone).orElse(Long.MAX_VALUE);
68+
cancunMilestone = protocolSchedule.milestoneFor(CANCUN);
7169
}
7270

7371
protected ValidationResult<RpcErrorType> validateParameter(

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV2.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
2222
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
2323
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
24+
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
2425

2526
import java.util.Optional;
2627

@@ -51,20 +52,22 @@ public String getName() {
5152
@Override
5253
protected Optional<JsonRpcErrorResponse> isPayloadAttributesValid(
5354
final Object requestId, final EnginePayloadAttributesParameter payloadAttributes) {
54-
if (payloadAttributes.getTimestamp() >= cancunTimestamp) {
55-
if (payloadAttributes.getParentBeaconBlockRoot() == null
56-
|| payloadAttributes.getParentBeaconBlockRoot().isEmpty()) {
57-
return Optional.of(new JsonRpcErrorResponse(requestId, RpcErrorType.UNSUPPORTED_FORK));
58-
} else {
59-
return Optional.of(
60-
new JsonRpcErrorResponse(requestId, RpcErrorType.INVALID_PAYLOAD_ATTRIBUTES));
61-
}
62-
} else if (payloadAttributes.getParentBeaconBlockRoot() != null) {
55+
56+
if (payloadAttributes.getParentBeaconBlockRoot() != null) {
6357
LOG.error(
64-
"Parent beacon block root hash present in payload attributes before cancun hardfork");
58+
"Parent beacon block root hash present in payload attributes before Cancun hardfork");
6559
return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError()));
66-
} else {
67-
return Optional.empty();
6860
}
61+
62+
return Optional.empty();
63+
}
64+
65+
@Override
66+
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
67+
if (cancunMilestone.isPresent() && blockTimestamp >= cancunMilestone.get()) {
68+
return ValidationResult.invalid(RpcErrorType.UNSUPPORTED_FORK);
69+
}
70+
71+
return ValidationResult.valid();
6972
}
7073
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineForkchoiceUpdatedV3.java

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
1616

17+
import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN;
18+
1719
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
1820
import org.hyperledger.besu.ethereum.ProtocolContext;
1921
import org.hyperledger.besu.ethereum.api.jsonrpc.RpcMethod;
@@ -22,7 +24,6 @@
2224
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcErrorResponse;
2325
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
2426
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
25-
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
2627
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
2728

2829
import java.util.Optional;
@@ -33,7 +34,6 @@
3334

3435
public class EngineForkchoiceUpdatedV3 extends AbstractEngineForkchoiceUpdated {
3536

36-
private final Optional<ScheduledProtocolSpec.Hardfork> supportedHardFork;
3737
private static final Logger LOG = LoggerFactory.getLogger(EngineForkchoiceUpdatedV3.class);
3838

3939
public EngineForkchoiceUpdatedV3(
@@ -43,11 +43,6 @@ public EngineForkchoiceUpdatedV3(
4343
final MergeMiningCoordinator mergeCoordinator,
4444
final EngineCallListener engineCallListener) {
4545
super(vertx, protocolSchedule, protocolContext, mergeCoordinator, engineCallListener);
46-
this.supportedHardFork =
47-
protocolSchedule.hardforkFor(
48-
s ->
49-
s.fork().name().equalsIgnoreCase("Cancun")
50-
|| s.fork().name().equalsIgnoreCase("Prague"));
5146
}
5247

5348
@Override
@@ -80,18 +75,7 @@ protected ValidationResult<RpcErrorType> validateParameter(
8075

8176
@Override
8277
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
83-
if (protocolSchedule.isPresent()) {
84-
if (supportedHardFork.isPresent() && blockTimestamp >= supportedHardFork.get().milestone()) {
85-
return ValidationResult.valid();
86-
} else {
87-
return ValidationResult.invalid(
88-
RpcErrorType.UNSUPPORTED_FORK,
89-
"Cancun configured to start at timestamp: " + supportedHardFork.get().milestone());
90-
}
91-
} else {
92-
return ValidationResult.invalid(
93-
RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Cancun fork set");
94-
}
78+
return ForkSupportHelper.validateForkSupported(CANCUN, cancunMilestone, blockTimestamp);
9579
}
9680

9781
@Override
@@ -101,12 +85,16 @@ protected Optional<JsonRpcErrorResponse> isPayloadAttributesValid(
10185
LOG.error(
10286
"Parent beacon block root hash not present in payload attributes after cancun hardfork");
10387
return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError()));
104-
} else if (payloadAttributes.getTimestamp().longValue() == 0) {
88+
}
89+
90+
if (payloadAttributes.getTimestamp() == 0) {
10591
return Optional.of(new JsonRpcErrorResponse(requestId, getInvalidPayloadAttributesError()));
106-
} else if (payloadAttributes.getTimestamp() < supportedHardFork.get().milestone()) {
92+
}
93+
94+
if (cancunMilestone.isEmpty() || payloadAttributes.getTimestamp() < cancunMilestone.get()) {
10795
return Optional.of(new JsonRpcErrorResponse(requestId, RpcErrorType.UNSUPPORTED_FORK));
108-
} else {
109-
return Optional.empty();
11096
}
97+
98+
return Optional.empty();
11199
}
112100
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV2.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
1616

17+
import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN;
18+
1719
import org.hyperledger.besu.consensus.merge.PayloadWrapper;
1820
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
1921
import org.hyperledger.besu.ethereum.ProtocolContext;
@@ -24,7 +26,6 @@
2426
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
2527
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
2628
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
27-
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
2829
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
2930

3031
import java.util.Optional;
@@ -33,7 +34,7 @@
3334

3435
public class EngineGetPayloadV2 extends AbstractEngineGetPayload {
3536

36-
private final Optional<ScheduledProtocolSpec.Hardfork> cancun;
37+
private final Optional<Long> cancunMilestone;
3738

3839
public EngineGetPayloadV2(
3940
final Vertx vertx,
@@ -49,7 +50,7 @@ public EngineGetPayloadV2(
4950
mergeMiningCoordinator,
5051
blockResultFactory,
5152
engineCallListener);
52-
this.cancun = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun"));
53+
cancunMilestone = schedule.milestoneFor(CANCUN);
5354
}
5455

5556
@Override
@@ -67,20 +68,10 @@ protected JsonRpcResponse createResponse(
6768

6869
@Override
6970
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
70-
if (protocolSchedule.isPresent()) {
71-
if (cancun.isPresent() && blockTimestamp >= cancun.get().milestone()) {
72-
return ValidationResult.invalid(
73-
RpcErrorType.UNSUPPORTED_FORK,
74-
"Cancun configured to start at timestamp: "
75-
+ cancun.get().milestone()
76-
+ " please call engine_getPayloadV3");
77-
} else {
78-
return ValidationResult.valid();
79-
}
80-
} else {
81-
return ValidationResult.invalid(
82-
RpcErrorType.UNSUPPORTED_FORK,
83-
"Configuration error, no schedule for Cancun fork set, not sure when to stop honoring use of V2");
71+
if (cancunMilestone.isPresent() && blockTimestamp >= cancunMilestone.get()) {
72+
return ValidationResult.invalid(RpcErrorType.UNSUPPORTED_FORK);
8473
}
74+
75+
return ValidationResult.valid();
8576
}
8677
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV3.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
1616

17+
import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN;
18+
1719
import org.hyperledger.besu.consensus.merge.PayloadWrapper;
1820
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
1921
import org.hyperledger.besu.ethereum.ProtocolContext;
@@ -24,7 +26,6 @@
2426
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
2527
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
2628
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
27-
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
2829
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
2930

3031
import java.util.Optional;
@@ -33,7 +34,7 @@
3334

3435
public class EngineGetPayloadV3 extends AbstractEngineGetPayload {
3536

36-
private final Optional<ScheduledProtocolSpec.Hardfork> cancun;
37+
private final Optional<Long> cancunMilestone;
3738

3839
public EngineGetPayloadV3(
3940
final Vertx vertx,
@@ -49,7 +50,7 @@ public EngineGetPayloadV3(
4950
mergeMiningCoordinator,
5051
blockResultFactory,
5152
engineCallListener);
52-
this.cancun = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun"));
53+
cancunMilestone = schedule.milestoneFor(CANCUN);
5354
}
5455

5556
@Override
@@ -67,17 +68,6 @@ protected JsonRpcResponse createResponse(
6768

6869
@Override
6970
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
70-
if (protocolSchedule.isPresent()) {
71-
if (cancun.isPresent() && blockTimestamp >= cancun.get().milestone()) {
72-
return ValidationResult.valid();
73-
} else {
74-
return ValidationResult.invalid(
75-
RpcErrorType.UNSUPPORTED_FORK,
76-
"Cancun configured to start at timestamp: " + cancun.get().milestone());
77-
}
78-
} else {
79-
return ValidationResult.invalid(
80-
RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Cancun fork set");
81-
}
71+
return ForkSupportHelper.validateForkSupported(CANCUN, cancunMilestone, blockTimestamp);
8272
}
8373
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineGetPayloadV4.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
1616

17+
import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.PRAGUE;
18+
1719
import org.hyperledger.besu.consensus.merge.PayloadWrapper;
1820
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
1921
import org.hyperledger.besu.ethereum.ProtocolContext;
@@ -24,7 +26,6 @@
2426
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.RpcErrorType;
2527
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.BlockResultFactory;
2628
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
27-
import org.hyperledger.besu.ethereum.mainnet.ScheduledProtocolSpec;
2829
import org.hyperledger.besu.ethereum.mainnet.ValidationResult;
2930

3031
import java.util.Optional;
@@ -33,7 +34,7 @@
3334

3435
public class EngineGetPayloadV4 extends AbstractEngineGetPayload {
3536

36-
private final Optional<ScheduledProtocolSpec.Hardfork> prague;
37+
private final Optional<Long> pragueMilestone;
3738

3839
public EngineGetPayloadV4(
3940
final Vertx vertx,
@@ -49,7 +50,7 @@ public EngineGetPayloadV4(
4950
mergeMiningCoordinator,
5051
blockResultFactory,
5152
engineCallListener);
52-
this.prague = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Prague"));
53+
pragueMilestone = schedule.milestoneFor(PRAGUE);
5354
}
5455

5556
@Override
@@ -67,17 +68,6 @@ protected JsonRpcResponse createResponse(
6768

6869
@Override
6970
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
70-
if (protocolSchedule.isPresent()) {
71-
if (prague.isPresent() && blockTimestamp >= prague.get().milestone()) {
72-
return ValidationResult.valid();
73-
} else {
74-
return ValidationResult.invalid(
75-
RpcErrorType.UNSUPPORTED_FORK,
76-
"Prague configured to start at timestamp: " + prague.get().milestone());
77-
}
78-
} else {
79-
return ValidationResult.invalid(
80-
RpcErrorType.UNSUPPORTED_FORK, "Configuration error, no schedule for Prague fork set");
81-
}
71+
return ForkSupportHelper.validateForkSupported(PRAGUE, pragueMilestone, blockTimestamp);
8272
}
8373
}

ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/engine/EngineNewPayloadV2.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.methods.engine;
1616

17+
import static org.hyperledger.besu.ethereum.mainnet.HardforkId.MainnetHardforkId.CANCUN;
18+
1719
import org.hyperledger.besu.consensus.merge.blockcreation.MergeMiningCoordinator;
1820
import org.hyperledger.besu.datatypes.VersionedHash;
1921
import org.hyperledger.besu.ethereum.ProtocolContext;
@@ -33,6 +35,7 @@
3335
import io.vertx.core.Vertx;
3436

3537
public class EngineNewPayloadV2 extends AbstractEngineNewPayload {
38+
private final Optional<Long> cancunMilestone;
3639

3740
public EngineNewPayloadV2(
3841
final Vertx vertx,
@@ -42,6 +45,7 @@ public EngineNewPayloadV2(
4245
final EthPeers ethPeers,
4346
final EngineCallListener engineCallListener) {
4447
super(vertx, protocolSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener);
48+
cancunMilestone = protocolSchedule.milestoneFor(CANCUN);
4549
}
4650

4751
@Override
@@ -74,4 +78,13 @@ protected ValidationResult<RpcErrorType> validateBlobs(
7478
final ProtocolSpec protocolSpec) {
7579
return ValidationResult.valid();
7680
}
81+
82+
@Override
83+
protected ValidationResult<RpcErrorType> validateForkSupported(final long blockTimestamp) {
84+
if (cancunMilestone.isPresent() && blockTimestamp >= cancunMilestone.get()) {
85+
return ValidationResult.invalid(RpcErrorType.UNSUPPORTED_FORK);
86+
}
87+
88+
return ValidationResult.valid();
89+
}
7790
}

0 commit comments

Comments
 (0)