Skip to content

Commit 8f8cf2b

Browse files
committed
rfqmsg+tapchannelmsg: add helper functions for asset ID detection
To easily find out if all asset IDs from a set are actually committed to a channel, we add helper functions for the different channel messages that we can encounter in our subsystems (depending on whether we get the message from a blob in a hook or as JSON over the RPC interface).
1 parent 60d99fc commit 8f8cf2b

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

rfqmsg/custom_channel_data.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
package rfqmsg
22

3+
import (
4+
"strings"
5+
6+
"github.com/lightninglabs/taproot-assets/asset"
7+
"github.com/lightninglabs/taproot-assets/fn"
8+
)
9+
310
// JsonAssetBalance is a struct that represents the balance of a single asset ID
411
// within a channel.
512
type JsonAssetBalance struct {
@@ -44,6 +51,33 @@ type JsonAssetChannel struct {
4451
IncomingHtlcBalance uint64 `json:"incoming_htlc_balance"`
4552
}
4653

54+
// HasAllAssetIDs checks if the OpenChannel contains all asset IDs in the
55+
// provided set. It returns true if all asset IDs are present, false otherwise.
56+
func (c *JsonAssetChannel) HasAllAssetIDs(ids fn.Set[asset.ID]) bool {
57+
// There is a possibility that we're checking the asset ID from an HTLC
58+
// that hasn't been materialized yet and could actually contain a group
59+
// key x-coordinate. That should only be the case if there is a single
60+
// asset ID.
61+
if len(ids) == 1 && c.GroupKey != "" {
62+
assetID := ids.ToSlice()[0]
63+
if strings.Contains(c.GroupKey, assetID.String()) {
64+
return true
65+
}
66+
}
67+
68+
availableIDStrings := fn.NewSet(fn.Map(
69+
c.FundingAssets, func(fundingAsset JsonAssetUtxo) string {
70+
return fundingAsset.AssetGenesis.AssetID
71+
},
72+
)...)
73+
targetIDStrings := fn.NewSet(fn.Map(
74+
ids.ToSlice(), func(id asset.ID) string {
75+
return id.String()
76+
},
77+
)...)
78+
return targetIDStrings.Subset(availableIDStrings)
79+
}
80+
4781
// JsonAssetChannelBalances is a struct that represents the balance information
4882
// of all assets within open and pending channels.
4983
type JsonAssetChannelBalances struct {

tapchannelmsg/records.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/url"
99

1010
"github.com/btcsuite/btcd/btcec/v2"
11+
"github.com/btcsuite/btcd/btcec/v2/schnorr"
1112
"github.com/btcsuite/btcd/txscript"
1213
"github.com/lightninglabs/taproot-assets/asset"
1314
"github.com/lightninglabs/taproot-assets/fn"
@@ -188,6 +189,46 @@ func (o *OpenChannel) Bytes() []byte {
188189
return buf.Bytes()
189190
}
190191

192+
// HasAllAssetIDs checks if the OpenChannel contains all asset IDs in the
193+
// provided set. It returns true if all asset IDs are present, false otherwise.
194+
func (o *OpenChannel) HasAllAssetIDs(ids fn.Set[asset.ID]) bool {
195+
// There is a possibility that we're checking the asset ID from an HTLC
196+
// that hasn't been materialized yet and could actually contain a group
197+
// key x-coordinate. That should only be the case if there is a single
198+
// asset ID.
199+
if len(ids) == 1 && o.GroupKey.IsSome() {
200+
assetID := ids.ToSlice()[0]
201+
groupKeyMatch := lfn.MapOptionZ(
202+
o.GroupKey.ValOpt(),
203+
func(groupKey *btcec.PublicKey) bool {
204+
if groupKey == nil {
205+
return false
206+
}
207+
208+
return bytes.Equal(
209+
assetID[:], schnorr.SerializePubKey(
210+
groupKey,
211+
),
212+
)
213+
},
214+
)
215+
216+
// Only if we get a match do we short-circuit the explicit asset
217+
// ID check.
218+
if groupKeyMatch {
219+
return true
220+
}
221+
}
222+
223+
availableIDs := fn.NewSet(fn.Map(
224+
o.Assets(), func(output *AssetOutput) asset.ID {
225+
return output.AssetID.Val
226+
},
227+
)...)
228+
229+
return ids.Subset(availableIDs)
230+
}
231+
191232
// DecodeOpenChannel deserializes an OpenChannel from the given blob.
192233
func DecodeOpenChannel(blob tlv.Blob) (*OpenChannel, error) {
193234
var o OpenChannel

0 commit comments

Comments
 (0)