discovery: cover requested range in ReplyChannelRange messages
In order to properly adhere to the spec, when handling a QueryChannelRange message, we must reply with a series of ReplyChannelRange messages, that when consumed together cover the entirety of the block range requested.
This commit is contained in:
parent
1f781ea431
commit
c7c0853531
@ -825,13 +825,13 @@ func (g *GossipSyncer) replyChanRangeQuery(query *lnwire.QueryChannelRange) erro
|
|||||||
// TODO(roasbeef): means can't send max uint above?
|
// TODO(roasbeef): means can't send max uint above?
|
||||||
// * or make internal 64
|
// * or make internal 64
|
||||||
|
|
||||||
// In the base case (no actual response) the first block and the last
|
// In the base case (no actual response) the first block and last block
|
||||||
// block in the query will be the same. In the loop below, we'll update
|
// will match those of the query. In the loop below, we'll update these
|
||||||
// these two variables incrementally with each chunk to properly
|
// two variables incrementally with each chunk to properly compute the
|
||||||
// compute the starting block for each response and the number of
|
// starting block for each response and the number of blocks in a
|
||||||
// blocks in a response.
|
// response.
|
||||||
firstBlockHeight := query.FirstBlockHeight
|
firstBlockHeight := startBlock
|
||||||
lastBlockHeight := query.FirstBlockHeight
|
lastBlockHeight := endBlock
|
||||||
|
|
||||||
numChannels := int32(len(channelRange))
|
numChannels := int32(len(channelRange))
|
||||||
numChansSent := int32(0)
|
numChansSent := int32(0)
|
||||||
@ -867,8 +867,25 @@ func (g *GossipSyncer) replyChanRangeQuery(query *lnwire.QueryChannelRange) erro
|
|||||||
// update our pointers to the first and last blocks for each
|
// update our pointers to the first and last blocks for each
|
||||||
// response.
|
// response.
|
||||||
if len(channelChunk) > 0 {
|
if len(channelChunk) > 0 {
|
||||||
firstBlockHeight = channelChunk[0].BlockHeight
|
// If this is the first response we'll send, we'll point
|
||||||
lastBlockHeight = channelChunk[len(channelChunk)-1].BlockHeight
|
// the first block to the first block in the query.
|
||||||
|
// Otherwise, we'll continue from the block we left off
|
||||||
|
// at.
|
||||||
|
if numChansSent == 0 {
|
||||||
|
firstBlockHeight = startBlock
|
||||||
|
} else {
|
||||||
|
firstBlockHeight = lastBlockHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is the last response we'll send, we'll point
|
||||||
|
// the last block to the last block of the query.
|
||||||
|
// Otherwise, we'll set it to the height of the last
|
||||||
|
// channel in the chunk.
|
||||||
|
if isFinalChunk {
|
||||||
|
lastBlockHeight = endBlock
|
||||||
|
} else {
|
||||||
|
lastBlockHeight = channelChunk[len(channelChunk)-1].BlockHeight
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The number of blocks contained in this response (the total
|
// The number of blocks contained in this response (the total
|
||||||
|
@ -783,52 +783,55 @@ func TestGossipSyncerReplyChanRangeQuery(t *testing.T) {
|
|||||||
t.Fatalf("expected ReplyChannelRange instead got %T", msg)
|
t.Fatalf("expected ReplyChannelRange instead got %T", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only for the first iteration do we set the offset to
|
// We'll determine the correct values of each field in
|
||||||
// zero as no chunks have been processed yet. For every
|
// each response based on the order that they were sent.
|
||||||
// other iteration, we want to move forward by the
|
var (
|
||||||
// chunkSize (from the staring block height).
|
expectedFirstBlockHeight uint32
|
||||||
offset := 0
|
expectedNumBlocks uint32
|
||||||
if i != 0 {
|
expectedComplete uint8
|
||||||
offset = 1
|
)
|
||||||
}
|
|
||||||
expectedFirstBlockHeight := (i+offset)*2 + startingBlockHeight
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
// If this is not the last chunk, then Complete should
|
// The first reply should range from our starting block
|
||||||
// be set to zero. Otherwise, it should be one.
|
// height until it reaches its maximum capacity of
|
||||||
case i < 2 && rangeResp.Complete != 0:
|
// channels.
|
||||||
t.Fatalf("non-final chunk should have "+
|
case i == 0:
|
||||||
"Complete=0: %v", spew.Sdump(rangeResp))
|
expectedFirstBlockHeight = startingBlockHeight
|
||||||
|
expectedNumBlocks = chunkSize + 1
|
||||||
|
|
||||||
case i < 2 && rangeResp.NumBlocks != chunkSize+1:
|
// The last reply should range starting from the next
|
||||||
t.Fatalf("NumBlocks fields in resp "+
|
// block of our previous reply up until the ending
|
||||||
"incorrect: expected %v got %v",
|
// height of the query. It should also have the Complete
|
||||||
chunkSize+1, rangeResp.NumBlocks)
|
// bit set.
|
||||||
|
case i == numExpectedChunks-1:
|
||||||
|
expectedFirstBlockHeight = respMsgs[len(respMsgs)-1].BlockHeight
|
||||||
|
expectedNumBlocks = endingBlockHeight - expectedFirstBlockHeight + 1
|
||||||
|
expectedComplete = 1
|
||||||
|
|
||||||
case i < 2 && rangeResp.FirstBlockHeight !=
|
// Any intermediate replies should range starting from
|
||||||
uint32(expectedFirstBlockHeight):
|
// the next block of our previous reply up until it
|
||||||
|
// reaches its maximum capacity of channels.
|
||||||
|
default:
|
||||||
|
expectedFirstBlockHeight = respMsgs[len(respMsgs)-1].BlockHeight
|
||||||
|
expectedNumBlocks = 5
|
||||||
|
}
|
||||||
|
|
||||||
t.Fatalf("FirstBlockHeight incorrect: "+
|
switch {
|
||||||
"expected %v got %v",
|
case rangeResp.FirstBlockHeight != expectedFirstBlockHeight:
|
||||||
rangeResp.FirstBlockHeight,
|
t.Fatalf("FirstBlockHeight in resp #%d "+
|
||||||
expectedFirstBlockHeight)
|
"incorrect: expected %v, got %v", i+1,
|
||||||
case i == 2 && rangeResp.Complete != 1:
|
expectedFirstBlockHeight,
|
||||||
t.Fatalf("final chunk should have "+
|
rangeResp.FirstBlockHeight)
|
||||||
"Complete=1: %v", spew.Sdump(rangeResp))
|
|
||||||
|
|
||||||
case i == 2 && rangeResp.NumBlocks != 1:
|
case rangeResp.NumBlocks != expectedNumBlocks:
|
||||||
t.Fatalf("NumBlocks fields in resp "+
|
t.Fatalf("NumBlocks in resp #%d incorrect: "+
|
||||||
"incorrect: expected %v got %v", 1,
|
"expected %v, got %v", i+1,
|
||||||
rangeResp.NumBlocks)
|
expectedNumBlocks, rangeResp.NumBlocks)
|
||||||
|
|
||||||
case i == 2 && rangeResp.FirstBlockHeight !=
|
|
||||||
queryResp[len(queryResp)-1].BlockHeight:
|
|
||||||
|
|
||||||
t.Fatalf("FirstBlockHeight incorrect: "+
|
|
||||||
"expected %v got %v",
|
|
||||||
rangeResp.FirstBlockHeight,
|
|
||||||
queryResp[len(queryResp)-1].BlockHeight)
|
|
||||||
|
|
||||||
|
case rangeResp.Complete != expectedComplete:
|
||||||
|
t.Fatalf("Complete in resp #%d incorrect: "+
|
||||||
|
"expected %v, got %v", i+1,
|
||||||
|
expectedNumBlocks, rangeResp.Complete)
|
||||||
}
|
}
|
||||||
|
|
||||||
respMsgs = append(respMsgs, rangeResp.ShortChanIDs...)
|
respMsgs = append(respMsgs, rangeResp.ShortChanIDs...)
|
||||||
|
Loading…
Reference in New Issue
Block a user