@@ -6685,16 +6685,10 @@ func (r *rpcServer) checkPeerChannel(ctx context.Context, peer route.Vertex,
66856685 // For any other case, we'll want to make sure there is a channel with
66866686 // a non-zero balance of the given asset to carry the order.
66876687 default :
6688- assetID , err := specifier .UnwrapIdOrErr ()
6689- if err != nil {
6690- return fmt .Errorf ("cannot check asset channel, " +
6691- "missing asset ID" )
6692- }
6693-
66946688 // If we don't get an error here, it means we do have an asset
66956689 // channel with the peer. The intention doesn't matter as we're
66966690 // just checking whether a channel exists.
6697- _ , err = r .rfqChannel (ctx , assetID , & peer , NoIntention )
6691+ _ , err : = r .rfqChannel (ctx , specifier , & peer , NoIntention )
66986692 if err != nil {
66996693 return fmt .Errorf ("error checking asset channel: %w" ,
67006694 err )
@@ -7370,9 +7364,11 @@ func (r *rpcServer) SendPayment(req *tchrpc.SendPaymentRequest,
73707364 peerPubKey = & parsedKey
73717365 }
73727366
7367+ specifier := asset .NewSpecifierFromId (assetID )
7368+
73737369 // We can now query the asset channels we have.
73747370 assetChan , err := r .rfqChannel (
7375- ctx , assetID , peerPubKey , SendIntention ,
7371+ ctx , specifier , peerPubKey , SendIntention ,
73767372 )
73777373 if err != nil {
73787374 return fmt .Errorf ("error finding asset channel to " +
@@ -7663,9 +7659,11 @@ func (r *rpcServer) AddInvoice(ctx context.Context,
76637659 peerPubKey = & parsedKey
76647660 }
76657661
7662+ specifier := asset .NewSpecifierFromId (assetID )
7663+
76667664 // We can now query the asset channels we have.
76677665 assetChan , err := r .rfqChannel (
7668- ctx , assetID , peerPubKey , ReceiveIntention ,
7666+ ctx , specifier , peerPubKey , ReceiveIntention ,
76697667 )
76707668 if err != nil {
76717669 return nil , fmt .Errorf ("error finding asset channel to use: %w" ,
@@ -7952,60 +7950,59 @@ const (
79527950
79537951// rfqChannel returns the channel to use for RFQ operations. If a peer public
79547952// key is specified, the channels are filtered by that peer. If there are
7955- // multiple channels for the same asset , the user must specify the peer public
7956- // key.
7957- func (r * rpcServer ) rfqChannel (ctx context.Context , id asset.ID ,
7953+ // multiple channels for the same specifier , the user must specify the peer
7954+ // public key.
7955+ func (r * rpcServer ) rfqChannel (ctx context.Context , specifier asset.Specifier ,
79587956 peerPubKey * route.Vertex ,
7959- intention chanIntention ) (* channelWithAsset , error ) {
7957+ intention chanIntention ) (* channelWithSpecifier , error ) {
79607958
7961- balances , err := r .computeChannelAssetBalance (ctx )
7959+ balances , err := r .computeChannelAssetBalance (ctx , specifier )
79627960 if err != nil {
79637961 return nil , fmt .Errorf ("error computing available asset " +
79647962 "channel balance: %w" , err )
79657963 }
79667964
7967- assetBalances , haveBalance := balances [id ]
7968- if ! haveBalance || len (assetBalances ) == 0 {
7969- return nil , fmt .Errorf ("no asset channel balance found for " +
7970- "asset %s" , id .String ())
7965+ if len (balances ) == 0 {
7966+ return nil , fmt .Errorf ("no asset channel balance found for %s" ,
7967+ & specifier )
79717968 }
79727969
79737970 // If a peer public key was specified, we always want to use that to
79747971 // filter the asset channels.
79757972 if peerPubKey != nil {
7976- assetBalances = fn .Filter (
7977- assetBalances , func (c channelWithAsset ) bool {
7973+ balances = fn .Filter (
7974+ balances , func (c channelWithSpecifier ) bool {
79787975 return c .channelInfo .PubKeyBytes == * peerPubKey
79797976 },
79807977 )
79817978 }
79827979
79837980 switch {
7984- // If there are multiple asset channels for the same asset , we need to
7985- // ask the user to specify the peer public key. Otherwise, we don't know
7986- // who to ask for a quote.
7987- case len (assetBalances ) > 1 && peerPubKey == nil :
7981+ // If there are multiple asset channels for the same specifier , we need
7982+ // to ask the user to specify the peer public key. Otherwise, we don't
7983+ // know who to ask for a quote.
7984+ case len (balances ) > 1 && peerPubKey == nil :
79887985 return nil , fmt .Errorf ("multiple asset channels found for " +
7989- "asset %s, please specify the peer pubkey" , id . String () )
7986+ "%s, please specify the peer pubkey" , & specifier )
79907987
79917988 // We don't have any channels with that asset ID and peer.
7992- case len (assetBalances ) == 0 :
7993- return nil , fmt .Errorf ("no asset channel found for asset %s " +
7994- "and peer %s" , id . String (), peerPubKey . String () )
7989+ case len (balances ) == 0 :
7990+ return nil , fmt .Errorf ("no asset channel found for %s" ,
7991+ & specifier )
79957992 }
79967993
79977994 // If the user specified a peer public key, and we still have multiple
79987995 // channels, it means we have multiple channels with the same asset and
79997996 // the same peer, as we ruled out the rest of the cases above.
80007997
80017998 // Initialize best balance to first channel of the list.
8002- bestBalance := assetBalances [0 ]
7999+ bestBalance := balances [0 ]
80038000
80048001 switch intention {
80058002 case ReceiveIntention :
80068003 // If the intention is to receive, return the channel
80078004 // with the best remote balance.
8008- fn .ForEach (assetBalances , func (b channelWithAsset ) {
8005+ fn .ForEach (balances , func (b channelWithSpecifier ) {
80098006 if b .assetInfo .RemoteBalance >
80108007 bestBalance .assetInfo .RemoteBalance {
80118008
@@ -8016,7 +8013,7 @@ func (r *rpcServer) rfqChannel(ctx context.Context, id asset.ID,
80168013 case SendIntention :
80178014 // If the intention is to send, return the channel with
80188015 // the best local balance.
8019- fn .ForEach (assetBalances , func (b channelWithAsset ) {
8016+ fn .ForEach (balances , func (b channelWithSpecifier ) {
80208017 if b .assetInfo .LocalBalance >
80218018 bestBalance .assetInfo .LocalBalance {
80228019
@@ -8032,28 +8029,33 @@ func (r *rpcServer) rfqChannel(ctx context.Context, id asset.ID,
80328029 return & bestBalance , nil
80338030}
80348031
8035- // channelWithAsset is a helper struct that combines the information of a single
8036- // asset within a channel with the channels' general information.
8037- type channelWithAsset struct {
8038- // assetInfo is the information about one of the assets in a channel.
8039- assetInfo rfqmsg.JsonAssetChanInfo
8032+ // channelWithSpecifier is a helper struct that combines the information of an
8033+ // asset specifier that is satisfied by a channel with the channels' general
8034+ // information.
8035+ type channelWithSpecifier struct {
8036+ // specifier is the asset specifier that is satisfied by this channels'
8037+ // assets.
8038+ specifier asset.Specifier
80408039
80418040 // channelInfo is the information about the channel the asset is
80428041 // committed to.
80438042 channelInfo lndclient.ChannelInfo
8043+
8044+ // assetInfo contains the asset related info of the channel.
8045+ assetInfo rfqmsg.JsonAssetChanInfo
80448046}
80458047
80468048// computeChannelAssetBalance computes the total local and remote balance for
8047- // each asset channel.
8048- func (r * rpcServer ) computeChannelAssetBalance (
8049- ctx context. Context ) (map [asset. ID ][] channelWithAsset , error ) {
8049+ // each asset channel that matches the provided asset specifier .
8050+ func (r * rpcServer ) computeChannelAssetBalance (ctx context. Context ,
8051+ specifier asset. Specifier ) ([] channelWithSpecifier , error ) {
80508052
80518053 activeChannels , err := r .cfg .Lnd .Client .ListChannels (ctx , true , false )
80528054 if err != nil {
80538055 return nil , fmt .Errorf ("unable to fetch channels: %w" , err )
80548056 }
80558057
8056- channelsByID := make (map [asset. ID ][] channelWithAsset )
8058+ channels := make ([] channelWithSpecifier , 0 )
80578059 for chanIdx := range activeChannels {
80588060 openChan := activeChannels [chanIdx ]
80598061 if len (openChan .CustomChannelData ) == 0 {
@@ -8067,27 +8069,37 @@ func (r *rpcServer) computeChannelAssetBalance(
80678069 "data: %w" , err )
80688070 }
80698071
8070- for assetIdx := range assetData .Assets {
8071- assetOutput := assetData .Assets [assetIdx ]
8072- assetIDStr := assetOutput .AssetInfo .AssetGenesis .AssetID
8073- assetIDBytes , err := hex .DecodeString (assetIDStr )
8074- if err != nil {
8075- return nil , fmt .Errorf ("error decoding asset " +
8076- "ID: %w" , err )
8072+ // Check if the assets of this channel match the provided
8073+ // specifier.
8074+ pass , err := r .cfg .RfqManager .ChannelCompatible (
8075+ ctx , assetData .Assets , specifier ,
8076+ )
8077+ if err != nil {
8078+ return nil , err
8079+ }
8080+
8081+ if pass {
8082+ // Since the assets of the channel passed the above
8083+ // filter, we're safe to aggregate their info to be
8084+ // represented as a single entity.
8085+ var aggrInfo rfqmsg.JsonAssetChanInfo
8086+
8087+ // TODO(george): refactor when JSON gets fixed
8088+ for _ , info := range assetData .Assets {
8089+ aggrInfo .Capacity += info .Capacity
8090+ aggrInfo .LocalBalance += info .LocalBalance
8091+ aggrInfo .RemoteBalance += info .RemoteBalance
80778092 }
8078- var assetID asset.ID
8079- copy (assetID [:], assetIDBytes )
80808093
8081- channelsByID [assetID ] = append (
8082- channelsByID [assetID ], channelWithAsset {
8083- assetInfo : assetOutput ,
8084- channelInfo : openChan ,
8085- },
8086- )
8094+ channels = append (channels , channelWithSpecifier {
8095+ specifier : specifier ,
8096+ channelInfo : openChan ,
8097+ assetInfo : aggrInfo ,
8098+ })
80878099 }
80888100 }
80898101
8090- return channelsByID , nil
8102+ return channels , nil
80918103}
80928104
80938105// getInboundPolicy returns the policy of the given channel that points towards
0 commit comments