Skip to content

Commit 9da1d71

Browse files
committed
rpcserver: skip rfq negotiation on manual SendPayment rfq
1 parent 24b46d2 commit 9da1d71

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

rpcserver.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7034,6 +7034,87 @@ func (r *rpcServer) SendPayment(req *tchrpc.SendPaymentRequest,
70347034
case len(firstHopRecords) > 0:
70357035
// Continue below.
70367036

7037+
case req.RfqId != nil:
7038+
// Check if the provided rfq ID matches the expected length.
7039+
if len(req.RfqId) != 32 {
7040+
return fmt.Errorf("rfq must be 32 bytes in length")
7041+
}
7042+
7043+
// Now let's try to perform an internal lookup to see if there's
7044+
// an actual quote on this ID.
7045+
var rfqID rfqmsg.ID
7046+
copy(rfqID[:], req.RfqId)
7047+
7048+
var quote *rfqmsg.SellAccept
7049+
for _, q := range r.cfg.RfqManager.PeerAcceptedSellQuotes() {
7050+
if q.ID == rfqID {
7051+
qCopy := q
7052+
quote = &qCopy
7053+
break
7054+
}
7055+
}
7056+
7057+
// This quote ID did not match anything.
7058+
if quote == nil {
7059+
return fmt.Errorf("quote ID did not match an " +
7060+
"accepted quote")
7061+
}
7062+
7063+
invoice, err := zpay32.Decode(
7064+
pReq.PaymentRequest, r.cfg.Lnd.ChainParams,
7065+
)
7066+
if err != nil {
7067+
return fmt.Errorf("error decoding payment request: %w",
7068+
err)
7069+
}
7070+
7071+
rate := quote.AssetRate.Rate
7072+
7073+
// Calculate the equivalent asset units for the given invoice
7074+
// amount based on the asset-to-BTC conversion rate.
7075+
numAssetUnits := rfqmath.MilliSatoshiToUnits(
7076+
*invoice.MilliSat, rate,
7077+
)
7078+
7079+
sellOrder := &rfqrpc.PeerAcceptedSellQuote{
7080+
Peer: quote.Peer.String(),
7081+
Id: quote.ID[:],
7082+
Scid: uint64(quote.ID.Scid()),
7083+
BidAssetRate: &rfqrpc.FixedPoint{
7084+
Coefficient: rate.Coefficient.String(),
7085+
Scale: uint32(rate.Scale),
7086+
},
7087+
AssetAmount: numAssetUnits.ToUint64(),
7088+
Expiry: uint64(quote.AssetRate.Expiry.Unix()),
7089+
}
7090+
7091+
// Send out the information about the quote on the stream.
7092+
err = stream.Send(&tchrpc.SendPaymentResponse{
7093+
Result: &tchrpc.SendPaymentResponse_AcceptedSellOrder{
7094+
AcceptedSellOrder: sellOrder,
7095+
},
7096+
})
7097+
if err != nil {
7098+
return fmt.Errorf("payment failed to send accepted "+
7099+
"sell order over stream: %v", err)
7100+
}
7101+
7102+
rpcsLog.Infof("Using quote for %v asset units at %v asset/BTC "+
7103+
"from peer %x with SCID %d", numAssetUnits,
7104+
rate.String(), quote.Peer, quote.ID.Scid())
7105+
7106+
htlc := rfqmsg.NewHtlc(nil, fn.Some(quote.ID))
7107+
7108+
// We'll now map the HTLC struct into a set of TLV records,
7109+
// which we can then encode into the expected map format.
7110+
htlcMapRecords, err := tlv.RecordsToMap(htlc.Records())
7111+
if err != nil {
7112+
return fmt.Errorf("unable to encode records as map: %w",
7113+
err)
7114+
}
7115+
7116+
pReq.FirstHopCustomRecords = htlcMapRecords
7117+
70377118
// The request wants to pay a specific invoice.
70387119
case pReq.PaymentRequest != "":
70397120
invoice, err := zpay32.Decode(

0 commit comments

Comments
 (0)