From deb4c2ba112c98d5745c9da3a93d67ddc4482a49 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Tue, 7 Nov 2023 16:18:31 +0200 Subject: [PATCH 1/5] discovery: Filter ChanUpdate2 messages --- discovery/syncer.go | 58 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/discovery/syncer.go b/discovery/syncer.go index a3a2945fa3..7ca3182f31 100644 --- a/discovery/syncer.go +++ b/discovery/syncer.go @@ -15,6 +15,7 @@ import ( "github.com/lightningnetwork/lnd/graph" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/tlv" "golang.org/x/time/rate" ) @@ -1433,14 +1434,25 @@ func (g *GossipSyncer) FilterGossipMsgs(msgs ...msgWithSenders) { endTime := startTime.Add( time.Duration(g.remoteUpdateHorizon.TimestampRange) * time.Second, ) + + var ( + startBlock tlv.RecordT[tlv.TlvType2, uint32] + endBlock tlv.RecordT[tlv.TlvType4, uint32] + ) + startBlock = g.remoteUpdateHorizon.FirstBlockHeight.UnwrapOr(startBlock) + endBlock = g.remoteUpdateHorizon.BlockRange.UnwrapOr(endBlock) g.Unlock() - passesFilter := func(timeStamp uint32) bool { + passesTimestampFilter := func(timeStamp uint32) bool { t := time.Unix(int64(timeStamp), 0) return t.Equal(startTime) || (t.After(startTime) && t.Before(endTime)) } + passesBlockHeightFilter := func(height uint32) bool { + return height >= startBlock.Val && height < endBlock.Val + } + msgsToSend := make([]lnwire.Message, 0, len(msgs)) for _, msg := range msgs { // If the target peer is the peer that sent us this message, @@ -1475,18 +1487,29 @@ func (g *GossipSyncer) FilterGossipMsgs(msgs ...msgWithSenders) { } for _, chanUpdate := range chanUpdates { - update, ok := chanUpdate.(*lnwire.ChannelUpdate1) - if !ok { - log.Errorf("expected "+ - "*lnwire.ChannelUpdate1, "+ - "got: %T", update) + switch update := chanUpdate.(type) { + case *lnwire.ChannelUpdate1: + if passesTimestampFilter( + update.Timestamp, + ) { - continue - } + msgsToSend = append( + msgsToSend, msg, + ) - if passesFilter(update.Timestamp) { - msgsToSend = append(msgsToSend, msg) - break + break + } + case *lnwire.ChannelUpdate2: + if passesBlockHeightFilter( + update.BlockHeight.Val, + ) { + + msgsToSend = append( + msgsToSend, msg, + ) + + break + } } } @@ -1494,17 +1517,24 @@ func (g *GossipSyncer) FilterGossipMsgs(msgs ...msgWithSenders) { msgsToSend = append(msgsToSend, msg) } - // For each channel update, we'll only send if it the timestamp + // For each channel update 1, we'll only send if the timestamp // is between our time range. case *lnwire.ChannelUpdate1: - if passesFilter(msg.Timestamp) { + if passesTimestampFilter(msg.Timestamp) { + msgsToSend = append(msgsToSend, msg) + } + + // For each channel update 2, we'll only send if the block + // height is between our block range. + case *lnwire.ChannelUpdate2: + if passesBlockHeightFilter(msg.BlockHeight.Val) { msgsToSend = append(msgsToSend, msg) } // Similarly, we only send node announcements if the update // timestamp ifs between our set gossip filter time range. case *lnwire.NodeAnnouncement: - if passesFilter(msg.Timestamp) { + if passesTimestampFilter(msg.Timestamp) { msgsToSend = append(msgsToSend, msg) } } From c248f60cbdd0daa96761bc2475e199ba80e9d335 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Tue, 7 Nov 2023 16:21:47 +0200 Subject: [PATCH 2/5] channeldb: Update ChanUpdatesInHorizon So that a start block and end block can also be passed in. --- channeldb/graph.go | 111 +++++++++++++++++++++++++++------------ channeldb/graph_test.go | 5 +- discovery/chan_series.go | 2 +- graph/builder.go | 12 ++++- graph/interfaces.go | 4 +- 5 files changed, 93 insertions(+), 41 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index cfe5484b1e..c8f5524e68 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -2129,7 +2129,7 @@ type ChannelEdge struct { // ChanUpdatesInHorizon returns all the known channel edges which have at least // one edge that has an update timestamp within the specified horizon. func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, - endTime time.Time) ([]ChannelEdge, error) { + endTime time.Time, startBlock, endBlock uint32) ([]ChannelEdge, error) { // To ensure we don't return duplicate ChannelEdges, we'll use an // additional map to keep track of the edges already seen to prevent @@ -2138,50 +2138,30 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, var edgesToCache map[uint64]ChannelEdge var edgesInHorizon []ChannelEdge - c.cacheMu.Lock() - defer c.cacheMu.Unlock() - var hits int - err := kvdb.View(c.db, func(tx kvdb.RTx) error { - edges := tx.ReadBucket(edgeBucket) - if edges == nil { - return ErrGraphNoEdgesFound - } - edgeIndex := edges.NestedReadBucket(edgeIndexBucket) - if edgeIndex == nil { - return ErrGraphNoEdgesFound - } - edgeUpdateIndex := edges.NestedReadBucket(edgeUpdateIndexBucket) + fetchUpdates := func(tx kvdb.RTx, edges, edgeIndex, nodes kvdb.RBucket, + updateIndexBkt []byte, startBytes, endBytes []byte, + chanIDFromKey func([]byte) []byte) error { + + edgeUpdateIndex := edges.NestedReadBucket(updateIndexBkt) if edgeUpdateIndex == nil { return ErrGraphNoEdgesFound } - nodes := tx.ReadBucket(nodeBucket) - if nodes == nil { - return ErrGraphNodesNotFound - } - // We'll now obtain a cursor to perform a range query within // the index to find all channels within the horizon. updateCursor := edgeUpdateIndex.ReadCursor() - var startTimeBytes, endTimeBytes [8 + 8]byte - byteOrder.PutUint64( - startTimeBytes[:8], uint64(startTime.Unix()), - ) - byteOrder.PutUint64( - endTimeBytes[:8], uint64(endTime.Unix()), - ) - // With our start and end times constructed, we'll step through // the index collecting the info and policy of each update of // each channel that has a last update within the time range. - for indexKey, _ := updateCursor.Seek(startTimeBytes[:]); indexKey != nil && - bytes.Compare(indexKey, endTimeBytes[:]) <= 0; indexKey, _ = updateCursor.Next() { + //nolint:lll + for indexKey, _ := updateCursor.Seek(startBytes); indexKey != nil && + bytes.Compare(indexKey, endBytes) <= 0; indexKey, _ = updateCursor.Next() { //nolint:whitespace // We have a new eligible entry, so we'll slice of the // chan ID so we can query it in the DB. - chanID := indexKey[8:] + chanID := chanIDFromKey(indexKey) // If we've already retrieved the info and policies for // this edge, then we can skip it as we don't need to do @@ -2218,16 +2198,15 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, err) } - var ( - node1Bytes = edgeInfo.Node1Bytes() - node2Bytes = edgeInfo.Node2Bytes() - ) + node1Bytes := edgeInfo.Node1Bytes() node1, err := fetchLightningNode(nodes, node1Bytes[:]) if err != nil { return err } + node2Bytes := edgeInfo.Node2Bytes() + node2, err := fetchLightningNode(nodes, node2Bytes[:]) if err != nil { return err @@ -2247,6 +2226,66 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, edgesToCache[chanIDInt] = channel } + return nil + } + + c.cacheMu.Lock() + defer c.cacheMu.Unlock() + + err := kvdb.View(c.db, func(tx kvdb.RTx) error { + edges := tx.ReadBucket(edgeBucket) + if edges == nil { + return ErrGraphNoEdgesFound + } + edgeIndex := edges.NestedReadBucket(edgeIndexBucket) + if edgeIndex == nil { + return ErrGraphNoEdgesFound + } + + nodes := tx.ReadBucket(nodeBucket) + if nodes == nil { + return ErrGraphNodesNotFound + } + + var startTimeBytes, endTimeBytes [8 + 8]byte + byteOrder.PutUint64( + startTimeBytes[:8], uint64(startTime.Unix()), + ) + byteOrder.PutUint64( + endTimeBytes[:8], uint64(endTime.Unix()), + ) + + var noEdgesFound bool + err := fetchUpdates( + tx, edges, edgeIndex, nodes, edgeUpdateIndexBucket, + startTimeBytes[:], endTimeBytes[:], + func(key []byte) []byte { + return key[8:] + }, + ) + if errors.Is(err, ErrGraphNoEdgesFound) { + noEdgesFound = true + } else if err != nil { + return err + } + + var startBlockBytes, endBlockBytes [4 + 8]byte + byteOrder.PutUint32(startTimeBytes[:4], startBlock) + byteOrder.PutUint32(endTimeBytes[:4], endBlock) + + err = fetchUpdates( + tx, edges, edgeIndex, nodes, edgeUpdate2IndexBucket, + startBlockBytes[:], endBlockBytes[:], + func(key []byte) []byte { + return key[4:] + }, + ) + if errors.Is(err, ErrGraphNoEdgesFound) && noEdgesFound { + return err + } else if err != nil { + return err + } + return nil }, func() { edgesSeen = make(map[uint64]struct{}) @@ -3664,7 +3703,9 @@ func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, // otherwise we can use the existing db transaction. var err error if tx == nil { - err = kvdb.View(c.db, fetchNodeFunc, func() { targetNode = nil }) + err = kvdb.View(c.db, fetchNodeFunc, func() { + targetNode = nil + }) } else { err = fetchNodeFunc(tx) } diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index e5f411c88a..94848449c6 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -1671,7 +1671,7 @@ func TestChanUpdatesInHorizon(t *testing.T) { // If we issue an arbitrary query before any channel updates are // inserted in the database, we should get zero results. chanUpdates, err := graph.ChanUpdatesInHorizon( - time.Unix(999, 0), time.Unix(9999, 0), + time.Unix(999, 0), time.Unix(9999, 0), 0, 0, ) require.NoError(t, err, "unable to updates for updates") if len(chanUpdates) != 0 { @@ -1789,7 +1789,7 @@ func TestChanUpdatesInHorizon(t *testing.T) { } for _, queryCase := range queryCases { resp, err := graph.ChanUpdatesInHorizon( - queryCase.start, queryCase.end, + queryCase.start, queryCase.end, 0, 0, ) if err != nil { t.Fatalf("unable to query for updates: %v", err) @@ -2317,6 +2317,7 @@ func TestStressTestChannelGraphAPI(t *testing.T) { fn: func() error { _, err := graph.ChanUpdatesInHorizon( time.Now().Add(-time.Hour), time.Now(), + 0, 0, ) return err diff --git a/discovery/chan_series.go b/discovery/chan_series.go index 93a37f0701..73aed49b4b 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -112,7 +112,7 @@ func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash, // First, we'll query for all the set of channels that have an update // that falls within the specified horizon. chansInHorizon, err := c.graph.ChanUpdatesInHorizon( - startTime, endTime, + startTime, endTime, 0, 0, ) if err != nil { return nil, err diff --git a/graph/builder.go b/graph/builder.go index 107f5a7eeb..94c73d88b5 100644 --- a/graph/builder.go +++ b/graph/builder.go @@ -607,7 +607,17 @@ func (b *Builder) pruneZombieChans() error { startTime := time.Unix(0, 0) endTime := time.Now().Add(-1 * chanExpiry) - oldEdges, err := b.cfg.Graph.ChanUpdatesInHorizon(startTime, endTime) + + startBlock := 0 + _, bestBlock, err := b.cfg.Chain.GetBestBlock() + if err != nil { + return err + } + endBlock := uint32(bestBlock) - uint32(chanExpiry.Hours()*6) + + oldEdges, err := b.cfg.Graph.ChanUpdatesInHorizon( + startTime, endTime, uint32(startBlock), endBlock, + ) if err != nil { return fmt.Errorf("unable to fetch expired channel updates "+ "chans: %v", err) diff --git a/graph/interfaces.go b/graph/interfaces.go index 1eede0a70d..7d6f4e0962 100644 --- a/graph/interfaces.go +++ b/graph/interfaces.go @@ -147,8 +147,8 @@ type DB interface { // ChanUpdatesInHorizon returns all the known channel edges which have // at least one edge that has an update timestamp within the specified // horizon. - ChanUpdatesInHorizon(startTime, endTime time.Time) ( - []channeldb.ChannelEdge, error) + ChanUpdatesInHorizon(startTime, endTime time.Time, startBlock, + endBlock uint32) ([]channeldb.ChannelEdge, error) // DeleteChannelEdges removes edges with the given channel IDs from the // database and marks them as zombies. This ensures that we're unable to From 332cad3c1d62c8950a395d8e04a0ab21490b9e75 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Tue, 7 Nov 2023 16:29:56 +0200 Subject: [PATCH 3/5] discovery: update UpdatesInHorizon --- discovery/chan_series.go | 10 +++++----- discovery/syncer.go | 9 ++++++++- discovery/syncer_test.go | 15 +++++++++------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/discovery/chan_series.go b/discovery/chan_series.go index 73aed49b4b..97ca6383d9 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -29,8 +29,8 @@ type ChannelGraphTimeSeries interface { // update timestamp between the start time and end time. We'll use this // to catch up a remote node to the set of channel updates that they // may have missed out on within the target chain. - UpdatesInHorizon(chain chainhash.Hash, - startTime time.Time, endTime time.Time) ([]lnwire.Message, error) + UpdatesInHorizon(startTime time.Time, endTime time.Time, startBlock, + endBlock uint32) ([]lnwire.Message, error) // FilterKnownChanIDs takes a target chain, and a set of channel ID's, // and returns a filtered set of chan ID's. This filtered set of chan @@ -104,15 +104,15 @@ func (c *ChanSeries) HighestChanID(chain chainhash.Hash) (*lnwire.ShortChannelID // within the target chain. // // NOTE: This is part of the ChannelGraphTimeSeries interface. -func (c *ChanSeries) UpdatesInHorizon(chain chainhash.Hash, - startTime time.Time, endTime time.Time) ([]lnwire.Message, error) { +func (c *ChanSeries) UpdatesInHorizon(startTime, endTime time.Time, startBlock, + endBlock uint32) ([]lnwire.Message, error) { var updates []lnwire.Message // First, we'll query for all the set of channels that have an update // that falls within the specified horizon. chansInHorizon, err := c.graph.ChanUpdatesInHorizon( - startTime, endTime, 0, 0, + startTime, endTime, startBlock, endBlock, ) if err != nil { return nil, err diff --git a/discovery/syncer.go b/discovery/syncer.go index 7ca3182f31..f9c774b956 100644 --- a/discovery/syncer.go +++ b/discovery/syncer.go @@ -1319,6 +1319,13 @@ func (g *GossipSyncer) ApplyGossipFilter(filter *lnwire.GossipTimestampRange) er time.Duration(g.remoteUpdateHorizon.TimestampRange) * time.Second, ) + var ( + startBlock = tlv.ZeroRecordT[tlv.TlvType2, uint32]() + endBlock = tlv.ZeroRecordT[tlv.TlvType4, uint32]() + ) + startBlock = g.remoteUpdateHorizon.FirstBlockHeight.UnwrapOr(startBlock) + endBlock = g.remoteUpdateHorizon.BlockRange.UnwrapOr(endBlock) + g.Unlock() // If requested, don't reply with historical gossip data when the remote @@ -1342,7 +1349,7 @@ func (g *GossipSyncer) ApplyGossipFilter(filter *lnwire.GossipTimestampRange) er // Now that the remote peer has applied their filter, we'll query the // database for all the messages that are beyond this filter. newUpdatestoSend, err := g.cfg.channelSeries.UpdatesInHorizon( - g.cfg.chainHash, startTime, endTime, + startTime, endTime, startBlock.Val, endBlock.Val, ) if err != nil { returnSema() diff --git a/discovery/syncer_test.go b/discovery/syncer_test.go index f176580578..1281dfbe82 100644 --- a/discovery/syncer_test.go +++ b/discovery/syncer_test.go @@ -28,10 +28,12 @@ var ( ) type horizonQuery struct { - chain chainhash.Hash - start time.Time - end time.Time + start time.Time + end time.Time + startBlock uint32 + endBlock uint32 } + type filterRangeReq struct { startHeight, endHeight uint32 } @@ -81,11 +83,12 @@ func newMockChannelGraphTimeSeries( func (m *mockChannelGraphTimeSeries) HighestChanID(chain chainhash.Hash) (*lnwire.ShortChannelID, error) { return &m.highestID, nil } -func (m *mockChannelGraphTimeSeries) UpdatesInHorizon(chain chainhash.Hash, - startTime time.Time, endTime time.Time) ([]lnwire.Message, error) { +func (m *mockChannelGraphTimeSeries) UpdatesInHorizon(startTime time.Time, + endTime time.Time, startBlock, endBlock uint32) ([]lnwire.Message, + error) { m.horizonReq <- horizonQuery{ - chain, startTime, endTime, + startTime, endTime, startBlock, endBlock, } return <-m.horizonResp, nil From 6e8d8e147df25f31b600ee345985e66c1018a786 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Tue, 7 Nov 2023 17:12:31 +0200 Subject: [PATCH 4/5] discovery: start sending block heights in range query --- discovery/syncer.go | 46 +++++++++++++++++++++++++++++++++++++--- discovery/syncer_test.go | 43 +++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/discovery/syncer.go b/discovery/syncer.go index f9c774b956..64bed25e48 100644 --- a/discovery/syncer.go +++ b/discovery/syncer.go @@ -622,8 +622,12 @@ func (g *GossipSyncer) channelGraphSyncer() { if g.localUpdateHorizon == nil && syncType.IsActiveSync() { + startBlock := g.cfg.bestHeight() + blockRange := uint32(math.MaxUint32) + err := g.sendGossipTimestampRange( time.Now(), math.MaxUint32, + &startBlock, &blockRange, ) if err != nil { log.Errorf("Unable to send update "+ @@ -690,12 +694,23 @@ func (g *GossipSyncer) replyHandler() { // sendGossipTimestampRange constructs and sets a GossipTimestampRange for the // syncer and sends it to the remote peer. func (g *GossipSyncer) sendGossipTimestampRange(firstTimestamp time.Time, - timestampRange uint32) error { + timestampRange uint32, firstBlock, blockRange *uint32) error { endTimestamp := firstTimestamp.Add( time.Duration(timestampRange) * time.Second, ) + if firstBlock != nil && blockRange != nil { + log.Infof("GossipSyncer(%x): applying "+ + "gossipFilter(start-time=%v, end-time=%v, "+ + "start-block=%v, block-range=%v)", g.cfg.peerPub[:], + firstTimestamp, endTimestamp, *firstBlock, *blockRange) + } else { + log.Infof("GossipSyncer(%x): applying "+ + "gossipFilter(start-time=%v, end-time=%v", + g.cfg.peerPub[:], firstTimestamp, endTimestamp) + } + log.Infof("GossipSyncer(%x): applying gossipFilter(start=%v, end=%v)", g.cfg.peerPub[:], firstTimestamp, endTimestamp) @@ -705,11 +720,28 @@ func (g *GossipSyncer) sendGossipTimestampRange(firstTimestamp time.Time, TimestampRange: timestampRange, } + if firstBlock != nil { + first := tlv.ZeroRecordT[tlv.TlvType2, uint32]() + first.Val = *firstBlock + + localUpdateHorizon.FirstBlockHeight = tlv.SomeRecordT(first) + } + + if blockRange != nil { + bRange := tlv.ZeroRecordT[tlv.TlvType4, uint32]() + bRange.Val = *blockRange + + localUpdateHorizon.BlockRange = tlv.SomeRecordT(bRange) + } + if err := g.cfg.sendToPeer(localUpdateHorizon); err != nil { return err } - if firstTimestamp == zeroTimestamp && timestampRange == 0 { + noTimeStamps := firstTimestamp == zeroTimestamp && timestampRange == 0 + noBlockHeights := firstBlock == nil && blockRange == nil + + if noTimeStamps && noBlockHeights { g.localUpdateHorizon = nil } else { g.localUpdateHorizon = localUpdateHorizon @@ -1661,6 +1693,8 @@ func (g *GossipSyncer) handleSyncTransition(req *syncTransitionReq) error { var ( firstTimestamp time.Time timestampRange uint32 + firstBlock *uint32 + blockRange *uint32 ) switch req.newSyncType { @@ -1669,6 +1703,10 @@ func (g *GossipSyncer) handleSyncTransition(req *syncTransitionReq) error { case ActiveSync, PinnedSync: firstTimestamp = time.Now() timestampRange = math.MaxUint32 + bestHeight := g.cfg.bestHeight() + firstBlock = &bestHeight + heightRange := uint32(math.MaxUint32) + blockRange = &heightRange // If a PassiveSync transition has been requested, then we should no // longer receive any new updates from the remote peer. We can do this @@ -1683,7 +1721,9 @@ func (g *GossipSyncer) handleSyncTransition(req *syncTransitionReq) error { req.newSyncType) } - err := g.sendGossipTimestampRange(firstTimestamp, timestampRange) + err := g.sendGossipTimestampRange( + firstTimestamp, timestampRange, firstBlock, blockRange, + ) if err != nil { return fmt.Errorf("unable to send local update horizon: %w", err) diff --git a/discovery/syncer_test.go b/discovery/syncer_test.go index 1281dfbe82..8d056aa0f0 100644 --- a/discovery/syncer_test.go +++ b/discovery/syncer_test.go @@ -15,6 +15,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/tlv" "github.com/stretchr/testify/require" ) @@ -2258,12 +2259,26 @@ func TestGossipSyncerSyncTransitions(t *testing.T) { // send out a message that indicates we want // all the updates from here on. firstTimestamp := uint32(time.Now().Unix()) - assertMsgSent( - t, mChan, &lnwire.GossipTimestampRange{ - FirstTimestamp: firstTimestamp, - TimestampRange: math.MaxUint32, - }, - ) + firstBlock := tlv.ZeroRecordT[ + tlv.TlvType2, uint32, + ]() + firstBlock.Val = uint32(latestKnownHeight) + + blockRange := tlv.ZeroRecordT[ + tlv.TlvType4, uint32, + ]() + blockRange.Val = uint32(math.MaxUint32) + + assertMsgSent(t, mChan, &lnwire.GossipTimestampRange{ //nolint:lll + FirstTimestamp: firstTimestamp, + TimestampRange: math.MaxUint32, + FirstBlockHeight: tlv.SomeRecordT( + firstBlock, + ), + BlockRange: tlv.SomeRecordT( + blockRange, + ), + }) // When transitioning from active to passive, we // should expect to see a new local update @@ -2298,10 +2313,26 @@ func TestGossipSyncerSyncTransitions(t *testing.T) { // horizon sent to the remote peer indicating // that it would like to receive any future // updates. + firstBlock := tlv.ZeroRecordT[ + tlv.TlvType2, uint32, + ]() + firstBlock.Val = uint32(latestKnownHeight) + + blockRange := tlv.ZeroRecordT[ + tlv.TlvType4, uint32, + ]() + blockRange.Val = uint32(math.MaxUint32) + firstTimestamp := uint32(time.Now().Unix()) assertMsgSent(t, msgChan, &lnwire.GossipTimestampRange{ FirstTimestamp: firstTimestamp, TimestampRange: math.MaxUint32, + FirstBlockHeight: tlv.SomeRecordT( + firstBlock, + ), + BlockRange: tlv.SomeRecordT( + blockRange, + ), }) syncState := g.syncState() From d95e2f3f6d094291b24eb9d56c86b915c280ac22 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Fri, 23 Aug 2024 14:49:34 +0200 Subject: [PATCH 5/5] docs: update release notes --- docs/release-notes/release-notes-0.19.0.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/release-notes/release-notes-0.19.0.md b/docs/release-notes/release-notes-0.19.0.md index 5feedd25ba..7491df7a31 100644 --- a/docs/release-notes/release-notes-0.19.0.md +++ b/docs/release-notes/release-notes-0.19.0.md @@ -59,6 +59,10 @@ [2](https://github.com/lightningnetwork/lnd/pull/8253). [3](https://github.com/lightningnetwork/lnd/pull/8254). +* Update the [gossip + protocol](https://github.com/lightningnetwork/lnd/pull/8255) to be able to + gossip new Gossip 1.75 messages. + ## Testing ## Database