Skip to content

Commit 7fea652

Browse files
committed
rfq: replace custom sell offer logic with PortfolioPilot integration
- Remove HasAssetSellOffer method. - Delegate buy quote request handling to PortfolioPilot. - Improve error management and response handling.
1 parent fb25ae3 commit 7fea652

1 file changed

Lines changed: 28 additions & 97 deletions

File tree

rfq/negotiator.go

Lines changed: 28 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -334,64 +334,46 @@ func (n *Negotiator) HandleIncomingBuyRequest(
334334
}
335335
}
336336

337-
// Reject the quote request if a price oracle is unavailable.
338-
if n.cfg.PriceOracle == nil {
339-
msg := rfqmsg.NewReject(
340-
request.Peer, request.ID,
341-
rfqmsg.ErrPriceOracleUnavailable,
342-
)
343-
go sendOutgoingMsg(msg)
344-
return nil
345-
}
346-
347-
// Ensure that we have a suitable sell offer for the asset that is being
348-
// requested. Here we can handle the case where this node does not wish
349-
// to sell a particular asset.
350-
offerAvailable := n.HasAssetSellOffer(
351-
request.AssetSpecifier, request.AssetMaxAmt,
352-
)
353-
if !offerAvailable {
354-
log.Infof("Would reject buy request: no suitable buy offer, " +
355-
"but ignoring for now")
356-
357-
// TODO(ffranr): Re-enable pre-price oracle rejection (i.e.
358-
// reject on missing offer)
359-
360-
// If we do not have a suitable sell offer, then we will reject
361-
// the quote request with an error.
362-
// reject := rfqmsg.NewReject(
363-
// request.Peer, request.ID,
364-
// rfqmsg.ErrNoSuitableSellOffer,
365-
// )
366-
// go sendOutgoingMsg(reject)
367-
//
368-
// return nil
369-
}
370-
371337
// Query the price oracle asynchronously using a separate goroutine.
372338
// The price oracle might be an external service, responses could be
373339
// delayed.
374340
n.Goroutine(func() error {
375-
var peerID fn.Option[route.Vertex]
376-
if n.cfg.SendPeerId {
377-
peerID = fn.Some(request.Peer)
378-
}
341+
ctx, cancel := n.WithCtxQuitNoTimeout()
342+
defer cancel()
379343

380-
// Query the price oracle for a sale price.
381-
assetRate, err := n.querySellFromPriceOracle(
382-
request.AssetSpecifier, fn.Some(request.AssetMaxAmt),
383-
fn.None[lnwire.MilliSatoshi](), request.AssetRateHint,
384-
peerID, request.PriceOracleMetadata, IntentRecvPayment,
344+
resp, err := n.cfg.PortfolioPilot.ResolveBuyRequest(
345+
ctx, request,
385346
)
386347
if err != nil {
387-
// Send a reject message to the peer.
348+
return fmt.Errorf("resolve buy request: %w", err)
349+
}
350+
351+
if resp.IsReject() {
352+
reason := rfqmsg.ErrUnknownReject
353+
resp.WhenReject(func(err rfqmsg.RejectErr) {
354+
reason = err
355+
})
356+
357+
msg := rfqmsg.NewReject(
358+
request.Peer, request.ID, reason,
359+
)
360+
sendOutgoingMsg(msg)
361+
return nil
362+
}
363+
364+
var assetRate *rfqmsg.AssetRate
365+
resp.WhenAccept(func(rate rfqmsg.AssetRate) {
366+
assetRate = &rate
367+
})
368+
if assetRate == nil {
388369
msg := rfqmsg.NewReject(
389370
request.Peer, request.ID,
390371
rfqmsg.ErrUnknownReject,
391372
)
392373
sendOutgoingMsg(msg)
393-
return fmt.Errorf("failed to query sell price from "+
394-
"oracle: %w", err)
374+
375+
return fmt.Errorf("resolve buy request: missing " +
376+
"asset rate on accept decision")
395377
}
396378

397379
// Construct and send a buy accept message.
@@ -1015,57 +997,6 @@ func (n *Negotiator) RemoveAssetSellOffer(assetID *asset.ID,
1015997
return nil
1016998
}
1017999

1018-
// HasAssetSellOffer returns true if the negotiator has an asset sell offer
1019-
// which matches the given asset ID/group and asset amount.
1020-
//
1021-
// TODO(ffranr): This method should return errors which can be used to
1022-
// differentiate between a missing offer and an invalid offer.
1023-
func (n *Negotiator) HasAssetSellOffer(assetSpecifier asset.Specifier,
1024-
assetAmt uint64) bool {
1025-
1026-
// If the asset group key is not nil, then we will use it as the key for
1027-
// the offer. Otherwise, we will use the asset ID as the key.
1028-
var sellOffer *SellOffer
1029-
1030-
assetSpecifier.WhenGroupPubKey(func(assetGroupKey btcec.PublicKey) {
1031-
keyFixedBytes := asset.ToSerialized(&assetGroupKey)
1032-
offer, ok := n.assetGroupSellOffers.Load(keyFixedBytes)
1033-
if !ok {
1034-
// Corresponding offer not found.
1035-
return
1036-
}
1037-
1038-
sellOffer = &offer
1039-
})
1040-
1041-
assetSpecifier.WhenId(func(assetID asset.ID) {
1042-
offer, ok := n.assetSellOffers.Load(assetID)
1043-
if !ok {
1044-
// Corresponding offer not found.
1045-
return
1046-
}
1047-
1048-
sellOffer = &offer
1049-
})
1050-
1051-
// We should never have a nil sell offer at this point. Check added here
1052-
// for robustness.
1053-
if sellOffer == nil {
1054-
return false
1055-
}
1056-
1057-
// If the asset amount is greater than the maximum asset amount under
1058-
// offer, then we will return false (we do not have a suitable offer).
1059-
if assetAmt > sellOffer.MaxUnits {
1060-
log.Warnf("asset amount is greater than sell offer max units "+
1061-
"(asset_amt=%d, sell_offer_max_units=%d)", assetAmt,
1062-
sellOffer.MaxUnits)
1063-
return false
1064-
}
1065-
1066-
return true
1067-
}
1068-
10691000
// BuyOffer is a struct that represents an asset buy offer. This data structure
10701001
// describes the maximum amount of an asset that this node is willing to
10711002
// purchase.

0 commit comments

Comments
 (0)