@@ -14,11 +14,13 @@ import (
1414 "github.com/lightninglabs/taproot-assets/fn"
1515 "github.com/lightninglabs/taproot-assets/rfqmath"
1616 "github.com/lightninglabs/taproot-assets/rfqmsg"
17+ "github.com/lightninglabs/taproot-assets/tapfeatures"
1718 "github.com/lightningnetwork/lnd/graph/db/models"
1819 "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
1920 "github.com/lightningnetwork/lnd/lnutils"
2021 "github.com/lightningnetwork/lnd/lnwallet"
2122 "github.com/lightningnetwork/lnd/lnwire"
23+ "github.com/lightningnetwork/lnd/routing/route"
2224 "github.com/lightningnetwork/lnd/tlv"
2325)
2426
@@ -125,13 +127,22 @@ type AssetSalePolicy struct {
125127 // wants us to produce NoOp HTLCs.
126128 NoOpHTLCs bool
127129
130+ // auxChannelNegotiator is used to query the supported feature bits that
131+ // are supported by a peer, or a channel.
132+ auxChanNegotiator * tapfeatures.AuxChannelNegotiator
133+
134+ // peer is the peer pub key of the peer we established this policy with.
135+ peer route.Vertex
136+
128137 // expiry is the policy's expiry unix timestamp after which the policy
129138 // is no longer valid.
130139 expiry uint64
131140}
132141
133142// NewAssetSalePolicy creates a new asset sale policy.
134- func NewAssetSalePolicy (quote rfqmsg.BuyAccept , noop bool ) * AssetSalePolicy {
143+ func NewAssetSalePolicy (quote rfqmsg.BuyAccept , noop bool ,
144+ chanNegotiator * tapfeatures.AuxChannelNegotiator ) * AssetSalePolicy {
145+
135146 htlcToAmtMap := make (map [models.CircuitKey ]lnwire.MilliSatoshi )
136147
137148 return & AssetSalePolicy {
@@ -142,6 +153,8 @@ func NewAssetSalePolicy(quote rfqmsg.BuyAccept, noop bool) *AssetSalePolicy {
142153 expiry : uint64 (quote .AssetRate .Expiry .Unix ()),
143154 htlcToAmt : htlcToAmtMap ,
144155 NoOpHTLCs : noop ,
156+ auxChanNegotiator : chanNegotiator ,
157+ peer : quote .Peer ,
145158 }
146159}
147160
@@ -290,10 +303,13 @@ func (c *AssetSalePolicy) GenerateInterceptorResponse(
290303 fn .None [[]rfqmsg.ID ](),
291304 )
292305
306+ peerFeatures := c .auxChanNegotiator .GetPeerFeatures (c .peer )
307+ supportNoOp := peerFeatures .HasFeature (tapfeatures .NoOpHTLCsOptional )
308+
293309 // We are about to create an outgoing HTLC that carries assets. Let's
294310 // set the noop flag in order to eventually only settle the assets but
295311 // never settle the sats anchor amount that will carry them.
296- if c .NoOpHTLCs {
312+ if c .NoOpHTLCs && supportNoOp {
297313 htlcRecord .SetNoopAdd (rfqmsg .UseNoOpHTLCs )
298314 }
299315
@@ -686,6 +702,11 @@ type OrderHandlerCfg struct {
686702 // NoOpHTLCs is a boolean indicating whether the daemon configuration
687703 // wants us to produce NoOp HTLCs.
688704 NoOpHTLCs bool
705+
706+ // AuxChannelNegotiator is responsible for producing the extra tlv blob
707+ // that is encapsulated in the init and reestablish peer messages. This
708+ // helps us communicate custom feature bits with our peer.
709+ AuxChanNegotiator * tapfeatures.AuxChannelNegotiator
689710}
690711
691712// OrderHandler orchestrates management of accepted quote bundles. It monitors
@@ -940,7 +961,10 @@ func (h *OrderHandler) RegisterAssetSalePolicy(buyAccept rfqmsg.BuyAccept) {
940961 log .Debugf ("Order handler is registering an asset sale policy given a " +
941962 "buy accept message: %s" , buyAccept .String ())
942963
943- policy := NewAssetSalePolicy (buyAccept , h .cfg .NoOpHTLCs )
964+ policy := NewAssetSalePolicy (
965+ buyAccept , h .cfg .NoOpHTLCs , h .cfg .AuxChanNegotiator ,
966+ )
967+
944968 h .policies .Store (policy .AcceptedQuoteId .Scid (), policy )
945969}
946970
0 commit comments