Fix for issue in BLOCK_SUMMARIES_V2 when sending an empty array of summaries.

The BLOCK_SUMMARIES message type would differentiate between an empty response and a missing/invalid response. However, in V2, a response with empty summaries would throw a BufferUnderflowException and be treated by the caller as a null message.

This caused problems when trying to find a common block with peers that have diverged by more than 8 blocks. With V1 the caller would know to search back further (e.g. 16 blocks) but in V2 it was treated as "no response" and so the caller would give up instead of increasing the look-back threshold.

This fix will identify BLOCK_SUMMARIES_V2 messages with no content, and return an empty array of block summaries instead of a null message.

Should be enough to recover any stuck nodes, as long as they haven't diverged more than 240 blocks from the main chain.
This commit is contained in:
CalDescent 2022-10-12 08:52:58 +01:00
parent d4aaba2293
commit 7c15d88cbc

View File

@ -68,13 +68,18 @@ public class BlockSummariesV2Message extends Message {
}
public static Message fromByteBuffer(int id, ByteBuffer bytes) {
List<BlockSummaryData> blockSummaries = new ArrayList<>();
// If there are no bytes remaining then we can treat this as an empty array of summaries
if (bytes.remaining() == 0)
return new BlockSummariesV2Message(id, blockSummaries);
int height = bytes.getInt();
// Expecting bytes remaining to be exact multiples of BLOCK_SUMMARY_V2_LENGTH
if (bytes.remaining() % BLOCK_SUMMARY_V2_LENGTH != 0)
throw new BufferUnderflowException();
List<BlockSummaryData> blockSummaries = new ArrayList<>();
while (bytes.hasRemaining()) {
byte[] signature = new byte[BlockTransformer.BLOCK_SIGNATURE_LENGTH];
bytes.get(signature);