htlcswitch: cap fee updates to max fee allocation

In this commit, we begin to enforce a maximum channel commitment fee for
channel initiators when attempting to update their commitment fee. Now,
if the new commitment fee happens to exceed their maximum, then a fee
update of the maximum fee allocation will be proposed instead if needed.

A default of up to 50% of the channel initiator's balance is enforced
for the maximum channel commitment fee. It can be modified through the
`--max-channel-fee-allocation` CLI flag.
This commit is contained in:
Wilmer Paulino committed 2019-09-03 16:49:59 -07:00
1 parent 047d5b173c
commit d8dd6b3245
5 files changed
+56 -11

No files matched your search

+20 -4
View File
@@ -4,6 +4,7 @@ import (
"bytes"
"crypto/sha256"
"fmt"
"math"
prand "math/rand"
"sync"
"sync/atomic"
@@ -50,6 +51,11 @@ const (
// DefaultMaxLinkFeeUpdateTimeout represents the maximum interval in
// which a link should propose to update its commitment fee rate.
DefaultMaxLinkFeeUpdateTimeout = 60 * time.Minute
// DefaultMaxLinkFeeAllocation is the highest allocation we'll allow
// a channel's commitment fee to be of its balance. This only applies to
// the initiator of the channel.
DefaultMaxLinkFeeAllocation float64 = 0.5
)
// ForwardingPolicy describes the set of constraints that a given ChannelLink
@@ -250,6 +256,11 @@ type ChannelLinkConfig struct {
// accept for a forwarded HTLC. The value is relative to the current
// block height.
MaxOutgoingCltvExpiry uint32
// MaxFeeAllocation is the highest allocation we'll allow a channel's
// commitment fee to be of its balance. This only applies to the
// initiator of the channel.
MaxFeeAllocation float64
}
// channelLink is the service which drives a channel's commitment update
@@ -995,22 +1006,27 @@ out:
// If we are the initiator, then we'll sample the
// current fee rate to get into the chain within 3
// blocks.
feePerKw, err := l.sampleNetworkFee()
netFee, err := l.sampleNetworkFee()
if err != nil {
log.Errorf("unable to sample network fee: %v", err)
continue
}
// We'll check to see if we should update the fee rate
// based on our current set fee rate.
// based on our current set fee rate. We'll cap the new
// fee rate to our max fee allocation.
commitFee := l.channel.CommitFeeRate()
if !shouldAdjustCommitFee(feePerKw, commitFee) {
maxFee := l.channel.MaxFeeRate(l.cfg.MaxFeeAllocation)
newCommitFee := lnwallet.SatPerKWeight(
math.Min(float64(netFee), float64(maxFee)),
)
if !shouldAdjustCommitFee(newCommitFee, commitFee) {
continue
}
// If we do, then we'll send a new UpdateFee message to
// the remote party, to be locked in with a new update.
if err := l.updateChannelFee(feePerKw); err != nil {
if err := l.updateChannelFee(newCommitFee); err != nil {
log.Errorf("unable to update fee rate: %v", err)
continue
}