Documentation
¶
Index ¶
- Constants
- func DisableLog()
- func UseLogger(logger btclog.Logger)
- type AcceptHtlcEvent
- type AssetForwardPolicy
- func (a *AssetForwardPolicy) CheckHtlcCompliance(htlc lndclient.InterceptedHtlc) error
- func (a *AssetForwardPolicy) Expiry() uint64
- func (a *AssetForwardPolicy) GenerateInterceptorResponse(htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
- func (a *AssetForwardPolicy) HasExpired() bool
- func (a *AssetForwardPolicy) Scid() uint64
- func (a *AssetForwardPolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
- func (a *AssetForwardPolicy) UntrackHtlc(circuitKey models.CircuitKey)
- type AssetPurchasePolicy
- func (c *AssetPurchasePolicy) CheckHtlcCompliance(htlc lndclient.InterceptedHtlc) error
- func (c *AssetPurchasePolicy) Expiry() uint64
- func (c *AssetPurchasePolicy) GenerateInterceptorResponse(htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
- func (c *AssetPurchasePolicy) HasExpired() bool
- func (c *AssetPurchasePolicy) Scid() uint64
- func (c *AssetPurchasePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
- func (c *AssetPurchasePolicy) UntrackHtlc(circuitKey models.CircuitKey)
- type AssetSalePolicy
- func (c *AssetSalePolicy) CheckHtlcCompliance(htlc lndclient.InterceptedHtlc) error
- func (c *AssetSalePolicy) Expiry() uint64
- func (c *AssetSalePolicy) GenerateInterceptorResponse(htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
- func (c *AssetSalePolicy) HasExpired() bool
- func (c *AssetSalePolicy) Scid() uint64
- func (c *AssetSalePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
- func (c *AssetSalePolicy) UntrackHtlc(circuitKey models.CircuitKey)
- type BuyAcceptMap
- type BuyOffer
- type BuyOrder
- type ChannelLister
- type CliConfig
- type HtlcInterceptor
- type HtlcSubscriber
- type IncomingRejectQuoteEvent
- type InvalidQuoteRespEvent
- type Manager
- func (m *Manager) LocalAcceptedBuyQuotes() BuyAcceptMap
- func (m *Manager) LocalAcceptedSellQuotes() SellAcceptMap
- func (m *Manager) PeerAcceptedBuyQuotes() BuyAcceptMap
- func (m *Manager) PeerAcceptedSellQuotes() SellAcceptMap
- func (m *Manager) RegisterSubscriber(receiver *fn.EventReceiver[fn.Event], deliverExisting bool, deliverFrom uint64) error
- func (m *Manager) RemoveAssetSellOffer(assetID *asset.ID, assetGroupKey *btcec.PublicKey) error
- func (m *Manager) RemoveSubscriber(subscriber *fn.EventReceiver[fn.Event]) error
- func (m *Manager) Start() error
- func (m *Manager) Stop() error
- func (m *Manager) UpsertAssetBuyOffer(offer BuyOffer) error
- func (m *Manager) UpsertAssetBuyOrder(order BuyOrder) error
- func (m *Manager) UpsertAssetSellOffer(offer SellOffer) error
- func (m *Manager) UpsertAssetSellOrder(order SellOrder) error
- type ManagerCfg
- type MockPriceOracle
- type Negotiator
- func (n *Negotiator) HandleIncomingBuyAccept(msg rfqmsg.BuyAccept, ...)
- func (n *Negotiator) HandleIncomingBuyRequest(request rfqmsg.BuyRequest) error
- func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept, ...)
- func (n *Negotiator) HandleIncomingSellRequest(request rfqmsg.SellRequest) error
- func (n *Negotiator) HandleOutgoingBuyOrder(buyOrder BuyOrder) error
- func (n *Negotiator) HandleOutgoingSellOrder(order SellOrder)
- func (n *Negotiator) HasAssetBuyOffer(assetSpecifier asset.Specifier, assetAmt uint64) bool
- func (n *Negotiator) HasAssetSellOffer(assetSpecifier asset.Specifier, assetAmt uint64) bool
- func (n *Negotiator) RemoveAssetSellOffer(assetID *asset.ID, assetGroupKey *btcec.PublicKey) error
- func (n *Negotiator) Start() error
- func (n *Negotiator) Stop() error
- func (n *Negotiator) UpsertAssetBuyOffer(offer BuyOffer) error
- func (n *Negotiator) UpsertAssetSellOffer(offer SellOffer) error
- type NegotiatorCfg
- type OracleAddr
- type OracleError
- type OracleResponse
- type OrderHandler
- type OrderHandlerCfg
- type PeerAcceptedBuyQuoteEvent
- type PeerAcceptedSellQuoteEvent
- type PeerMessenger
- type Policy
- type PriceOracle
- type QuoteRespStatus
- type RpcPriceOracle
- type ScidAliasManager
- type SellAcceptMap
- type SellOffer
- type SellOrder
- type SerialisedScid
- type StreamHandler
- type StreamHandlerCfg
Constants ¶
const ( MockPriceOracleServiceAddress = "use_mock_price_oracle_service_" + "promise_to_not_use_on_mainnet" // MinAssetsPerBTC is the minimum number of asset units that one BTC // should cost. If the value is lower, then one asset unit would cost // too much to be able to represent small amounts of satoshis. With this // value, one asset unit would still cost 1k sats. MinAssetsPerBTC = 100_000 )
const ( // DefaultTimeout is the default timeout used for context operations. DefaultTimeout = 30 * time.Second // DefaultInvoiceExpiry is the default expiry time for asset invoices. // The current value corresponds to 5 minutes. DefaultInvoiceExpiry = time.Second * 300 // CacheCleanupInterval is the interval at which local runtime caches // are cleaned up. CacheCleanupInterval = 30 * time.Second )
const ( // DefaultAcceptPriceDeviationPpm is the default price deviation in // parts per million that is accepted by the RFQ negotiator. // // NOTE: This value is set to 5% (50,000 ppm). DefaultAcceptPriceDeviationPpm = 50_000 )
const ( // RfqRpcOracleAddrScheme is the URL address scheme used by an RPC price // oracle service. RfqRpcOracleAddrScheme string = "rfqrpc" )
const Subsystem = "RFQS"
Subsystem defines the logging code for this subsystem.
Variables ¶
This section is empty.
Functions ¶
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
Types ¶
type AcceptHtlcEvent ¶
type AcceptHtlcEvent struct { // Htlc is the intercepted HTLC. Htlc lndclient.InterceptedHtlc // Policy is the policy with which the HTLC is compliant. Policy Policy // contains filtered or unexported fields }
AcceptHtlcEvent is an event that is sent to the accept HTLCs channel when an HTLC is accepted.
func NewAcceptHtlcEvent ¶
func NewAcceptHtlcEvent(htlc lndclient.InterceptedHtlc, policy Policy) *AcceptHtlcEvent
NewAcceptHtlcEvent creates a new AcceptedHtlcEvent.
func (*AcceptHtlcEvent) Timestamp ¶
func (q *AcceptHtlcEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type AssetForwardPolicy ¶
type AssetForwardPolicy struct {
// contains filtered or unexported fields
}
AssetForwardPolicy is a struct that holds the terms which determine whether a channel HTLC for an asset-to-asset forward is accepted or rejected.
func NewAssetForwardPolicy ¶
func NewAssetForwardPolicy(incoming, outgoing Policy) (*AssetForwardPolicy, error)
NewAssetForwardPolicy creates a new asset forward policy.
func (*AssetForwardPolicy) CheckHtlcCompliance ¶
func (a *AssetForwardPolicy) CheckHtlcCompliance( htlc lndclient.InterceptedHtlc) error
CheckHtlcCompliance returns an error if the given HTLC intercept descriptor does not satisfy the subject policy.
func (*AssetForwardPolicy) Expiry ¶
func (a *AssetForwardPolicy) Expiry() uint64
Expiry returns the policy's expiry time as a unix timestamp in seconds. The returned expiry time is the earliest expiry time of the incoming and outgoing policies.
func (*AssetForwardPolicy) GenerateInterceptorResponse ¶
func (a *AssetForwardPolicy) GenerateInterceptorResponse( htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
GenerateInterceptorResponse generates an interceptor response for the policy.
func (*AssetForwardPolicy) HasExpired ¶
func (a *AssetForwardPolicy) HasExpired() bool
HasExpired returns true if the policy has expired.
func (*AssetForwardPolicy) Scid ¶
func (a *AssetForwardPolicy) Scid() uint64
Scid returns the serialised short channel ID (SCID) of the channel to which the policy applies. This is the SCID of the incoming policy.
func (*AssetForwardPolicy) TrackAcceptedHtlc ¶ added in v0.5.0
func (a *AssetForwardPolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
TrackAcceptedHtlc accounts for the newly accepted HTLC. This may affect the acceptance of future HTLCs.
func (*AssetForwardPolicy) UntrackHtlc ¶ added in v0.5.0
func (a *AssetForwardPolicy) UntrackHtlc(circuitKey models.CircuitKey)
UntrackHtlc stops tracking the uniquely identified HTLC.
type AssetPurchasePolicy ¶
type AssetPurchasePolicy struct { // AssetSpecifier is the identifier for the specific asset or asset // group to which this policy applies. AssetSpecifier asset.Specifier // AcceptedQuoteId is the ID of the accepted quote. AcceptedQuoteId rfqmsg.ID // CurrentAssetAmountMsat is the total amount that is held currently in // accepted HTLCs. CurrentAmountMsat lnwire.MilliSatoshi // BidAssetRate is the quote's asset to BTC conversion rate. BidAssetRate rfqmath.BigIntFixedPoint // PaymentMaxAmt is the maximum agreed BTC payment. PaymentMaxAmt lnwire.MilliSatoshi // contains filtered or unexported fields }
AssetPurchasePolicy is a struct that holds the terms which determine whether an asset purchase channel HTLC is accepted or rejected.
func NewAssetPurchasePolicy ¶
func NewAssetPurchasePolicy(quote rfqmsg.SellAccept) *AssetPurchasePolicy
NewAssetPurchasePolicy creates a new asset purchase policy.
func (*AssetPurchasePolicy) CheckHtlcCompliance ¶
func (c *AssetPurchasePolicy) CheckHtlcCompliance( htlc lndclient.InterceptedHtlc) error
CheckHtlcCompliance returns an error if the given HTLC intercept descriptor does not satisfy the subject policy.
func (*AssetPurchasePolicy) Expiry ¶
func (c *AssetPurchasePolicy) Expiry() uint64
Expiry returns the policy's expiry time as a unix timestamp in seconds.
func (*AssetPurchasePolicy) GenerateInterceptorResponse ¶
func (c *AssetPurchasePolicy) GenerateInterceptorResponse( htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
GenerateInterceptorResponse generates an interceptor response for the policy.
func (*AssetPurchasePolicy) HasExpired ¶
func (c *AssetPurchasePolicy) HasExpired() bool
HasExpired returns true if the policy has expired.
func (*AssetPurchasePolicy) Scid ¶
func (c *AssetPurchasePolicy) Scid() uint64
Scid returns the serialised short channel ID (SCID) of the channel to which the policy applies.
func (*AssetPurchasePolicy) TrackAcceptedHtlc ¶ added in v0.5.0
func (c *AssetPurchasePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
TrackAcceptedHtlc accounts for the newly accepted HTLC. This may affect the acceptance of future HTLCs.
func (*AssetPurchasePolicy) UntrackHtlc ¶ added in v0.5.0
func (c *AssetPurchasePolicy) UntrackHtlc(circuitKey models.CircuitKey)
UntrackHtlc stops tracking the uniquely identified HTLC.
type AssetSalePolicy ¶
type AssetSalePolicy struct { // AssetSpecifier is the identifier for the specific asset or asset // group to which this policy applies. AssetSpecifier asset.Specifier // AcceptedQuoteId is the unique identifier of the RFQ session quote // accept message that the policy is associated with. AcceptedQuoteId rfqmsg.ID // MaxOutboundAssetAmount represents the maximum asset amount permitted // by policy for outbound transactions. It sets an upper limit on the // amount of assets this node is willing to divest within the remit of // the policy. MaxOutboundAssetAmount uint64 // CurrentAssetAmountMsat is the total amount that is held currently in // accepted HTLCs. CurrentAmountMsat lnwire.MilliSatoshi // AskAssetRate is the quote's asking asset unit to BTC conversion rate. AskAssetRate rfqmath.BigIntFixedPoint // contains filtered or unexported fields }
AssetSalePolicy is a struct that holds the terms which determine whether an asset sale channel HTLC is accepted or rejected.
func NewAssetSalePolicy ¶
func NewAssetSalePolicy(quote rfqmsg.BuyAccept) *AssetSalePolicy
NewAssetSalePolicy creates a new asset sale policy.
func (*AssetSalePolicy) CheckHtlcCompliance ¶
func (c *AssetSalePolicy) CheckHtlcCompliance( htlc lndclient.InterceptedHtlc) error
CheckHtlcCompliance returns an error if the given HTLC intercept descriptor does not satisfy the subject policy.
The HTLC examined by this function was likely created by a peer unaware of the RFQ agreement (i.e., they are simply paying an invoice), with the SCID included as a hop hint within the invoice. The SCID is the only piece of information used to determine the policy applicable to the HTLC. As a result, HTLC custom records are not expected to be present.
func (*AssetSalePolicy) Expiry ¶
func (c *AssetSalePolicy) Expiry() uint64
Expiry returns the policy's expiry time as a unix timestamp.
func (*AssetSalePolicy) GenerateInterceptorResponse ¶
func (c *AssetSalePolicy) GenerateInterceptorResponse( htlc lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error)
GenerateInterceptorResponse generates an interceptor response for the policy.
func (*AssetSalePolicy) HasExpired ¶
func (c *AssetSalePolicy) HasExpired() bool
HasExpired returns true if the policy has expired.
func (*AssetSalePolicy) Scid ¶
func (c *AssetSalePolicy) Scid() uint64
Scid returns the serialised short channel ID (SCID) of the channel to which the policy applies.
func (*AssetSalePolicy) TrackAcceptedHtlc ¶ added in v0.5.0
func (c *AssetSalePolicy) TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi)
TrackAcceptedHtlc accounts for the newly accepted HTLC. This may affect the acceptance of future HTLCs.
func (*AssetSalePolicy) UntrackHtlc ¶ added in v0.5.0
func (c *AssetSalePolicy) UntrackHtlc(circuitKey models.CircuitKey)
UntrackHtlc stops tracking the uniquely identified HTLC.
type BuyAcceptMap ¶ added in v0.5.0
type BuyAcceptMap map[SerialisedScid]rfqmsg.BuyAccept
BuyAcceptMap is a map of buy accepts, keyed by the serialised SCID.
type BuyOffer ¶
type BuyOffer struct { // AssetID represents the identifier of the subject asset. AssetID *asset.ID // AssetGroupKey is the public group key of the subject asset. AssetGroupKey *btcec.PublicKey // MaxUnits is the maximum amount of the asset which this node is // willing to purchase. MaxUnits uint64 }
BuyOffer is a struct that represents an asset buy offer. This data structure describes the maximum amount of an asset that this node is willing to purchase.
A buy offer is passive (unlike a buy order), meaning that it does not actively lead to a buy request being sent to a peer. Instead, it is used by the node to selectively accept or reject incoming asset sell quote requests before price is considered.
type BuyOrder ¶
type BuyOrder struct { // AssetSpecifier is the asset that the buyer is interested in. AssetSpecifier asset.Specifier // AssetMaxAmt is the maximum amount of the asset that the provider must // be willing to offer. AssetMaxAmt uint64 // Expiry is the time at which the order expires. Expiry time.Time // Peer is the peer that the buy order is intended for. This field is // optional. // // TODO(ffranr): Currently, this field must be specified. In the future, // the negotiator should be able to determine the optimal peer. Peer fn.Option[route.Vertex] }
BuyOrder instructs the RFQ (Request For Quote) system to request a quote from one or more peers for the acquisition of an asset.
The normal use of a buy order is as follows:
- Alice, operating a wallet node, wants to receive a Tap asset as payment by issuing a Lightning invoice.
- Alice has an asset channel established with Bob's edge node.
- Before issuing the invoice, Alice needs to agree on an exchange rate with Bob, who will facilitate the asset transfer.
- To obtain the best exchange rate, Alice creates a buy order specifying the desired asset.
- Alice's RFQ subsystem processes the buy order and sends buy requests to relevant peers to find the best rate. In this example, Bob is the only available peer.
- Once Bob provides a satisfactory quote, Alice accepts it.
- Alice issues the Lightning invoice, which Charlie will pay.
- Instead of paying Alice directly, Charlie pays Bob.
- Bob then forwards the agreed amount of the Tap asset to Alice over their asset channel.
type ChannelLister ¶
type ChannelLister interface { // ListChannels returns a list of channels that are available for // routing. ListChannels(ctx context.Context) ([]lndclient.ChannelInfo, error) }
ChannelLister is an interface that provides a list of channels that are available for routing.
type CliConfig ¶
type CliConfig struct { PriceOracleAddress string `` /* 215-byte string literal not displayed */ AcceptPriceDeviationPpm uint64 `` /* 132-byte string literal not displayed */ SkipAcceptQuotePriceCheck bool `long:"skipacceptquotepricecheck" description:"Accept any price quote returned by RFQ peer, skipping price validation"` MockOracleAssetsPerBTC uint64 `` /* 270-byte string literal not displayed */ // TODO(ffranr): Remove in favour of MockOracleAssetsPerBTC. MockOracleSatsPerAsset uint64 `` /* 289-byte string literal not displayed */ }
CliConfig is a struct that holds tapd cli configuration options for the RFQ service.
nolint: lll
type HtlcInterceptor ¶
type HtlcInterceptor interface { // InterceptHtlcs intercepts HTLCs, using the handling function provided // to respond to HTLCs. InterceptHtlcs(context.Context, lndclient.HtlcInterceptHandler) error }
HtlcInterceptor is an interface that abstracts the hash time locked contract (HTLC) intercept functionality.
type HtlcSubscriber ¶ added in v0.5.0
type HtlcSubscriber interface { // SubscribeHtlcEvents subscribes to a stream of events related to // HTLC updates. SubscribeHtlcEvents(ctx context.Context) (<-chan *routerrpc.HtlcEvent, <-chan error, error) }
HtlcSubscriber is an interface that contains the function necessary for retrieving live HTLC event updates.
type IncomingRejectQuoteEvent ¶
type IncomingRejectQuoteEvent struct { // Reject is the rejected quote. rfqmsg.Reject // contains filtered or unexported fields }
IncomingRejectQuoteEvent is an event that is broadcast when the RFQ manager receives a reject quote message from a peer.
func NewIncomingRejectQuoteEvent ¶
func NewIncomingRejectQuoteEvent( reject *rfqmsg.Reject) *IncomingRejectQuoteEvent
NewIncomingRejectQuoteEvent creates a new IncomingRejectQuoteEvent.
func (*IncomingRejectQuoteEvent) Timestamp ¶
func (q *IncomingRejectQuoteEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type InvalidQuoteRespEvent ¶
type InvalidQuoteRespEvent struct { // QuoteResponse is the quote response received from the peer which was // deemed invalid. QuoteResponse rfqmsg.QuoteResponse // Status is the status of the quote response. Status QuoteRespStatus // contains filtered or unexported fields }
InvalidQuoteRespEvent is an event that is broadcast when the RFQ manager receives an unacceptable quote response message from a peer.
func NewInvalidQuoteRespEvent ¶
func NewInvalidQuoteRespEvent(quoteResponse rfqmsg.QuoteResponse, status QuoteRespStatus) *InvalidQuoteRespEvent
NewInvalidQuoteRespEvent creates a new InvalidBuyRespEvent.
func (*InvalidQuoteRespEvent) Timestamp ¶
func (q *InvalidQuoteRespEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type Manager ¶
type Manager struct { // ContextGuard provides a wait group and main quit channel that can be // used to create guarded contexts. *fn.ContextGuard // contains filtered or unexported fields }
Manager is a struct that manages the request for quote (RFQ) system.
func NewManager ¶
func NewManager(cfg ManagerCfg) (*Manager, error)
NewManager creates a new RFQ manager.
func (*Manager) LocalAcceptedBuyQuotes ¶
func (m *Manager) LocalAcceptedBuyQuotes() BuyAcceptMap
LocalAcceptedBuyQuotes returns buy quotes that were accepted by our node and have been requested by our peers. These quotes are exclusively available to our node for the acquisition of assets.
func (*Manager) LocalAcceptedSellQuotes ¶
func (m *Manager) LocalAcceptedSellQuotes() SellAcceptMap
LocalAcceptedSellQuotes returns sell quotes that were accepted by our node and have been requested by our peers. These quotes are exclusively available to our node for the sale of assets.
func (*Manager) PeerAcceptedBuyQuotes ¶
func (m *Manager) PeerAcceptedBuyQuotes() BuyAcceptMap
PeerAcceptedBuyQuotes returns buy quotes that were requested by our node and have been accepted by our peers. These quotes are exclusively available to our node for the acquisition of assets.
func (*Manager) PeerAcceptedSellQuotes ¶
func (m *Manager) PeerAcceptedSellQuotes() SellAcceptMap
PeerAcceptedSellQuotes returns sell quotes that were requested by our node and have been accepted by our peers. These quotes are exclusively available to our node for the sale of assets.
func (*Manager) RegisterSubscriber ¶
func (m *Manager) RegisterSubscriber( receiver *fn.EventReceiver[fn.Event], deliverExisting bool, deliverFrom uint64) error
RegisterSubscriber adds a new subscriber to the set of subscribers that will be notified of any new events that are broadcast.
TODO(ffranr): Add support for delivering existing events to new subscribers.
func (*Manager) RemoveAssetSellOffer ¶
RemoveAssetSellOffer removes an asset sell offer from the RFQ manager.
func (*Manager) RemoveSubscriber ¶
RemoveSubscriber removes a subscriber from the set of subscribers that will be notified of any new events that are broadcast.
func (*Manager) UpsertAssetBuyOffer ¶
UpsertAssetBuyOffer upserts an asset buy offer for management by the RFQ system. If the offer already exists for the given asset, it will be updated.
func (*Manager) UpsertAssetBuyOrder ¶
UpsertAssetBuyOrder upserts an asset buy order for management.
func (*Manager) UpsertAssetSellOffer ¶
UpsertAssetSellOffer upserts an asset sell offer for management by the RFQ system. If the offer already exists for the given asset, it will be updated.
func (*Manager) UpsertAssetSellOrder ¶
UpsertAssetSellOrder upserts an asset sell order for management.
type ManagerCfg ¶
type ManagerCfg struct { // PeerMessenger is the peer messenger. This component provides the RFQ // manager with the ability to send and receive raw peer messages. PeerMessenger PeerMessenger // HtlcInterceptor is the HTLC interceptor. This component is used to // intercept and accept/reject HTLCs. HtlcInterceptor HtlcInterceptor // HtlcSubscriber is a subscriber that is used to retrieve live HTLC // event updates. HtlcSubscriber HtlcSubscriber // PriceOracle is the price oracle that the RFQ manager will use to // determine whether a quote is accepted or rejected. PriceOracle PriceOracle // ChannelLister is the channel lister that the RFQ manager will use to // determine the available channels for routing. ChannelLister ChannelLister // AliasManager is the SCID alias manager. This component is injected // into the manager once lnd and tapd are hooked together. AliasManager ScidAliasManager // AcceptPriceDeviationPpm is the price deviation in // parts per million that is accepted by the RFQ negotiator. // // Example: 50,000 ppm => price deviation is set to 5% . AcceptPriceDeviationPpm uint64 // SkipAcceptQuotePriceCheck is a flag that, when set, will cause the // RFQ negotiator to skip price validation on incoming quote accept // messages (this means that the price oracle will not be queried). SkipAcceptQuotePriceCheck bool // ErrChan is the main error channel which will be used to report back // critical errors to the main server. ErrChan chan<- error }
ManagerCfg is a struct that holds the configuration parameters for the RFQ manager.
type MockPriceOracle ¶
type MockPriceOracle struct { // Mock is the underlying mock object used to track method invocations // in tests. mock.Mock // contains filtered or unexported fields }
MockPriceOracle is a mock implementation of the PriceOracle interface. It returns the suggested rate as the exchange rate.
func NewMockPriceOracle ¶
func NewMockPriceOracle(expiryDelay, assetRateCoefficient uint64) *MockPriceOracle
NewMockPriceOracle creates a new mock price oracle.
func NewMockPriceOracleSatPerAsset ¶
func NewMockPriceOracleSatPerAsset(expiryDelay uint64, satsPerAsset uint64) *MockPriceOracle
NewMockPriceOracleSatPerAsset creates a new mock price oracle with a specified satoshis per asset rate.
func (*MockPriceOracle) QueryAskPrice ¶
func (m *MockPriceOracle) QueryAskPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate]) (*OracleResponse, error)
QueryAskPrice returns the ask price for the given asset amount.
func (*MockPriceOracle) QueryBidPrice ¶
func (m *MockPriceOracle) QueryBidPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate]) (*OracleResponse, error)
QueryBidPrice returns a bid price for the given asset amount.
type Negotiator ¶
type Negotiator struct { // ContextGuard provides a wait group and main quit channel that can be // used to create guarded contexts. *fn.ContextGuard // contains filtered or unexported fields }
Negotiator is a struct that handles the negotiation of quotes. It is a RFQ subsystem. It determines whether a quote request is accepted or rejected.
func NewNegotiator ¶
func NewNegotiator(cfg NegotiatorCfg) (*Negotiator, error)
NewNegotiator creates a new quote negotiator.
func (*Negotiator) HandleIncomingBuyAccept ¶
func (n *Negotiator) HandleIncomingBuyAccept(msg rfqmsg.BuyAccept, finalise func(rfqmsg.BuyAccept, fn.Option[InvalidQuoteRespEvent]))
HandleIncomingBuyAccept handles an incoming buy accept message. This method is called when a peer accepts a quote request from this node. The method checks the price and expiry time of the quote accept message. Once validation is complete, the finalise callback function is called.
func (*Negotiator) HandleIncomingBuyRequest ¶
func (n *Negotiator) HandleIncomingBuyRequest( request rfqmsg.BuyRequest) error
HandleIncomingBuyRequest handles an incoming asset buy quote request.
func (*Negotiator) HandleIncomingSellAccept ¶
func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept, finalise func(rfqmsg.SellAccept, fn.Option[InvalidQuoteRespEvent]))
HandleIncomingSellAccept handles an incoming sell accept message. This method is called when a peer accepts a quote request from this node. The method checks the price and expiry time of the quote accept message. Once validation is complete, the finalise callback function is called.
func (*Negotiator) HandleIncomingSellRequest ¶
func (n *Negotiator) HandleIncomingSellRequest( request rfqmsg.SellRequest) error
HandleIncomingSellRequest handles an incoming asset sell quote request. This is a request by our peer to sell an asset to us.
func (*Negotiator) HandleOutgoingBuyOrder ¶
func (n *Negotiator) HandleOutgoingBuyOrder(buyOrder BuyOrder) error
HandleOutgoingBuyOrder handles an outgoing buy order by constructing buy requests and passing them to the outgoing messages channel. These requests are sent to peers.
func (*Negotiator) HandleOutgoingSellOrder ¶
func (n *Negotiator) HandleOutgoingSellOrder(order SellOrder)
HandleOutgoingSellOrder handles an outgoing sell order by constructing sell requests and passing them to the outgoing messages channel. These requests are sent to peers.
func (*Negotiator) HasAssetBuyOffer ¶
func (n *Negotiator) HasAssetBuyOffer(assetSpecifier asset.Specifier, assetAmt uint64) bool
HasAssetBuyOffer returns true if the negotiator has an asset buy offer which matches the given asset ID/group and asset amount.
TODO(ffranr): This method should return errors which can be used to differentiate between a missing offer and an invalid offer.
func (*Negotiator) HasAssetSellOffer ¶
func (n *Negotiator) HasAssetSellOffer(assetSpecifier asset.Specifier, assetAmt uint64) bool
HasAssetSellOffer returns true if the negotiator has an asset sell offer which matches the given asset ID/group and asset amount.
TODO(ffranr): This method should return errors which can be used to differentiate between a missing offer and an invalid offer.
func (*Negotiator) RemoveAssetSellOffer ¶
func (n *Negotiator) RemoveAssetSellOffer(assetID *asset.ID, assetGroupKey *btcec.PublicKey) error
RemoveAssetSellOffer removes an asset sell offer from the negotiator.
func (*Negotiator) UpsertAssetBuyOffer ¶
func (n *Negotiator) UpsertAssetBuyOffer(offer BuyOffer) error
UpsertAssetBuyOffer upserts an asset buy offer. If the offer already exists for the given asset, it will be updated.
func (*Negotiator) UpsertAssetSellOffer ¶
func (n *Negotiator) UpsertAssetSellOffer(offer SellOffer) error
UpsertAssetSellOffer upserts an asset sell offer. If the offer already exists for the given asset, it will be updated.
type NegotiatorCfg ¶
type NegotiatorCfg struct { // PriceOracle is the price oracle that the negotiator will use to // determine whether a quote is accepted or rejected. PriceOracle PriceOracle // OutgoingMessages is a channel which is populated with outgoing peer // messages. These are messages which are destined to be sent to peers. OutgoingMessages chan<- rfqmsg.OutgoingMsg // AcceptPriceDeviationPpm specifies the maximum allowable price // deviation in parts per million (PPM). This parameter defines the // threshold for the price returned by the price oracle service, // indicating how much it can deviate from a peer's quote accept price // for the node to consider using the accepted quote. AcceptPriceDeviationPpm uint64 // SkipAcceptQuotePriceCheck is a flag that, if set, will skip the // price check when validating an incoming quote accept message. This is // useful for testing purposes. SkipAcceptQuotePriceCheck bool // ErrChan is a channel that is populated with errors by this subsystem. ErrChan chan<- error }
NegotiatorCfg holds the configuration for the negotiator.
type OracleAddr ¶
OracleAddr is a type alias for a URL type that represents a price oracle service address.
func ParsePriceOracleAddress ¶
func ParsePriceOracleAddress(addrStr string) (*OracleAddr, error)
ParsePriceOracleAddress parses a price oracle service address string and returns a URL type instance.
type OracleError ¶
type OracleError struct { // Code is a code which uniquely identifies the error type. Code uint8 // Msg is a human-readable error message. Msg string }
OracleError is a struct that holds an error returned by the price oracle service.
func (*OracleError) Error ¶
func (o *OracleError) Error() string
Error returns a human-readable string representation of the error.
type OracleResponse ¶ added in v0.5.0
type OracleResponse struct { // AssetRate is the asset to BTC rate. Other asset in the transfer is // assumed to be BTC and therefore not included in the response. AssetRate rfqmsg.AssetRate // Err is an optional error returned by the price oracle service. Err *OracleError }
OracleResponse is a struct that holds the price oracle's suggested buy or sell price for an asset swap.
type OrderHandler ¶
type OrderHandler struct { // ContextGuard provides a wait group and main quit channel that can be // used to create guarded contexts. *fn.ContextGuard // contains filtered or unexported fields }
OrderHandler orchestrates management of accepted quote bundles. It monitors HTLCs (Hash Time Locked Contracts), and determines acceptance/rejection based on the terms of the associated accepted quote.
func NewOrderHandler ¶
func NewOrderHandler(cfg OrderHandlerCfg) (*OrderHandler, error)
NewOrderHandler creates a new struct instance.
func (*OrderHandler) RegisterAssetPurchasePolicy ¶
func (h *OrderHandler) RegisterAssetPurchasePolicy( sellAccept rfqmsg.SellAccept)
RegisterAssetPurchasePolicy generates and registers an asset buy policy with the order handler. This function takes an incoming sell accept message as an argument.
func (*OrderHandler) RegisterAssetSalePolicy ¶
func (h *OrderHandler) RegisterAssetSalePolicy(buyAccept rfqmsg.BuyAccept)
RegisterAssetSalePolicy generates and registers an asset sale policy with the order handler. This function takes an outgoing buy accept message as an argument.
type OrderHandlerCfg ¶
type OrderHandlerCfg struct { // CleanupInterval is the interval at which the order handler cleans up // expired accepted quotes from its local cache. CleanupInterval time.Duration // HtlcInterceptor is the HTLC interceptor. This component is used to // intercept and accept/reject HTLCs. HtlcInterceptor HtlcInterceptor // AcceptHtlcEvents is a channel that receives accepted HTLCs. AcceptHtlcEvents chan<- *AcceptHtlcEvent // HtlcSubscriber is a subscriber that is used to retrieve live HTLC // event updates. HtlcSubscriber HtlcSubscriber }
OrderHandlerCfg is a struct that holds the configuration parameters for the order handler service.
type PeerAcceptedBuyQuoteEvent ¶
type PeerAcceptedBuyQuoteEvent struct { // BuyAccept is the accepted asset buy quote. rfqmsg.BuyAccept // contains filtered or unexported fields }
PeerAcceptedBuyQuoteEvent is an event that is broadcast when the RFQ manager receives an accept quote message from a peer. This is a quote which was requested by our node and has been accepted by a peer.
func NewPeerAcceptedBuyQuoteEvent ¶
func NewPeerAcceptedBuyQuoteEvent( buyAccept *rfqmsg.BuyAccept) *PeerAcceptedBuyQuoteEvent
NewPeerAcceptedBuyQuoteEvent creates a new PeerAcceptedBuyQuoteEvent.
func (*PeerAcceptedBuyQuoteEvent) Timestamp ¶
func (q *PeerAcceptedBuyQuoteEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type PeerAcceptedSellQuoteEvent ¶
type PeerAcceptedSellQuoteEvent struct { // SellAccept is the accepted asset sell quote. rfqmsg.SellAccept // contains filtered or unexported fields }
PeerAcceptedSellQuoteEvent is an event that is broadcast when the RFQ manager receives an asset sell request accept quote message from a peer. This is a quote which was requested by our node and has been accepted by a peer.
func NewPeerAcceptedSellQuoteEvent ¶
func NewPeerAcceptedSellQuoteEvent( sellAccept *rfqmsg.SellAccept) *PeerAcceptedSellQuoteEvent
NewPeerAcceptedSellQuoteEvent creates a new PeerAcceptedSellQuoteEvent.
func (*PeerAcceptedSellQuoteEvent) Timestamp ¶
func (q *PeerAcceptedSellQuoteEvent) Timestamp() time.Time
Timestamp returns the event creation UTC timestamp.
type PeerMessenger ¶
type PeerMessenger interface { // SubscribeCustomMessages creates a subscription to raw messages // received from our peers. SubscribeCustomMessages( ctx context.Context) (<-chan lndclient.CustomMessage, <-chan error, error) // SendCustomMessage sends a raw message to a peer. SendCustomMessage(context.Context, lndclient.CustomMessage) error }
PeerMessenger is an interface that abstracts the peer message transport layer.
type Policy ¶
type Policy interface { // CheckHtlcCompliance returns an error if the given HTLC intercept // descriptor does not satisfy the subject policy. CheckHtlcCompliance(htlc lndclient.InterceptedHtlc) error // Expiry returns the policy's expiry time as a unix timestamp. Expiry() uint64 // HasExpired returns true if the policy has expired. HasExpired() bool // Scid returns the serialised short channel ID (SCID) of the channel to // which the policy applies. Scid() uint64 // TrackAcceptedHtlc makes the policy aware of this new accepted HTLC. // This is important in cases where the set of existing HTLCs may affect // whether the next compliance check passes. TrackAcceptedHtlc(circuitKey models.CircuitKey, amt lnwire.MilliSatoshi) // UntrackHtlc stops tracking the uniquely identified HTLC. UntrackHtlc(circuitKey models.CircuitKey) // GenerateInterceptorResponse generates an interceptor response for the // HTLC interceptor from the policy. GenerateInterceptorResponse( lndclient.InterceptedHtlc) (*lndclient.InterceptedHtlcResponse, error) }
Policy is an interface that abstracts the terms which determine whether an asset sale/purchase channel HTLC is accepted or rejected.
type PriceOracle ¶
type PriceOracle interface { // QueryAskPrice returns the ask price for a given asset amount. // The ask price is the amount the oracle suggests a peer should accept // from another peer to provide the specified asset amount. QueryAskPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate]) ( *OracleResponse, error) // QueryBidPrice returns the bid price for a given asset amount. // The bid price is the amount the oracle suggests a peer should pay // to another peer to receive the specified asset amount. QueryBidPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate]) ( *OracleResponse, error) }
PriceOracle is an interface that provides exchange rate information for assets.
type QuoteRespStatus ¶
type QuoteRespStatus uint8
QuoteRespStatus is an enumeration of possible quote response statuses.
const ( // 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. InvalidExpiryQuoteRespStatus QuoteRespStatus = 1 // PriceOracleQueryErrQuoteRespStatus indicates that an error occurred // when querying the price oracle whilst evaluating the quote response. PriceOracleQueryErrQuoteRespStatus QuoteRespStatus = 2 )
type RpcPriceOracle ¶
type RpcPriceOracle struct {
// contains filtered or unexported fields
}
RpcPriceOracle is a price oracle that uses an external RPC server to get exchange rate information.
func NewRpcPriceOracle ¶
func NewRpcPriceOracle(addrStr string, dialInsecure bool) (*RpcPriceOracle, error)
NewRpcPriceOracle creates a new RPC price oracle handle given the address of the price oracle RPC server.
func (*RpcPriceOracle) QueryAskPrice ¶
func (r *RpcPriceOracle) QueryAskPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate]) (*OracleResponse, error)
QueryAskPrice returns the ask price for the given asset amount.
func (*RpcPriceOracle) QueryBidPrice ¶
func (r *RpcPriceOracle) QueryBidPrice(ctx context.Context, assetSpecifier asset.Specifier, assetMaxAmt fn.Option[uint64], paymentMaxAmt fn.Option[lnwire.MilliSatoshi], assetRateHint fn.Option[rfqmsg.AssetRate]) (*OracleResponse, error)
QueryBidPrice returns a bid price for the given asset amount.
type ScidAliasManager ¶
type ScidAliasManager interface { // AddLocalAlias adds a database mapping from the passed alias to the // passed base SCID. AddLocalAlias(ctx context.Context, alias, baseScid lnwire.ShortChannelID) error // DeleteLocalAlias removes a mapping from the database and the // Manager's maps. DeleteLocalAlias(ctx context.Context, alias, baseScid lnwire.ShortChannelID) error }
ScidAliasManager is an interface that can add short channel ID (SCID) aliases to the local SCID alias store.
type SellAcceptMap ¶ added in v0.5.0
type SellAcceptMap map[SerialisedScid]rfqmsg.SellAccept
SellAcceptMap is a map of sell accepts, keyed by the serialised SCID.
type SellOffer ¶
type SellOffer struct { // AssetID represents the identifier of the subject asset. AssetID *asset.ID // AssetGroupKey is the public group key of the subject asset. AssetGroupKey *btcec.PublicKey // MaxUnits is the maximum amount of the asset under offer. MaxUnits uint64 }
SellOffer is a struct that represents an asset sell offer. This data structure describes the maximum amount of an asset that is available for sale.
A sell offer is passive (unlike a buy order), meaning that it does not actively lead to a bid request from a peer. Instead, it is used by the node to selectively accept or reject incoming quote requests early before price considerations.
type SellOrder ¶
type SellOrder struct { // AssetSpecifier is the asset that the seller is interested in. AssetSpecifier asset.Specifier // PaymentMaxAmt is the maximum msat amount that the responding peer // must agree to pay. PaymentMaxAmt lnwire.MilliSatoshi // Expiry is the time at which the order expires. Expiry time.Time // Peer is the peer that the buy order is intended for. This field is // optional. Peer fn.Option[route.Vertex] }
SellOrder instructs the RFQ (Request For Quote) system to request a quote from one or more peers for the disposition of an asset.
Normal usage of a sell order:
- Alice creates a Lightning invoice for Bob to pay.
- Bob wants to pay the invoice using a Tap asset. To do so, Bob pays an edge node with a Tap asset, and the edge node forwards the payment to the network to settle Alice's invoice. Bob submits a SellOrder to his local RFQ service.
- The RFQ service converts the SellOrder into one or more SellRequests. These requests are sent to Charlie (the edge node), who shares a relevant Tap asset channel with Bob and can forward payments to settle Alice's invoice.
- Charlie responds with a quote that satisfies Bob.
- Bob transfers the appropriate Tap asset amount to Charlie via their shared Tap asset channel, and Charlie forwards the corresponding amount to Alice to settle the Lightning invoice.
type SerialisedScid ¶
type SerialisedScid = rfqmsg.SerialisedScid
SerialisedScid is a serialised short channel id (SCID).
type StreamHandler ¶
type StreamHandler struct { // ContextGuard provides a wait group and main quit channel that can be // used to create guarded contexts. *fn.ContextGuard // contains filtered or unexported fields }
StreamHandler is a struct that handles incoming and outgoing peer RFQ stream messages.
This component subscribes to incoming raw peer messages (custom messages). It processes those messages with the aim of extracting relevant request for quotes (RFQs).
func NewStreamHandler ¶
func NewStreamHandler(ctx context.Context, cfg StreamHandlerCfg) (*StreamHandler, error)
NewStreamHandler creates and starts a new RFQ stream handler.
TODO(ffranr): Pass in a signer so that we can create a signature over output message fields.
func (*StreamHandler) HandleOutgoingMessage ¶
func (h *StreamHandler) HandleOutgoingMessage( outgoingMsg rfqmsg.OutgoingMsg) error
HandleOutgoingMessage handles an outgoing RFQ message.
type StreamHandlerCfg ¶
type StreamHandlerCfg struct { // PeerMessenger is the peer messenger. This component provides the RFQ // manager with the ability to send and receive raw peer messages. PeerMessenger PeerMessenger // IncomingMessages is a channel which is populated with incoming // (received) RFQ messages. These messages have been extracted from the // raw peer wire messages by the stream handler service. IncomingMessages chan<- rfqmsg.IncomingMsg }
StreamHandlerCfg is a struct that holds the configuration parameters for the RFQ peer message stream handler.