From 1c8a6ce20436153bc10bd3c9e4f3ead2812440fe Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 26 Nov 2022 11:52:27 +0000 Subject: [PATCH] When synchronizing, filter out peers that have a recent block with an invalid signer. This avoids the wasted time and consensus confusion causes by syncing and then validation failing. This is significant after the algo has run, as many signers will become invalid. --- .../org/qortal/controller/Controller.java | 22 +++++++++++++++++++ .../org/qortal/controller/Synchronizer.java | 3 +++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index bcd010e8..f2ca853d 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -29,6 +29,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider; +import org.qortal.account.Account; import org.qortal.api.ApiService; import org.qortal.api.DomainMapService; import org.qortal.api.GatewayService; @@ -756,6 +757,27 @@ public class Controller extends Thread { return peer.isAtLeastVersion(minPeerVersion) == false; }; + public static final Predicate hasInvalidSigner = peer -> { + final List peerChainTipSummaries = peer.getChainTipSummaries(); + if (peerChainTipSummaries == null) { + return true; + } + + try (Repository repository = RepositoryManager.getRepository()) { + for (BlockSummaryData blockSummaryData : peerChainTipSummaries) { + if (Account.getRewardShareEffectiveMintingLevel(repository, blockSummaryData.getMinterPublicKey()) == 0) { + return true; + } + } + } catch (DataException e) { + return true; + } + + // We got this far without encountering invalid or missing summaries, nor was an exception thrown, + // so it is safe to assume that all of this peer's recent blocks had a valid signer. + return false; + }; + private long getRandomRepositoryMaintenanceInterval() { final long minInterval = Settings.getInstance().getRepositoryMaintenanceMinInterval(); final long maxInterval = Settings.getInstance().getRepositoryMaintenanceMaxInterval(); diff --git a/src/main/java/org/qortal/controller/Synchronizer.java b/src/main/java/org/qortal/controller/Synchronizer.java index cd9483e9..e3ace9ed 100644 --- a/src/main/java/org/qortal/controller/Synchronizer.java +++ b/src/main/java/org/qortal/controller/Synchronizer.java @@ -247,6 +247,9 @@ public class Synchronizer extends Thread { // Disregard peers that are on the same block as last sync attempt and we didn't like their chain peers.removeIf(Controller.hasInferiorChainTip); + // Disregard peers that have a block with an invalid signer + peers.removeIf(Controller.hasInvalidSigner); + final int peersBeforeComparison = peers.size(); // Request recent block summaries from the remaining peers, and locate our common block with each