Skip to content

Commit cb19dd6

Browse files
committed
tapchannel: fix split root when initiator has 0 balance
A previous bug fix was wrong... In the case where an HTLC sends all the balance from the initiator to the recipient, then the initiator has zero balance _and_ there is no HTLC going to the initiator. So the root split still becomes nil and we panic. So we re-declare the rule for the case where the initiator has zero balance: If the initiator doesn't have any balance to carry the split root, then the very first HTLC will carry the split root. If there is no HTLC, it means all the balance is on the recipient's side and there is no split (hence no split root required).
1 parent 395a180 commit cb19dd6

File tree

1 file changed

+9
-30
lines changed

1 file changed

+9
-30
lines changed

tapchannel/commitment.go

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -667,9 +667,8 @@ func CreateAllocations(chanState *channeldb.OpenChannel, ourBalance,
667667

668668
// Next, we add the HTLC outputs, using this helper function to
669669
// distinguish between incoming and outgoing HTLCs. The haveHtlcSplit
670-
// boolean is used to determine if one of the HTLCs needs to become the
671-
// split root. See below where it's used for a more in-depth
672-
// explanation.
670+
// boolean is used to store if one of the HTLCs has already been chosen
671+
// to be the split root (only the very first HTLC might be chosen).
673672
var haveHtlcSplitRoot bool
674673
addHtlc := func(htlc *DecodedDescriptor, isIncoming bool) error {
675674
htlcScript, err := lnwallet.GenTaprootHtlcScript(
@@ -688,34 +687,14 @@ func CreateAllocations(chanState *channeldb.OpenChannel, ourBalance,
688687
"sibling: %w", err)
689688
}
690689

691-
// The "incoming" vs. "outgoing" naming is always viewed from
692-
// the perspective of the local node and independent of
693-
// isOurCommit. So to find out if an HTLC is for the initiator
694-
// it only depends on the direction and whether we are the
695-
// initiator. The human-readable version of the below switch
696-
// statement is: Either we're the initiator and the HTLC is
697-
// incoming, or we're not the initiator and the HTLC is
698-
// outgoing.
699-
var htlcIsForInitiator bool
700-
switch {
701-
// If the HTLC is incoming and the local node is the channel
702-
// initiator, then the HTLC is for the channel initiator.
703-
case chanState.IsInitiator && isIncoming:
704-
htlcIsForInitiator = true
705-
706-
// If the HTLC is outgoing and the local node is not the
707-
// channel initiator, then the HTLC is for the channel
708-
// initiator.
709-
case !chanState.IsInitiator && !isIncoming:
710-
htlcIsForInitiator = true
711-
}
712-
713-
// We should always just have a single split root on the side
714-
// of the initiator. So if the initiator doesn't have any normal
715-
// asset output to house the split root, then we'll take the
716-
// _first_ HTLC that pays to the initiator.
690+
// We should always just have a single split root, which
691+
// normally is the initiator's balance. However, if the
692+
// initiator has no balance, then we choose the very first HTLC
693+
// in the list to be the split root. If there are no HTLCs, then
694+
// all the balance is on the receiver side and we don't need a
695+
// split root.
717696
shouldHouseSplitRoot := initiatorAssetBalance == 0 &&
718-
htlcIsForInitiator && !haveHtlcSplitRoot
697+
!haveHtlcSplitRoot
719698

720699
// Make sure we only select the very first HTLC that pays to the
721700
// initiator.

0 commit comments

Comments
 (0)