Merge pull request #3785 from Roasbeef/gossip-queries-fix
discovery: properly set FirstBlockHeight and NumBlocks in responses
This commit is contained in:
commit
a7c2b12f5c
@ -824,6 +824,14 @@ func (g *GossipSyncer) replyChanRangeQuery(query *lnwire.QueryChannelRange) erro
|
||||
// TODO(roasbeef): means can't send max uint above?
|
||||
// * or make internal 64
|
||||
|
||||
// In the base case (no actual response) the first block and the last
|
||||
// block in the query will be the same. In the loop below, we'll update
|
||||
// these two variables incrementally with each chunk to properly
|
||||
// compute the starting block for each response and the number of
|
||||
// blocks in a response.
|
||||
firstBlockHeight := query.FirstBlockHeight
|
||||
lastBlockHeight := query.FirstBlockHeight
|
||||
|
||||
numChannels := int32(len(channelRange))
|
||||
numChansSent := int32(0)
|
||||
for {
|
||||
@ -854,13 +862,31 @@ func (g *GossipSyncer) replyChanRangeQuery(query *lnwire.QueryChannelRange) erro
|
||||
"size=%v", g.cfg.peerPub[:], len(channelChunk))
|
||||
}
|
||||
|
||||
// If we have any channels at all to return, then we need to
|
||||
// update our pointers to the first and last blocks for each
|
||||
// response.
|
||||
if len(channelChunk) > 0 {
|
||||
firstBlockHeight = channelChunk[0].BlockHeight
|
||||
lastBlockHeight = channelChunk[len(channelChunk)-1].BlockHeight
|
||||
}
|
||||
|
||||
// The number of blocks contained in this response (the total
|
||||
// span) is the difference between the last channel ID and the
|
||||
// first in the range. We add one as even if all channels
|
||||
// returned are in the same block, we need to count that.
|
||||
numBlocksInResp := lastBlockHeight - firstBlockHeight + 1
|
||||
|
||||
// With our chunk assembled, we'll now send to the remote peer
|
||||
// the current chunk.
|
||||
replyChunk := lnwire.ReplyChannelRange{
|
||||
QueryChannelRange: *query,
|
||||
Complete: 0,
|
||||
EncodingType: g.cfg.encodingType,
|
||||
ShortChanIDs: channelChunk,
|
||||
QueryChannelRange: lnwire.QueryChannelRange{
|
||||
ChainHash: query.ChainHash,
|
||||
NumBlocks: numBlocksInResp,
|
||||
FirstBlockHeight: firstBlockHeight,
|
||||
},
|
||||
Complete: 0,
|
||||
EncodingType: g.cfg.encodingType,
|
||||
ShortChanIDs: channelChunk,
|
||||
}
|
||||
if isFinalChunk {
|
||||
replyChunk.Complete = 1
|
||||
|
@ -709,20 +709,31 @@ func TestGossipSyncerReplyChanRangeQuery(t *testing.T) {
|
||||
|
||||
// Next, we'll craft a query to ask for all the new chan ID's after
|
||||
// block 100.
|
||||
const startingBlockHeight int = 100
|
||||
query := &lnwire.QueryChannelRange{
|
||||
FirstBlockHeight: 100,
|
||||
FirstBlockHeight: uint32(startingBlockHeight),
|
||||
NumBlocks: 50,
|
||||
}
|
||||
|
||||
// We'll then launch a goroutine to reply to the query with a set of 5
|
||||
// responses. This will ensure we get two full chunks, and one partial
|
||||
// chunk.
|
||||
resp := []lnwire.ShortChannelID{
|
||||
lnwire.NewShortChanIDFromInt(1),
|
||||
lnwire.NewShortChanIDFromInt(2),
|
||||
lnwire.NewShortChanIDFromInt(3),
|
||||
lnwire.NewShortChanIDFromInt(4),
|
||||
lnwire.NewShortChanIDFromInt(5),
|
||||
queryResp := []lnwire.ShortChannelID{
|
||||
{
|
||||
BlockHeight: uint32(startingBlockHeight),
|
||||
},
|
||||
{
|
||||
BlockHeight: 102,
|
||||
},
|
||||
{
|
||||
BlockHeight: 104,
|
||||
},
|
||||
{
|
||||
BlockHeight: 106,
|
||||
},
|
||||
{
|
||||
BlockHeight: 108,
|
||||
},
|
||||
}
|
||||
|
||||
errCh := make(chan error, 1)
|
||||
@ -740,7 +751,7 @@ func TestGossipSyncerReplyChanRangeQuery(t *testing.T) {
|
||||
|
||||
// If the proper request was sent, then we'll respond
|
||||
// with our set of short channel ID's.
|
||||
chanSeries.filterRangeResp <- resp
|
||||
chanSeries.filterRangeResp <- queryResp
|
||||
errCh <- nil
|
||||
}
|
||||
}()
|
||||
@ -767,16 +778,52 @@ func TestGossipSyncerReplyChanRangeQuery(t *testing.T) {
|
||||
t.Fatalf("expected ReplyChannelRange instead got %T", msg)
|
||||
}
|
||||
|
||||
// Only for the first iteration do we set the offset to
|
||||
// zero as no chunks have been processed yet. For every
|
||||
// other iteration, we want to move forward by the
|
||||
// chunkSize (from the staring block height).
|
||||
offset := 0
|
||||
if i != 0 {
|
||||
offset = 1
|
||||
}
|
||||
expectedFirstBlockHeight := (i+offset)*2 + startingBlockHeight
|
||||
|
||||
switch {
|
||||
// If this is not the last chunk, then Complete should
|
||||
// be set to zero. Otherwise, it should be one.
|
||||
switch {
|
||||
case i < 2 && rangeResp.Complete != 0:
|
||||
t.Fatalf("non-final chunk should have "+
|
||||
"Complete=0: %v", spew.Sdump(rangeResp))
|
||||
|
||||
case i < 2 && rangeResp.NumBlocks != chunkSize+1:
|
||||
t.Fatalf("NumBlocks fields in resp "+
|
||||
"incorrect: expected %v got %v",
|
||||
chunkSize+1, rangeResp.NumBlocks)
|
||||
|
||||
case i < 2 && rangeResp.FirstBlockHeight !=
|
||||
uint32(expectedFirstBlockHeight):
|
||||
|
||||
t.Fatalf("FirstBlockHeight incorrect: "+
|
||||
"expected %v got %v",
|
||||
rangeResp.FirstBlockHeight,
|
||||
expectedFirstBlockHeight)
|
||||
case i == 2 && rangeResp.Complete != 1:
|
||||
t.Fatalf("final chunk should have "+
|
||||
"Complete=1: %v", spew.Sdump(rangeResp))
|
||||
|
||||
case i == 2 && rangeResp.NumBlocks != 1:
|
||||
t.Fatalf("NumBlocks fields in resp "+
|
||||
"incorrect: expected %v got %v", 1,
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
respMsgs = append(respMsgs, rangeResp.ShortChanIDs...)
|
||||
@ -785,13 +832,13 @@ func TestGossipSyncerReplyChanRangeQuery(t *testing.T) {
|
||||
|
||||
// We should get back exactly 5 short chan ID's, and they should match
|
||||
// exactly the ID's we sent as a reply.
|
||||
if len(respMsgs) != len(resp) {
|
||||
if len(respMsgs) != len(queryResp) {
|
||||
t.Fatalf("expected %v chan ID's, instead got %v",
|
||||
len(resp), spew.Sdump(respMsgs))
|
||||
len(queryResp), spew.Sdump(respMsgs))
|
||||
}
|
||||
if !reflect.DeepEqual(resp, respMsgs) {
|
||||
if !reflect.DeepEqual(queryResp, respMsgs) {
|
||||
t.Fatalf("mismatched response: expected %v, got %v",
|
||||
spew.Sdump(resp), spew.Sdump(respMsgs))
|
||||
spew.Sdump(queryResp), spew.Sdump(respMsgs))
|
||||
}
|
||||
|
||||
// Wait for error from goroutine.
|
||||
|
Loading…
Reference in New Issue
Block a user