-
Notifications
You must be signed in to change notification settings - Fork 107
Update litcli for multi-rfq send #1125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: tapd-main-branch
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,14 +5,14 @@ import ( | |
"context" | ||
"crypto/rand" | ||
"encoding/hex" | ||
"errors" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/lightninglabs/taproot-assets/rfq" | ||
"github.com/lightninglabs/taproot-assets/rfqmath" | ||
"github.com/lightninglabs/taproot-assets/rpcutils" | ||
"github.com/lightninglabs/taproot-assets/taprpc" | ||
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc" | ||
tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc" | ||
"github.com/lightningnetwork/lnd/cmd/commands" | ||
"github.com/lightningnetwork/lnd/lnrpc" | ||
|
@@ -210,9 +210,8 @@ var ( | |
rfqPeerPubKeyFlag = cli.StringFlag{ | ||
Name: "rfq_peer_pubkey", | ||
Usage: "(optional) the public key of the peer to ask for a " + | ||
"quote when converting from assets to sats; must be " + | ||
"set if there are multiple channels with the same " + | ||
"asset ID present", | ||
"quote when converting from assets to sats; if left " + | ||
"unset then rfq peers will be picked automatically", | ||
} | ||
|
||
allowOverpayFlag = cli.BoolFlag{ | ||
|
@@ -237,74 +236,80 @@ type resultStreamWrapper struct { | |
// | ||
// NOTE: This method is part of the PaymentResultStream interface. | ||
func (w *resultStreamWrapper) Recv() (*lnrpc.Payment, error) { | ||
resp, err := w.stream.Recv() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
res := resp.Result | ||
switch r := res.(type) { | ||
// The very first response might be an accepted sell order, which we | ||
// just print out. | ||
case *tchrpc.SendPaymentResponse_AcceptedSellOrder: | ||
quote := r.AcceptedSellOrder | ||
// printQuote unmarshals and prints an accepted quote. | ||
printQuote := func(quote *rfqrpc.PeerAcceptedSellQuote) error { | ||
rpcRate := quote.BidAssetRate | ||
rate, err := rpcutils.UnmarshalRfqFixedPoint(rpcRate) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to unmarshal fixed "+ | ||
"point: %w", err) | ||
return fmt.Errorf("unable to unmarshal fixed point: %w", | ||
err) | ||
} | ||
|
||
amountMsat := lnwire.MilliSatoshi(w.amountMsat) | ||
milliSatsFP := rfqmath.MilliSatoshiToUnits(amountMsat, *rate) | ||
numUnits := milliSatsFP.ScaleTo(0).ToUint64() | ||
|
||
// If the calculated number of units is 0 then the asset rate | ||
// was not sufficient to represent the value of this payment. | ||
// The purpose of this function is just to print, so let's avoid | ||
// dividing by zero or reporting an invalid msat/unit rate. | ||
if numUnits == 0 { | ||
// We will calculate the minimum amount that can be | ||
// effectively sent with this asset by calculating the | ||
// value of a single asset unit, based on the provided | ||
// asset rate. | ||
|
||
// We create the single unit. | ||
unit := rfqmath.FixedPointFromUint64[rfqmath.BigInt]( | ||
1, 0, | ||
) | ||
|
||
// We derive the minimum amount. | ||
minAmt := rfqmath.UnitsToMilliSatoshi(unit, *rate) | ||
|
||
// We return the error to the user. | ||
return nil, fmt.Errorf("smallest payment with asset "+ | ||
"rate %v is %v, cannot send %v", | ||
rate.ToUint64(), minAmt, amountMsat) | ||
return nil | ||
} | ||
|
||
msatPerUnit := uint64(w.amountMsat) / numUnits | ||
|
||
fmt.Printf("Got quote for %v asset units at %v msat/unit from "+ | ||
"peer %s with SCID %d\n", numUnits, msatPerUnit, | ||
" peer %s with SCID %d\n", numUnits, msatPerUnit, | ||
quote.Peer, quote.Scid) | ||
|
||
resp, err = w.stream.Recv() | ||
return nil | ||
} | ||
|
||
// A boolean to indicate whether the first quote was printed via the | ||
// legacy single-rfq response field. | ||
legacyFirstPrint := false | ||
|
||
for { | ||
resp, err := w.stream.Recv() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if resp == nil || resp.Result == nil || | ||
resp.GetPaymentResult() == nil { | ||
res := resp.Result | ||
|
||
return nil, errors.New("unexpected nil result") | ||
} | ||
switch r := res.(type) { | ||
case *tchrpc.SendPaymentResponse_AcceptedSellOrder: | ||
err := printQuote(r.AcceptedSellOrder) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return resp.GetPaymentResult(), nil | ||
legacyFirstPrint = true | ||
|
||
case *tchrpc.SendPaymentResponse_PaymentResult: | ||
return r.PaymentResult, nil | ||
case *tchrpc.SendPaymentResponse_AcceptedSellOrders: | ||
quotes := r.AcceptedSellOrders.AcceptedSellOrders | ||
|
||
default: | ||
return nil, fmt.Errorf("unexpected response type: %T", r) | ||
for _, quote := range quotes { | ||
// If the first item was returned via the legacy | ||
// field then skip printing it again here. This | ||
// skip only applies to the first element. | ||
if legacyFirstPrint { | ||
legacyFirstPrint = false | ||
continue | ||
} | ||
|
||
err := printQuote(quote) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
Comment on lines
+280
to
+304
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just checking that this is correct behaviour: |
||
|
||
case *tchrpc.SendPaymentResponse_PaymentResult: | ||
return r.PaymentResult, nil | ||
|
||
default: | ||
return nil, fmt.Errorf("unexpected response type: %T", | ||
r) | ||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmmm not seeing that the rest of the changes in this PR actually changes this? If this is due to some other change that's already been merged previously, consider splitting this change into a separate commit and explain why this is now added.