Skip to content

Commit

Permalink
Merge pull request #1156 from lightninglabs/rfq-rm-rate-tick
Browse files Browse the repository at this point in the history
Remove remaining instances of "rate tick" from RFQ systems
  • Loading branch information
ffranr authored Oct 22, 2024
2 parents 36a85b6 + 07ac6a4 commit eeadc03
Show file tree
Hide file tree
Showing 19 changed files with 537 additions and 540 deletions.
97 changes: 48 additions & 49 deletions docs/examples/basic-price-oracle/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// This example demonstrates a basic RPC price oracle server that implements the
// QueryRateTick RPC method. The server listens on localhost:8095 and returns a
// rate tick for a given transaction type, subject asset, and payment asset. The
// rate tick is the exchange rate between the subject asset and the payment
// QueryAssetRates RPC method. The server listens on localhost:8095 and returns
// the asset rates for a given transaction type, subject asset, and payment
// asset.
package main

Expand Down Expand Up @@ -103,10 +102,10 @@ func isSupportedSubjectAsset(subjectAsset *oraclerpc.AssetSpecifier) bool {
return false
}

// getRateTick returns a rate tick for a given transaction type and subject
// asset max amount.
func getRateTick(transactionType oraclerpc.TransactionType,
subjectAssetMaxAmount uint64) (oraclerpc.RateTick, error) {
// getAssetRates returns the asset rates for a given transaction type and
// subject asset max amount.
func getAssetRates(transactionType oraclerpc.TransactionType,
subjectAssetMaxAmount uint64) (oraclerpc.AssetRates, error) {

// Determine the rate based on the transaction type.
var subjectAssetRate rfqmath.BigIntFixedPoint
Expand Down Expand Up @@ -142,61 +141,61 @@ func getRateTick(transactionType oraclerpc.TransactionType,
subjectAssetRate,
)
if err != nil {
return oraclerpc.RateTick{}, err
return oraclerpc.AssetRates{}, err
}

// Marshal payment asset rate to RPC format.
rpcPaymentAssetToBtcRate, err := oraclerpc.MarshalBigIntFixedPoint(
rfqmsg.MilliSatPerBtc,
)
if err != nil {
return oraclerpc.RateTick{}, err
return oraclerpc.AssetRates{}, err
}

return oraclerpc.RateTick{
return oraclerpc.AssetRates{
SubjectAssetRate: rpcSubjectAssetToBtcRate,
PaymentAssetRate: rpcPaymentAssetToBtcRate,
ExpiryTimestamp: uint64(expiry),
}, nil
}

// QueryRateTick queries the rate tick for a given transaction type, subject
// asset, and payment asset. The rate tick is the exchange rate between the
// subject asset and the payment asset.
// QueryAssetRates queries the asset rates for a given transaction type, subject
// asset, and payment asset. An asset rate is the number of asset units per
// BTC.
//
// Example use case:
//
// Alice is trying to pay an invoice by spending an asset. Alice therefore
// requests that Bob (her asset channel counterparty) purchase the asset from
// her. Bob's payment, in BTC, will pay the invoice.
//
// Alice requests a bid quote from Bob. Her request includes a rate tick
// hint (ask). Alice get the rate tick hint by calling this endpoint. She sets:
// Alice requests a bid quote from Bob. Her request includes an asset rates hint
// (ask). Alice obtains the asset rates hint by calling this endpoint. She sets:
// - `SubjectAsset` to the asset she is trying to sell.
// - `SubjectAssetMaxAmount` to the max channel asset outbound.
// - `PaymentAsset` to BTC.
// - `TransactionType` to SALE.
// - `RateTickHint` to nil.
// - `AssetRateHint` to nil.
//
// Bob calls this endpoint to get the bid quote rate tick that he will send as a
// response to Alice's request. He sets:
// Bob calls this endpoint to get the bid quote asset rates that he will send as
// a response to Alice's request. He sets:
// - `SubjectAsset` to the asset that Alice is trying to sell.
// - `SubjectAssetMaxAmount` to the value given in Alice's quote request.
// - `PaymentAsset` to BTC.
// - `TransactionType` to PURCHASE.
// - `RateTickHint` to the value given in Alice's quote request.
func (p *RpcPriceOracleServer) QueryRateTick(_ context.Context,
req *oraclerpc.QueryRateTickRequest) (
*oraclerpc.QueryRateTickResponse, error) {
// - `AssetRateHint` to the value given in Alice's quote request.
func (p *RpcPriceOracleServer) QueryAssetRates(_ context.Context,
req *oraclerpc.QueryAssetRatesRequest) (
*oraclerpc.QueryAssetRatesResponse, error) {

// Ensure that the payment asset is BTC. We only support BTC as the
// payment asset in this example.
if !oraclerpc.IsAssetBtc(req.PaymentAsset) {
logrus.Infof("Payment asset is not BTC: %v", req.PaymentAsset)

return &oraclerpc.QueryRateTickResponse{
Result: &oraclerpc.QueryRateTickResponse_Error{
Error: &oraclerpc.QueryRateTickErrResponse{
return &oraclerpc.QueryAssetRatesResponse{
Result: &oraclerpc.QueryAssetRatesResponse_Error{
Error: &oraclerpc.QueryAssetRatesErrResponse{
Message: "unsupported payment asset, " +
"only BTC is supported",
},
Expand All @@ -215,55 +214,55 @@ func (p *RpcPriceOracleServer) QueryRateTick(_ context.Context,
logrus.Infof("Unsupported subject asset ID str: %v\n",
req.SubjectAsset)

return &oraclerpc.QueryRateTickResponse{
Result: &oraclerpc.QueryRateTickResponse_Error{
Error: &oraclerpc.QueryRateTickErrResponse{
return &oraclerpc.QueryAssetRatesResponse{
Result: &oraclerpc.QueryAssetRatesResponse_Error{
Error: &oraclerpc.QueryAssetRatesErrResponse{
Message: "unsupported subject asset",
},
},
}, nil
}

// Determine which rate tick to return.
// Determine which asset rate to return.
var (
rateTick oraclerpc.RateTick
err error
assetRates oraclerpc.AssetRates
err error
)

if req.RateTickHint != nil {
// If a rate tick hint is provided, return it as the rate tick.
// In doing so, we effectively accept the rate tick proposed by
// our peer.
if req.AssetRatesHint != nil {
// If the asset rates hint is provided, return it as the asset
// rate. In doing so, we effectively accept the asset rates
// proposed by our peer.
logrus.Info("Suggested asset to BTC rate provided, " +
"returning rate as accepted rate")

rateTick = oraclerpc.RateTick{
SubjectAssetRate: req.RateTickHint.SubjectAssetRate,
PaymentAssetRate: req.RateTickHint.PaymentAssetRate,
ExpiryTimestamp: req.RateTickHint.ExpiryTimestamp,
assetRates = oraclerpc.AssetRates{
SubjectAssetRate: req.AssetRatesHint.SubjectAssetRate,
PaymentAssetRate: req.AssetRatesHint.PaymentAssetRate,
ExpiryTimestamp: req.AssetRatesHint.ExpiryTimestamp,
}
} else {
// If a rate tick hint is not provided, fetch a rate tick from
// our internal system.
// If an asset rates hint is not provided, fetch asset rates
// from our internal system.
logrus.Info("Suggested asset to BTC rate not provided, " +
"querying internal system for rate")

rateTick, err = getRateTick(
assetRates, err = getAssetRates(
req.TransactionType, req.SubjectAssetMaxAmount,
)
if err != nil {
return nil, err
}
}

logrus.Infof("QueryRateTick returning rate (subject_asset_rate=%v, "+
"payment_asset_rate=%v)", rateTick.SubjectAssetRate,
rateTick.PaymentAssetRate)
logrus.Infof("QueryAssetRates returning rates (subject_asset_rate=%v, "+
"payment_asset_rate=%v)", assetRates.SubjectAssetRate,
assetRates.PaymentAssetRate)

return &oraclerpc.QueryRateTickResponse{
Result: &oraclerpc.QueryRateTickResponse_Success{
Success: &oraclerpc.QueryRateTickSuccessResponse{
RateTick: &rateTick,
return &oraclerpc.QueryAssetRatesResponse{
Result: &oraclerpc.QueryAssetRatesResponse_Ok{
Ok: &oraclerpc.QueryAssetRatesOkResponse{
AssetRates: &assetRates,
},
},
}, nil
Expand Down
6 changes: 3 additions & 3 deletions rfq/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -922,9 +922,9 @@ var _ fn.Event = (*PeerAcceptedBuyQuoteEvent)(nil)
type QuoteRespStatus uint8

const (
// InvalidRateTickQuoteRespStatus indicates that the rate tick in the
// quote response is invalid.
InvalidRateTickQuoteRespStatus QuoteRespStatus = 0
// InvalidAssetRatesQuoteRespStatus indicates that the asset rates in
// the quote response is invalid.
InvalidAssetRatesQuoteRespStatus QuoteRespStatus = 0

// InvalidExpiryQuoteRespStatus indicates that the expiry in the quote
// response is invalid.
Expand Down
14 changes: 7 additions & 7 deletions rfq/negotiator.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import (
)

const (
// minRateTickExpiryLifetime is the minimum rate tick expiry lifetime in
// seconds.
minRateTickExpiryLifetime = 60
// minAssetRatesExpiryLifetime is the minimum asset rates expiry
// lifetime in seconds.
minAssetRatesExpiryLifetime = 60

// DefaultAcceptPriceDeviationPpm is the default price deviation in
// parts per million that is accepted by the RFQ negotiator.
Expand Down Expand Up @@ -517,7 +517,7 @@ func (n *Negotiator) HandleIncomingBuyAccept(msg rfqmsg.BuyAccept,
// TODO(ffranr): Sanity check the buy accept quote expiry
// timestamp given the expiry timestamp provided by the price
// oracle.
if !expiryWithinBounds(msg.Expiry, minRateTickExpiryLifetime) {
if !expiryWithinBounds(msg.Expiry, minAssetRatesExpiryLifetime) {
// The expiry time is not within the acceptable bounds.
log.Debugf("Buy accept quote expiry time is not within "+
"acceptable bounds (expiry=%d)", msg.Expiry)
Expand Down Expand Up @@ -616,7 +616,7 @@ func (n *Negotiator) HandleIncomingBuyAccept(msg rfqmsg.BuyAccept,
// can inform the peer that the quote response has not
// validated successfully.
invalidQuoteRespEvent := NewInvalidQuoteRespEvent(
&msg, InvalidRateTickQuoteRespStatus,
&msg, InvalidAssetRatesQuoteRespStatus,
)
finalise(
msg, fn.Some[InvalidQuoteRespEvent](
Expand All @@ -642,7 +642,7 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
//
// TODO(ffranr): Sanity check the quote expiry timestamp given
// the expiry timestamp provided by the price oracle.
if !expiryWithinBounds(msg.Expiry, minRateTickExpiryLifetime) {
if !expiryWithinBounds(msg.Expiry, minAssetRatesExpiryLifetime) {
// The expiry time is not within the acceptable bounds.
log.Debugf("Sell accept quote expiry time is not within "+
"acceptable bounds (expiry=%d)", msg.Expiry)
Expand Down Expand Up @@ -740,7 +740,7 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
// can inform the peer that the quote response has not
// validated successfully.
invalidQuoteRespEvent := NewInvalidQuoteRespEvent(
&msg, InvalidRateTickQuoteRespStatus,
&msg, InvalidAssetRatesQuoteRespStatus,
)
finalise(
msg, fn.Some[InvalidQuoteRespEvent](
Expand Down
Loading

0 comments on commit eeadc03

Please sign in to comment.