@@ -932,21 +932,36 @@ func (c *ChannelArbitrator) stateStep(
932932 // arbitrating for. If a commitment has confirmed, then we'll
933933 // use the set snapshot from the chain, otherwise we'll use our
934934 // current set.
935- var htlcs map [HtlcSetKey ]htlcSet
936- if confCommitSet != nil {
937- htlcs = confCommitSet .toActiveHTLCSets ()
938- } else {
935+ var (
936+ chainActions ChainActionMap
937+ err error
938+ )
939+
940+ // Normally if we force close the channel locally we will have
941+ // no confCommitSet. However when the remote commitment confirms
942+ // without us ever broadcasting our local commitment we need to
943+ // make sure we cancel all upstream HTLCs for outgoing dust
944+ // HTLCs as well hence we need to fetch the chain actions here
945+ // as well.
946+ if confCommitSet == nil {
939947 // Update the set of activeHTLCs so
940948 // checkLocalChainActions has an up-to-date view of the
941949 // commitments.
942950 c .updateActiveHTLCs ()
943- htlcs = c .activeHTLCs
944- }
945- chainActions , err := c .checkLocalChainActions (
946- triggerHeight , trigger , htlcs , false ,
947- )
948- if err != nil {
949- return StateDefault , nil , err
951+ htlcs := c .activeHTLCs
952+ chainActions , err = c .checkLocalChainActions (
953+ triggerHeight , trigger , htlcs , false ,
954+ )
955+ if err != nil {
956+ return StateDefault , nil , err
957+ }
958+ } else {
959+ chainActions , err = c .constructChainActions (
960+ confCommitSet , triggerHeight , trigger ,
961+ )
962+ if err != nil {
963+ return StateDefault , nil , err
964+ }
950965 }
951966
952967 // If there are no actions to be made, then we'll remain in the
@@ -964,6 +979,25 @@ func (c *ChannelArbitrator) stateStep(
964979 log .Tracef ("ChannelArbitrator(%v): logging chain_actions=%v" ,
965980 c .cfg .ChanPoint , lnutils .SpewLogClosure (chainActions ))
966981
982+ // Cancel upstream HTLCs for all outgoing dust HTLCs available
983+ // either on the local or the remote/remote pending commitment
984+ // transaction.
985+ dustHTLCs := chainActions [HtlcFailDustAction ]
986+ if len (dustHTLCs ) > 0 {
987+ log .Debugf ("ChannelArbitrator(%v): canceling %v dust " +
988+ "HTLCs backwards" , c .cfg .ChanPoint ,
989+ len (dustHTLCs ))
990+
991+ getIdx := func (htlc channeldb.HTLC ) uint64 {
992+ return htlc .HtlcIndex
993+ }
994+ dustHTLCSet := fn .NewSet (fn .Map (getIdx , dustHTLCs )... )
995+ err = c .abandonForwards (dustHTLCSet )
996+ if err != nil {
997+ return StateError , closeTx , err
998+ }
999+ }
1000+
9671001 // Depending on the type of trigger, we'll either "tunnel"
9681002 // through to a farther state, or just proceed linearly to the
9691003 // next state.
@@ -1214,18 +1248,19 @@ func (c *ChannelArbitrator) stateStep(
12141248 return StateError , closeTx , err
12151249 }
12161250
1217- // In case its a breach transaction we fail back all outgoing
1218- // HTLCs on the remote commitment set.
1251+ // In case its a breach transaction we fail back all upstream
1252+ // HTLCs for their corresponding outgoing HTLCs on the remote
1253+ // commitment set (remote and remote pending set).
12191254 if contractResolutions .BreachResolution != nil {
12201255 // cancelBreachedHTLCs is a set which holds HTLCs whose
12211256 // corresponding incoming HTLCs will be failed back
12221257 // because the peer broadcasted an old state.
12231258 cancelBreachedHTLCs := fn .NewSet [uint64 ]()
12241259
1225- // We'll use the CommitSet, we'll fail back all outgoing
1226- // HTLC's that exist on either of the remote
1227- // commitments. The map is used to deduplicate any
1228- // shared HTLC's.
1260+ // We'll use the CommitSet, we'll fail back all
1261+ // upstream HTLCs for their corresponding outgoing
1262+ // HTLC that exist on either of the remote commitments.
1263+ // The map is used to deduplicate any shared HTLC's.
12291264 for htlcSetKey , htlcs := range confCommitSet .HtlcSets {
12301265 if ! htlcSetKey .IsRemote {
12311266 continue
@@ -1256,9 +1291,11 @@ func (c *ChannelArbitrator) stateStep(
12561291 return StateError , closeTx , err
12571292 }
12581293
1259- // We can fail the upstream HTLC for an outgoing
1260- // dangling and dust HTLC because we can be sure they
1261- // will not be resolved onchain.
1294+ // We fail the upstream HTLCs for all remote pending
1295+ // outgoing HTLCs as soon as the commitment is
1296+ // confirmed. The upstream HTLCs for outgoing dust
1297+ // HTLCs have already been resolved before we reach
1298+ // this point.
12621299 getIdx := func (htlc channeldb.HTLC ) uint64 {
12631300 return htlc .HtlcIndex
12641301 }
@@ -1269,15 +1306,6 @@ func (c *ChannelArbitrator) stateStep(
12691306 if err != nil {
12701307 return StateError , closeTx , err
12711308 }
1272-
1273- dustHTLCs := fn .NewSet (fn .Map (
1274- getIdx , htlcActions [HtlcFailDustAction ],
1275- )... )
1276-
1277- err = c .abandonForwards (dustHTLCs )
1278- if err != nil {
1279- return StateError , closeTx , err
1280- }
12811309 }
12821310
12831311 // Now that we know we'll need to act, we'll process all the
0 commit comments