fundingmanager: when funding new channels, set a default max htlc

In this commit, we set a default max HTLC value in ChannelUpdates
sent out for newly funded channels. As a result, we also default
to setting `MessageFlags` equal to 1 in each new ChannelUpdate, since
the max HTLC field is an optional field and MessageFlags indicates
the presence of optional fields within the ChannelUpdate.

For a default max HTLC, we choose the maximum msats worth of
HTLCs that can be pending (or in-flight) on our side of the channel.
The reason for this is because the spec specifies that the max
HTLC present in a ChannelUpdate must be less than or equal to
both total channel capacity and the maximum in-flight amount set
by the peer. Since this in-flight value will always be less than
or equal to channel capacity, it is a safe spec-compliant default.

Co-authored-by: Johan T. Halseth <johanth@gmail.com>
This commit is contained in:
Valentine Wallace 2019-01-12 18:59:45 +01:00 committed by Johan T. Halseth
parent 4f9de9bf1d
commit a66a1e113f
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26

@ -2111,11 +2111,18 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
// need to determine the smallest HTLC it deems economically relevant. // need to determine the smallest HTLC it deems economically relevant.
fwdMinHTLC := completeChan.LocalChanCfg.MinHTLC fwdMinHTLC := completeChan.LocalChanCfg.MinHTLC
// We'll obtain the max HTLC value we can forward in our direction, as
// we'll use this value within our ChannelUpdate. This value must be <=
// channel capacity and <= the maximum in-flight msats set by the peer, so
// we default to max in-flight msats as this value will always be <=
// channel capacity.
fwdMaxHTLC := completeChan.LocalChanCfg.MaxPendingAmount
ann, err := f.newChanAnnouncement( ann, err := f.newChanAnnouncement(
f.cfg.IDKey, completeChan.IdentityPub, f.cfg.IDKey, completeChan.IdentityPub,
completeChan.LocalChanCfg.MultiSigKey.PubKey, completeChan.LocalChanCfg.MultiSigKey.PubKey,
completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID, completeChan.RemoteChanCfg.MultiSigKey.PubKey, *shortChanID,
chanID, fwdMinHTLC, chanID, fwdMinHTLC, fwdMaxHTLC,
) )
if err != nil { if err != nil {
return fmt.Errorf("error generating channel "+ return fmt.Errorf("error generating channel "+
@ -2280,13 +2287,20 @@ func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
// HTLC it deems economically relevant. // HTLC it deems economically relevant.
fwdMinHTLC := completeChan.LocalChanCfg.MinHTLC fwdMinHTLC := completeChan.LocalChanCfg.MinHTLC
// We'll obtain the max HTLC value we can forward in our direction, as
// we'll use this value within our ChannelUpdate. This value must be <=
// channel capacity and <= the maximum in-flight msats set by the peer,
// so we default to max in-flight msats as this value will always be <=
// channel capacity.
fwdMaxHTLC := completeChan.LocalChanCfg.MaxPendingAmount
// Create and broadcast the proofs required to make this channel // Create and broadcast the proofs required to make this channel
// public and usable for other nodes for routing. // public and usable for other nodes for routing.
err = f.announceChannel( err = f.announceChannel(
f.cfg.IDKey, completeChan.IdentityPub, f.cfg.IDKey, completeChan.IdentityPub,
completeChan.LocalChanCfg.MultiSigKey.PubKey, completeChan.LocalChanCfg.MultiSigKey.PubKey,
completeChan.RemoteChanCfg.MultiSigKey.PubKey, completeChan.RemoteChanCfg.MultiSigKey.PubKey,
*shortChanID, chanID, fwdMinHTLC, *shortChanID, chanID, fwdMinHTLC, fwdMaxHTLC,
) )
if err != nil { if err != nil {
return fmt.Errorf("channel announcement failed: %v", err) return fmt.Errorf("channel announcement failed: %v", err)
@ -2453,7 +2467,7 @@ type chanAnnouncement struct {
func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey, func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey,
localFundingKey, remoteFundingKey *btcec.PublicKey, localFundingKey, remoteFundingKey *btcec.PublicKey,
shortChanID lnwire.ShortChannelID, chanID lnwire.ChannelID, shortChanID lnwire.ShortChannelID, chanID lnwire.ChannelID,
fwdMinHTLC lnwire.MilliSatoshi) (*chanAnnouncement, error) { fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi) (*chanAnnouncement, error) {
chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash
@ -2498,13 +2512,17 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey,
chanFlags = 1 chanFlags = 1
} }
// Our channel update message flags will signal that we support the
// max_htlc field.
msgFlags := lnwire.ChanUpdateOptionMaxHtlc
// We announce the channel with the default values. Some of // We announce the channel with the default values. Some of
// these values can later be changed by crafting a new ChannelUpdate. // these values can later be changed by crafting a new ChannelUpdate.
chanUpdateAnn := &lnwire.ChannelUpdate{ chanUpdateAnn := &lnwire.ChannelUpdate{
ShortChannelID: shortChanID, ShortChannelID: shortChanID,
ChainHash: chainHash, ChainHash: chainHash,
Timestamp: uint32(time.Now().Unix()), Timestamp: uint32(time.Now().Unix()),
MessageFlags: 0, MessageFlags: msgFlags,
ChannelFlags: chanFlags, ChannelFlags: chanFlags,
TimeLockDelta: uint16(f.cfg.DefaultRoutingPolicy.TimeLockDelta), TimeLockDelta: uint16(f.cfg.DefaultRoutingPolicy.TimeLockDelta),
@ -2512,6 +2530,7 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey,
// to use, as our ChannelUpdate will be used to carry HTLCs // to use, as our ChannelUpdate will be used to carry HTLCs
// towards them. // towards them.
HtlcMinimumMsat: fwdMinHTLC, HtlcMinimumMsat: fwdMinHTLC,
HtlcMaximumMsat: fwdMaxHTLC,
BaseFee: uint32(f.cfg.DefaultRoutingPolicy.BaseFee), BaseFee: uint32(f.cfg.DefaultRoutingPolicy.BaseFee),
FeeRate: uint32(f.cfg.DefaultRoutingPolicy.FeeRate), FeeRate: uint32(f.cfg.DefaultRoutingPolicy.FeeRate),
@ -2590,7 +2609,7 @@ func (f *fundingManager) newChanAnnouncement(localPubKey, remotePubKey,
// finish, either successfully or with an error. // finish, either successfully or with an error.
func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKey, func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKey,
remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID, remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID,
chanID lnwire.ChannelID, fwdMinHTLC lnwire.MilliSatoshi) error { chanID lnwire.ChannelID, fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi) error {
// First, we'll create the batch of announcements to be sent upon // First, we'll create the batch of announcements to be sent upon
// initial channel creation. This includes the channel announcement // initial channel creation. This includes the channel announcement
@ -2598,7 +2617,7 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
// proof needed to fully authenticate the channel. // proof needed to fully authenticate the channel.
ann, err := f.newChanAnnouncement(localIDKey, remoteIDKey, ann, err := f.newChanAnnouncement(localIDKey, remoteIDKey,
localFundingKey, remoteFundingKey, shortChanID, chanID, localFundingKey, remoteFundingKey, shortChanID, chanID,
fwdMinHTLC, fwdMinHTLC, fwdMaxHTLC,
) )
if err != nil { if err != nil {
fndgLog.Errorf("can't generate channel announcement: %v", err) fndgLog.Errorf("can't generate channel announcement: %v", err)