@@ -12,7 +12,6 @@ import (
1212 "github.com/lightninglabs/taproot-assets/rfqmsg"
1313 "github.com/lightningnetwork/lnd/lnutils"
1414 "github.com/lightningnetwork/lnd/lnwire"
15- "github.com/lightningnetwork/lnd/routing/route"
1615)
1716
1817const (
@@ -105,8 +104,8 @@ func NewNegotiator(cfg NegotiatorCfg) (*Negotiator, error) {
105104
106105// queryBidFromPriceOracle queries the price oracle for a bid price. It returns
107106// an appropriate outgoing response message which should be sent to the peer.
108- func (n * Negotiator ) queryBidFromPriceOracle (peer route. Vertex ,
109- assetSpecifier asset. Specifier , assetMaxAmt fn.Option [uint64 ],
107+ func (n * Negotiator ) queryBidFromPriceOracle (assetSpecifier asset. Specifier ,
108+ assetMaxAmt fn.Option [uint64 ],
110109 paymentMaxAmt fn.Option [lnwire.MilliSatoshi ],
111110 assetRateHint fn.Option [rfqmsg.AssetRate ]) (* rfqmsg.AssetRate , error ) {
112111
@@ -177,8 +176,11 @@ func (n *Negotiator) HandleOutgoingBuyOrder(buyOrder BuyOrder) error {
177176 buyOrder .AssetSpecifier .IsSome () {
178177
179178 // Query the price oracle for a bid price.
179+ //
180+ // TODO(ffranr): Pass the BuyOrder expiry to the price
181+ // oracle at this point.
180182 assetRate , err := n .queryBidFromPriceOracle (
181- peer , buyOrder .AssetSpecifier ,
183+ buyOrder .AssetSpecifier ,
182184 fn .Some (buyOrder .AssetMaxAmt ),
183185 fn .None [lnwire.MilliSatoshi ](),
184186 fn .None [rfqmsg.AssetRate ](),
@@ -227,8 +229,8 @@ func (n *Negotiator) HandleOutgoingBuyOrder(buyOrder BuyOrder) error {
227229// queryAskFromPriceOracle queries the price oracle for an asking price. It
228230// returns an appropriate outgoing response message which should be sent to the
229231// peer.
230- func (n * Negotiator ) queryAskFromPriceOracle (peer * route. Vertex ,
231- assetSpecifier asset. Specifier , assetMaxAmt fn.Option [uint64 ],
232+ func (n * Negotiator ) queryAskFromPriceOracle (assetSpecifier asset. Specifier ,
233+ assetMaxAmt fn.Option [uint64 ],
232234 paymentMaxAmt fn.Option [lnwire.MilliSatoshi ],
233235 assetRateHint fn.Option [rfqmsg.AssetRate ]) (* rfqmsg.AssetRate , error ) {
234236
@@ -326,7 +328,7 @@ func (n *Negotiator) HandleIncomingBuyRequest(
326328
327329 // Query the price oracle for an asking price.
328330 assetRate , err := n .queryAskFromPriceOracle (
329- nil , request .AssetSpecifier ,
331+ request .AssetSpecifier ,
330332 fn .Some (request .AssetMaxAmt ),
331333 fn .None [lnwire.MilliSatoshi ](),
332334 request .AssetRateHint ,
@@ -347,10 +349,7 @@ func (n *Negotiator) HandleIncomingBuyRequest(
347349 }
348350
349351 // Construct and send a buy accept message.
350- expiry := uint64 (assetRate .Expiry .Unix ())
351- msg := rfqmsg .NewBuyAcceptFromRequest (
352- request , assetRate .Rate , expiry ,
353- )
352+ msg := rfqmsg .NewBuyAcceptFromRequest (request , * assetRate )
354353 sendOutgoingMsg (msg )
355354 }()
356355
@@ -426,9 +425,8 @@ func (n *Negotiator) HandleIncomingSellRequest(
426425 // are willing to pay for the asset that our peer is trying to
427426 // sell to us.
428427 assetRate , err := n .queryBidFromPriceOracle (
429- request .Peer , request .AssetSpecifier ,
430- fn .None [uint64 ](), fn .Some (request .PaymentMaxAmt ),
431- request .AssetRateHint ,
428+ request .AssetSpecifier , fn .None [uint64 ](),
429+ fn .Some (request .PaymentMaxAmt ), request .AssetRateHint ,
432430 )
433431 if err != nil {
434432 // Send a reject message to the peer.
@@ -446,10 +444,7 @@ func (n *Negotiator) HandleIncomingSellRequest(
446444 }
447445
448446 // Construct and send a sell accept message.
449- expiry := uint64 (assetRate .Expiry .Unix ())
450- msg := rfqmsg .NewSellAcceptFromRequest (
451- request , assetRate .Rate , expiry ,
452- )
447+ msg := rfqmsg .NewSellAcceptFromRequest (request , * assetRate )
453448 sendOutgoingMsg (msg )
454449 }()
455450
@@ -467,27 +462,27 @@ func (n *Negotiator) HandleOutgoingSellOrder(order SellOrder) {
467462 go func () {
468463 defer n .Wg .Done ()
469464
465+ // Unwrap the peer from the order. For now, we can assume that
466+ // the peer is always specified.
467+ peer , err := order .Peer .UnwrapOrErr (
468+ fmt .Errorf ("buy order peer must be specified" ),
469+ )
470+ if err != nil {
471+ n .cfg .ErrChan <- err
472+ }
473+
470474 // We calculate a proposed ask price for our peer's
471475 // consideration. If a price oracle is not specified we will
472476 // skip this step.
473477 var assetRateHint fn.Option [rfqmsg.AssetRate ]
474478
475- // Construct an asset specifier from the order.
476- // TODO(ffranr): The order should have an asset specifier.
477- assetSpecifier , err := asset .NewSpecifier (
478- order .AssetID , order .AssetGroupKey , nil ,
479- true ,
480- )
481- if err != nil {
482- log .Warnf ("failed to construct asset " +
483- "specifier from buy order: %v" , err )
484- }
485-
486- if n .cfg .PriceOracle != nil && assetSpecifier .IsSome () {
479+ if n .cfg .PriceOracle != nil && order .AssetSpecifier .IsSome () {
487480 // Query the price oracle for an asking price.
481+ //
482+ // TODO(ffranr): Pass the SellOrder expiry to the
483+ // price oracle at this point.
488484 assetRate , err := n .queryAskFromPriceOracle (
489- order .Peer , assetSpecifier ,
490- fn .None [uint64 ](),
485+ order .AssetSpecifier , fn .None [uint64 ](),
491486 fn .Some (order .PaymentMaxAmt ),
492487 fn .None [rfqmsg.AssetRate ](),
493488 )
@@ -498,12 +493,12 @@ func (n *Negotiator) HandleOutgoingSellOrder(order SellOrder) {
498493 return
499494 }
500495
501- assetRateHint = fn.Some [rfqmsg. AssetRate ]( * assetRate )
496+ assetRateHint = fn .MaybeSome ( assetRate )
502497 }
503498
504499 request , err := rfqmsg .NewSellRequest (
505- * order . Peer , order .AssetID , order .AssetGroupKey ,
506- order . PaymentMaxAmt , assetRateHint ,
500+ peer , order .AssetSpecifier , order .PaymentMaxAmt ,
501+ assetRateHint ,
507502 )
508503 if err != nil {
509504 err := fmt .Errorf ("unable to create sell request " +
@@ -530,12 +525,8 @@ func (n *Negotiator) HandleOutgoingSellOrder(order SellOrder) {
530525// expiryWithinBounds checks if a quote expiry unix timestamp (in seconds) is
531526// within acceptable bounds. This check ensures that the expiry timestamp is far
532527// enough in the future for the quote to be useful.
533- func expiryWithinBounds (expiryUnixTimestamp uint64 ,
534- minExpiryLifetime uint64 ) bool {
535-
536- // Convert the expiry timestamp into a time.Time.
537- actualExpiry := time .Unix (int64 (expiryUnixTimestamp ), 0 )
538- diff := actualExpiry .Unix () - time .Now ().Unix ()
528+ func expiryWithinBounds (expiry time.Time , minExpiryLifetime uint64 ) bool {
529+ diff := expiry .Unix () - time .Now ().Unix ()
539530 return diff >= int64 (minExpiryLifetime )
540531}
541532
@@ -549,12 +540,16 @@ func (n *Negotiator) HandleIncomingBuyAccept(msg rfqmsg.BuyAccept,
549540 // Ensure that the quote expiry time is within acceptable bounds.
550541 //
551542 // TODO(ffranr): Sanity check the buy accept quote expiry
552- // timestamp given the expiry timestamp provided by the price
553- // oracle.
554- if ! expiryWithinBounds (msg .Expiry , minAssetRatesExpiryLifetime ) {
543+ // timestamp given the expiry timestamp in our outgoing buy request.
544+ // The expiry timestamp in the outgoing request relates to the lifetime
545+ // of the lightning invoice.
546+ if ! expiryWithinBounds (
547+ msg .AssetRate .Expiry , minAssetRatesExpiryLifetime ,
548+ ) {
555549 // The expiry time is not within the acceptable bounds.
556550 log .Debugf ("Buy accept quote expiry time is not within " +
557- "acceptable bounds (expiry=%d)" , msg .Expiry )
551+ "acceptable bounds (asset_rate=%s)" ,
552+ msg .AssetRate .String ())
558553
559554 // Construct an invalid quote response event so that we can
560555 // inform the peer that the quote response has not validated
@@ -601,10 +596,9 @@ func (n *Negotiator) HandleIncomingBuyAccept(msg rfqmsg.BuyAccept,
601596 // for an ask price. We will then compare the ask price returned
602597 // by the price oracle with the ask price provided by the peer.
603598 assetRate , err := n .queryAskFromPriceOracle (
604- & msg . Peer , msg .Request .AssetSpecifier ,
599+ msg .Request .AssetSpecifier ,
605600 fn .Some (msg .Request .AssetMaxAmt ),
606- fn .None [lnwire.MilliSatoshi ](),
607- fn .None [rfqmsg.AssetRate ](),
601+ fn .None [lnwire.MilliSatoshi ](), fn .Some (msg .AssetRate ),
608602 )
609603 if err != nil {
610604 // The price oracle returned an error. We will return
@@ -635,17 +629,17 @@ func (n *Negotiator) HandleIncomingBuyAccept(msg rfqmsg.BuyAccept,
635629 tolerance := rfqmath .NewBigIntFromUint64 (
636630 n .cfg .AcceptPriceDeviationPpm ,
637631 )
638- acceptablePrice := msg .AssetRate .WithinTolerance (
632+ acceptablePrice := msg .AssetRate .Rate . WithinTolerance (
639633 assetRate .Rate , tolerance ,
640634 )
641635 if ! acceptablePrice {
642636 // The price is not within the acceptable tolerance.
643637 // We will return without calling the quote accept
644638 // callback.
645639 log .Debugf ("Buy accept price is not within " +
646- "acceptable bounds (ask_asset_rate=%v , " +
647- "oracle_asset_rate=%v )" , msg .AssetRate ,
648- assetRate )
640+ "acceptable bounds (peer_asset_rate=%s , " +
641+ "oracle_asset_rate=%s )" , msg .AssetRate . String () ,
642+ assetRate . String () )
649643
650644 // Construct an invalid quote response event so that we
651645 // can inform the peer that the quote response has not
@@ -677,10 +671,13 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
677671 //
678672 // TODO(ffranr): Sanity check the quote expiry timestamp given
679673 // the expiry timestamp provided by the price oracle.
680- if ! expiryWithinBounds (msg .Expiry , minAssetRatesExpiryLifetime ) {
674+ if ! expiryWithinBounds (
675+ msg .AssetRate .Expiry , minAssetRatesExpiryLifetime ,
676+ ) {
681677 // The expiry time is not within the acceptable bounds.
682678 log .Debugf ("Sell accept quote expiry time is not within " +
683- "acceptable bounds (expiry=%d)" , msg .Expiry )
679+ "acceptable bounds (asset_rate=%s)" ,
680+ msg .AssetRate .String ())
684681
685682 // Construct an invalid quote response event so that we can
686683 // inform the peer that the quote response has not validated
@@ -727,8 +724,7 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
727724 // for a bid price. We will then compare the bid price returned
728725 // by the price oracle with the bid price provided by the peer.
729726 assetRate , err := n .queryBidFromPriceOracle (
730- msg .Peer , msg .Request .AssetSpecifier ,
731- fn .None [uint64 ](),
727+ msg .Request .AssetSpecifier , fn .None [uint64 ](),
732728 fn .Some (msg .Request .PaymentMaxAmt ),
733729 msg .Request .AssetRateHint ,
734730 )
@@ -761,7 +757,7 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
761757 tolerance := rfqmath .NewBigIntFromUint64 (
762758 n .cfg .AcceptPriceDeviationPpm ,
763759 )
764- acceptablePrice := msg .AssetRate .WithinTolerance (
760+ acceptablePrice := msg .AssetRate .Rate . WithinTolerance (
765761 assetRate .Rate , tolerance ,
766762 )
767763 if ! acceptablePrice {
0 commit comments