discovery: add support for PinnedSyncers

A pinned syncer is an ActiveSyncer that is configured to always remain
active for the lifetime of the connection. Pinned syncers do not count
towards the total NumActiveSyncer count, which are rotated periodically.

This features allows nodes to more tightly synchronize their routing
tables by ensuring they are always receiving gossip from distinguished
subset of peers.
This commit is contained in:
Conner Fromknecht committed 2021-01-29 00:19:47 -08:00
1 parent 9e932f2a64
commit 2f0d56d539
4 files changed
+114 -8

No files matched your search

+45 -5
View File
@@ -7,9 +7,11 @@ import (
"testing"
"time"
"github.com/btcsuite/btcd/btcec"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/ticker"
"github.com/stretchr/testify/require"
)
@@ -18,8 +20,13 @@ import (
func randPeer(t *testing.T, quit chan struct{}) *mockPeer {
t.Helper()
pk := randPubKey(t)
return peerWithPubkey(pk, quit)
}
func peerWithPubkey(pk *btcec.PublicKey, quit chan struct{}) *mockPeer {
return &mockPeer{
pk: randPubKey(t),
pk: pk,
sentMsgs: make(chan lnwire.Message),
quit: quit,
}
@@ -28,6 +35,14 @@ func randPeer(t *testing.T, quit chan struct{}) *mockPeer {
// newTestSyncManager creates a new test SyncManager using mock implementations
// of its dependencies.
func newTestSyncManager(numActiveSyncers int) *SyncManager {
return newPinnedTestSyncManager(numActiveSyncers, nil)
}
// newTestSyncManager creates a new test SyncManager with a set of pinned
// syncers using mock implementations of its dependencies.
func newPinnedTestSyncManager(numActiveSyncers int,
pinnedSyncers PinnedSyncers) *SyncManager {
hID := lnwire.ShortChannelID{BlockHeight: latestKnownHeight}
return newSyncManager(&SyncManagerCfg{
ChanSeries: newMockChannelGraphTimeSeries(hID),
@@ -37,6 +52,7 @@ func newTestSyncManager(numActiveSyncers int) *SyncManager {
BestHeight: func() uint32 {
return latestKnownHeight
},
PinnedSyncers: pinnedSyncers,
})
}
@@ -48,14 +64,38 @@ func TestSyncManagerNumActiveSyncers(t *testing.T) {
// We'll start by creating our test sync manager which will hold up to
// 3 active syncers.
const numActiveSyncers = 3
const numSyncers = numActiveSyncers + 1
const numPinnedSyncers = 3
const numInactiveSyncers = 1
syncMgr := newTestSyncManager(numActiveSyncers)
pinnedSyncers := make(PinnedSyncers)
pinnedPubkeys := make(map[route.Vertex]*btcec.PublicKey)
for i := 0; i < numPinnedSyncers; i++ {
pubkey := randPubKey(t)
vertex := route.NewVertex(pubkey)
pinnedSyncers[vertex] = struct{}{}
pinnedPubkeys[vertex] = pubkey
}
syncMgr := newPinnedTestSyncManager(numActiveSyncers, pinnedSyncers)
syncMgr.Start()
defer syncMgr.Stop()
// First we'll start by adding the pinned syncers. These should
// immediately be assigned PinnedSync.
for _, pubkey := range pinnedPubkeys {
peer := peerWithPubkey(pubkey, syncMgr.quit)
err := syncMgr.InitSyncState(peer)
require.NoError(t, err)
s := assertSyncerExistence(t, syncMgr, peer)
assertSyncerStatus(t, s, chansSynced, PinnedSync)
}
// We'll go ahead and create our syncers. We'll gather the ones which
// should be active and passive to check them later on.
// should be active and passive to check them later on. The pinned peers
// added above should not influence the active syncer count.
for i := 0; i < numActiveSyncers; i++ {
peer := randPeer(t, syncMgr.quit)
err := syncMgr.InitSyncState(peer)
@@ -72,7 +112,7 @@ func TestSyncManagerNumActiveSyncers(t *testing.T) {
assertSyncerStatus(t, s, chansSynced, ActiveSync)
}
for i := 0; i < numSyncers-numActiveSyncers; i++ {
for i := 0; i < numInactiveSyncers; i++ {
peer := randPeer(t, syncMgr.quit)
err := syncMgr.InitSyncState(peer)
require.NoError(t, err)