@@ -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