@@ -10,11 +10,14 @@ import (
1010 "github.com/lightninglabs/taproot-assets/address"
1111 "github.com/lightninglabs/taproot-assets/fn"
1212 cmsg "github.com/lightninglabs/taproot-assets/tapchannelmsg"
13+ "github.com/lightninglabs/taproot-assets/tapfeatures"
1314 "github.com/lightningnetwork/lnd/channeldb"
1415 lfn "github.com/lightningnetwork/lnd/fn/v2"
1516 "github.com/lightningnetwork/lnd/input"
1617 "github.com/lightningnetwork/lnd/lntypes"
1718 lnwl "github.com/lightningnetwork/lnd/lnwallet"
19+ "github.com/lightningnetwork/lnd/lnwire"
20+ "github.com/lightningnetwork/lnd/routing/route"
1821 "github.com/lightningnetwork/lnd/tlv"
1922)
2023
@@ -24,10 +27,22 @@ const (
2427 DefaultTimeout = 30 * time .Second
2528)
2629
30+ // FeatureBitFetcher is responsible for fetching feature bits either by
31+ // referencing a remote peer, or an established channel.
32+ type FeatureBitFetcher interface {
33+ // GetPeerFeatures returns the negotiated features with the given peer.
34+ GetPeerFeatures (peer route.Vertex ) * lnwire.FeatureVector
35+
36+ // GetChannelFeatures returns the negotiated features that are active
37+ // over the channel identifier by the provided channelID.
38+ GetChannelFeatures (cid lnwire.ChannelID ) * lnwire.FeatureVector
39+ }
40+
2741// FetchLeavesFromView attempts to fetch the auxiliary leaves that correspond to
2842// the passed aux blob, and pending fully evaluated HTLC view.
2943func FetchLeavesFromView (chainParams * address.ChainParams ,
30- in lnwl.CommitDiffAuxInput ) lfn.Result [lnwl.CommitDiffAuxResult ] {
44+ in lnwl.CommitDiffAuxInput ,
45+ bitFetcher FeatureBitFetcher ) lfn.Result [lnwl.CommitDiffAuxResult ] {
3146
3247 type returnType = lnwl.CommitDiffAuxResult
3348
@@ -50,10 +65,16 @@ func FetchLeavesFromView(chainParams *address.ChainParams,
5065 "commit state: %w" , err ))
5166 }
5267
68+ supportsSTXO := bitFetcher .GetChannelFeatures (
69+ lnwire .NewChanIDFromOutPoint (
70+ in .ChannelState .FundingOutpoint ,
71+ ),
72+ ).HasFeature (tapfeatures .STXOOptional )
73+
5374 allocations , newCommitment , err := GenerateCommitmentAllocations (
5475 prevState , in .ChannelState , chanAssetState , in .WhoseCommit ,
5576 in .OurBalance , in .TheirBalance , in .UnfilteredView , chainParams ,
56- in .KeyRing , false ,
77+ in .KeyRing , supportsSTXO ,
5778 )
5879 if err != nil {
5980 return lfn.Err [returnType ](fmt .Errorf ("unable to generate " +
@@ -80,8 +101,8 @@ func FetchLeavesFromView(chainParams *address.ChainParams,
80101// to the passed aux blob, and an existing channel commitment.
81102func FetchLeavesFromCommit (chainParams * address.ChainParams ,
82103 chanState lnwl.AuxChanState , com channeldb.ChannelCommitment ,
83- keys lnwl.CommitmentKeyRing ,
84- whoseCommit lntypes. ChannelParty ) lfn.Result [lnwl.CommitDiffAuxResult ] {
104+ keys lnwl.CommitmentKeyRing , whoseCommit lntypes. ChannelParty ,
105+ bitFetcher FeatureBitFetcher ) lfn.Result [lnwl.CommitDiffAuxResult ] {
85106
86107 type returnType = lnwl.CommitDiffAuxResult
87108
@@ -90,6 +111,9 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
90111 return lfn .Ok (lnwl.CommitDiffAuxResult {})
91112 }
92113
114+ supportSTXO := bitFetcher .GetPeerFeatures (chanState .PeerPubKey ).
115+ HasFeature (tapfeatures .STXOOptional )
116+
93117 commitment , err := cmsg .DecodeCommitment (
94118 com .CustomBlob .UnsafeFromSome (),
95119 )
@@ -129,7 +153,7 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
129153 leaf , err := CreateSecondLevelHtlcTx (
130154 chanState , com .CommitTx , htlc .Amt .ToSatoshis (),
131155 keys , chainParams , htlcOutputs , cltvTimeout ,
132- htlc .HtlcIndex , false ,
156+ htlc .HtlcIndex , supportSTXO ,
133157 )
134158 if err != nil {
135159 return lfn.Err [returnType ](fmt .Errorf ("unable " +
@@ -170,7 +194,7 @@ func FetchLeavesFromCommit(chainParams *address.ChainParams,
170194 leaf , err := CreateSecondLevelHtlcTx (
171195 chanState , com .CommitTx , htlc .Amt .ToSatoshis (),
172196 keys , chainParams , htlcOutputs , cltvTimeout ,
173- htlc .HtlcIndex , false ,
197+ htlc .HtlcIndex , supportSTXO ,
174198 )
175199 if err != nil {
176200 return lfn.Err [returnType ](fmt .Errorf ("unable " +
@@ -225,7 +249,8 @@ func FetchLeavesFromRevocation(
225249// channel's blob. Given the old blob, and an HTLC view, then a new
226250// blob should be returned that reflects the pending updates.
227251func ApplyHtlcView (chainParams * address.ChainParams ,
228- in lnwl.CommitDiffAuxInput ) lfn.Result [lfn.Option [tlv.Blob ]] {
252+ in lnwl.CommitDiffAuxInput ,
253+ bitFetcher FeatureBitFetcher ) lfn.Result [lfn.Option [tlv.Blob ]] {
229254
230255 type returnType = lfn.Option [tlv.Blob ]
231256
@@ -248,10 +273,18 @@ func ApplyHtlcView(chainParams *address.ChainParams,
248273 "commit state: %w" , err ))
249274 }
250275
276+ supportSTXO := bitFetcher .GetChannelFeatures (
277+ lnwire .NewChanIDFromOutPoint (
278+ in .ChannelState .FundingOutpoint ,
279+ ),
280+ ).HasFeature (
281+ tapfeatures .STXOOptional ,
282+ )
283+
251284 _ , newCommitment , err := GenerateCommitmentAllocations (
252285 prevState , in .ChannelState , chanAssetState , in .WhoseCommit ,
253286 in .OurBalance , in .TheirBalance , in .UnfilteredView , chainParams ,
254- in .KeyRing , false ,
287+ in .KeyRing , supportSTXO ,
255288 )
256289 if err != nil {
257290 return lfn.Err [returnType ](fmt .Errorf ("unable to generate " +
0 commit comments