discovery+lnwire: remove embedding within ReplyChannelRange
In order to prep for allowing TLV extensions for the `ReplyChannelRange` and `QueryChannelRange` messages, we'll need to remove the struct embedding as is. If we don't remove this, then we'll attempt to decode TLV extensions from both the embedded and outer struct. All relevant call sites have been updated to reflect this minor change.
This commit is contained in:
parent
466c079bbe
commit
dd6f0ba931
@ -629,8 +629,10 @@ func assertTransitionToChansSynced(t *testing.T, s *GossipSyncer, peer *mockPeer
|
|||||||
}, time.Second, 500*time.Millisecond)
|
}, time.Second, 500*time.Millisecond)
|
||||||
|
|
||||||
require.NoError(t, s.ProcessQueryMsg(&lnwire.ReplyChannelRange{
|
require.NoError(t, s.ProcessQueryMsg(&lnwire.ReplyChannelRange{
|
||||||
QueryChannelRange: *query,
|
ChainHash: query.ChainHash,
|
||||||
Complete: 1,
|
FirstBlockHeight: query.FirstBlockHeight,
|
||||||
|
NumBlocks: query.NumBlocks,
|
||||||
|
Complete: 1,
|
||||||
}, nil))
|
}, nil))
|
||||||
|
|
||||||
chanSeries := s.cfg.channelSeries.(*mockChannelGraphTimeSeries)
|
chanSeries := s.cfg.channelSeries.(*mockChannelGraphTimeSeries)
|
||||||
|
@ -753,7 +753,9 @@ func (g *GossipSyncer) synchronizeChanIDs() (bool, error) {
|
|||||||
func isLegacyReplyChannelRange(query *lnwire.QueryChannelRange,
|
func isLegacyReplyChannelRange(query *lnwire.QueryChannelRange,
|
||||||
reply *lnwire.ReplyChannelRange) bool {
|
reply *lnwire.ReplyChannelRange) bool {
|
||||||
|
|
||||||
return reply.QueryChannelRange == *query
|
return (reply.ChainHash == query.ChainHash &&
|
||||||
|
reply.FirstBlockHeight == query.FirstBlockHeight &&
|
||||||
|
reply.NumBlocks == query.NumBlocks)
|
||||||
}
|
}
|
||||||
|
|
||||||
// processChanRangeReply is called each time the GossipSyncer receives a new
|
// processChanRangeReply is called each time the GossipSyncer receives a new
|
||||||
@ -773,7 +775,7 @@ func (g *GossipSyncer) processChanRangeReply(msg *lnwire.ReplyChannelRange) erro
|
|||||||
// The last block should also be. We don't need to check the
|
// The last block should also be. We don't need to check the
|
||||||
// intermediate ones because they should already be in sorted
|
// intermediate ones because they should already be in sorted
|
||||||
// order.
|
// order.
|
||||||
replyLastHeight := msg.QueryChannelRange.LastBlockHeight()
|
replyLastHeight := msg.LastBlockHeight()
|
||||||
queryLastHeight := g.curQueryRangeMsg.LastBlockHeight()
|
queryLastHeight := g.curQueryRangeMsg.LastBlockHeight()
|
||||||
if replyLastHeight > queryLastHeight {
|
if replyLastHeight > queryLastHeight {
|
||||||
return fmt.Errorf("reply includes channels for height "+
|
return fmt.Errorf("reply includes channels for height "+
|
||||||
@ -832,7 +834,7 @@ func (g *GossipSyncer) processChanRangeReply(msg *lnwire.ReplyChannelRange) erro
|
|||||||
|
|
||||||
// Otherwise, we'll look at the reply's height range.
|
// Otherwise, we'll look at the reply's height range.
|
||||||
default:
|
default:
|
||||||
replyLastHeight := msg.QueryChannelRange.LastBlockHeight()
|
replyLastHeight := msg.LastBlockHeight()
|
||||||
queryLastHeight := g.curQueryRangeMsg.LastBlockHeight()
|
queryLastHeight := g.curQueryRangeMsg.LastBlockHeight()
|
||||||
|
|
||||||
// TODO(wilmer): This might require some padding if the remote
|
// TODO(wilmer): This might require some padding if the remote
|
||||||
@ -997,10 +999,12 @@ func (g *GossipSyncer) replyChanRangeQuery(query *lnwire.QueryChannelRange) erro
|
|||||||
g.cfg.chainHash)
|
g.cfg.chainHash)
|
||||||
|
|
||||||
return g.cfg.sendToPeerSync(&lnwire.ReplyChannelRange{
|
return g.cfg.sendToPeerSync(&lnwire.ReplyChannelRange{
|
||||||
QueryChannelRange: *query,
|
ChainHash: query.ChainHash,
|
||||||
Complete: 0,
|
FirstBlockHeight: query.FirstBlockHeight,
|
||||||
EncodingType: g.cfg.encodingType,
|
NumBlocks: query.NumBlocks,
|
||||||
ShortChanIDs: nil,
|
Complete: 0,
|
||||||
|
EncodingType: g.cfg.encodingType,
|
||||||
|
ShortChanIDs: nil,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1040,14 +1044,12 @@ func (g *GossipSyncer) replyChanRangeQuery(query *lnwire.QueryChannelRange) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
return g.cfg.sendToPeerSync(&lnwire.ReplyChannelRange{
|
return g.cfg.sendToPeerSync(&lnwire.ReplyChannelRange{
|
||||||
QueryChannelRange: lnwire.QueryChannelRange{
|
ChainHash: query.ChainHash,
|
||||||
ChainHash: query.ChainHash,
|
NumBlocks: numBlocks,
|
||||||
NumBlocks: numBlocks,
|
FirstBlockHeight: firstHeight,
|
||||||
FirstBlockHeight: firstHeight,
|
Complete: complete,
|
||||||
},
|
EncodingType: g.cfg.encodingType,
|
||||||
Complete: complete,
|
ShortChanIDs: channelChunk,
|
||||||
EncodingType: g.cfg.encodingType,
|
|
||||||
ShortChanIDs: channelChunk,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,10 +609,9 @@ func TestGossipSyncerQueryChannelRangeWrongChainHash(t *testing.T) {
|
|||||||
t.Fatalf("expected lnwire.ReplyChannelRange, got %T", msg)
|
t.Fatalf("expected lnwire.ReplyChannelRange, got %T", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.QueryChannelRange != *query {
|
if msg.ChainHash != query.ChainHash {
|
||||||
t.Fatalf("wrong query channel range in reply: "+
|
t.Fatalf("wrong chain hash: expected %v got %v",
|
||||||
"expected: %v\ngot: %v", spew.Sdump(*query),
|
query.ChainHash, msg.ChainHash)
|
||||||
spew.Sdump(msg.QueryChannelRange))
|
|
||||||
}
|
}
|
||||||
if msg.Complete != 0 {
|
if msg.Complete != 0 {
|
||||||
t.Fatalf("expected complete set to 0, got %v",
|
t.Fatalf("expected complete set to 0, got %v",
|
||||||
@ -1227,34 +1226,13 @@ func testGossipSyncerProcessChanRangeReply(t *testing.T, legacy bool) {
|
|||||||
t.Fatalf("unable to generate channel range query: %v", err)
|
t.Fatalf("unable to generate channel range query: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var replyQueries []*lnwire.QueryChannelRange
|
// When interpreting block ranges, the first reply should start from
|
||||||
if legacy {
|
// our requested first block, and the last should end at our requested
|
||||||
// Each reply query is the same as the original query in the
|
// last block.
|
||||||
// legacy mode.
|
|
||||||
replyQueries = []*lnwire.QueryChannelRange{query, query, query}
|
|
||||||
} else {
|
|
||||||
// When interpreting block ranges, the first reply should start
|
|
||||||
// from our requested first block, and the last should end at
|
|
||||||
// our requested last block.
|
|
||||||
replyQueries = []*lnwire.QueryChannelRange{
|
|
||||||
{
|
|
||||||
FirstBlockHeight: 0,
|
|
||||||
NumBlocks: 11,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
FirstBlockHeight: 11,
|
|
||||||
NumBlocks: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
FirstBlockHeight: 12,
|
|
||||||
NumBlocks: query.NumBlocks - 12,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
replies := []*lnwire.ReplyChannelRange{
|
replies := []*lnwire.ReplyChannelRange{
|
||||||
{
|
{
|
||||||
QueryChannelRange: *replyQueries[0],
|
FirstBlockHeight: 0,
|
||||||
|
NumBlocks: 11,
|
||||||
ShortChanIDs: []lnwire.ShortChannelID{
|
ShortChanIDs: []lnwire.ShortChannelID{
|
||||||
{
|
{
|
||||||
BlockHeight: 10,
|
BlockHeight: 10,
|
||||||
@ -1262,7 +1240,8 @@ func testGossipSyncerProcessChanRangeReply(t *testing.T, legacy bool) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
QueryChannelRange: *replyQueries[1],
|
FirstBlockHeight: 11,
|
||||||
|
NumBlocks: 1,
|
||||||
ShortChanIDs: []lnwire.ShortChannelID{
|
ShortChanIDs: []lnwire.ShortChannelID{
|
||||||
{
|
{
|
||||||
BlockHeight: 11,
|
BlockHeight: 11,
|
||||||
@ -1270,8 +1249,9 @@ func testGossipSyncerProcessChanRangeReply(t *testing.T, legacy bool) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
QueryChannelRange: *replyQueries[2],
|
FirstBlockHeight: 12,
|
||||||
Complete: 1,
|
NumBlocks: query.NumBlocks - 12,
|
||||||
|
Complete: 1,
|
||||||
ShortChanIDs: []lnwire.ShortChannelID{
|
ShortChanIDs: []lnwire.ShortChannelID{
|
||||||
{
|
{
|
||||||
BlockHeight: 12,
|
BlockHeight: 12,
|
||||||
@ -1280,6 +1260,19 @@ func testGossipSyncerProcessChanRangeReply(t *testing.T, legacy bool) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Each reply query is the same as the original query in the legacy
|
||||||
|
// mode.
|
||||||
|
if legacy {
|
||||||
|
replies[0].FirstBlockHeight = query.FirstBlockHeight
|
||||||
|
replies[0].NumBlocks = query.NumBlocks
|
||||||
|
|
||||||
|
replies[1].FirstBlockHeight = query.FirstBlockHeight
|
||||||
|
replies[1].NumBlocks = query.NumBlocks
|
||||||
|
|
||||||
|
replies[2].FirstBlockHeight = query.FirstBlockHeight
|
||||||
|
replies[2].NumBlocks = query.NumBlocks
|
||||||
|
}
|
||||||
|
|
||||||
// We'll begin by sending the syncer a set of non-complete channel
|
// We'll begin by sending the syncer a set of non-complete channel
|
||||||
// range replies.
|
// range replies.
|
||||||
if err := syncer.processChanRangeReply(replies[0]); err != nil {
|
if err := syncer.processChanRangeReply(replies[0]); err != nil {
|
||||||
@ -2377,7 +2370,9 @@ func TestGossipSyncerMaxChannelRangeReplies(t *testing.T) {
|
|||||||
// order to transition the syncer's state.
|
// order to transition the syncer's state.
|
||||||
for i := uint32(0); i < syncer.cfg.maxQueryChanRangeReplies; i++ {
|
for i := uint32(0); i < syncer.cfg.maxQueryChanRangeReplies; i++ {
|
||||||
reply := &lnwire.ReplyChannelRange{
|
reply := &lnwire.ReplyChannelRange{
|
||||||
QueryChannelRange: *query,
|
ChainHash: query.ChainHash,
|
||||||
|
FirstBlockHeight: query.FirstBlockHeight,
|
||||||
|
NumBlocks: query.NumBlocks,
|
||||||
ShortChanIDs: []lnwire.ShortChannelID{
|
ShortChanIDs: []lnwire.ShortChannelID{
|
||||||
{
|
{
|
||||||
BlockHeight: query.FirstBlockHeight + i,
|
BlockHeight: query.FirstBlockHeight + i,
|
||||||
@ -2408,7 +2403,9 @@ func TestGossipSyncerMaxChannelRangeReplies(t *testing.T) {
|
|||||||
// Finally, attempting to process another reply for the same query
|
// Finally, attempting to process another reply for the same query
|
||||||
// should result in an error.
|
// should result in an error.
|
||||||
require.Error(t, syncer.ProcessQueryMsg(&lnwire.ReplyChannelRange{
|
require.Error(t, syncer.ProcessQueryMsg(&lnwire.ReplyChannelRange{
|
||||||
QueryChannelRange: *query,
|
ChainHash: query.ChainHash,
|
||||||
|
FirstBlockHeight: query.FirstBlockHeight,
|
||||||
|
NumBlocks: query.NumBlocks,
|
||||||
ShortChanIDs: []lnwire.ShortChannelID{
|
ShortChanIDs: []lnwire.ShortChannelID{
|
||||||
{
|
{
|
||||||
BlockHeight: query.LastBlockHeight() + 1,
|
BlockHeight: query.LastBlockHeight() + 1,
|
||||||
|
@ -810,10 +810,8 @@ func TestLightningWireProtocol(t *testing.T) {
|
|||||||
},
|
},
|
||||||
MsgReplyChannelRange: func(v []reflect.Value, r *rand.Rand) {
|
MsgReplyChannelRange: func(v []reflect.Value, r *rand.Rand) {
|
||||||
req := ReplyChannelRange{
|
req := ReplyChannelRange{
|
||||||
QueryChannelRange: QueryChannelRange{
|
FirstBlockHeight: uint32(r.Int31()),
|
||||||
FirstBlockHeight: uint32(r.Int31()),
|
NumBlocks: uint32(r.Int31()),
|
||||||
NumBlocks: uint32(r.Int31()),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := rand.Read(req.ChainHash[:]); err != nil {
|
if _, err := rand.Read(req.ChainHash[:]); err != nil {
|
||||||
|
@ -1,14 +1,29 @@
|
|||||||
package lnwire
|
package lnwire
|
||||||
|
|
||||||
import "io"
|
import (
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
|
)
|
||||||
|
|
||||||
// ReplyChannelRange is the response to the QueryChannelRange message. It
|
// ReplyChannelRange is the response to the QueryChannelRange message. It
|
||||||
// includes the original query, and the next streaming chunk of encoded short
|
// includes the original query, and the next streaming chunk of encoded short
|
||||||
// channel ID's as the response. We'll also include a byte that indicates if
|
// channel ID's as the response. We'll also include a byte that indicates if
|
||||||
// this is the last query in the message.
|
// this is the last query in the message.
|
||||||
type ReplyChannelRange struct {
|
type ReplyChannelRange struct {
|
||||||
// QueryChannelRange is the corresponding query to this response.
|
// ChainHash denotes the target chain that we're trying to synchronize
|
||||||
QueryChannelRange
|
// channel graph state for.
|
||||||
|
ChainHash chainhash.Hash
|
||||||
|
|
||||||
|
// FirstBlockHeight is the first block in the query range. The
|
||||||
|
// responder should send all new short channel IDs from this block
|
||||||
|
// until this block plus the specified number of blocks.
|
||||||
|
FirstBlockHeight uint32
|
||||||
|
|
||||||
|
// NumBlocks is the number of blocks beyond the first block that short
|
||||||
|
// channel ID's should be sent for.
|
||||||
|
NumBlocks uint32
|
||||||
|
|
||||||
// Complete denotes if this is the conclusion of the set of streaming
|
// Complete denotes if this is the conclusion of the set of streaming
|
||||||
// responses to the original query.
|
// responses to the original query.
|
||||||
@ -43,17 +58,21 @@ var _ Message = (*ReplyChannelRange)(nil)
|
|||||||
//
|
//
|
||||||
// This is part of the lnwire.Message interface.
|
// This is part of the lnwire.Message interface.
|
||||||
func (c *ReplyChannelRange) Decode(r io.Reader, pver uint32) error {
|
func (c *ReplyChannelRange) Decode(r io.Reader, pver uint32) error {
|
||||||
err := c.QueryChannelRange.Decode(r, pver)
|
err := ReadElements(r,
|
||||||
|
c.ChainHash[:],
|
||||||
|
&c.FirstBlockHeight,
|
||||||
|
&c.NumBlocks,
|
||||||
|
&c.Complete,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ReadElements(r, &c.Complete); err != nil {
|
c.EncodingType, c.ShortChanIDs, err = decodeShortChanIDs(r)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.EncodingType, c.ShortChanIDs, err = decodeShortChanIDs(r)
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,15 +81,22 @@ func (c *ReplyChannelRange) Decode(r io.Reader, pver uint32) error {
|
|||||||
//
|
//
|
||||||
// This is part of the lnwire.Message interface.
|
// This is part of the lnwire.Message interface.
|
||||||
func (c *ReplyChannelRange) Encode(w io.Writer, pver uint32) error {
|
func (c *ReplyChannelRange) Encode(w io.Writer, pver uint32) error {
|
||||||
if err := c.QueryChannelRange.Encode(w, pver); err != nil {
|
err := WriteElements(w,
|
||||||
|
c.ChainHash[:],
|
||||||
|
c.FirstBlockHeight,
|
||||||
|
c.NumBlocks,
|
||||||
|
c.Complete,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := WriteElements(w, c.Complete); err != nil {
|
err = encodeShortChanIDs(w, c.EncodingType, c.ShortChanIDs, c.noSort)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return encodeShortChanIDs(w, c.EncodingType, c.ShortChanIDs, c.noSort)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgType returns the integer uniquely identifying this message type on the
|
// MsgType returns the integer uniquely identifying this message type on the
|
||||||
@ -88,3 +114,14 @@ func (c *ReplyChannelRange) MsgType() MessageType {
|
|||||||
func (c *ReplyChannelRange) MaxPayloadLength(uint32) uint32 {
|
func (c *ReplyChannelRange) MaxPayloadLength(uint32) uint32 {
|
||||||
return MaxMessagePayload
|
return MaxMessagePayload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LastBlockHeight returns the last block height covered by the range of a
|
||||||
|
// QueryChannelRange message.
|
||||||
|
func (c *ReplyChannelRange) LastBlockHeight() uint32 {
|
||||||
|
// Handle overflows by casting to uint64.
|
||||||
|
lastBlockHeight := uint64(c.FirstBlockHeight) + uint64(c.NumBlocks) - 1
|
||||||
|
if lastBlockHeight > math.MaxUint32 {
|
||||||
|
return math.MaxUint32
|
||||||
|
}
|
||||||
|
return uint32(lastBlockHeight)
|
||||||
|
}
|
||||||
|
@ -30,7 +30,7 @@ func TestReplyChannelRangeUnsorted(t *testing.T) {
|
|||||||
var req2 ReplyChannelRange
|
var req2 ReplyChannelRange
|
||||||
err = req2.Decode(bytes.NewReader(b.Bytes()), 0)
|
err = req2.Decode(bytes.NewReader(b.Bytes()), 0)
|
||||||
if _, ok := err.(ErrUnsortedSIDs); !ok {
|
if _, ok := err.(ErrUnsortedSIDs); !ok {
|
||||||
t.Fatalf("expected ErrUnsortedSIDs, got: %T",
|
t.Fatalf("expected ErrUnsortedSIDs, got: %v",
|
||||||
err)
|
err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -67,13 +67,11 @@ func TestReplyChannelRangeEmpty(t *testing.T) {
|
|||||||
test := test
|
test := test
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
req := ReplyChannelRange{
|
req := ReplyChannelRange{
|
||||||
QueryChannelRange: QueryChannelRange{
|
FirstBlockHeight: 1,
|
||||||
FirstBlockHeight: 1,
|
NumBlocks: 2,
|
||||||
NumBlocks: 2,
|
Complete: 1,
|
||||||
},
|
EncodingType: test.encType,
|
||||||
Complete: 1,
|
ShortChanIDs: nil,
|
||||||
EncodingType: test.encType,
|
|
||||||
ShortChanIDs: nil,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First decode the hex string in the test case into a
|
// First decode the hex string in the test case into a
|
||||||
|
Loading…
Reference in New Issue
Block a user