Browse Source

Fix for "numberSignaturesRequired" calculation error in Synchronizer.syncToPeerChain()

This bug often prevented the correct amount of block signatures (and blocks) from being requested from a peer, when trying to sync to it.

It could result in quite serious consequences, as it would trigger orphaning back to the common block without first requesting all of the necessary blocks from the peer's chain. Rather than applying a complete copy of the peer's chain, it could orphan back to the common block and then only apply a few blocks beyond that, leaving the node in an unexpected state, potentially hundreds of blocks behind the peer's current height, which it then has to try and obtain from other peers.

When there are forks present, this could result in it hopping from chain to chain, each time being unable to fully synchronise with the peer. Given that we currently discard our chain if it is deemed that our latest block isn't "recent", it is very important that nodes are brought up to the latest block when synchronising with a peer, to avoid constantly triggering discards.

The severity of this bug increased when there was a large disparity between the peer's latest block and the common block height, and prevented us from being able to increase MAXIMUM_COMMON_DELTA.
blockminter-updates
CalDescent 4 years ago
parent
commit
e694a51cdd
  1. 4
      src/main/java/org/qortal/controller/Synchronizer.java

4
src/main/java/org/qortal/controller/Synchronizer.java

@ -351,7 +351,9 @@ public class Synchronizer {
List<byte[]> peerBlockSignatures = peerBlockSummaries.stream().map(BlockSummaryData::getSignature).collect(Collectors.toList());
// Fetch remaining block signatures, if needed
int numberSignaturesRequired = peerBlockSignatures.size() - (peerHeight - commonBlockHeight);
int additionalPeerBlocksAfterCommonBlock = peerHeight - commonBlockHeight; // Calculate the total number of additional blocks this peer has beyond the common block
int numberSignaturesRequired = additionalPeerBlocksAfterCommonBlock - peerBlockSignatures.size(); // Subtract the number of signatures that we already have, as we don't need to request them again
if (numberSignaturesRequired > 0) {
byte[] latestPeerSignature = peerBlockSignatures.isEmpty() ? commonBlockSig : peerBlockSignatures.get(peerBlockSignatures.size() - 1);

Loading…
Cancel
Save