diff --git a/fundingmanager.go b/fundingmanager.go index 05acb70a..b6108437 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -1199,6 +1199,18 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { // reservation attempt may be rejected. Note that since we're on the // responding side of a single funder workflow, we don't commit any // funds to the channel ourselves. + // + // Before we init the channel, we'll also check to see if we've + // negotiated the new tweakless commitment format. This is only the + // case if *both* us and the remote peer are signaling the proper + // feature bit. + localTweakless := fmsg.peer.LocalGlobalFeatures().HasFeature( + lnwire.StaticRemoteKeyOptional, + ) + remoteTweakless := fmsg.peer.RemoteGlobalFeatures().HasFeature( + lnwire.StaticRemoteKeyOptional, + ) + tweaklessCommitment := localTweakless && remoteTweakless chainHash := chainhash.Hash(msg.ChainHash) req := &lnwallet.InitFundingReserveMsg{ ChainHash: &chainHash, @@ -1211,6 +1223,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { PushMSat: msg.PushAmount, Flags: msg.ChannelFlags, MinConfs: 1, + Tweakless: tweaklessCommitment, } reservation, err := f.cfg.Wallet.InitChannelReservation(req) @@ -1246,8 +1259,9 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) { } fndgLog.Infof("Requiring %v confirmations for pendingChan(%x): "+ - "amt=%v, push_amt=%v", numConfsReq, fmsg.msg.PendingChannelID, - amt, msg.PushAmount) + "amt=%v, push_amt=%v, tweakless=%v", numConfsReq, + fmsg.msg.PendingChannelID, amt, msg.PushAmount, + tweaklessCommitment) // Generate our required constraints for the remote party. remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt) @@ -2440,7 +2454,7 @@ func (f *fundingManager) handleFundingLocked(fmsg *fundingLockedMsg) { // Launch a defer so we _ensure_ that the channel barrier is properly // closed even if the target peer is no longer online at this point. defer func() { - // Close the active channel barrier signalling the readHandler + // Close the active channel barrier signaling the readHandler // that commitment related modifications to this channel can // now proceed. f.barrierMtx.Lock() @@ -2748,6 +2762,18 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) { // Initialize a funding reservation with the local wallet. If the // wallet doesn't have enough funds to commit to this channel, then the // request will fail, and be aborted. + // + // Before we init the channel, we'll also check to see if we've + // negotiated the new tweakless commitment format. This is only the + // case if *both* us and the remote peer are signaling the proper + // feature bit. + localTweakless := msg.peer.LocalGlobalFeatures().HasFeature( + lnwire.StaticRemoteKeyOptional, + ) + remoteTweakless := msg.peer.RemoteGlobalFeatures().HasFeature( + lnwire.StaticRemoteKeyOptional, + ) + tweaklessCommitment := localTweakless && remoteTweakless req := &lnwallet.InitFundingReserveMsg{ ChainHash: &msg.chainHash, NodeID: peerKey, @@ -2760,6 +2786,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) { PushMSat: msg.pushAmt, Flags: channelFlags, MinConfs: msg.minConfs, + Tweakless: tweaklessCommitment, } reservation, err := f.cfg.Wallet.InitChannelReservation(req) @@ -2828,8 +2855,8 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) { maxValue := f.cfg.RequiredRemoteMaxValue(capacity) maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(capacity) - fndgLog.Infof("Starting funding workflow with %v for pendingID(%x)", - msg.peer.Address(), chanID) + fndgLog.Infof("Starting funding workflow with %v for pendingID(%x), "+ + "tweakless=%v", msg.peer.Address(), chanID, tweaklessCommitment) fundingOpen := lnwire.OpenChannel{ ChainHash: *f.cfg.Wallet.Cfg.NetParams.GenesisHash, diff --git a/lncfg/protocol_legacy_off.go b/lncfg/protocol_legacy_off.go index 6f5660e9..7e1e47d3 100644 --- a/lncfg/protocol_legacy_off.go +++ b/lncfg/protocol_legacy_off.go @@ -14,3 +14,9 @@ type LegacyProtocol struct { func (l *LegacyProtocol) LegacyOnion() bool { return false } + +// LegacyOnion returns true if the old commitment format should be used for new +// funded channels. +func (l *LegacyProtocol) LegacyCommitment() bool { + return false +} diff --git a/lncfg/protocol_legacy_on.go b/lncfg/protocol_legacy_on.go index 52bd9388..d384adc8 100644 --- a/lncfg/protocol_legacy_on.go +++ b/lncfg/protocol_legacy_on.go @@ -10,6 +10,12 @@ type LegacyProtocol struct { // As a result, nodes that include us in the route won't use the new // modern onion framing. Onion bool `long:"onion" description:"force node to not advertise the new modern TLV onion format"` + + // CommitmentTweak guards if we should use the old legacy commitment + // protocol, or the newer variant that doesn't have a tweak for the + // remote party's output in the commitment. If set to true, then we + // won't signal StaticRemoteKeyOptional. + CommitmentTweak bool `long:"committweak" description:"force node to not advertise the new commitment format"` } // LegacyOnion returns true if the old legacy onion format should be used when @@ -18,3 +24,9 @@ type LegacyProtocol struct { func (l *LegacyProtocol) LegacyOnion() bool { return l.Onion } + +// LegacyOnion returns true if the old commitment format should be used for new +// funded channels. +func (l *LegacyProtocol) LegacyCommitment() bool { + return l.CommitmentTweak +} diff --git a/server.go b/server.go index 05d8bed5..e8f0618b 100644 --- a/server.go +++ b/server.go @@ -324,6 +324,12 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, globalFeatures.Set(lnwire.TLVOnionPayloadOptional) } + // Similarly, we default to the new modern commitment format unless the + // legacy commitment config is set to true. + if !cfg.LegacyProtocol.LegacyCommitment() { + globalFeatures.Set(lnwire.StaticRemoteKeyOptional) + } + var serializedPubKey [33]byte copy(serializedPubKey[:], privKey.PubKey().SerializeCompressed()) @@ -388,8 +394,9 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, peerConnectedListeners: make(map[string][]chan<- lnpeer.Peer), peerDisconnectedListeners: make(map[string][]chan<- struct{}), - globalFeatures: lnwire.NewFeatureVector(globalFeatures, - lnwire.GlobalFeatures), + globalFeatures: lnwire.NewFeatureVector( + globalFeatures, lnwire.GlobalFeatures, + ), quit: make(chan struct{}), }