Merge remote-tracking branch 'catbref/sync-long-tip' into sync-long-tip

This commit is contained in:
CalDescent 2022-06-16 18:35:16 +01:00
commit 5ed1ec8809
4 changed files with 87 additions and 21 deletions

View File

@ -69,6 +69,7 @@ public class BlockChain {
newBlockSigHeight, newBlockSigHeight,
shareBinFix, shareBinFix,
calcChainWeightTimestamp, calcChainWeightTimestamp,
newConsensusTimestamp,
transactionV5Timestamp, transactionV5Timestamp,
transactionV6Timestamp, transactionV6Timestamp,
disableReferenceTimestamp disableReferenceTimestamp
@ -403,6 +404,10 @@ public class BlockChain {
return this.featureTriggers.get(FeatureTrigger.calcChainWeightTimestamp.name()).longValue(); return this.featureTriggers.get(FeatureTrigger.calcChainWeightTimestamp.name()).longValue();
} }
public long getNewConsensusTimestamp() {
return this.featureTriggers.get(FeatureTrigger.newConsensusTimestamp.name()).longValue();
}
public long getTransactionV5Timestamp() { public long getTransactionV5Timestamp() {
return this.featureTriggers.get(FeatureTrigger.transactionV5Timestamp.name()).longValue(); return this.featureTriggers.get(FeatureTrigger.transactionV5Timestamp.name()).longValue();
} }

View File

@ -715,6 +715,24 @@ public class Controller extends Thread {
return lastMisbehaved != null && lastMisbehaved > NTP.getTime() - MISBEHAVIOUR_COOLOFF; return lastMisbehaved != null && lastMisbehaved > NTP.getTime() - MISBEHAVIOUR_COOLOFF;
}; };
/** True if peer has unknown height or lower height. */
public static final Predicate<Peer> hasShorterBlockchain = peer -> {
BlockData ourLatestBlockData = getInstance().getChainTip();
int ourHeight = ourLatestBlockData.getHeight();
final PeerChainTipData peerChainTipData = peer.getChainTipData();
// Ensure we have chain tip data for this peer
if (peerChainTipData == null)
return true;
// Remove if peer is at a lower height than us
Integer peerHeight = peerChainTipData.getLastHeight();
if (peerHeight == null || peerHeight < ourHeight)
return true;
return false;
};
public static final Predicate<Peer> hasNoRecentBlock = peer -> { public static final Predicate<Peer> hasNoRecentBlock = peer -> {
final Long minLatestBlockTimestamp = getMinimumLatestBlockTimestamp(); final Long minLatestBlockTimestamp = getMinimumLatestBlockTimestamp();
final PeerChainTipData peerChainTipData = peer.getChainTipData(); final PeerChainTipData peerChainTipData = peer.getChainTipData();

View File

@ -199,6 +199,8 @@ public class Synchronizer extends Thread {
if (this.isSynchronizing) if (this.isSynchronizing)
return true; return true;
boolean isNewConsensusActive = NTP.getTime() >= BlockChain.getInstance().getNewConsensusTimestamp();
// Needs a mutable copy of the unmodifiableList // Needs a mutable copy of the unmodifiableList
List<Peer> peers = new ArrayList<>(Network.getInstance().getImmutableHandshakedPeers()); List<Peer> peers = new ArrayList<>(Network.getInstance().getImmutableHandshakedPeers());
@ -227,6 +229,10 @@ public class Synchronizer extends Thread {
if (peers.size() < Settings.getInstance().getMinBlockchainPeers()) if (peers.size() < Settings.getInstance().getMinBlockchainPeers())
return true; return true;
if (isNewConsensusActive)
// Disregard peers with a shorter chain
peers.removeIf(Controller.hasShorterBlockchain);
// Disregard peers that have no block signature or the same block signature as us // Disregard peers that have no block signature or the same block signature as us
peers.removeIf(Controller.hasNoOrSameBlock); peers.removeIf(Controller.hasNoOrSameBlock);
@ -235,11 +241,13 @@ public class Synchronizer extends Thread {
final int peersBeforeComparison = peers.size(); final int peersBeforeComparison = peers.size();
if (isNewConsensusActive) {
// Request recent block summaries from the remaining peers, and locate our common block with each // Request recent block summaries from the remaining peers, and locate our common block with each
Synchronizer.getInstance().findCommonBlocksWithPeers(peers); // Synchronizer.getInstance().findCommonBlocksWithPeers(peers);
// Compare the peers against each other, and against our chain, which will return an updated list excluding those without common blocks // Compare the peers against each other, and against our chain, which will return an updated list excluding those without common blocks
peers = Synchronizer.getInstance().comparePeers(peers); // peers = Synchronizer.getInstance().comparePeers(peers);
}
// We may have added more inferior chain tips when comparing peers, so remove any peers that are currently on those chains // We may have added more inferior chain tips when comparing peers, so remove any peers that are currently on those chains
peers.removeIf(Controller.hasInferiorChainTip); peers.removeIf(Controller.hasInferiorChainTip);
@ -985,8 +993,13 @@ public class Synchronizer extends Thread {
return SynchronizationResult.NOTHING_TO_DO; return SynchronizationResult.NOTHING_TO_DO;
} }
boolean isNewConsensusActive = NTP.getTime() >= BlockChain.getInstance().getNewConsensusTimestamp();
// Unless we're doing a forced sync, we might need to compare blocks after common block // Unless we're doing a forced sync, we might need to compare blocks after common block
if (!force && ourInitialHeight > commonBlockHeight) { boolean isBlockComparisonNeeded = isNewConsensusActive
? ourInitialHeight == peerHeight
: ourInitialHeight > commonBlockHeight;
if (!force && isBlockComparisonNeeded) {
SynchronizationResult chainCompareResult = compareChains(repository, commonBlockData, ourLatestBlockData, peer, peerHeight, peerBlockSummaries); SynchronizationResult chainCompareResult = compareChains(repository, commonBlockData, ourLatestBlockData, peer, peerHeight, peerBlockSummaries);
if (chainCompareResult != SynchronizationResult.OK) if (chainCompareResult != SynchronizationResult.OK)
return chainCompareResult; return chainCompareResult;
@ -1187,6 +1200,34 @@ public class Synchronizer extends Thread {
peerBlockSummaries.addAll(moreBlockSummaries); peerBlockSummaries.addAll(moreBlockSummaries);
} }
boolean isNewConsensusActive = NTP.getTime() >= BlockChain.getInstance().getNewConsensusTimestamp();
if (isNewConsensusActive) {
int parentHeight = ourLatestBlockData.getHeight() - 1;
BlockSummaryData ourLatestBlockSummary = new BlockSummaryData(ourLatestBlockData);
byte[] ourParentBlockSignature = ourLatestBlockData.getReference();
BlockSummaryData peersLatestBlockSummary = peerBlockSummaries.get(peerBlockSummaries.size() - 1);
byte[] peersParentBlockSignature = peerBlockSummaries.size() > 1
? peerBlockSummaries.get(peerBlockSummaries.size() - 1 - 1).getSignature()
: commonBlockSig;
// Populate minter account levels for both lists of block summaries
populateBlockSummariesMinterLevels(repository, Collections.singletonList(ourLatestBlockSummary));
populateBlockSummariesMinterLevels(repository, Collections.singletonList(peersLatestBlockSummary));
BigInteger ourChainWeight = Block.calcBlockWeight(parentHeight, ourParentBlockSignature, ourLatestBlockSummary);
BigInteger peerChainWeight = Block.calcBlockWeight(parentHeight, peersParentBlockSignature, peersLatestBlockSummary);
NumberFormat accurateFormatter = new DecimalFormat("0.################E0");
LOGGER.debug(String.format("Our chain weight: %s, peer's chain weight: %s (higher is better)", accurateFormatter.format(ourChainWeight), accurateFormatter.format(peerChainWeight)));
// If our blockchain has greater weight then don't synchronize with peer
if (ourChainWeight.compareTo(peerChainWeight) >= 0) {
LOGGER.debug(String.format("Not synchronizing with peer %s as we have better blockchain", peer));
return SynchronizationResult.INFERIOR_CHAIN;
}
} else {
// Fetch our corresponding block summaries // Fetch our corresponding block summaries
List<BlockSummaryData> ourBlockSummaries = repository.getBlockRepository().getBlockSummaries(commonBlockHeight + 1, ourLatestBlockData.getHeight()); List<BlockSummaryData> ourBlockSummaries = repository.getBlockRepository().getBlockSummaries(commonBlockHeight + 1, ourLatestBlockData.getHeight());
@ -1210,6 +1251,7 @@ public class Synchronizer extends Thread {
return SynchronizationResult.INFERIOR_CHAIN; return SynchronizationResult.INFERIOR_CHAIN;
} }
} }
}
return SynchronizationResult.OK; return SynchronizationResult.OK;
} }

View File

@ -58,6 +58,7 @@
"newBlockSigHeight": 320000, "newBlockSigHeight": 320000,
"shareBinFix": 399000, "shareBinFix": 399000,
"calcChainWeightTimestamp": 1620579600000, "calcChainWeightTimestamp": 1620579600000,
"newConsensusTimestamp": 9999999999999,
"transactionV5Timestamp": 1642176000000, "transactionV5Timestamp": 1642176000000,
"transactionV6Timestamp": 9999999999999, "transactionV6Timestamp": 9999999999999,
"disableReferenceTimestamp": 1655222400000 "disableReferenceTimestamp": 1655222400000