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