Documentation ¶
Index ¶
- Variables
- func DisableLog()
- func UseLogger(logger btclog.Logger)
- type BudgetAggregator
- type BudgetInputSet
- func (b *BudgetInputSet) AddWalletInputs(wallet Wallet) error
- func (b *BudgetInputSet) Budget() btcutil.Amount
- func (b *BudgetInputSet) DeadlineHeight() int32
- func (b *BudgetInputSet) Inputs() []input.Input
- func (b *BudgetInputSet) NeedWalletInput() bool
- func (b *BudgetInputSet) StartingFeeRate() fn.Option[chainfee.SatPerKWeight]
- func (b *BudgetInputSet) String() string
- type BumpEvent
- type BumpRequest
- type BumpResult
- type Bumper
- type CoinSelectionLocker
- type DeliveryAddr
- type FeeEstimateInfo
- type FeeFunction
- type FeePreference
- type InputSet
- type InputsMap
- type LinearFeeFunction
- type MockNotifier
- func (m *MockNotifier) ConfirmTx(txid *chainhash.Hash, height uint32) error
- func (m *MockNotifier) NotifyEpoch(height int32)
- func (m *MockNotifier) NotifyEpochNonBlocking(height int32)
- func (m *MockNotifier) RegisterBlockEpochNtfn(bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error)
- func (m *MockNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash, _ []byte, numConfs, heightHint uint32, ...) (*chainntnfs.ConfirmationEvent, error)
- func (m *MockNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, _ []byte, heightHint uint32) (*chainntnfs.SpendEvent, error)
- func (m *MockNotifier) SpendOutpoint(outpoint wire.OutPoint, spendingTx wire.MsgTx)
- func (m *MockNotifier) Start() error
- func (m *MockNotifier) Started() bool
- func (m *MockNotifier) Stop() error
- type OutputLeaser
- type Params
- type PendingInputResponse
- type RBFInfo
- type Result
- type SweepState
- type SweeperInput
- type SweeperStore
- type TxPublisher
- type TxPublisherConfig
- type TxRecord
- type UtxoAggregator
- type UtxoSource
- type UtxoSweeper
- func (s *UtxoSweeper) IsSweeperOutpoint(op wire.OutPoint) bool
- func (s *UtxoSweeper) ListSweeps() ([]chainhash.Hash, error)
- func (s *UtxoSweeper) PendingInputs() (map[wire.OutPoint]*PendingInputResponse, error)
- func (s *UtxoSweeper) RelayFeePerKW() chainfee.SatPerKWeight
- func (s *UtxoSweeper) Start() error
- func (s *UtxoSweeper) Stop() error
- func (s *UtxoSweeper) SweepInput(inp input.Input, params Params) (chan Result, error)
- func (s *UtxoSweeper) UpdateParams(input wire.OutPoint, params Params) (chan Result, error)
- type UtxoSweeperConfig
- type Wallet
- type WalletSweepPackage
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidBumpResult is returned when the bump result is invalid. ErrInvalidBumpResult = errors.New("invalid bump result") // ErrNotEnoughBudget is returned when the fee bumper decides the // current budget cannot cover the fee. ErrNotEnoughBudget = errors.New("not enough budget") // ErrLocktimeImmature is returned when sweeping an input whose // locktime is not reached. ErrLocktimeImmature = errors.New("immature input") // ErrTxNoOutput is returned when an output cannot be created during tx // preparation, usually due to the output being dust. ErrTxNoOutput = errors.New("tx has no output") // ErrThirdPartySpent is returned when a third party has spent the // input in the sweeping tx. ErrThirdPartySpent = errors.New("third party spent the output") )
var ( // ErrRemoteSpend is returned in case an output that we try to sweep is // confirmed in a tx of the remote party. ErrRemoteSpend = errors.New("remote party swept utxo") // ErrFeePreferenceTooLow is returned when the fee preference gives a // fee rate that's below the relay fee rate. ErrFeePreferenceTooLow = errors.New("fee preference too low") // ErrExclusiveGroupSpend is returned in case a different input of the // same exclusive group was spent. ErrExclusiveGroupSpend = errors.New("other member of exclusive group " + "was spent") // ErrSweeperShuttingDown is an error returned when a client attempts to // make a request to the UtxoSweeper, but it is unable to handle it as // it is/has already been stopped. ErrSweeperShuttingDown = errors.New("utxo sweeper shutting down") // DefaultDeadlineDelta defines a default deadline delta (1 week) to be // used when sweeping inputs with no deadline pressure. DefaultDeadlineDelta = int32(1008) )
var ( // ErrNotEnoughInputs is returned when there are not enough wallet // inputs to construct a non-dust change output for an input set. ErrNotEnoughInputs = fmt.Errorf("not enough inputs") // ErrDeadlinesMismatch is returned when the deadlines of the input // sets do not match. ErrDeadlinesMismatch = fmt.Errorf("deadlines mismatch") // ErrDustOutput is returned when the output value is below the dust // limit. ErrDustOutput = fmt.Errorf("dust output") )
var ( // DefaultMaxInputsPerTx specifies the default maximum number of inputs // allowed in a single sweep tx. If more need to be swept, multiple txes // are created and published. DefaultMaxInputsPerTx = uint32(100) // ErrLocktimeConflict is returned when inputs with different // transaction nLockTime values are included in the same transaction. // // NOTE: due the SINGLE|ANYONECANPAY sighash flag, which is used in the // second level success/timeout txns, only the txns sharing the same // nLockTime can exist in the same tx. ErrLocktimeConflict = errors.New("incompatible locktime") )
var ( // ErrNoFeePreference is returned when we attempt to satisfy a sweep // request from a client whom did not specify a fee preference. ErrNoFeePreference = errors.New("no fee preference specified") // ErrFeePreferenceConflict is returned when both a fee rate and a conf // target is set for a fee preference. ErrFeePreferenceConflict = errors.New("fee preference conflict") )
var ( // DefaultMaxFeeRate is the default maximum fee rate allowed within the // UtxoSweeper. The current value is equivalent to a fee rate of 1,000 // sat/vbyte. DefaultMaxFeeRate chainfee.SatPerVByte = 1e3 )
var ( // ErrMaxPosition is returned when trying to increase the position of // the fee function while it's already at its max. ErrMaxPosition = errors.New("position already at max") )
var ( // ErrTxNotFound is returned when querying using a txid that's not // found in our db. ErrTxNotFound = errors.New("tx not found") )
Functions ¶
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
Types ¶
type BudgetAggregator ¶
type BudgetAggregator struct {
// contains filtered or unexported fields
}
BudgetAggregator is a budget-based aggregator that creates clusters based on deadlines and budgets of inputs.
func NewBudgetAggregator ¶
func NewBudgetAggregator(estimator chainfee.Estimator, maxInputs uint32) *BudgetAggregator
NewBudgetAggregator creates a new instance of a BudgetAggregator.
func (*BudgetAggregator) ClusterInputs ¶
func (b *BudgetAggregator) ClusterInputs(inputs InputsMap) []InputSet
ClusterInputs creates a list of input sets from pending inputs. 1. filter out inputs whose budget cannot cover min relay fee. 2. filter a list of exclusive inputs. 3. group the inputs into clusters based on their deadline height. 4. sort the inputs in each cluster by their budget. 5. optionally split a cluster if it exceeds the max input limit. 6. create input sets from each of the clusters. 7. create input sets for each of the exclusive inputs.
type BudgetInputSet ¶
type BudgetInputSet struct {
// contains filtered or unexported fields
}
BudgetInputSet implements the interface `InputSet`. It takes a list of pending inputs which share the same deadline height and groups them into a set conditionally based on their economical values.
func NewBudgetInputSet ¶
func NewBudgetInputSet(inputs []SweeperInput, deadlineHeight int32) (*BudgetInputSet, error)
NewBudgetInputSet creates a new BudgetInputSet.
func (*BudgetInputSet) AddWalletInputs ¶
func (b *BudgetInputSet) AddWalletInputs(wallet Wallet) error
AddWalletInputs adds wallet inputs to the set until the specified budget is met. When sweeping inputs with required outputs, although there's budget specified, it cannot be directly spent from these required outputs. Instead, we need to borrow budget from other inputs to make the sweep happen. There are two sources to borrow from: 1) other inputs, 2) wallet utxos. If we are calling this method, it means other inputs cannot cover the specified budget, so we need to borrow from wallet utxos.
Return an error if there are not enough wallet inputs, and the budget set is set to its initial state by removing any wallet inputs added.
NOTE: must be called with the wallet lock held via `WithCoinSelectLock`.
func (*BudgetInputSet) Budget ¶
func (b *BudgetInputSet) Budget() btcutil.Amount
Budget returns the total budget of the set.
NOTE: part of the InputSet interface.
func (*BudgetInputSet) DeadlineHeight ¶
func (b *BudgetInputSet) DeadlineHeight() int32
DeadlineHeight returns the deadline height of the set.
NOTE: part of the InputSet interface.
func (*BudgetInputSet) Inputs ¶
func (b *BudgetInputSet) Inputs() []input.Input
Inputs returns the inputs that should be used to create a tx.
NOTE: part of the InputSet interface.
func (*BudgetInputSet) NeedWalletInput ¶
func (b *BudgetInputSet) NeedWalletInput() bool
NeedWalletInput returns true if the input set needs more wallet inputs.
A set may need wallet inputs when it has a required output or its total value cannot cover its total budget.
func (*BudgetInputSet) StartingFeeRate ¶
func (b *BudgetInputSet) StartingFeeRate() fn.Option[chainfee.SatPerKWeight]
StartingFeeRate returns the max starting fee rate found in the inputs.
NOTE: part of the InputSet interface.
func (*BudgetInputSet) String ¶
func (b *BudgetInputSet) String() string
String returns a human-readable description of the input set.
type BumpEvent ¶
type BumpEvent uint8
BumpEvent represents the event of a fee bumping attempt.
const ( // TxPublished is sent when the broadcast attempt is finished. TxPublished BumpEvent = iota // TxFailed is sent when the broadcast attempt fails. TxFailed // TxReplaced is sent when the original tx is replaced by a new one. TxReplaced // TxConfirmed is sent when the tx is confirmed. TxConfirmed )
type BumpRequest ¶
type BumpRequest struct { // Budget givens the total amount that can be used as fees by these // inputs. Budget btcutil.Amount // Inputs is the set of inputs to sweep. Inputs []input.Input // DeadlineHeight is the block height at which the tx should be // confirmed. DeadlineHeight int32 // DeliveryAddress is the script to send the change output to. DeliveryAddress []byte // MaxFeeRate is the maximum fee rate that can be used for fee bumping. MaxFeeRate chainfee.SatPerKWeight // StartingFeeRate is an optional parameter that can be used to specify // the initial fee rate to use for the fee function. StartingFeeRate fn.Option[chainfee.SatPerKWeight] }
BumpRequest is used by the caller to give the Bumper the necessary info to create and manage potential fee bumps for a set of inputs.
func (*BumpRequest) MaxFeeRateAllowed ¶
func (r *BumpRequest) MaxFeeRateAllowed() (chainfee.SatPerKWeight, error)
MaxFeeRateAllowed returns the maximum fee rate allowed for the given request. It calculates the feerate using the supplied budget and the weight, compares it with the specified MaxFeeRate, and returns the smaller of the two.
type BumpResult ¶
type BumpResult struct { // Event is the type of event that the result is for. Event BumpEvent // Tx is the tx being broadcast. Tx *wire.MsgTx // ReplacedTx is the old, replaced tx if a fee bump is attempted. ReplacedTx *wire.MsgTx // FeeRate is the fee rate used for the new tx. FeeRate chainfee.SatPerKWeight // Fee is the fee paid by the new tx. Fee btcutil.Amount // Err is the error that occurred during the broadcast. Err error // contains filtered or unexported fields }
BumpResult is used by the Bumper to send updates about the tx being broadcast.
func (*BumpResult) Validate ¶
func (b *BumpResult) Validate() error
Validate validates the BumpResult so it's safe to use.
type Bumper ¶
type Bumper interface { // Broadcast is used to publish the tx created from the given inputs // specified in the request. It handles the tx creation, broadcasts it, // and monitors its confirmation status for potential fee bumping. It // returns a chan that the caller can use to receive updates about the // broadcast result and potential RBF attempts. Broadcast(req *BumpRequest) (<-chan *BumpResult, error) }
Bumper defines an interface that can be used by other subsystems for fee bumping.
type CoinSelectionLocker ¶
type CoinSelectionLocker interface { // WithCoinSelectLock will execute the passed function closure in a // synchronized manner preventing any coin selection operations from // proceeding while the closure is executing. This can be seen as the // ability to execute a function closure under an exclusive coin // selection lock. WithCoinSelectLock(func() error) error }
CoinSelectionLocker is an interface that allows the caller to perform an operation, which is synchronized with all coin selection attempts. This can be used when an operation requires that all coin selection operations cease forward progress. Think of this as an exclusive lock on coin selection operations.
type DeliveryAddr ¶
type DeliveryAddr struct { // Addr is the address to pay to. Addr btcutil.Address // Amt is the amount to pay to the given address. Amt btcutil.Amount }
DeliveryAddr is a pair of (address, amount) used to craft a transaction paying to more than one specified address.
type FeeEstimateInfo ¶
type FeeEstimateInfo struct { // ConfTarget if non-zero, signals a fee preference expressed in the // number of desired blocks between first broadcast, and confirmation. ConfTarget uint32 // FeeRate if non-zero, signals a fee pre fence expressed in the fee // rate expressed in sat/kw for a particular transaction. FeeRate chainfee.SatPerKWeight }
FeeEstimateInfo allows callers to express their time value for inclusion of a transaction into a block via either a confirmation target, or a fee rate.
func (FeeEstimateInfo) Estimate ¶
func (f FeeEstimateInfo) Estimate(estimator chainfee.Estimator, maxFeeRate chainfee.SatPerKWeight) (chainfee.SatPerKWeight, error)
Estimate returns a fee rate for the given fee preference. It ensures that the fee rate respects the bounds of the relay fee and the max fee rates, if specified.
func (FeeEstimateInfo) String ¶
func (f FeeEstimateInfo) String() string
String returns a human-readable string of the fee preference.
type FeeFunction ¶
type FeeFunction interface { // FeeRate returns the current fee rate calculated by the fee function. FeeRate() chainfee.SatPerKWeight // Increment increases the fee rate by one step. The definition of one // step is up to the implementation. After calling this method, it's // expected to change the state of the fee function such that calling // `FeeRate` again will return the increased value. // // It returns a boolean to indicate whether the fee rate is increased, // as fee bump should not be attempted if the increased fee rate is not // greater than the current fee rate, which may happen if the algorithm // gives the same fee rates at two positions. // // An error is returned when the max fee rate is reached. // // NOTE: we intentionally don't return the new fee rate here, so both // the implementation and the caller are aware of the state change. Increment() (bool, error) // IncreaseFeeRate increases the fee rate to the new position // calculated using (width - confTarget). It returns a boolean to // indicate whether the fee rate is increased, and an error if the // position is greater than the width. // // NOTE: this method is provided to allow the caller to increase the // fee rate based on a conf target without taking care of the fee // function's current state (position). IncreaseFeeRate(confTarget uint32) (bool, error) }
FeeFunction defines an interface that is used to calculate fee rates for transactions. It's expected the implementations use three params, the starting fee rate, the ending fee rate, and number of blocks till deadline block height, to build an algorithm to calculate the fee rate based on the current block height.
type FeePreference ¶
type FeePreference interface { // String returns a human-readable string of the fee preference. String() string // Estimate takes a fee estimator and a max allowed fee rate and // returns a fee rate for the given fee preference. It ensures that the // fee rate respects the bounds of the relay fee and the specified max // fee rates. Estimate(chainfee.Estimator, chainfee.SatPerKWeight) (chainfee.SatPerKWeight, error) }
FeePreference defines an interface that allows the caller to specify how the fee rate should be handled. Depending on the implementation, the fee rate can either be specified directly, or via a conf target which relies on the chain backend(`bitcoind`) to give a fee estimation, or a customized fee function which handles fee calculation based on the specified urgency(deadline).
type InputSet ¶
type InputSet interface { // Inputs returns the set of inputs that should be used to create a tx. Inputs() []input.Input // AddWalletInputs adds wallet inputs to the set until a non-dust // change output can be made. Return an error if there are not enough // wallet inputs. AddWalletInputs(wallet Wallet) error // NeedWalletInput returns true if the input set needs more wallet // inputs. NeedWalletInput() bool // DeadlineHeight returns an absolute block height to express the // time-sensitivity of the input set. The outputs from a force close tx // have different time preferences: // - to_local: no time pressure as it can only be swept by us. // - first level outgoing HTLC: must be swept before its corresponding // incoming HTLC's CLTV is reached. // - first level incoming HTLC: must be swept before its CLTV is // reached. // - second level HTLCs: no time pressure. // - anchor: for CPFP-purpose anchor, it must be swept before any of // the above CLTVs is reached. For non-CPFP purpose anchor, there's // no time pressure. DeadlineHeight() int32 // Budget givens the total amount that can be used as fees by this // input set. Budget() btcutil.Amount // StartingFeeRate returns the max starting fee rate found in the // inputs. StartingFeeRate() fn.Option[chainfee.SatPerKWeight] }
InputSet defines an interface that's responsible for filtering a set of inputs that can be swept economically.
type InputsMap ¶
type InputsMap = map[wire.OutPoint]*SweeperInput
InputsMap is a type alias for a set of pending inputs.
type LinearFeeFunction ¶
type LinearFeeFunction struct {
// contains filtered or unexported fields
}
LinearFeeFunction implements the FeeFunction interface with a linear function:
feeRate = startingFeeRate + position * delta. - width: deadlineBlockHeight - startingBlockHeight - delta: (endingFeeRate - startingFeeRate) / width - position: currentBlockHeight - startingBlockHeight
The fee rate will be capped at endingFeeRate.
TODO(yy): implement more functions specified here: - https://github.com/lightningnetwork/lnd/issues/4215
func NewLinearFeeFunction ¶
func NewLinearFeeFunction(maxFeeRate chainfee.SatPerKWeight, confTarget uint32, estimator chainfee.Estimator, startingFeeRate fn.Option[chainfee.SatPerKWeight]) ( *LinearFeeFunction, error)
NewLinearFeeFunction creates a new linear fee function and initializes it with a starting fee rate which is an estimated value returned from the fee estimator using the initial conf target.
func (*LinearFeeFunction) FeeRate ¶
func (l *LinearFeeFunction) FeeRate() chainfee.SatPerKWeight
FeeRate returns the current fee rate.
NOTE: part of the FeeFunction interface.
func (*LinearFeeFunction) IncreaseFeeRate ¶
func (l *LinearFeeFunction) IncreaseFeeRate(confTarget uint32) (bool, error)
IncreaseFeeRate calculate a new position using the given conf target, and increases the fee rate to the new position by calling the Increment method.
NOTE: this method will change the state of the fee function as it increases its current fee rate.
NOTE: part of the FeeFunction interface.
func (*LinearFeeFunction) Increment ¶
func (l *LinearFeeFunction) Increment() (bool, error)
Increment increases the fee rate by one position, returns a boolean to indicate whether the fee rate was increased, and an error if the position is greater than the width. The increased fee rate will be set as the current fee rate, and the internal position will be incremented.
NOTE: this method will change the state of the fee function as it increases its current fee rate.
NOTE: part of the FeeFunction interface.
type MockNotifier ¶
type MockNotifier struct {
// contains filtered or unexported fields
}
MockNotifier simulates the chain notifier for test purposes. This type is exported because it is used in nursery tests.
func NewMockNotifier ¶
func NewMockNotifier(t *testing.T) *MockNotifier
NewMockNotifier instantiates a new mock notifier.
func (*MockNotifier) ConfirmTx ¶
func (m *MockNotifier) ConfirmTx(txid *chainhash.Hash, height uint32) error
ConfirmTx simulates a tx confirming.
func (*MockNotifier) NotifyEpoch ¶
func (m *MockNotifier) NotifyEpoch(height int32)
NotifyEpoch simulates a new epoch arriving.
func (*MockNotifier) NotifyEpochNonBlocking ¶
func (m *MockNotifier) NotifyEpochNonBlocking(height int32)
NotifyEpochNonBlocking simulates a new epoch arriving without blocking when the epochChan is not read.
func (*MockNotifier) RegisterBlockEpochNtfn ¶
func (m *MockNotifier) RegisterBlockEpochNtfn( bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error)
RegisterBlockEpochNtfn registers a block notification.
func (*MockNotifier) RegisterConfirmationsNtfn ¶
func (m *MockNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash, _ []byte, numConfs, heightHint uint32, opt ...chainntnfs.NotifierOption) (*chainntnfs.ConfirmationEvent, error)
RegisterConfirmationsNtfn registers for tx confirm notifications.
func (*MockNotifier) RegisterSpendNtfn ¶
func (m *MockNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint, _ []byte, heightHint uint32) (*chainntnfs.SpendEvent, error)
RegisterSpendNtfn registers for spend notifications.
func (*MockNotifier) SpendOutpoint ¶
func (m *MockNotifier) SpendOutpoint(outpoint wire.OutPoint, spendingTx wire.MsgTx)
SpendOutpoint simulates a utxo being spent.
type OutputLeaser ¶
type OutputLeaser interface { // LeaseOutput leases a target output, rendering it unusable for coin // selection. LeaseOutput(i wtxmgr.LockID, o wire.OutPoint, d time.Duration) ( time.Time, []byte, btcutil.Amount, error) // ReleaseOutput releases a target output, allowing it to be used for // coin selection once again. ReleaseOutput(i wtxmgr.LockID, o wire.OutPoint) error }
OutputLeaser allows a caller to lease/release an output. When leased, the outputs shouldn't be used for any sort of channel funding or coin selection. Leased outputs are expected to be persisted between restarts.
type Params ¶
type Params struct { // ExclusiveGroup is an identifier that, if set, prevents other inputs // with the same identifier from being batched together. ExclusiveGroup *uint64 // DeadlineHeight specifies an absolute block height that this input // should be confirmed by. This value is used by the fee bumper to // decide its urgency and adjust its feerate used. DeadlineHeight fn.Option[int32] // Budget specifies the maximum amount of satoshis that can be spent on // fees for this sweep. Budget btcutil.Amount // Immediate indicates that the input should be swept immediately // without waiting for blocks to come to trigger the sweeping of // inputs. Immediate bool // StartingFeeRate is an optional parameter that can be used to specify // the initial fee rate to use for the fee function. StartingFeeRate fn.Option[chainfee.SatPerKWeight] }
Params contains the parameters that control the sweeping process.
type PendingInputResponse ¶
type PendingInputResponse struct { // OutPoint is the identify outpoint of the input being swept. OutPoint wire.OutPoint // WitnessType is the witness type of the input being swept. WitnessType input.WitnessType // Amount is the amount of the input being swept. Amount btcutil.Amount // LastFeeRate is the most recent fee rate used for the input being // swept within a transaction broadcast to the network. LastFeeRate chainfee.SatPerKWeight // BroadcastAttempts is the number of attempts we've made to sweept the // input. BroadcastAttempts int // Params contains the sweep parameters for this pending request. Params Params // DeadlineHeight records the deadline height of this input. DeadlineHeight uint32 }
PendingInputResponse contains information about an input that is currently being swept by the UtxoSweeper.
type RBFInfo ¶
type RBFInfo struct { // Txid is the txid of the sweeping tx. Txid chainhash.Hash // FeeRate is the fee rate of the sweeping tx. FeeRate chainfee.SatPerKWeight // Fee is the total fee of the sweeping tx. Fee btcutil.Amount }
RBFInfo stores the information required to perform a RBF bump on a pending sweeping tx.
type Result ¶
type Result struct { // Err is the final result of the sweep. It is nil when the input is // swept successfully by us. ErrRemoteSpend is returned when another // party took the input. Err error // Tx is the transaction that spent the input. Tx *wire.MsgTx }
Result is the struct that is pushed through the result channel. Callers can use this to be informed of the final sweep result. In case of a remote spend, Err will be ErrRemoteSpend.
type SweepState ¶
type SweepState uint8
SweepState represents the current state of a pending input.
const ( // Init is the initial state of a pending input. This is set when a new // sweeping request for a given input is made. Init SweepState = iota // PendingPublish specifies an input's state where it's already been // included in a sweeping tx but the tx is not published yet. Inputs // in this state should not be used for grouping again. PendingPublish // Published is the state where the input's sweeping tx has // successfully been published. Inputs in this state can only be // updated via RBF. Published // PublishFailed is the state when an error is returned from publishing // the sweeping tx. Inputs in this state can be re-grouped in to a new // sweeping tx. PublishFailed // Swept is the final state of a pending input. This is set when the // input has been successfully swept. Swept // Excluded is the state of a pending input that has been excluded and // can no longer be swept. For instance, when one of the three anchor // sweeping transactions confirmed, the remaining two will be excluded. Excluded // Failed is the state when a pending input has too many failed publish // atttempts or unknown broadcast error is returned. Failed )
func (SweepState) String ¶
func (s SweepState) String() string
String gives a human readable text for the sweep states.
type SweeperInput ¶
type SweeperInput struct { input.Input // DeadlineHeight is the deadline height for this input. This is // different from the DeadlineHeight in its params as it's an actual // value than an option. DeadlineHeight int32 // contains filtered or unexported fields }
SweeperInput is created when an input reaches the main loop for the first time. It wraps the input and tracks all relevant state that is needed for sweeping.
func (*SweeperInput) String ¶
func (p *SweeperInput) String() string
String returns a human readable interpretation of the pending input.
type SweeperStore ¶
type SweeperStore interface { // IsOurTx determines whether a tx is published by us, based on its // hash. IsOurTx(hash chainhash.Hash) (bool, error) // StoreTx stores a tx hash we are about to publish. StoreTx(*TxRecord) error // ListSweeps lists all the sweeps we have successfully published. ListSweeps() ([]chainhash.Hash, error) // GetTx queries the database to find the tx that matches the given // txid. Returns ErrTxNotFound if it cannot be found. GetTx(hash chainhash.Hash) (*TxRecord, error) // DeleteTx removes a tx specified by the hash from the store. DeleteTx(hash chainhash.Hash) error }
SweeperStore stores published txes.
func NewSweeperStore ¶
NewSweeperStore returns a new store instance.
type TxPublisher ¶
type TxPublisher struct {
// contains filtered or unexported fields
}
TxPublisher is an implementation of the Bumper interface. It utilizes the `testmempoolaccept` RPC to bump the fee of txns it created based on different fee function selected or configed by the caller. Its purpose is to take a list of inputs specified, and create a tx that spends them to a specified output. It will then monitor the confirmation status of the tx, and if it's not confirmed within a certain time frame, it will attempt to bump the fee of the tx by creating a new tx that spends the same inputs to the same output, but with a higher fee rate. It will continue to do this until the tx is confirmed or the fee rate reaches the maximum fee rate specified by the caller.
func NewTxPublisher ¶
func NewTxPublisher(cfg TxPublisherConfig) *TxPublisher
NewTxPublisher creates a new TxPublisher.
func (*TxPublisher) Broadcast ¶
func (t *TxPublisher) Broadcast(req *BumpRequest) (<-chan *BumpResult, error)
Broadcast is used to publish the tx created from the given inputs. It will, 1. init a fee function based on the given strategy. 2. create an RBF-compliant tx and monitor it for confirmation. 3. notify the initial broadcast result back to the caller. The initial broadcast is guaranteed to be RBF-compliant unless the budget specified cannot cover the fee.
NOTE: part of the Bumper interface.
func (*TxPublisher) Start ¶
func (t *TxPublisher) Start() error
Start starts the publisher by subscribing to block epoch updates and kicking off the monitor loop.
func (*TxPublisher) Stop ¶
func (t *TxPublisher) Stop()
Stop stops the publisher and waits for the monitor loop to exit.
type TxPublisherConfig ¶
type TxPublisherConfig struct { // Signer is used to create the tx signature. Signer input.Signer // Wallet is used primarily to publish the tx. Wallet Wallet // Estimator is used to estimate the fee rate for the new tx based on // its deadline conf target. Estimator chainfee.Estimator // Notifier is used to monitor the confirmation status of the tx. Notifier chainntnfs.ChainNotifier }
TxPublisherConfig is the config used to create a new TxPublisher.
type TxRecord ¶
type TxRecord struct { // Txid is the sweeping tx's txid, which is used as the key to store // the following values. Txid chainhash.Hash // FeeRate is the fee rate of the sweeping tx, unit is sats/kw. FeeRate uint64 // Fee is the fee of the sweeping tx, unit is sat. Fee uint64 // Published indicates whether the tx has been published. Published bool }
TxRecord specifies a record of a tx that's stored in the database.
type UtxoAggregator ¶
type UtxoAggregator interface { // ClusterInputs takes a list of inputs and groups them into input // sets. Each input set will be used to create a sweeping transaction. ClusterInputs(inputs InputsMap) []InputSet }
UtxoAggregator defines an interface that takes a list of inputs and aggregate them into groups. Each group is used as the inputs to create a sweeping transaction.
type UtxoSource ¶
type UtxoSource interface { // ListUnspentWitness returns all UTXOs from the default wallet account // that have between minConfs and maxConfs number of confirmations. ListUnspentWitnessFromDefaultAccount(minConfs, maxConfs int32) ( []*lnwallet.Utxo, error) }
UtxoSource is an interface that allows a caller to access a source of UTXOs to use when crafting sweep transactions.
type UtxoSweeper ¶
type UtxoSweeper struct {
// contains filtered or unexported fields
}
UtxoSweeper is responsible for sweeping outputs back into the wallet
func (*UtxoSweeper) IsSweeperOutpoint ¶
func (s *UtxoSweeper) IsSweeperOutpoint(op wire.OutPoint) bool
IsSweeperOutpoint determines whether the outpoint was created by the sweeper.
NOTE: It is enough to check the txid because the sweeper will create outpoints which solely belong to the internal LND wallet.
func (*UtxoSweeper) ListSweeps ¶
func (s *UtxoSweeper) ListSweeps() ([]chainhash.Hash, error)
ListSweeps returns a list of the sweeps recorded by the sweep store.
func (*UtxoSweeper) PendingInputs ¶
func (s *UtxoSweeper) PendingInputs() ( map[wire.OutPoint]*PendingInputResponse, error)
PendingInputs returns the set of inputs that the UtxoSweeper is currently attempting to sweep.
func (*UtxoSweeper) RelayFeePerKW ¶
func (s *UtxoSweeper) RelayFeePerKW() chainfee.SatPerKWeight
RelayFeePerKW returns the minimum fee rate required for transactions to be relayed.
func (*UtxoSweeper) Start ¶
func (s *UtxoSweeper) Start() error
Start starts the process of constructing and publish sweep txes.
func (*UtxoSweeper) Stop ¶
func (s *UtxoSweeper) Stop() error
Stop stops sweeper from listening to block epochs and constructing sweep txes.
func (*UtxoSweeper) SweepInput ¶
SweepInput sweeps inputs back into the wallet. The inputs will be batched and swept after the batch time window ends. A custom fee preference can be provided to determine what fee rate should be used for the input. Note that the input may not always be swept with this exact value, as its possible for it to be batched under the same transaction with other similar fee rate inputs.
NOTE: Extreme care needs to be taken that input isn't changed externally. Because it is an interface and we don't know what is exactly behind it, we cannot make a local copy in sweeper.
TODO(yy): make sure the caller is using the Result chan.
func (*UtxoSweeper) UpdateParams ¶
UpdateParams allows updating the sweep parameters of a pending input in the UtxoSweeper. This function can be used to provide an updated fee preference and force flag that will be used for a new sweep transaction of the input that will act as a replacement transaction (RBF) of the original sweeping transaction, if any. The exclusive group is left unchanged.
NOTE: This currently doesn't do any fee rate validation to ensure that a bump is actually successful. The responsibility of doing so should be handled by the caller.
type UtxoSweeperConfig ¶
type UtxoSweeperConfig struct { // GenSweepScript generates a P2WKH script belonging to the wallet where // funds can be swept. GenSweepScript func() ([]byte, error) // FeeEstimator is used when crafting sweep transactions to estimate // the necessary fee relative to the expected size of the sweep // transaction. FeeEstimator chainfee.Estimator // Wallet contains the wallet functions that sweeper requires. Wallet Wallet // Notifier is an instance of a chain notifier we'll use to watch for // certain on-chain events. Notifier chainntnfs.ChainNotifier // Mempool is the mempool watcher that will be used to query whether a // given input is already being spent by a transaction in the mempool. Mempool chainntnfs.MempoolWatcher // Store stores the published sweeper txes. Store SweeperStore // Signer is used by the sweeper to generate valid witnesses at the // time the incubated outputs need to be spent. Signer input.Signer // MaxInputsPerTx specifies the default maximum number of inputs allowed // in a single sweep tx. If more need to be swept, multiple txes are // created and published. MaxInputsPerTx uint32 // MaxFeeRate is the maximum fee rate allowed within the UtxoSweeper. MaxFeeRate chainfee.SatPerVByte // Aggregator is used to group inputs into clusters based on its // implemention-specific strategy. Aggregator UtxoAggregator // Publisher is used to publish the sweep tx crafted here and monitors // it for potential fee bumps. Publisher Bumper // NoDeadlineConfTarget is the conf target to use when sweeping // non-time-sensitive outputs. NoDeadlineConfTarget uint32 }
UtxoSweeperConfig contains dependencies of UtxoSweeper.
type Wallet ¶
type Wallet interface { // PublishTransaction performs cursory validation (dust checks, etc) and // broadcasts the passed transaction to the Bitcoin network. PublishTransaction(tx *wire.MsgTx, label string) error // ListUnspentWitnessFromDefaultAccount returns all unspent outputs // which are version 0 witness programs from the default wallet account. // The 'minConfs' and 'maxConfs' parameters indicate the minimum // and maximum number of confirmations an output needs in order to be // returned by this method. ListUnspentWitnessFromDefaultAccount(minConfs, maxConfs int32) ( []*lnwallet.Utxo, error) // WithCoinSelectLock will execute the passed function closure in a // synchronized manner preventing any coin selection operations from // proceeding while the closure is executing. This can be seen as the // ability to execute a function closure under an exclusive coin // selection lock. WithCoinSelectLock(f func() error) error // RemoveDescendants removes any wallet transactions that spends // outputs created by the specified transaction. RemoveDescendants(*wire.MsgTx) error // FetchTx returns the transaction that corresponds to the transaction // hash passed in. If the transaction can't be found then a nil // transaction pointer is returned. FetchTx(chainhash.Hash) (*wire.MsgTx, error) // CancelRebroadcast is used to inform the rebroadcaster sub-system // that it no longer needs to try to rebroadcast a transaction. This is // used to ensure that invalid transactions (inputs spent) aren't // retried in the background. CancelRebroadcast(tx chainhash.Hash) // CheckMempoolAcceptance checks whether a transaction follows mempool // policies and returns an error if it cannot be accepted into the // mempool. CheckMempoolAcceptance(tx *wire.MsgTx) error // GetTransactionDetails returns a detailed description of a tx given // its transaction hash. GetTransactionDetails(txHash *chainhash.Hash) ( *lnwallet.TransactionDetail, error) // BackEnd returns a name for the wallet's backing chain service, // which could be e.g. btcd, bitcoind, neutrino, or another consensus // service. BackEnd() string }
Wallet contains all wallet related functionality required by sweeper.
type WalletSweepPackage ¶
type WalletSweepPackage struct { // SweepTx is a fully signed, and valid transaction that is broadcast, // will sweep ALL confirmed coins in the wallet with a single // transaction. SweepTx *wire.MsgTx // CancelSweepAttempt allows the caller to cancel the sweep attempt. // // NOTE: If the sweeping transaction isn't or cannot be broadcast, then // this closure MUST be called, otherwise all selected utxos will be // unable to be used. CancelSweepAttempt func() }
WalletSweepPackage is a package that gives the caller the ability to sweep ALL funds from a wallet in a single transaction. We also package a function closure that allows one to abort the operation.
func CraftSweepAllTx ¶
func CraftSweepAllTx(feeRate, maxFeeRate chainfee.SatPerKWeight, blockHeight uint32, deliveryAddrs []DeliveryAddr, changeAddr btcutil.Address, coinSelectLocker CoinSelectionLocker, utxoSource UtxoSource, outputLeaser OutputLeaser, signer input.Signer, minConfs int32) (*WalletSweepPackage, error)
CraftSweepAllTx attempts to craft a WalletSweepPackage which will allow the caller to sweep ALL outputs within the wallet to a list of outputs. Any leftover amount after these outputs and transaction fee, is sent to a single output, as specified by the change address. The sweep transaction will be crafted with the target fee rate, and will use the utxoSource and outputLeaser as sources for wallet funds.