From 781c6e5bea78bb9d5c650f5d52e8c5017646d7e9 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Wed, 25 Nov 2020 15:05:36 -0800 Subject: [PATCH] wtclient: add anchor-aware session negotiation and filtering --- watchtower/wtclient/client.go | 17 +++++++++++------ watchtower/wtclient/session_negotiator.go | 13 ++++++++++++- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/watchtower/wtclient/client.go b/watchtower/wtclient/client.go index d0cb4283..36f36d19 100644 --- a/watchtower/wtclient/client.go +++ b/watchtower/wtclient/client.go @@ -41,13 +41,14 @@ const ( DefaultForceQuitDelay = 10 * time.Second ) -var ( - // activeSessionFilter is a filter that ignored any sessions which are - // not active. - activeSessionFilter = func(s *wtdb.ClientSession) bool { - return s.Status == wtdb.CSessionActive +// genActiveSessionFilter generates a filter that selects active sessions that +// also match the desired channel type, either legacy or anchor. +func genActiveSessionFilter(anchor bool) func(*wtdb.ClientSession) bool { + return func(s *wtdb.ClientSession) bool { + return s.Status == wtdb.CSessionActive && + anchor == s.Policy.IsAnchorChannel() } -) +} // RegisteredTower encompasses information about a registered watchtower with // the client. @@ -280,6 +281,8 @@ func New(config *Config) (*TowerClient, error) { // the client. We will use any of these session if their policies match // the current policy of the client, otherwise they will be ignored and // new sessions will be requested. + isAnchorClient := cfg.Policy.IsAnchorChannel() + activeSessionFilter := genActiveSessionFilter(isAnchorClient) candidateSessions, err := getClientSessions( cfg.DB, cfg.SecretKeyRing, nil, activeSessionFilter, ) @@ -1068,6 +1071,8 @@ func (c *TowerClient) handleNewTower(msg *newTowerMsg) error { c.candidateTowers.AddCandidate(tower) // Include all of its corresponding sessions to our set of candidates. + isAnchorClient := c.cfg.Policy.IsAnchorChannel() + activeSessionFilter := genActiveSessionFilter(isAnchorClient) sessions, err := getClientSessions( c.cfg.DB, c.cfg.SecretKeyRing, &tower.ID, activeSessionFilter, ) diff --git a/watchtower/wtclient/session_negotiator.go b/watchtower/wtclient/session_negotiator.go index 67be526d..59ad59f3 100644 --- a/watchtower/wtclient/session_negotiator.go +++ b/watchtower/wtclient/session_negotiator.go @@ -112,8 +112,19 @@ var _ SessionNegotiator = (*sessionNegotiator)(nil) // newSessionNegotiator initializes a fresh sessionNegotiator instance. func newSessionNegotiator(cfg *NegotiatorConfig) *sessionNegotiator { + // Generate the set of features the negitator will present to the tower + // upon connection. For anchor channels, we'll conditionally signal that + // we require support for anchor channels depdening on the requested + // policy. + features := []lnwire.FeatureBit{ + wtwire.AltruistSessionsRequired, + } + if cfg.Policy.IsAnchorChannel() { + features = append(features, wtwire.AnchorCommitRequired) + } + localInit := wtwire.NewInitMessage( - lnwire.NewRawFeatureVector(wtwire.AltruistSessionsRequired), + lnwire.NewRawFeatureVector(features...), cfg.ChainHash, )