lnwallet+size: select HTLC fees based on channel type

This commit is contained in:
Johan T. Halseth 2020-03-06 16:11:49 +01:00
parent ea2a58e80f
commit b7885dbbae
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
4 changed files with 125 additions and 64 deletions

View File

@ -202,6 +202,23 @@ const (
// which will transition an incoming HTLC to the delay-and-claim state. // which will transition an incoming HTLC to the delay-and-claim state.
HtlcSuccessWeight = 703 HtlcSuccessWeight = 703
// HtlcConfirmedScriptOverhead is the extra length of an HTLC script
// that requires confirmation before it can be spent. These extra bytes
// is a result of the extra CSV check.
HtlcConfirmedScriptOverhead = 3
// HtlcTimeoutWeightConfirmed is the weight of the HTLC timeout
// transaction which will transition an outgoing HTLC to the
// delay-and-claim state, for the confirmed HTLC outputs. It is 3 bytes
// larger because of the additional CSV check in the input script.
HtlcTimeoutWeightConfirmed = HtlcTimeoutWeight + HtlcConfirmedScriptOverhead
// HtlcSuccessWeightCOnfirmed is the weight of the HTLC success
// transaction which will transition an incoming HTLC to the
// delay-and-claim state, for the confirmed HTLC outputs. It is 3 bytes
// larger because of the cdditional CSV check in the input script.
HtlcSuccessWeightConfirmed = HtlcSuccessWeight + HtlcConfirmedScriptOverhead
// MaxHTLCNumber is the maximum number HTLCs which can be included in a // MaxHTLCNumber is the maximum number HTLCs which can be included in a
// commitment transaction. This limit was chosen such that, in the case // commitment transaction. This limit was chosen such that, in the case
// of a contract breach, the punishment transaction is able to sweep // of a contract breach, the punishment transaction is able to sweep

View File

@ -596,7 +596,7 @@ func locateOutputIndex(p *PaymentDescriptor, tx *wire.MsgTx, ourCommit bool,
// we need to keep track of the indexes of each HTLC in order to properly write // we need to keep track of the indexes of each HTLC in order to properly write
// the current state to disk, and also to locate the PaymentDescriptor // the current state to disk, and also to locate the PaymentDescriptor
// corresponding to HTLC outputs in the commitment transaction. // corresponding to HTLC outputs in the commitment transaction.
func (c *commitment) populateHtlcIndexes() error { func (c *commitment) populateHtlcIndexes(chanType channeldb.ChannelType) error {
// First, we'll set up some state to allow us to locate the output // First, we'll set up some state to allow us to locate the output
// index of the all the HTLC's within the commitment transaction. We // index of the all the HTLC's within the commitment transaction. We
// must keep this index so we can validate the HTLC signatures sent to // must keep this index so we can validate the HTLC signatures sent to
@ -608,8 +608,10 @@ func (c *commitment) populateHtlcIndexes() error {
// populateIndex is a helper function that populates the necessary // populateIndex is a helper function that populates the necessary
// indexes within the commitment view for a particular HTLC. // indexes within the commitment view for a particular HTLC.
populateIndex := func(htlc *PaymentDescriptor, incoming bool) error { populateIndex := func(htlc *PaymentDescriptor, incoming bool) error {
isDust := htlcIsDust(incoming, c.isOurs, c.feePerKw, isDust := htlcIsDust(
htlc.Amount.ToSatoshis(), c.dustLimit) chanType, incoming, c.isOurs, c.feePerKw,
htlc.Amount.ToSatoshis(), c.dustLimit,
)
var err error var err error
switch { switch {
@ -782,8 +784,10 @@ func (lc *LightningChannel) diskHtlcToPayDesc(feeRate chainfee.SatPerKWeight,
// generate them in order to locate the outputs within the commitment // generate them in order to locate the outputs within the commitment
// transaction. As we'll mark dust with a special output index in the // transaction. As we'll mark dust with a special output index in the
// on-disk state snapshot. // on-disk state snapshot.
isDustLocal := htlcIsDust(htlc.Incoming, true, feeRate, isDustLocal := htlcIsDust(
htlc.Amt.ToSatoshis(), lc.channelState.LocalChanCfg.DustLimit) chanType, htlc.Incoming, true, feeRate,
htlc.Amt.ToSatoshis(), lc.channelState.LocalChanCfg.DustLimit,
)
if !isDustLocal && localCommitKeys != nil { if !isDustLocal && localCommitKeys != nil {
ourP2WSH, ourWitnessScript, err = genHtlcScript( ourP2WSH, ourWitnessScript, err = genHtlcScript(
chanType, htlc.Incoming, true, htlc.RefundTimeout, chanType, htlc.Incoming, true, htlc.RefundTimeout,
@ -793,8 +797,10 @@ func (lc *LightningChannel) diskHtlcToPayDesc(feeRate chainfee.SatPerKWeight,
return pd, err return pd, err
} }
} }
isDustRemote := htlcIsDust(htlc.Incoming, false, feeRate, isDustRemote := htlcIsDust(
htlc.Amt.ToSatoshis(), lc.channelState.RemoteChanCfg.DustLimit) chanType, htlc.Incoming, false, feeRate,
htlc.Amt.ToSatoshis(), lc.channelState.RemoteChanCfg.DustLimit,
)
if !isDustRemote && remoteCommitKeys != nil { if !isDustRemote && remoteCommitKeys != nil {
theirP2WSH, theirWitnessScript, err = genHtlcScript( theirP2WSH, theirWitnessScript, err = genHtlcScript(
chanType, htlc.Incoming, false, htlc.RefundTimeout, chanType, htlc.Incoming, false, htlc.RefundTimeout,
@ -930,7 +936,8 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal bool,
// Finally, we'll re-populate the HTLC index for this state so we can // Finally, we'll re-populate the HTLC index for this state so we can
// properly locate each HTLC within the commitment transaction. // properly locate each HTLC within the commitment transaction.
if err := commit.populateHtlcIndexes(); err != nil { err = commit.populateHtlcIndexes(lc.channelState.ChanType)
if err != nil {
return nil, err return nil, err
} }
@ -1410,8 +1417,10 @@ func (lc *LightningChannel) logUpdateToPayDesc(logUpdate *channeldb.LogUpdate,
pd.OnionBlob = make([]byte, len(wireMsg.OnionBlob)) pd.OnionBlob = make([]byte, len(wireMsg.OnionBlob))
copy(pd.OnionBlob[:], wireMsg.OnionBlob[:]) copy(pd.OnionBlob[:], wireMsg.OnionBlob[:])
isDustRemote := htlcIsDust(false, false, feeRate, isDustRemote := htlcIsDust(
wireMsg.Amount.ToSatoshis(), remoteDustLimit) lc.channelState.ChanType, false, false, feeRate,
wireMsg.Amount.ToSatoshis(), remoteDustLimit,
)
if !isDustRemote { if !isDustRemote {
theirP2WSH, theirWitnessScript, err := genHtlcScript( theirP2WSH, theirWitnessScript, err := genHtlcScript(
lc.channelState.ChanType, false, false, lc.channelState.ChanType, false, false,
@ -2168,7 +2177,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
// If the HTLC is dust, then we'll skip it as it doesn't have // If the HTLC is dust, then we'll skip it as it doesn't have
// an output on the commitment transaction. // an output on the commitment transaction.
if htlcIsDust( if htlcIsDust(
htlc.Incoming, false, chanState.ChanType, htlc.Incoming, false,
chainfee.SatPerKWeight(revokedSnapshot.FeePerKw), chainfee.SatPerKWeight(revokedSnapshot.FeePerKw),
htlc.Amt.ToSatoshis(), chanState.RemoteChanCfg.DustLimit, htlc.Amt.ToSatoshis(), chanState.RemoteChanCfg.DustLimit,
) { ) {
@ -2239,25 +2248,14 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
}, nil }, nil
} }
// htlcTimeoutFee returns the fee in satoshis required for an HTLC timeout
// transaction based on the current fee rate.
func htlcTimeoutFee(feePerKw chainfee.SatPerKWeight) btcutil.Amount {
return feePerKw.FeeForWeight(input.HtlcTimeoutWeight)
}
// htlcSuccessFee returns the fee in satoshis required for an HTLC success
// transaction based on the current fee rate.
func htlcSuccessFee(feePerKw chainfee.SatPerKWeight) btcutil.Amount {
return feePerKw.FeeForWeight(input.HtlcSuccessWeight)
}
// htlcIsDust determines if an HTLC output is dust or not depending on two // htlcIsDust determines if an HTLC output is dust or not depending on two
// bits: if the HTLC is incoming and if the HTLC will be placed on our // bits: if the HTLC is incoming and if the HTLC will be placed on our
// commitment transaction, or theirs. These two pieces of information are // commitment transaction, or theirs. These two pieces of information are
// require as we currently used second-level HTLC transactions as off-chain // require as we currently used second-level HTLC transactions as off-chain
// covenants. Depending on the two bits, we'll either be using a timeout or // covenants. Depending on the two bits, we'll either be using a timeout or
// success transaction which have different weights. // success transaction which have different weights.
func htlcIsDust(incoming, ourCommit bool, feePerKw chainfee.SatPerKWeight, func htlcIsDust(chanType channeldb.ChannelType,
incoming, ourCommit bool, feePerKw chainfee.SatPerKWeight,
htlcAmt, dustLimit btcutil.Amount) bool { htlcAmt, dustLimit btcutil.Amount) bool {
// First we'll determine the fee required for this HTLC based on if this is // First we'll determine the fee required for this HTLC based on if this is
@ -2269,25 +2267,25 @@ func htlcIsDust(incoming, ourCommit bool, feePerKw chainfee.SatPerKWeight,
// If this is an incoming HTLC on our commitment transaction, then the // If this is an incoming HTLC on our commitment transaction, then the
// second-level transaction will be a success transaction. // second-level transaction will be a success transaction.
case incoming && ourCommit: case incoming && ourCommit:
htlcFee = htlcSuccessFee(feePerKw) htlcFee = HtlcSuccessFee(chanType, feePerKw)
// If this is an incoming HTLC on their commitment transaction, then // If this is an incoming HTLC on their commitment transaction, then
// we'll be using a second-level timeout transaction as they've added // we'll be using a second-level timeout transaction as they've added
// this HTLC. // this HTLC.
case incoming && !ourCommit: case incoming && !ourCommit:
htlcFee = htlcTimeoutFee(feePerKw) htlcFee = HtlcTimeoutFee(chanType, feePerKw)
// If this is an outgoing HTLC on our commitment transaction, then // If this is an outgoing HTLC on our commitment transaction, then
// we'll be using a timeout transaction as we're the sender of the // we'll be using a timeout transaction as we're the sender of the
// HTLC. // HTLC.
case !incoming && ourCommit: case !incoming && ourCommit:
htlcFee = htlcTimeoutFee(feePerKw) htlcFee = HtlcTimeoutFee(chanType, feePerKw)
// If this is an outgoing HTLC on their commitment transaction, then // If this is an outgoing HTLC on their commitment transaction, then
// we'll be using an HTLC success transaction as they're the receiver // we'll be using an HTLC success transaction as they're the receiver
// of this HTLC. // of this HTLC.
case !incoming && !ourCommit: case !incoming && !ourCommit:
htlcFee = htlcSuccessFee(feePerKw) htlcFee = HtlcSuccessFee(chanType, feePerKw)
} }
return (htlcAmt - htlcFee) < dustLimit return (htlcAmt - htlcFee) < dustLimit
@ -2431,7 +2429,7 @@ func (lc *LightningChannel) fetchCommitmentView(remoteChain bool,
// Finally, we'll populate all the HTLC indexes so we can track the // Finally, we'll populate all the HTLC indexes so we can track the
// locations of each HTLC in the commitment state. // locations of each HTLC in the commitment state.
if err := c.populateHtlcIndexes(); err != nil { if err := c.populateHtlcIndexes(lc.channelState.ChanType); err != nil {
return nil, err return nil, err
} }
@ -2769,8 +2767,10 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
// dust output after taking into account second-level HTLC fees, then a // dust output after taking into account second-level HTLC fees, then a
// sigJob will be generated and appended to the current batch. // sigJob will be generated and appended to the current batch.
for _, htlc := range remoteCommitView.incomingHTLCs { for _, htlc := range remoteCommitView.incomingHTLCs {
if htlcIsDust(true, false, feePerKw, htlc.Amount.ToSatoshis(), if htlcIsDust(
dustLimit) { chanType, true, false, feePerKw,
htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }
@ -2785,7 +2785,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
// HTLC timeout transaction for them. The output of the timeout // HTLC timeout transaction for them. The output of the timeout
// transaction needs to account for fees, so we'll compute the // transaction needs to account for fees, so we'll compute the
// required fee and output now. // required fee and output now.
htlcFee := htlcTimeoutFee(feePerKw) htlcFee := HtlcTimeoutFee(chanType, feePerKw)
outputAmt := htlc.Amount.ToSatoshis() - htlcFee outputAmt := htlc.Amount.ToSatoshis() - htlcFee
// With the fee calculate, we can properly create the HTLC // With the fee calculate, we can properly create the HTLC
@ -2822,8 +2822,10 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
sigBatch = append(sigBatch, sigJob) sigBatch = append(sigBatch, sigJob)
} }
for _, htlc := range remoteCommitView.outgoingHTLCs { for _, htlc := range remoteCommitView.outgoingHTLCs {
if htlcIsDust(false, false, feePerKw, htlc.Amount.ToSatoshis(), if htlcIsDust(
dustLimit) { chanType, false, false, feePerKw,
htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }
@ -2836,7 +2838,7 @@ func genRemoteHtlcSigJobs(keyRing *CommitmentKeyRing,
// HTLC success transaction for them. The output of the timeout // HTLC success transaction for them. The output of the timeout
// transaction needs to account for fees, so we'll compute the // transaction needs to account for fees, so we'll compute the
// required fee and output now. // required fee and output now.
htlcFee := htlcSuccessFee(feePerKw) htlcFee := HtlcSuccessFee(chanType, feePerKw)
outputAmt := htlc.Amount.ToSatoshis() - htlcFee outputAmt := htlc.Amount.ToSatoshis() - htlcFee
// With the proper output amount calculated, we can now // With the proper output amount calculated, we can now
@ -3785,16 +3787,20 @@ func (lc *LightningChannel) computeView(view *htlcView, remoteChain bool,
// weight, needed to calculate the transaction fee. // weight, needed to calculate the transaction fee.
var totalHtlcWeight int64 var totalHtlcWeight int64
for _, htlc := range filteredHTLCView.ourUpdates { for _, htlc := range filteredHTLCView.ourUpdates {
if htlcIsDust(remoteChain, !remoteChain, feePerKw, if htlcIsDust(
htlc.Amount.ToSatoshis(), dustLimit) { lc.channelState.ChanType, remoteChain, !remoteChain,
feePerKw, htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }
totalHtlcWeight += input.HTLCWeight totalHtlcWeight += input.HTLCWeight
} }
for _, htlc := range filteredHTLCView.theirUpdates { for _, htlc := range filteredHTLCView.theirUpdates {
if htlcIsDust(!remoteChain, !remoteChain, feePerKw, if htlcIsDust(
htlc.Amount.ToSatoshis(), dustLimit) { lc.channelState.ChanType, !remoteChain, !remoteChain,
feePerKw, htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }
@ -3857,7 +3863,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
Index: uint32(htlc.localOutputIndex), Index: uint32(htlc.localOutputIndex),
} }
htlcFee := htlcSuccessFee(feePerKw) htlcFee := HtlcSuccessFee(chanType, feePerKw)
outputAmt := htlc.Amount.ToSatoshis() - htlcFee outputAmt := htlc.Amount.ToSatoshis() - htlcFee
successTx, err := createHtlcSuccessTx( successTx, err := createHtlcSuccessTx(
@ -3911,7 +3917,7 @@ func genHtlcSigValidationJobs(localCommitmentView *commitment,
Index: uint32(htlc.localOutputIndex), Index: uint32(htlc.localOutputIndex),
} }
htlcFee := htlcTimeoutFee(feePerKw) htlcFee := HtlcTimeoutFee(chanType, feePerKw)
outputAmt := htlc.Amount.ToSatoshis() - htlcFee outputAmt := htlc.Amount.ToSatoshis() - htlcFee
timeoutTx, err := createHtlcTimeoutTx( timeoutTx, err := createHtlcTimeoutTx(
@ -5383,7 +5389,7 @@ func newOutgoingHtlcResolution(signer input.Signer,
// In order to properly reconstruct the HTLC transaction, we'll need to // In order to properly reconstruct the HTLC transaction, we'll need to
// re-calculate the fee required at this state, so we can add the // re-calculate the fee required at this state, so we can add the
// correct output value amount to the transaction. // correct output value amount to the transaction.
htlcFee := htlcTimeoutFee(feePerKw) htlcFee := HtlcTimeoutFee(chanType, feePerKw)
secondLevelOutputAmt := htlc.Amt.ToSatoshis() - htlcFee secondLevelOutputAmt := htlc.Amt.ToSatoshis() - htlcFee
// With the fee calculated, re-construct the second level timeout // With the fee calculated, re-construct the second level timeout
@ -5513,7 +5519,7 @@ func newIncomingHtlcResolution(signer input.Signer,
// First, we'll reconstruct the original HTLC success transaction, // First, we'll reconstruct the original HTLC success transaction,
// taking into account the fee rate used. // taking into account the fee rate used.
htlcFee := htlcSuccessFee(feePerKw) htlcFee := HtlcSuccessFee(chanType, feePerKw)
secondLevelOutputAmt := htlc.Amt.ToSatoshis() - htlcFee secondLevelOutputAmt := htlc.Amt.ToSatoshis() - htlcFee
successTx, err := createHtlcSuccessTx( successTx, err := createHtlcSuccessTx(
chanType, op, secondLevelOutputAmt, csvDelay, chanType, op, secondLevelOutputAmt, csvDelay,
@ -5637,8 +5643,10 @@ func extractHtlcResolutions(feePerKw chainfee.SatPerKWeight, ourCommit bool,
// We'll skip any HTLC's which were dust on the commitment // We'll skip any HTLC's which were dust on the commitment
// transaction, as these don't have a corresponding output // transaction, as these don't have a corresponding output
// within the commitment transaction. // within the commitment transaction.
if htlcIsDust(htlc.Incoming, ourCommit, feePerKw, if htlcIsDust(
htlc.Amt.ToSatoshis(), dustLimit) { chanType, htlc.Incoming, ourCommit, feePerKw,
htlc.Amt.ToSatoshis(), dustLimit,
) {
continue continue
} }
@ -6141,7 +6149,7 @@ func (lc *LightningChannel) availableCommitmentBalance(view *htlcView,
// For an extra HTLC fee to be paid on our commitment, the HTLC must be // For an extra HTLC fee to be paid on our commitment, the HTLC must be
// large enough to make a non-dust HTLC timeout transaction. // large enough to make a non-dust HTLC timeout transaction.
htlcFee := lnwire.NewMSatFromSatoshis( htlcFee := lnwire.NewMSatFromSatoshis(
htlcTimeoutFee(feePerKw), HtlcTimeoutFee(lc.channelState.ChanType, feePerKw),
) )
// If we are looking at the remote commitment, we must use the remote // If we are looking at the remote commitment, we must use the remote
@ -6151,7 +6159,7 @@ func (lc *LightningChannel) availableCommitmentBalance(view *htlcView,
lc.channelState.RemoteChanCfg.DustLimit, lc.channelState.RemoteChanCfg.DustLimit,
) )
htlcFee = lnwire.NewMSatFromSatoshis( htlcFee = lnwire.NewMSatFromSatoshis(
htlcSuccessFee(feePerKw), HtlcSuccessFee(lc.channelState.ChanType, feePerKw),
) )
} }

View File

@ -1011,7 +1011,8 @@ func TestHTLCDustLimit(t *testing.T) {
// The amount of the HTLC should be above Alice's dust limit and below // The amount of the HTLC should be above Alice's dust limit and below
// Bob's dust limit. // Bob's dust limit.
htlcSat := (btcutil.Amount(500) + htlcTimeoutFee( htlcSat := (btcutil.Amount(500) + HtlcTimeoutFee(
aliceChannel.channelState.ChanType,
chainfee.SatPerKWeight( chainfee.SatPerKWeight(
aliceChannel.channelState.LocalCommitment.FeePerKw, aliceChannel.channelState.LocalCommitment.FeePerKw,
), ),
@ -1119,8 +1120,12 @@ func TestHTLCSigNumber(t *testing.T) {
t.Fatalf("unable to get fee: %v", err) t.Fatalf("unable to get fee: %v", err)
} }
belowDust := btcutil.Amount(500) + htlcTimeoutFee(feePerKw) belowDust := btcutil.Amount(500) + HtlcTimeoutFee(
aboveDust := btcutil.Amount(1400) + htlcSuccessFee(feePerKw) channeldb.SingleFunderTweaklessBit, feePerKw,
)
aboveDust := btcutil.Amount(1400) + HtlcSuccessFee(
channeldb.SingleFunderTweaklessBit, feePerKw,
)
// =================================================================== // ===================================================================
// Test that Bob will reject a commitment if Alice doesn't send enough // Test that Bob will reject a commitment if Alice doesn't send enough
@ -1278,7 +1283,8 @@ func TestChannelBalanceDustLimit(t *testing.T) {
defaultFee := calcStaticFee(1) defaultFee := calcStaticFee(1)
aliceBalance := aliceChannel.channelState.LocalCommitment.LocalBalance.ToSatoshis() aliceBalance := aliceChannel.channelState.LocalCommitment.LocalBalance.ToSatoshis()
htlcSat := aliceBalance - defaultFee htlcSat := aliceBalance - defaultFee
htlcSat += htlcSuccessFee( htlcSat += HtlcSuccessFee(
aliceChannel.channelState.ChanType,
chainfee.SatPerKWeight( chainfee.SatPerKWeight(
aliceChannel.channelState.LocalCommitment.FeePerKw, aliceChannel.channelState.LocalCommitment.FeePerKw,
), ),
@ -4759,10 +4765,10 @@ func TestChanAvailableBalanceNearHtlcFee(t *testing.T) {
aliceChannel.channelState.LocalCommitment.CommitFee, aliceChannel.channelState.LocalCommitment.CommitFee,
) )
htlcTimeoutFee := lnwire.NewMSatFromSatoshis( htlcTimeoutFee := lnwire.NewMSatFromSatoshis(
htlcTimeoutFee(feeRate), HtlcTimeoutFee(aliceChannel.channelState.ChanType, feeRate),
) )
htlcSuccessFee := lnwire.NewMSatFromSatoshis( htlcSuccessFee := lnwire.NewMSatFromSatoshis(
htlcSuccessFee(feeRate), HtlcSuccessFee(aliceChannel.channelState.ChanType, feeRate),
) )
// Helper method to check the current reported balance. // Helper method to check the current reported balance.
@ -6273,7 +6279,8 @@ func TestChanReserveLocalInitiatorDustHtlc(t *testing.T) {
// limit (1300 sat). It is considered dust if the amount remaining // limit (1300 sat). It is considered dust if the amount remaining
// after paying the HTLC fee is below the dustlimit, so we choose a // after paying the HTLC fee is below the dustlimit, so we choose a
// size of 500+htlcFee. // size of 500+htlcFee.
htlcSat := btcutil.Amount(500) + htlcTimeoutFee( htlcSat := btcutil.Amount(500) + HtlcTimeoutFee(
aliceChannel.channelState.ChanType,
chainfee.SatPerKWeight( chainfee.SatPerKWeight(
aliceChannel.channelState.LocalCommitment.FeePerKw, aliceChannel.channelState.LocalCommitment.FeePerKw,
), ),

View File

@ -255,6 +255,29 @@ func CommitWeight(chanType channeldb.ChannelType) int64 {
return input.CommitWeight return input.CommitWeight
} }
// HtlcTimeoutFee returns the fee in satoshis required for an HTLC timeout
// transaction based on the current fee rate.
func HtlcTimeoutFee(chanType channeldb.ChannelType,
feePerKw chainfee.SatPerKWeight) btcutil.Amount {
if chanType.HasAnchors() {
return feePerKw.FeeForWeight(input.HtlcTimeoutWeightConfirmed)
}
return feePerKw.FeeForWeight(input.HtlcTimeoutWeight)
}
// HtlcSuccessFee returns the fee in satoshis required for an HTLC success
// transaction based on the current fee rate.
func HtlcSuccessFee(chanType channeldb.ChannelType,
feePerKw chainfee.SatPerKWeight) btcutil.Amount {
if chanType.HasAnchors() {
return feePerKw.FeeForWeight(input.HtlcSuccessWeightConfirmed)
}
return feePerKw.FeeForWeight(input.HtlcSuccessWeight)
}
// CommitScriptAnchors return the scripts to use for the local and remote // CommitScriptAnchors return the scripts to use for the local and remote
// anchor. // anchor.
func CommitScriptAnchors(localChanCfg, func CommitScriptAnchors(localChanCfg,
@ -373,18 +396,20 @@ func (cb *CommitmentBuilder) createUnsignedCommitmentTx(ourBalance,
numHTLCs := int64(0) numHTLCs := int64(0)
for _, htlc := range filteredHTLCView.ourUpdates { for _, htlc := range filteredHTLCView.ourUpdates {
if htlcIsDust(false, isOurs, feePerKw, if htlcIsDust(
htlc.Amount.ToSatoshis(), dustLimit) { cb.chanState.ChanType, false, isOurs, feePerKw,
htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }
numHTLCs++ numHTLCs++
} }
for _, htlc := range filteredHTLCView.theirUpdates { for _, htlc := range filteredHTLCView.theirUpdates {
if htlcIsDust(true, isOurs, feePerKw, if htlcIsDust(
htlc.Amount.ToSatoshis(), dustLimit) { cb.chanState.ChanType, true, isOurs, feePerKw,
htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }
@ -460,8 +485,10 @@ func (cb *CommitmentBuilder) createUnsignedCommitmentTx(ourBalance,
// purposes of sorting. // purposes of sorting.
cltvs := make([]uint32, len(commitTx.TxOut)) cltvs := make([]uint32, len(commitTx.TxOut))
for _, htlc := range filteredHTLCView.ourUpdates { for _, htlc := range filteredHTLCView.ourUpdates {
if htlcIsDust(false, isOurs, feePerKw, if htlcIsDust(
htlc.Amount.ToSatoshis(), dustLimit) { cb.chanState.ChanType, false, isOurs, feePerKw,
htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }
@ -475,8 +502,10 @@ func (cb *CommitmentBuilder) createUnsignedCommitmentTx(ourBalance,
cltvs = append(cltvs, htlc.Timeout) cltvs = append(cltvs, htlc.Timeout)
} }
for _, htlc := range filteredHTLCView.theirUpdates { for _, htlc := range filteredHTLCView.theirUpdates {
if htlcIsDust(true, isOurs, feePerKw, if htlcIsDust(
htlc.Amount.ToSatoshis(), dustLimit) { cb.chanState.ChanType, true, isOurs, feePerKw,
htlc.Amount.ToSatoshis(), dustLimit,
) {
continue continue
} }