diff --git a/infrastructure/logging/src/main/java/tech/pegasys/teku/infrastructure/logging/StatusLogger.java b/infrastructure/logging/src/main/java/tech/pegasys/teku/infrastructure/logging/StatusLogger.java index b4e21d2e649..194e0b85681 100644 --- a/infrastructure/logging/src/main/java/tech/pegasys/teku/infrastructure/logging/StatusLogger.java +++ b/infrastructure/logging/src/main/java/tech/pegasys/teku/infrastructure/logging/StatusLogger.java @@ -502,6 +502,14 @@ public void warnFlagDeprecation(final String oldFlag, final String newFlag) { Color.YELLOW); } + public void warnIgnoringWeakSubjectivityPeriod() { + log.warn( + print( + "Ignoring weak subjectivity period check (--ignore-weak-subjectivity-period-enabled). Syncing " + + "from outside of the weak subjectivity period is considered UNSAFE.", + Color.YELLOW)); + } + private void logWithColorIfLevelGreaterThanInfo( final Level level, final String msg, final ColorConsolePrinter.Color color) { final boolean useColor = level.compareTo(Level.INFO) < 0; diff --git a/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java b/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java index e6a0cf48c1b..e80f0764336 100644 --- a/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java +++ b/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/BeaconChainController.java @@ -409,17 +409,24 @@ protected SafeFuture initialize() { spec)) .thenCompose( client -> { + if (isAllowSyncOutsideWeakSubjectivityPeriod()) { + STATUS_LOG.warnIgnoringWeakSubjectivityPeriod(); + } + // Setup chain storage this.recentChainData = client; if (recentChainData.isPreGenesis()) { setupInitialState(client); - } else if (beaconConfig - .eth2NetworkConfig() - .getNetworkBoostrapConfig() - .isUsingCustomInitialState()) { - STATUS_LOG.warnInitialStateIgnored(); + return SafeFuture.completedFuture(client); + } else { + if (isUsingCustomInitialState()) { + STATUS_LOG.warnInitialStateIgnored(); + } + if (!isAllowSyncOutsideWeakSubjectivityPeriod()) { + validateWeakSubjectivityPeriod(client); + } + return SafeFuture.completedFuture(client); } - return SafeFuture.completedFuture(client); }) // Init other services .thenRun(this::initAll) @@ -431,6 +438,26 @@ protected SafeFuture initialize() { .thenCompose(__ -> timerService.start()); } + private boolean isUsingCustomInitialState() { + return beaconConfig.eth2NetworkConfig().getNetworkBoostrapConfig().isUsingCustomInitialState(); + } + + private boolean isAllowSyncOutsideWeakSubjectivityPeriod() { + return beaconConfig + .eth2NetworkConfig() + .getNetworkBoostrapConfig() + .isAllowSyncOutsideWeakSubjectivityPeriod(); + } + + private void validateWeakSubjectivityPeriod(final RecentChainData client) { + final AnchorPoint latestFinalizedAnchor = client.getStore().getLatestFinalized(); + final UInt64 currentSlot = getCurrentSlot(client.getGenesisTime()); + final WeakSubjectivityCalculator wsCalculator = + WeakSubjectivityCalculator.create(beaconConfig.weakSubjectivity()); + wsInitializer.validateAnchorIsWithinWeakSubjectivityPeriod( + latestFinalizedAnchor, currentSlot, spec, wsCalculator); + } + public void initAll() { initKeyValueStore(); initExecutionLayer(); @@ -1281,10 +1308,7 @@ protected void setupInitialState(final RecentChainData client) { WeakSubjectivityPeriodCalculator to the WeakSubjectivityInitializer. Otherwise, we pass an Optional.empty(). */ final Optional maybeWsCalculator; - if (beaconConfig - .eth2NetworkConfig() - .getNetworkBoostrapConfig() - .isAllowSyncOutsideWeakSubjectivityPeriod()) { + if (isAllowSyncOutsideWeakSubjectivityPeriod()) { maybeWsCalculator = Optional.empty(); } else { maybeWsCalculator = diff --git a/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializer.java b/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializer.java index 3bc6897a2fd..07074781926 100644 --- a/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializer.java +++ b/services/beaconchain/src/main/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializer.java @@ -139,6 +139,24 @@ public SafeFuture finalizeAndStoreConfig( }); } + public void validateAnchorIsWithinWeakSubjectivityPeriod( + final AnchorPoint initialAnchor, + final UInt64 currentSlot, + final Spec spec, + final WeakSubjectivityCalculator weakSubjectivityCalculator) { + final CheckpointState checkpointState = + CheckpointState.create( + spec, + initialAnchor.getCheckpoint(), + initialAnchor.getBlockSummary(), + initialAnchor.getState()); + if (!weakSubjectivityCalculator.isWithinWeakSubjectivityPeriod(checkpointState, currentSlot)) { + throw new IllegalStateException( + "Cannot sync outside of weak subjectivity period. Consider re-syncing your node using --checkpoint-sync-url or use --ignore-weak-subjectivity-period-enabled to ignore this check."); + } + ; + } + public void validateInitialAnchor( final AnchorPoint initialAnchor, final UInt64 currentSlot, @@ -154,18 +172,9 @@ public void validateInitialAnchor( } maybeWsCalculator.ifPresent( - weakSubjectivityCalculator -> { - final CheckpointState checkpointState = - CheckpointState.create( - spec, - initialAnchor.getCheckpoint(), - initialAnchor.getBlockSummary(), - initialAnchor.getState()); - if (!weakSubjectivityCalculator.isWithinWeakSubjectivityPeriod( - checkpointState, currentSlot)) { - throw new IllegalStateException("Cannot sync outside of weak subjectivity period."); - } - }); + wsCalculator -> + validateAnchorIsWithinWeakSubjectivityPeriod( + initialAnchor, currentSlot, spec, wsCalculator)); if (initialAnchor.isGenesis()) { // Skip extra validations for genesis state diff --git a/services/beaconchain/src/test/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializerTest.java b/services/beaconchain/src/test/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializerTest.java index a7795171490..b61de9d44dc 100644 --- a/services/beaconchain/src/test/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializerTest.java +++ b/services/beaconchain/src/test/java/tech/pegasys/teku/services/beaconchain/WeakSubjectivityInitializerTest.java @@ -274,7 +274,7 @@ public void validateInitialAnchor_withSubjectivityCheck_outOfWeakSubjectivityPer initializer.validateInitialAnchor( anchor, currentSlot, spec, Optional.of(wsCalculator))) .isInstanceOf(IllegalStateException.class) - .hasMessageContaining("Cannot sync outside of weak subjectivity period."); + .hasMessageContaining("Cannot sync outside of weak subjectivity period"); } @Test