multi: start asking for update timestamps in QueryChannelRange

This commit also adds a new `protocol.no-timestamp-query-option` option
to disable the new behaviour.
This commit is contained in:
Elle Mouton 2023-09-20 09:34:21 +02:00
parent 893147d83e
commit a439cc970f
No known key found for this signature in database
GPG Key ID: D7D916376026F177
9 changed files with 72 additions and 11 deletions

View File

@ -261,6 +261,11 @@ type Config struct {
// gossip syncers will be passive.
NumActiveSyncers int
// NoTimestampQueries will prevent the GossipSyncer from querying
// timestamps of announcement messages from the peer and from replying
// to timestamp queries.
NoTimestampQueries bool
// RotateTicker is a ticker responsible for notifying the SyncManager
// when it should rotate its active syncers. A single active syncer with
// a chansSynced state will be exchanged for a passive syncer in order
@ -510,6 +515,7 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper
RotateTicker: cfg.RotateTicker,
HistoricalSyncTicker: cfg.HistoricalSyncTicker,
NumActiveSyncers: cfg.NumActiveSyncers,
NoTimestampQueries: cfg.NoTimestampQueries,
IgnoreHistoricalFilters: cfg.IgnoreHistoricalFilters,
BestHeight: gossiper.latestHeight,
PinnedSyncers: cfg.PinnedSyncers,

View File

@ -73,6 +73,11 @@ type SyncManagerCfg struct {
// gossip syncers will be passive.
NumActiveSyncers int
// NoTimestampQueries will prevent the GossipSyncer from querying
// timestamps of announcement messages from the peer and from responding
// to timestamp queries
NoTimestampQueries bool
// RotateTicker is a ticker responsible for notifying the SyncManager
// when it should rotate its active syncers. A single active syncer with
// a chansSynced state will be exchanged for a passive syncer in order
@ -495,6 +500,7 @@ func (m *SyncManager) createGossipSyncer(peer lnpeer.Peer) *GossipSyncer {
bestHeight: m.cfg.BestHeight,
markGraphSynced: m.markGraphSynced,
maxQueryChanRangeReplies: maxQueryChanRangeReplies,
noTimestampQueryOption: m.cfg.NoTimestampQueries,
})
// Gossip syncers are initialized by default in a PassiveSync type

View File

@ -277,6 +277,7 @@ func TestSyncManagerInitialHistoricalSync(t *testing.T) {
assertMsgSent(t, peer, &lnwire.QueryChannelRange{
FirstBlockHeight: 0,
NumBlocks: latestKnownHeight,
QueryOptions: lnwire.NewTimestampQueryOption(),
})
// The graph should not be considered as synced since the initial
@ -379,6 +380,7 @@ func TestSyncManagerForceHistoricalSync(t *testing.T) {
assertMsgSent(t, peer, &lnwire.QueryChannelRange{
FirstBlockHeight: 0,
NumBlocks: latestKnownHeight,
QueryOptions: lnwire.NewTimestampQueryOption(),
})
// If an additional peer connects, then a historical sync should not be
@ -394,6 +396,7 @@ func TestSyncManagerForceHistoricalSync(t *testing.T) {
assertMsgSent(t, extraPeer, &lnwire.QueryChannelRange{
FirstBlockHeight: 0,
NumBlocks: latestKnownHeight,
QueryOptions: lnwire.NewTimestampQueryOption(),
})
}
@ -415,6 +418,7 @@ func TestSyncManagerGraphSyncedAfterHistoricalSyncReplacement(t *testing.T) {
assertMsgSent(t, peer, &lnwire.QueryChannelRange{
FirstBlockHeight: 0,
NumBlocks: latestKnownHeight,
QueryOptions: lnwire.NewTimestampQueryOption(),
})
// The graph should not be considered as synced since the initial
@ -620,6 +624,7 @@ func assertTransitionToChansSynced(t *testing.T, s *GossipSyncer, peer *mockPeer
query := &lnwire.QueryChannelRange{
FirstBlockHeight: 0,
NumBlocks: latestKnownHeight,
QueryOptions: lnwire.NewTimestampQueryOption(),
}
assertMsgSent(t, peer, query)

View File

@ -271,6 +271,11 @@ type gossipSyncerCfg struct {
// peer.
noReplyQueries bool
// noTimestampQueryOption will prevent the GossipSyncer from querying
// timestamps of announcement messages from the peer, and it will
// prevent it from responding to timestamp queries.
noTimestampQueryOption bool
// ignoreHistoricalFilters will prevent syncers from replying with
// historical data when the remote peer sets a gossip_timestamp_range.
// This prevents ranges with old start times from causing us to dump the
@ -922,7 +927,7 @@ func (g *GossipSyncer) genChanRangeQuery(
case newestChan.BlockHeight <= chanRangeQueryBuffer:
startHeight = 0
default:
startHeight = uint32(newestChan.BlockHeight - chanRangeQueryBuffer)
startHeight = newestChan.BlockHeight - chanRangeQueryBuffer
}
// Determine the number of blocks to request based on our best height.
@ -945,6 +950,11 @@ func (g *GossipSyncer) genChanRangeQuery(
FirstBlockHeight: startHeight,
NumBlocks: numBlocks,
}
if !g.cfg.noTimestampQueryOption {
query.QueryOptions = lnwire.NewTimestampQueryOption()
}
g.curQueryRangeMsg = query
return query, nil

View File

@ -160,23 +160,30 @@ func newTestSyncer(hID lnwire.ShortChannelID,
flags ...bool) (chan []lnwire.Message,
*GossipSyncer, *mockChannelGraphTimeSeries) {
syncChannels := true
replyQueries := true
var (
syncChannels = true
replyQueries = true
timestamps = false
)
if len(flags) > 0 {
syncChannels = flags[0]
}
if len(flags) > 1 {
replyQueries = flags[1]
}
if len(flags) > 2 {
timestamps = flags[2]
}
msgChan := make(chan []lnwire.Message, 20)
cfg := gossipSyncerCfg{
channelSeries: newMockChannelGraphTimeSeries(hID),
encodingType: encodingType,
chunkSize: chunkSize,
batchSize: chunkSize,
noSyncChannels: !syncChannels,
noReplyQueries: !replyQueries,
channelSeries: newMockChannelGraphTimeSeries(hID),
encodingType: encodingType,
chunkSize: chunkSize,
batchSize: chunkSize,
noSyncChannels: !syncChannels,
noReplyQueries: !replyQueries,
noTimestampQueryOption: !timestamps,
sendToPeer: func(msgs ...lnwire.Message) error {
msgChan <- msgs
return nil
@ -2250,7 +2257,7 @@ func TestGossipSyncerHistoricalSync(t *testing.T) {
// historical sync requests in this state.
msgChan, syncer, _ := newTestSyncer(
lnwire.ShortChannelID{BlockHeight: latestKnownHeight},
defaultEncoding, defaultChunkSize,
defaultEncoding, defaultChunkSize, true, true, true,
)
syncer.setSyncType(PassiveSync)
syncer.setSyncState(chansSynced)
@ -2265,6 +2272,7 @@ func TestGossipSyncerHistoricalSync(t *testing.T) {
expectedMsg := &lnwire.QueryChannelRange{
FirstBlockHeight: 0,
NumBlocks: latestKnownHeight,
QueryOptions: lnwire.NewTimestampQueryOption(),
}
select {

View File

@ -46,7 +46,14 @@ type ProtocolOptions struct {
// NoOptionAnySegwit should be set to true if we don't want to use any
// Taproot (and beyond) addresses for co-op closing.
NoOptionAnySegwit bool `long:"no-any-segwit" description:"disallow using any segiwt witness version as a co-op close address"`
NoOptionAnySegwit bool `long:"no-any-segwit" description:"disallow using any segwit witness version as a co-op close address"`
// NoTimestampQueryOption should be set to true if we don't want our
// syncing peers to also send us the timestamps of announcement messages
// when we send them a channel range query. Setting this to true will
// also mean that we won't respond with timestamps if requested by our
// peers.
NoTimestampQueryOption bool `long:"no-timestamp-query-option" description:"do not query syncing peers for announcement timestamps and do not respond with timestamps if requested"`
}
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo
@ -82,3 +89,11 @@ func (l *ProtocolOptions) ZeroConf() bool {
func (l *ProtocolOptions) NoAnySegwit() bool {
return l.NoOptionAnySegwit
}
// NoTimestampsQuery returns true if we should not ask our syncing peers to also
// send us the timestamps of announcement messages when we send them a channel
// range query, and it also means that we will not respond with timestamps if
// requested by our peer.
func (l *ProtocolOptions) NoTimestampsQuery() bool {
return l.NoTimestampQueryOption
}

View File

@ -50,6 +50,13 @@ type ProtocolOptions struct {
// NoOptionAnySegwit should be set to true if we don't want to use any
// Taproot (and beyond) addresses for co-op closing.
NoOptionAnySegwit bool `long:"no-any-segwit" description:"disallow using any segiwt witness version as a co-op close address"`
// NoTimestampQueryOption should be set to true if we don't want our
// syncing peers to also send us the timestamps of announcement messages
// when we send them a channel range query. Setting this to true will
// also mean that we won't respond with timestamps if requested by our
// peers.
NoTimestampQueryOption bool `long:"no-timestamp-query-option" description:"do not query syncing peers for announcement timestamps and do not respond with timestamps if requested"`
}
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo

View File

@ -1272,6 +1272,9 @@
; closing.
; protocol.no-any-segwit=false
; Set to disable querying our peers for the timestamps of announcement
; messages and to disable responding to such queries
; protocol.no-timestamp-query-option=false
; Set to enable support for the experimental taproot channel type.
; protocol.simple-taproot-chans=false

View File

@ -1018,6 +1018,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
RotateTicker: ticker.New(discovery.DefaultSyncerRotationInterval),
HistoricalSyncTicker: ticker.New(cfg.HistoricalSyncInterval),
NumActiveSyncers: cfg.NumGraphSyncPeers,
NoTimestampQueries: cfg.ProtocolOptions.NoTimestampQueryOption, //nolint:lll
MinimumBatchSize: 10,
SubBatchDelay: cfg.Gossip.SubBatchDelay,
IgnoreHistoricalFilters: cfg.IgnoreHistoricalGossipFilters,