@@ -6569,16 +6569,10 @@ func (r *rpcServer) checkPeerChannel(ctx context.Context, peer route.Vertex,
6569
6569
// For any other case, we'll want to make sure there is a channel with
6570
6570
// a non-zero balance of the given asset to carry the order.
6571
6571
default :
6572
- assetID , err := specifier .UnwrapIdOrErr ()
6573
- if err != nil {
6574
- return fmt .Errorf ("cannot check asset channel, " +
6575
- "missing asset ID" )
6576
- }
6577
-
6578
6572
// If we don't get an error here, it means we do have an asset
6579
6573
// channel with the peer. The intention doesn't matter as we're
6580
6574
// just checking whether a channel exists.
6581
- _ , err = r .rfqChannel (ctx , assetID , & peer , NoIntention )
6575
+ _ , err : = r .rfqChannel (ctx , specifier , & peer , NoIntention )
6582
6576
if err != nil {
6583
6577
return fmt .Errorf ("error checking asset channel: %w" ,
6584
6578
err )
@@ -7217,9 +7211,11 @@ func (r *rpcServer) SendPayment(req *tchrpc.SendPaymentRequest,
7217
7211
peerPubKey = & parsedKey
7218
7212
}
7219
7213
7214
+ specifier := asset .NewSpecifierFromId (assetID )
7215
+
7220
7216
// We can now query the asset channels we have.
7221
7217
assetChan , err := r .rfqChannel (
7222
- ctx , assetID , peerPubKey , SendIntention ,
7218
+ ctx , specifier , peerPubKey , SendIntention ,
7223
7219
)
7224
7220
if err != nil {
7225
7221
return fmt .Errorf ("error finding asset channel to " +
@@ -7510,9 +7506,11 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
7510
7506
peerPubKey = & parsedKey
7511
7507
}
7512
7508
7509
+ specifier := asset .NewSpecifierFromId (assetID )
7510
+
7513
7511
// We can now query the asset channels we have.
7514
7512
assetChan , err := r .rfqChannel (
7515
- ctx , assetID , peerPubKey , ReceiveIntention ,
7513
+ ctx , specifier , peerPubKey , ReceiveIntention ,
7516
7514
)
7517
7515
if err != nil {
7518
7516
return nil , fmt .Errorf ("error finding asset channel to use: %w" ,
@@ -7799,62 +7797,62 @@ const (
7799
7797
7800
7798
// rfqChannel returns the channel to use for RFQ operations. If a peer public
7801
7799
// key is specified, the channels are filtered by that peer. If there are
7802
- // multiple channels for the same asset , the user must specify the peer public
7803
- // key.
7804
- func (r * rpcServer ) rfqChannel (ctx context.Context , id asset.ID ,
7800
+ // multiple channels for the same specifier , the user must specify the peer
7801
+ // public key.
7802
+ func (r * rpcServer ) rfqChannel (ctx context.Context , specifier asset.Specifier ,
7805
7803
peerPubKey * route.Vertex ,
7806
- intention chanIntention ) (* channelWithAsset , error ) {
7804
+ intention chanIntention ) (* channelWithSpecifier , error ) {
7807
7805
7808
- balances , err := r .computeChannelAssetBalance (ctx )
7806
+ balances , err := r .computeChannelAssetBalance (ctx , specifier )
7809
7807
if err != nil {
7810
7808
return nil , fmt .Errorf ("error computing available asset " +
7811
7809
"channel balance: %w" , err )
7812
7810
}
7813
7811
7814
- assetBalances , haveBalance := balances [id ]
7815
- if ! haveBalance || len (assetBalances ) == 0 {
7816
- return nil , fmt .Errorf ("no asset channel balance found for " +
7817
- "asset %s" , id .String ())
7812
+ if len (balances ) == 0 {
7813
+ return nil , fmt .Errorf ("no asset channel balance found for %s" ,
7814
+ specifier .String ())
7818
7815
}
7819
7816
7820
7817
// If a peer public key was specified, we always want to use that to
7821
7818
// filter the asset channels.
7822
7819
if peerPubKey != nil {
7823
- assetBalances = fn .Filter (
7824
- assetBalances , func (c channelWithAsset ) bool {
7820
+ balances = fn .Filter (
7821
+ balances , func (c channelWithSpecifier ) bool {
7825
7822
return c .channelInfo .PubKeyBytes == * peerPubKey
7826
7823
},
7827
7824
)
7828
7825
}
7829
7826
7830
7827
switch {
7831
- // If there are multiple asset channels for the same asset , we need to
7832
- // ask the user to specify the peer public key. Otherwise, we don't know
7833
- // who to ask for a quote.
7834
- case len (assetBalances ) > 1 && peerPubKey == nil :
7828
+ // If there are multiple asset channels for the same specifier , we need
7829
+ // to ask the user to specify the peer public key. Otherwise, we don't
7830
+ // know who to ask for a quote.
7831
+ case len (balances ) > 1 && peerPubKey == nil :
7835
7832
return nil , fmt .Errorf ("multiple asset channels found for " +
7836
- "asset %s, please specify the peer pubkey" , id .String ())
7833
+ "%s, please specify the peer pubkey" ,
7834
+ specifier .String ())
7837
7835
7838
7836
// We don't have any channels with that asset ID and peer.
7839
- case len (assetBalances ) == 0 :
7840
- return nil , fmt .Errorf ("no asset channel found for asset %s " +
7841
- "and peer %s" , id . String (), peerPubKey . String () )
7837
+ case len (balances ) == 0 :
7838
+ return nil , fmt .Errorf ("no asset channel found for %v" ,
7839
+ specifier )
7842
7840
}
7843
7841
7844
7842
// If the user specified a peer public key, and we still have multiple
7845
7843
// channels, it means we have multiple channels with the same asset and
7846
7844
// the same peer, as we ruled out the rest of the cases above.
7847
7845
7848
7846
// Initialize best balance to first channel of the list.
7849
- bestBalance := assetBalances [0 ]
7847
+ bestBalance := balances [0 ]
7850
7848
7851
7849
switch intention {
7852
7850
case ReceiveIntention :
7853
7851
// If the intention is to receive, return the channel
7854
7852
// with the best remote balance.
7855
- fn .ForEach (assetBalances , func (b channelWithAsset ) {
7856
- if b .assetInfo .RemoteBalance >
7857
- bestBalance .assetInfo .RemoteBalance {
7853
+ fn .ForEach (balances , func (b channelWithSpecifier ) {
7854
+ if b .channelInfo .RemoteBalance >
7855
+ bestBalance .channelInfo .RemoteBalance {
7858
7856
7859
7857
bestBalance = b
7860
7858
}
@@ -7863,9 +7861,9 @@ func (r *rpcServer) rfqChannel(ctx context.Context, id asset.ID,
7863
7861
case SendIntention :
7864
7862
// If the intention is to send, return the channel with
7865
7863
// the best local balance.
7866
- fn .ForEach (assetBalances , func (b channelWithAsset ) {
7867
- if b .assetInfo .LocalBalance >
7868
- bestBalance .assetInfo .LocalBalance {
7864
+ fn .ForEach (balances , func (b channelWithSpecifier ) {
7865
+ if b .channelInfo .LocalBalance >
7866
+ bestBalance .channelInfo .LocalBalance {
7869
7867
7870
7868
bestBalance = b
7871
7869
}
@@ -7879,28 +7877,64 @@ func (r *rpcServer) rfqChannel(ctx context.Context, id asset.ID,
7879
7877
return & bestBalance , nil
7880
7878
}
7881
7879
7882
- // channelWithAsset is a helper struct that combines the information of a single
7883
- // asset within a channel with the channels' general information.
7884
- type channelWithAsset struct {
7885
- // assetInfo is the information about one of the assets in a channel.
7886
- assetInfo rfqmsg.JsonAssetChanInfo
7880
+ // channelWithSpecifier is a helper struct that combines the information of an
7881
+ // asset specifier that is satisfied by a channel with the channels' general
7882
+ // information.
7883
+ type channelWithSpecifier struct {
7884
+ // specifier is the asset specifier that is satisfied by this channels'
7885
+ // assets.
7886
+ specifier asset.Specifier
7887
7887
7888
7888
// channelInfo is the information about the channel the asset is
7889
7889
// committed to.
7890
7890
channelInfo lndclient.ChannelInfo
7891
7891
}
7892
7892
7893
7893
// computeChannelAssetBalance computes the total local and remote balance for
7894
- // each asset channel.
7895
- func (r * rpcServer ) computeChannelAssetBalance (
7896
- ctx context. Context ) (map [asset. ID ][] channelWithAsset , error ) {
7894
+ // each asset channel that matches the provided asset specifier .
7895
+ func (r * rpcServer ) computeChannelAssetBalance (ctx context. Context ,
7896
+ specifier asset. Specifier ) ([] channelWithSpecifier , error ) {
7897
7897
7898
7898
activeChannels , err := r .cfg .Lnd .Client .ListChannels (ctx , true , false )
7899
7899
if err != nil {
7900
7900
return nil , fmt .Errorf ("unable to fetch channels: %w" , err )
7901
7901
}
7902
7902
7903
- channelsByID := make (map [asset.ID ][]channelWithAsset )
7903
+ // specifierFilter is a helper function that checks if the assets of a
7904
+ // channel satisfy the provided asset specifier.
7905
+ specifierFilter := func (
7906
+ assets []rfqmsg.JsonAssetChanInfo ) (bool , error ) {
7907
+
7908
+ for assetIdx := range assets {
7909
+ assetOutput := assets [assetIdx ]
7910
+ assetGen := assetOutput .AssetInfo .AssetGenesis
7911
+ assetIDBytes , err := hex .DecodeString (
7912
+ assetGen .AssetID ,
7913
+ )
7914
+ if err != nil {
7915
+ return false , fmt .Errorf ("error " +
7916
+ "decoding asset ID: %w" , err )
7917
+ }
7918
+
7919
+ var assetID asset.ID
7920
+ copy (assetID [:], assetIDBytes )
7921
+
7922
+ match , err := r .cfg .RfqManager .AssetMatchesSpecifier (
7923
+ ctx , specifier , assetID ,
7924
+ )
7925
+ if err != nil {
7926
+ return false , err
7927
+ }
7928
+
7929
+ if ! match {
7930
+ return false , nil
7931
+ }
7932
+ }
7933
+
7934
+ return true , nil
7935
+ }
7936
+
7937
+ channels := make ([]channelWithSpecifier , 0 )
7904
7938
for chanIdx := range activeChannels {
7905
7939
openChan := activeChannels [chanIdx ]
7906
7940
if len (openChan .CustomChannelData ) == 0 {
@@ -7914,27 +7948,22 @@ func (r *rpcServer) computeChannelAssetBalance(
7914
7948
"data: %w" , err )
7915
7949
}
7916
7950
7917
- for assetIdx := range assetData .Assets {
7918
- assetOutput := assetData .Assets [assetIdx ]
7919
- assetIDStr := assetOutput .AssetInfo .AssetGenesis .AssetID
7920
- assetIDBytes , err := hex .DecodeString (assetIDStr )
7921
- if err != nil {
7922
- return nil , fmt .Errorf ("error decoding asset " +
7923
- "ID: %w" , err )
7924
- }
7925
- var assetID asset.ID
7926
- copy (assetID [:], assetIDBytes )
7951
+ // Check if the assets of this channel match the provided
7952
+ // specifier.
7953
+ pass , err := specifierFilter (assetData .Assets )
7954
+ if err != nil {
7955
+ return nil , err
7956
+ }
7927
7957
7928
- channelsByID [assetID ] = append (
7929
- channelsByID [assetID ], channelWithAsset {
7930
- assetInfo : assetOutput ,
7931
- channelInfo : openChan ,
7932
- },
7933
- )
7958
+ if pass {
7959
+ channels = append (channels , channelWithSpecifier {
7960
+ specifier : specifier ,
7961
+ channelInfo : openChan ,
7962
+ })
7934
7963
}
7935
7964
}
7936
7965
7937
- return channelsByID , nil
7966
+ return channels , nil
7938
7967
}
7939
7968
7940
7969
// getInboundPolicy returns the policy of the given channel that points towards
0 commit comments