Skip to content

Commit

Permalink
rpc: refactor obtaining an RFQ send quote into new method
Browse files Browse the repository at this point in the history
  • Loading branch information
Roasbeef committed Dec 13, 2024
1 parent 515a0b2 commit ad994f1
Showing 1 changed file with 63 additions and 47 deletions.
110 changes: 63 additions & 47 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -6989,6 +6989,65 @@ func (r *rpcServer) EncodeCustomRecords(_ context.Context,
}
}

// fetchSendRfqQuote fetches a sell quote from the RFQ manager to fulfill an
// invoice with the given set of params.
func (r *rpcServer) fetchSendRfqQuote(ctx context.Context, assetID asset.ID,
invoiceAmt lnwire.MilliSatoshi, peerPubKey *route.Vertex,
expiryTimestamp time.Time) (*rfqrpc.PeerAcceptedSellQuote, error) {

// We can now query the asset channels we have.
assetChan, err := r.rfqChannel(ctx, assetID, peerPubKey)
if err != nil {
return nil, fmt.Errorf("error finding asset channel to "+
"use: %w", err)
}

// Even if the user didn't specify the peer public key before, we
// definitely know it now. So let's make sure it's always set.
peerPubKey = &assetChan.channelInfo.PubKeyBytes

sendQuote, err := r.AddAssetSellOrder(
ctx, &rfqrpc.AddAssetSellOrderRequest{
AssetSpecifier: &rfqrpc.AssetSpecifier{
Id: &rfqrpc.AssetSpecifier_AssetId{
AssetId: assetID[:],
},
},
PaymentMaxAmt: uint64(invoiceAmt),
Expiry: uint64(expiryTimestamp.Unix()),
PeerPubKey: peerPubKey[:],
TimeoutSeconds: uint32(
rfq.DefaultTimeout.Seconds(),
),
},
)
if err != nil {
return nil, fmt.Errorf("error adding sell order: %w", err)
}

var acceptedQuote *rfqrpc.PeerAcceptedSellQuote
switch r := sendQuote.Response.(type) {
case *rfqrpc.AddAssetSellOrderResponse_AcceptedQuote:
acceptedQuote = r.AcceptedQuote

case *rfqrpc.AddAssetSellOrderResponse_InvalidQuote:
return nil, fmt.Errorf("peer %v sent back an invalid "+
"quote, status: %v", r.InvalidQuote.Peer,
r.InvalidQuote.Status.String())

case *rfqrpc.AddAssetSellOrderResponse_RejectedQuote:
return nil, fmt.Errorf("peer %v rejected the quote, code: "+
"%v, error message: %v", r.RejectedQuote.Peer,
r.RejectedQuote.ErrorCode,
r.RejectedQuote.ErrorMessage)

default:
return nil, fmt.Errorf("unexpected response type: %T", r)
}

return acceptedQuote, nil
}

// SendPayment is a wrapper around lnd's routerrpc.SendPaymentV2 RPC method
// with asset specific parameters. It allows RPC users to send asset keysend
// payments (direct payments) or payments to an invoice with a specified asset
Expand Down Expand Up @@ -7113,18 +7172,6 @@ func (r *rpcServer) SendPayment(req *tchrpc.SendPaymentRequest,
peerPubKey = &parsedKey
}

// We can now query the asset channels we have.
assetChan, err := r.rfqChannel(ctx, assetID, peerPubKey)
if err != nil {
return fmt.Errorf("error finding asset channel to "+
"use: %w", err)
}

// Even if the user didn't specify the peer public key before,
// we definitely know it now. So let's make sure it's always
// set.
peerPubKey = &assetChan.channelInfo.PubKeyBytes

// paymentMaxAmt is the maximum amount that the counterparty is
// expected to pay. This is the amount that the invoice is
// asking for plus the fee limit in milli-satoshis.
Expand Down Expand Up @@ -7157,43 +7204,12 @@ func (r *rpcServer) SendPayment(req *tchrpc.SendPaymentRequest,
paymentMaxAmt += feeLimit

expiryTimestamp := invoice.Timestamp.Add(invoice.Expiry())
resp, err := r.AddAssetSellOrder(
ctx, &rfqrpc.AddAssetSellOrderRequest{
AssetSpecifier: &rfqrpc.AssetSpecifier{
Id: &rfqrpc.AssetSpecifier_AssetId{
AssetId: assetID[:],
},
},
PaymentMaxAmt: uint64(paymentMaxAmt),
Expiry: uint64(expiryTimestamp.Unix()),
PeerPubKey: peerPubKey[:],
TimeoutSeconds: uint32(
rfq.DefaultTimeout.Seconds(),
),
},
acceptedQuote, err := r.fetchSendRfqQuote(
ctx, assetID, paymentMaxAmt, peerPubKey,
expiryTimestamp,
)
if err != nil {
return fmt.Errorf("error adding sell order: %w", err)
}

var acceptedQuote *rfqrpc.PeerAcceptedSellQuote
switch r := resp.Response.(type) {
case *rfqrpc.AddAssetSellOrderResponse_AcceptedQuote:
acceptedQuote = r.AcceptedQuote

case *rfqrpc.AddAssetSellOrderResponse_InvalidQuote:
return fmt.Errorf("peer %v sent back an invalid "+
"quote, status: %v", r.InvalidQuote.Peer,
r.InvalidQuote.Status.String())

case *rfqrpc.AddAssetSellOrderResponse_RejectedQuote:
return fmt.Errorf("peer %v rejected the quote, code: "+
"%v, error message: %v", r.RejectedQuote.Peer,
r.RejectedQuote.ErrorCode,
r.RejectedQuote.ErrorMessage)

default:
return fmt.Errorf("unexpected response type: %T", r)
return fmt.Errorf("error sending RFQ quote: %w", err)
}

// Send out the information about the quote on the stream.
Expand Down

0 comments on commit ad994f1

Please sign in to comment.