forked from Qortal/qortal
Validate blocks in syncToPeerChain() before orphaning
This prevents a valid block candidate being discarded in favour of an invalid one. We can't actually validate a block before orphaning (because it will fail due to various reasons such as already existing transactions, an existing block with the same height, etc) so we will instead just check the signature against the list of known invalid blocks.
This commit is contained in:
parent
8a7446fb40
commit
47a34c2f54
@ -343,7 +343,7 @@ public class Synchronizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ignore this peer if it holds an invalid block
|
// Ignore this peer if it holds an invalid block
|
||||||
if (this.containsInvalidBlock(peer.getCommonBlockData().getBlockSummariesAfterCommonBlock())) {
|
if (this.containsInvalidBlockSummary(peer.getCommonBlockData().getBlockSummariesAfterCommonBlock())) {
|
||||||
LOGGER.debug("Ignoring peer %s because it holds an invalid block", peer);
|
LOGGER.debug("Ignoring peer %s because it holds an invalid block", peer);
|
||||||
peers.remove(peer);
|
peers.remove(peer);
|
||||||
}
|
}
|
||||||
@ -503,7 +503,7 @@ public class Synchronizer {
|
|||||||
}
|
}
|
||||||
invalidBlockSignatures.add(signature);
|
invalidBlockSignatures.add(signature);
|
||||||
}
|
}
|
||||||
private boolean containsInvalidBlock(List<BlockSummaryData> blockSummaries) {
|
private boolean containsInvalidBlockSummary(List<BlockSummaryData> blockSummaries) {
|
||||||
if (blockSummaries == null || invalidBlockSignatures == null) {
|
if (blockSummaries == null || invalidBlockSignatures == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -519,6 +519,21 @@ public class Synchronizer {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
private boolean containsInvalidBlockSignature(List<byte[]> blockSignatures) {
|
||||||
|
if (blockSignatures == null || invalidBlockSignatures == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through supplied block signatures and check each one against our known invalid blocks
|
||||||
|
for (byte[] signature : blockSignatures) {
|
||||||
|
for (byte[] invalidSignature : invalidBlockSignatures) {
|
||||||
|
if (Arrays.equals(signature, invalidSignature)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -920,6 +935,12 @@ public class Synchronizer {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Catch a block with an invalid signature before orphaning, so that we retain our existing valid candidate
|
||||||
|
if (this.containsInvalidBlockSignature(peerBlockSignatures)) {
|
||||||
|
LOGGER.info(String.format("Peer %s sent invalid block signature: %.8s", peer, Base58.encode(latestPeerSignature)));
|
||||||
|
return SynchronizationResult.INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
byte[] nextPeerSignature = peerBlockSignatures.get(0);
|
byte[] nextPeerSignature = peerBlockSignatures.get(0);
|
||||||
int nextHeight = height + 1;
|
int nextHeight = height + 1;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user