From c815821679d7b1ab3985eb11b312f492d74075d9 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Thu, 17 Jan 2019 16:53:43 -0800 Subject: [PATCH 1/2] server: require the DLP bit for all incoming/outgoing connections In this commit, we modify our default local feature bits to require the Data Loss Protection (DLP) feature to be active. Once full Static Channel Backups are implemented, if we connect to a peer that doesn't follow the DLP protocol, then the SCBs are useless, as we may not be able to recover funds. As a result, in prep for full SCB deployment, we'll now ensure that any peer we connect to, knows of the DLP bit. This could be a bit more relaxed and allow _connections_ to non-DLP peers, but reject channel requests to/from them. However, this implementation is much simpler. --- server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.go b/server.go index 7f423e6e..04c62c38 100644 --- a/server.go +++ b/server.go @@ -2368,7 +2368,7 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq, // We'll signal that we understand the data loss protection feature, // and also that we support the new gossip query features. - localFeatures.Set(lnwire.DataLossProtectOptional) + localFeatures.Set(lnwire.DataLossProtectRequired) localFeatures.Set(lnwire.GossipQueriesOptional) // Now that we've established a connection, create a peer, and it to From b7244244ae910a9778a08bc004df77f05b494359 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Fri, 18 Jan 2019 18:30:55 -0800 Subject: [PATCH 2/2] peer: disconnect peers that don't have our required feature bits --- peer.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/peer.go b/peer.go index 62a8d297..7ec8cd0d 100644 --- a/peer.go +++ b/peer.go @@ -958,9 +958,9 @@ func (p *peer) readHandler() { p.Disconnect(err) }) - // Initialize our negotiated gossip sync method before reading - // messages off the wire. When using gossip queries, this ensures - // a gossip syncer is active by the time query messages arrive. + // Initialize our negotiated gossip sync method before reading messages + // off the wire. When using gossip queries, this ensures a gossip + // syncer is active by the time query messages arrive. // // TODO(conner): have peer store gossip syncer directly and bypass // gossiper? @@ -2146,18 +2146,21 @@ func (p *peer) WipeChannel(chanPoint *wire.OutPoint) error { // handleInitMsg handles the incoming init message which contains global and // local features vectors. If feature vectors are incompatible then disconnect. func (p *peer) handleInitMsg(msg *lnwire.Init) error { - p.remoteLocalFeatures = lnwire.NewFeatureVector(msg.LocalFeatures, - lnwire.LocalFeatures) - p.remoteGlobalFeatures = lnwire.NewFeatureVector(msg.GlobalFeatures, - lnwire.GlobalFeatures) + p.remoteLocalFeatures = lnwire.NewFeatureVector( + msg.LocalFeatures, lnwire.LocalFeatures, + ) + p.remoteGlobalFeatures = lnwire.NewFeatureVector( + msg.GlobalFeatures, lnwire.GlobalFeatures, + ) + // Now that we have their features loaded, we'll ensure that they + // didn't set any required bits that we don't know of. unknownLocalFeatures := p.remoteLocalFeatures.UnknownRequiredFeatures() if len(unknownLocalFeatures) > 0 { err := fmt.Errorf("Peer set unknown local feature bits: %v", unknownLocalFeatures) return err } - unknownGlobalFeatures := p.remoteGlobalFeatures.UnknownRequiredFeatures() if len(unknownGlobalFeatures) > 0 { err := fmt.Errorf("Peer set unknown global feature bits: %v", @@ -2165,6 +2168,13 @@ func (p *peer) handleInitMsg(msg *lnwire.Init) error { return err } + // Now that we know we understand their requirements, we'll check to + // see if they don't support anything that we deem to be mandatory. + switch { + case !p.remoteLocalFeatures.HasFeature(lnwire.DataLossProtectRequired): + return fmt.Errorf("data loss protection required") + } + return nil }