From a108643b52a15e814e17ef5c3a46beab3151ada9 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 1 Dec 2020 15:38:52 +0100 Subject: [PATCH] funding: add min HTLC slots check add channel opening --- fundingmanager.go | 35 +++++++++++++++++++++++---- lnwallet/commitment.go | 55 ++++++++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/fundingmanager.go b/fundingmanager.go index 15eb0b31e9..47ab186eed 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -3237,6 +3237,36 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) { // SubtractFees=true. capacity := reservation.Capacity() + // We'll use the current value of the channels and our default policy + // to determine of required commitment constraints for the remote + // party. + chanReserve := f.cfg.RequiredRemoteChanReserve(capacity, ourDustLimit) + + // As a sanity check, we ensure that the user is not trying to open a + // tiny anchor channel that would be unusable because of the fee siphon + // check we do. + if commitType == lnwallet.CommitmentTypeAnchors { + timeoutFee := lnwallet.HtlcTimeoutFee( + channeldb.AnchorOutputsBit, + f.cfg.MaxAnchorsCommitFeeRate, + ) + + maxNumHtlcs := chanReserve / timeoutFee + if maxNumHtlcs < lnwallet.MinAnchorHtlcSlots { + if err := reservation.Cancel(); err != nil { + fndgLog.Errorf("unable to cancel "+ + "reservation: %v", err) + } + + maxHtlcErr := fmt.Errorf("tiny channel, only room "+ + "for %d HTLCs. Consider making a larger "+ + "channel or reducing the max commit fee rate", + maxNumHtlcs) + msg.err <- maxHtlcErr + return + } + } + fndgLog.Infof("Target commit tx sat/kw for pendingID(%x): %v", chanID, int64(commitFeePerKw)) @@ -3292,11 +3322,6 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) { // request to the remote peer, kicking off the funding workflow. ourContribution := reservation.OurContribution() - // Finally, we'll use the current value of the channels and our default - // policy to determine of required commitment constraints for the - // remote party. - chanReserve := f.cfg.RequiredRemoteChanReserve(capacity, ourDustLimit) - fndgLog.Infof("Starting funding workflow with %v for pending_id(%x), "+ "committype=%v", msg.peer.Address(), chanID, commitType) diff --git a/lnwallet/commitment.go b/lnwallet/commitment.go index 52e181c363..8bd27d5780 100644 --- a/lnwallet/commitment.go +++ b/lnwallet/commitment.go @@ -14,29 +14,38 @@ import ( "github.com/lightningnetwork/lnd/lnwire" ) -// anchorSize is the constant anchor output size. -const anchorSize = btcutil.Amount(330) - -// DefaultAnchorsCommitMaxFeeRateSatPerVByte is the default max fee rate in -// sat/vbyte the initiator will use for anchor channels. -// -// This caps the update fee the initiator will send when the anchors channel -// type is used. We do not limit anything on the receiver side, only on the -// sender (initiator) side. This keeps us spec compatible, while defaulting to -// a reasonable feerate if initiator is lnd. Receiver side we will allow any -// fee and add updates as long as the fee siphon invariant is not violated. -// -// Defaults to 10 sat/vbyte. This will make give HTLC a timeout fee of -// -// 666 * 2500 / 1000 = 1665 sats -// -// An example: -// For a channel size of 0.01 BTC = 1,000,000 sats and a channel reserve of -// 1%, this leaves room for (1,000,000 / 100) / 1665 = 6 HTLCs. -// -// Bigger channels, larger reserves, or lower fee rates will open up for more -// room. -const DefaultAnchorsCommitMaxFeeRateSatPerVByte = 10 +const ( + // anchorSize is the constant anchor output size. + anchorSize = btcutil.Amount(330) + + // DefaultAnchorsCommitMaxFeeRateSatPerVByte is the default max fee + // rate in sat/vbyte the initiator will use for anchor channels. + // + // This caps the update fee the initiator will send when the anchors + // channel type is used. We do not limit anything on the receiver side, + // only on the sender (initiator) side. This keeps us spec compatible, + // while defaulting to a reasonable feerate if initiator is lnd. + // Receiver side we will allow any fee and add updates as long as the + // fee siphon invariant is not violated. + // + // Defaults to 10 sat/vbyte. This will make give HTLC a timeout fee of + // + // 666 * 2500 / 1000 = 1665 sats + // + // An example: + // For a channel size of 0.01 BTC = 1,000,000 sats and a channel + // reserve of 1%, this leaves room for (1,000,000 / 100) / 1665 = 6 + // HTLCs. + // + // Bigger channels, larger reserves, or lower fee rates will open up + // for more room. + DefaultAnchorsCommitMaxFeeRateSatPerVByte = 10 + + // MinAnchorHtlcSlots is the minimum number of slots we require to be + // available for HTLCs when opening an anchor channels and checking fee + // leaks. See doc for DefaultAnchorsCommitMaxFeeRateSatPerVByte + MinAnchorHtlcSlots = 6 +) // CommitmentKeyRing holds all derived keys needed to construct commitment and // HTLC transactions. The keys are derived differently depending whether the