liquidity

package
v0.11.2-beta Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 8, 2020 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package liquidity is responsible for monitoring our node's liquidity. It allows setting of a liquidity rule which describes the desired liquidity balance on a per-channel basis.

Swap suggestions are limited to channels that are not currently being used for a pending swap. If we are currently processing an unrestricted swap (ie, a loop out with no outgoing channel targets set or a loop in with no last hop set), we will not suggest any swaps because these swaps will shift the balances of our channels in ways we can't predict.

Fee restrictions are placed on swap suggestions to ensure that we only suggest swaps that fit the configured fee preferences.

  • Sweep Fee Rate Limit: the maximum sat/vByte fee estimate for our sweep transaction to confirm within our configured number of confirmations that we will suggest swaps for.
  • Maximum Swap Fee PPM: the maximum server fee, expressed as parts per million of the full swap amount
  • Maximum Routing Fee PPM: the maximum off-chain routing fees for the swap invoice, expressed as parts per million of the swap amount.
  • Maximum Prepay Routing Fee PPM: the maximum off-chain routing fees for the swap prepayment, expressed as parts per million of the prepay amount.
  • Maximum Prepay: the maximum now-show fee, expressed in satoshis. This amount is only payable in the case where the swap server broadcasts a htlc and the client fails to sweep the preimage.
  • Maximum miner fee: the maximum miner fee we are willing to pay to sweep the on chain htlc. Note that the client will use current fee estimates to sweep, so this value acts more as a sanity check in the case of a large fee spike.

The maximum fee per-swap is calculated as follows: (swap amount * serverPPM/1e6) + miner fee + (swap amount * routingPPM/1e6) + (prepay amount * prepayPPM/1e6).

Index

Constants

View Source
const (

	// FeeBase is the base that we use to express fees.
	FeeBase = 1e6

	// DefaultAutoOutTicker is the default amount of time between automated
	// loop out checks.
	DefaultAutoOutTicker = time.Minute * 10
)
View Source
const Subsystem = "LQDY"

Subsystem defines the sub system name of this package.

Variables

View Source
var (

	// ErrZeroChannelID is returned if we get a rule for a 0 channel ID.
	ErrZeroChannelID = fmt.Errorf("zero channel ID not allowed")

	// ErrInvalidSweepFeeRateLimit is returned if an invalid sweep fee limit
	// is set.
	ErrInvalidSweepFeeRateLimit = fmt.Errorf("sweep fee rate limit must "+
		"be > %v sat/vByte",
		satPerKwToSatPerVByte(chainfee.AbsoluteFeePerKwFloor))

	// ErrZeroMinerFee is returned if a zero maximum miner fee is set.
	ErrZeroMinerFee = errors.New("maximum miner fee must be non-zero")

	// ErrZeroSwapFeePPM is returned if a zero server fee ppm is set.
	ErrZeroSwapFeePPM = errors.New("swap fee PPM must be non-zero")

	// ErrZeroRoutingPPM is returned if a zero routing fee ppm is set.
	ErrZeroRoutingPPM = errors.New("routing fee PPM must be non-zero")

	// ErrZeroPrepayPPM is returned if a zero prepay routing fee ppm is set.
	ErrZeroPrepayPPM = errors.New("prepay routing fee PPM must be non-zero")

	// ErrZeroPrepay is returned if a zero maximum prepay is set.
	ErrZeroPrepay = errors.New("maximum prepay must be non-zero")

	// ErrNegativeBudget is returned if a negative swap budget is set.
	ErrNegativeBudget = errors.New("swap budget must be >= 0")

	// ErrZeroInFlight is returned is a zero in flight swaps value is set.
	ErrZeroInFlight = errors.New("max in flight swaps must be >=0")

	// ErrMinimumExceedsMaximumAmt is returned when the minimum configured
	// swap amount is more than the maximum.
	ErrMinimumExceedsMaximumAmt = errors.New("minimum swap amount " +
		"exceeds maximum")

	// ErrMaxExceedsServer is returned if the maximum swap amount set is
	// more than the server offers.
	ErrMaxExceedsServer = errors.New("maximum swap amount is more than " +
		"server maximum")

	// ErrMinLessThanServer is returned if the minimum swap amount set is
	// less than the server minimum.
	ErrMinLessThanServer = errors.New("minimum swap amount is less than " +
		"server minimum")
)

Functions

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

Types

type Config

type Config struct {
	// AutoOutTicker determines how often we should check whether we want
	// to dispatch an automated loop out. We use a force ticker so that
	// we can trigger autoloop in itests.
	AutoOutTicker *ticker.Force

	// LoopOutRestrictions returns the restrictions that the server applies
	// to loop out swaps.
	LoopOutRestrictions func(ctx context.Context) (*Restrictions, error)

	// Lnd provides us with access to lnd's rpc servers.
	Lnd *lndclient.LndServices

	// ListLoopOut returns all of the loop our swaps stored on disk.
	ListLoopOut func() ([]*loopdb.LoopOut, error)

	// ListLoopIn returns all of the loop in swaps stored on disk.
	ListLoopIn func() ([]*loopdb.LoopIn, error)

	// LoopOutQuote gets swap fee, estimated miner fee and prepay amount for
	// a loop out swap.
	LoopOutQuote func(ctx context.Context,
		request *loop.LoopOutQuoteRequest) (*loop.LoopOutQuote, error)

	// LoopOut dispatches a loop out.
	LoopOut func(ctx context.Context, request *loop.OutRequest) (
		*loop.LoopOutSwapInfo, error)

	// Clock allows easy mocking of time in unit tests.
	Clock clock.Clock

	// MinimumConfirmations is the minimum number of confirmations we allow
	// setting for sweep target.
	MinimumConfirmations int32
}

Config contains the external functionality required to run the liquidity manager.

type LoopOutRecommendation

type LoopOutRecommendation struct {
	// Amount is the total amount to swap.
	Amount btcutil.Amount

	// Channel is the target outgoing channel.
	Channel lnwire.ShortChannelID
}

LoopOutRecommendation contains the information required to recommend a loop out.

func (*LoopOutRecommendation) String

func (l *LoopOutRecommendation) String() string

String returns a string representation of a loop out recommendation.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager contains a set of desired liquidity rules for our channel balances.

func NewManager

func NewManager(cfg *Config) *Manager

NewManager creates a liquidity manager which has no rules set.

func (*Manager) ForceAutoLoop

func (m *Manager) ForceAutoLoop(ctx context.Context) error

ForceAutoLoop force-ticks our auto-out ticker.

func (*Manager) GetParameters

func (m *Manager) GetParameters() Parameters

GetParameters returns a copy of our current parameters.

func (*Manager) Run

func (m *Manager) Run(ctx context.Context) error

Run periodically checks whether we should automatically dispatch a loop out. We run this loop even if automated swaps are not currently enabled rather than managing starting and stopping the ticker as our parameters are updated.

func (*Manager) SetParameters

func (m *Manager) SetParameters(ctx context.Context, params Parameters) error

SetParameters updates our current set of parameters if the new parameters provided are valid.

func (*Manager) SuggestSwaps

func (m *Manager) SuggestSwaps(ctx context.Context, autoOut bool) (
	[]loop.OutRequest, error)

SuggestSwaps returns a set of swap suggestions based on our current liquidity balance for the set of rules configured for the manager, failing if there are no rules set. It takes an autoOut boolean that indicates whether the suggestions are being used for our internal autolooper. This boolean is used to determine the information we add to our swap suggestion and whether we return any suggestions.

type Parameters

type Parameters struct {
	// AutoOut enables automatic dispatch of loop out swaps.
	AutoOut bool

	// AutoFeeBudget is the total amount we allow to be spent on
	// automatically dispatched swaps. Once this budget has been used, we
	// will stop dispatching swaps until the budget is increased or the
	// start date is moved.
	AutoFeeBudget btcutil.Amount

	// AutoFeeStartDate is the date from which we will include automatically
	// dispatched swaps in our current budget, inclusive.
	AutoFeeStartDate time.Time

	// MaxAutoInFlight is the maximum number of in-flight automatically
	// dispatched swaps we allow.
	MaxAutoInFlight int

	// FailureBackOff is the amount of time that we require passes after a
	// channel has been part of a failed loop out swap before we suggest
	// using it again.
	// TODO(carla): add exponential backoff
	FailureBackOff time.Duration

	// SweepFeeRateLimit is the limit that we place on our estimated sweep
	// fee. A swap will not be suggested if estimated fee rate is above this
	// value.
	SweepFeeRateLimit chainfee.SatPerKWeight

	// SweepConfTarget is the number of blocks we aim to confirm our sweep
	// transaction in. This value affects the on chain fees we will pay.
	SweepConfTarget int32

	// MaximumPrepay is the maximum prepay amount we are willing to pay per
	// swap.
	MaximumPrepay btcutil.Amount

	// MaximumSwapFeePPM is the maximum server fee we are willing to pay per
	// swap expressed as parts per million of the swap volume.
	MaximumSwapFeePPM int

	// MaximumRoutingFeePPM is the maximum off-chain routing fee we
	// are willing to pay for off chain invoice routing fees per swap,
	// expressed as parts per million of the swap amount.
	MaximumRoutingFeePPM int

	// MaximumPrepayRoutingFeePPM is the maximum off-chain routing fee we
	// are willing to pay for off chain prepay routing fees per swap,
	// expressed as parts per million of the prepay amount.
	MaximumPrepayRoutingFeePPM int

	// MaximumMinerFee is the maximum on chain fee that we cap our miner
	// fee at in case where we need to claim on chain because we have
	// revealed the preimage, but fees have spiked. We will not initiate a
	// swap if we estimate that the sweep cost will be above our sweep
	// fee limit, and we use fee estimates at time of sweep to set our fees,
	// so this is just a sane cap covering the special case where we need to
	// sweep during a fee spike.
	MaximumMinerFee btcutil.Amount

	// ClientRestrictions are the restrictions placed on swap size by the
	// client.
	ClientRestrictions Restrictions

	// ChannelRules maps a short channel ID to a rule that describes how we
	// would like liquidity to be managed.
	ChannelRules map[lnwire.ShortChannelID]*ThresholdRule
}

Parameters is a set of parameters provided by the user which guide how we assess liquidity.

func (Parameters) String

func (p Parameters) String() string

String returns the string representation of our parameters.

type Restrictions

type Restrictions struct {
	// Minimum is the minimum amount we can swap, inclusive.
	Minimum btcutil.Amount

	// Maximum is the maximum amount we can swap, inclusive.
	Maximum btcutil.Amount
}

Restrictions indicates the restrictions placed on a swap.

func NewRestrictions

func NewRestrictions(minimum, maximum btcutil.Amount) *Restrictions

NewRestrictions creates a set of restrictions.

func (*Restrictions) String

func (r *Restrictions) String() string

String returns a string representation of a set of restrictions.

type ThresholdRule

type ThresholdRule struct {
	// MinimumIncoming is the percentage of incoming liquidity that we do
	// not want to drop below.
	MinimumIncoming int

	// MinimumOutgoing is the percentage of outgoing liquidity that we do
	// not want to drop below.
	MinimumOutgoing int
}

ThresholdRule is a liquidity rule that implements minimum incoming and outgoing liquidity threshold.

func NewThresholdRule

func NewThresholdRule(minIncoming, minOutgoing int) *ThresholdRule

NewThresholdRule returns a new threshold rule.

func (*ThresholdRule) String

func (r *ThresholdRule) String() string

String returns a string representation of a rule.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL