Skip to content

Commit 56df35c

Browse files
committed
litcli: update payinvoice for multirfq
With the introduction of multi-rfq send in taproot assets (see related PR lightninglabs/taproot-assets#1613) we extended the behavior of the SendPayment RPC slightly. Now we may not specify an RFQ peer in order for a list of peers to be created & used automatically. When that happens, we will return multiple quotes over the RPC. The content of this commit changes our client wrapper around the handling of the payment result. Previously we'd expect for exactly a single quote to be returned over the stream (for the single defined peer). Now we read all of the quotes that are returned in the new quotes array field of the RPC. To maintain backwards compatibility we also kept the previous single-quote RPC field, which we make sure to only read once now that we read both fields (avoid a duplicate quote from appearing in the logs).
1 parent d9b6f4c commit 56df35c

File tree

1 file changed

+52
-47
lines changed

1 file changed

+52
-47
lines changed

cmd/litcli/ln.go

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import (
55
"context"
66
"crypto/rand"
77
"encoding/hex"
8-
"errors"
98
"fmt"
109
"time"
1110

1211
"github.com/lightninglabs/taproot-assets/rfq"
1312
"github.com/lightninglabs/taproot-assets/rfqmath"
1413
"github.com/lightninglabs/taproot-assets/rpcutils"
1514
"github.com/lightninglabs/taproot-assets/taprpc"
15+
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
1616
tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
1717
"github.com/lightningnetwork/lnd/cmd/commands"
1818
"github.com/lightningnetwork/lnd/lnrpc"
@@ -210,9 +210,8 @@ var (
210210
rfqPeerPubKeyFlag = cli.StringFlag{
211211
Name: "rfq_peer_pubkey",
212212
Usage: "(optional) the public key of the peer to ask for a " +
213-
"quote when converting from assets to sats; must be " +
214-
"set if there are multiple channels with the same " +
215-
"asset ID present",
213+
"quote when converting from assets to sats; if left " +
214+
"unset then rfq peers will be picked automatically",
216215
}
217216

218217
allowOverpayFlag = cli.BoolFlag{
@@ -237,74 +236,80 @@ type resultStreamWrapper struct {
237236
//
238237
// NOTE: This method is part of the PaymentResultStream interface.
239238
func (w *resultStreamWrapper) Recv() (*lnrpc.Payment, error) {
240-
resp, err := w.stream.Recv()
241-
if err != nil {
242-
return nil, err
243-
}
244-
245-
res := resp.Result
246-
switch r := res.(type) {
247-
// The very first response might be an accepted sell order, which we
248-
// just print out.
249-
case *tchrpc.SendPaymentResponse_AcceptedSellOrder:
250-
quote := r.AcceptedSellOrder
239+
// printQuote unmarshals and prints an accepted quote.
240+
printQuote := func(quote *rfqrpc.PeerAcceptedSellQuote) error {
251241
rpcRate := quote.BidAssetRate
252242
rate, err := rpcutils.UnmarshalRfqFixedPoint(rpcRate)
253243
if err != nil {
254-
return nil, fmt.Errorf("unable to unmarshal fixed "+
255-
"point: %w", err)
244+
return fmt.Errorf("unable to unmarshal fixed point: %w",
245+
err)
256246
}
257247

258248
amountMsat := lnwire.MilliSatoshi(w.amountMsat)
259249
milliSatsFP := rfqmath.MilliSatoshiToUnits(amountMsat, *rate)
260250
numUnits := milliSatsFP.ScaleTo(0).ToUint64()
261251

262-
// If the calculated number of units is 0 then the asset rate
263-
// was not sufficient to represent the value of this payment.
252+
// The purpose of this function is just to print, so let's avoid
253+
// dividing by zero or reporting an invalid msat/unit rate.
264254
if numUnits == 0 {
265-
// We will calculate the minimum amount that can be
266-
// effectively sent with this asset by calculating the
267-
// value of a single asset unit, based on the provided
268-
// asset rate.
269-
270-
// We create the single unit.
271-
unit := rfqmath.FixedPointFromUint64[rfqmath.BigInt](
272-
1, 0,
273-
)
274-
275-
// We derive the minimum amount.
276-
minAmt := rfqmath.UnitsToMilliSatoshi(unit, *rate)
277-
278-
// We return the error to the user.
279-
return nil, fmt.Errorf("smallest payment with asset "+
280-
"rate %v is %v, cannot send %v",
281-
rate.ToUint64(), minAmt, amountMsat)
255+
return nil
282256
}
283257

284258
msatPerUnit := uint64(w.amountMsat) / numUnits
285259

286260
fmt.Printf("Got quote for %v asset units at %v msat/unit from "+
287-
"peer %s with SCID %d\n", numUnits, msatPerUnit,
261+
" peer %s with SCID %d\n", numUnits, msatPerUnit,
288262
quote.Peer, quote.Scid)
289263

290-
resp, err = w.stream.Recv()
264+
return nil
265+
}
266+
267+
// A boolean to indicate whether the first quote was printed via the
268+
// legacy single-rfq response field.
269+
legacyFirstPrint := false
270+
271+
for {
272+
resp, err := w.stream.Recv()
291273
if err != nil {
292274
return nil, err
293275
}
294276

295-
if resp == nil || resp.Result == nil ||
296-
resp.GetPaymentResult() == nil {
277+
res := resp.Result
297278

298-
return nil, errors.New("unexpected nil result")
299-
}
279+
switch r := res.(type) {
280+
case *tchrpc.SendPaymentResponse_AcceptedSellOrder:
281+
err := printQuote(r.AcceptedSellOrder)
282+
if err != nil {
283+
return nil, err
284+
}
300285

301-
return resp.GetPaymentResult(), nil
286+
legacyFirstPrint = true
302287

303-
case *tchrpc.SendPaymentResponse_PaymentResult:
304-
return r.PaymentResult, nil
288+
case *tchrpc.SendPaymentResponse_AcceptedSellOrders:
289+
quotes := r.AcceptedSellOrders.AcceptedSellOrders
305290

306-
default:
307-
return nil, fmt.Errorf("unexpected response type: %T", r)
291+
for _, quote := range quotes {
292+
// If the first item was returned via the legacy
293+
// field then skip printing it again here. This
294+
// skip only applies to the first element.
295+
if legacyFirstPrint {
296+
legacyFirstPrint = false
297+
continue
298+
}
299+
300+
err := printQuote(quote)
301+
if err != nil {
302+
return nil, err
303+
}
304+
}
305+
306+
case *tchrpc.SendPaymentResponse_PaymentResult:
307+
return r.PaymentResult, nil
308+
309+
default:
310+
return nil, fmt.Errorf("unexpected response type: %T",
311+
r)
312+
}
308313
}
309314
}
310315

0 commit comments

Comments
 (0)