mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-07 13:39:46 +02:00
lnrpc+sweep: make sure public interface takes public types as params
This commit exports and renames the following variable names: - `PendingInput` is now `PendingInputResponse` as it's responding to a request. - `pendingInput` is now renamed and exported as `SweeperInput`. - `pendingInputs` is now renamed and exported as `InputsMap`. This commit is first made from running: ``` gofmt -d -w -r 'PendingInput -> PendingInputResponse' . gofmt -d -w -r 'pendingInput -> SweeperInput' . gofmt -d -w -r 'pendingInputs -> InputsMap' . ``` And followed by some docs and variable names fixes.
This commit is contained in:
parent
9e7d4b7e0b
commit
28df2d7327
@ -863,27 +863,27 @@ func (w *WalletKit) PendingSweeps(ctx context.Context,
|
|||||||
|
|
||||||
// Retrieve all of the outputs the UtxoSweeper is currently trying to
|
// Retrieve all of the outputs the UtxoSweeper is currently trying to
|
||||||
// sweep.
|
// sweep.
|
||||||
pendingInputs, err := w.cfg.Sweeper.PendingInputs()
|
inputsMap, err := w.cfg.Sweeper.PendingInputs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert them into their respective RPC format.
|
// Convert them into their respective RPC format.
|
||||||
rpcPendingSweeps := make([]*PendingSweep, 0, len(pendingInputs))
|
rpcPendingSweeps := make([]*PendingSweep, 0, len(inputsMap))
|
||||||
for _, pendingInput := range pendingInputs {
|
for _, sweeperInput := range inputsMap {
|
||||||
witnessType, ok := allWitnessTypes[pendingInput.WitnessType]
|
witnessType, ok := allWitnessTypes[sweeperInput.WitnessType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unhandled witness type %v for "+
|
return nil, fmt.Errorf("unhandled witness type %v for "+
|
||||||
"input %v", pendingInput.WitnessType,
|
"input %v", sweeperInput.WitnessType,
|
||||||
pendingInput.OutPoint)
|
sweeperInput.OutPoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
op := lnrpc.MarshalOutPoint(&pendingInput.OutPoint)
|
op := lnrpc.MarshalOutPoint(&sweeperInput.OutPoint)
|
||||||
amountSat := uint32(pendingInput.Amount)
|
amountSat := uint32(sweeperInput.Amount)
|
||||||
satPerVbyte := uint64(pendingInput.LastFeeRate.FeePerVByte())
|
satPerVbyte := uint64(sweeperInput.LastFeeRate.FeePerVByte())
|
||||||
broadcastAttempts := uint32(pendingInput.BroadcastAttempts)
|
broadcastAttempts := uint32(sweeperInput.BroadcastAttempts)
|
||||||
|
|
||||||
feePref := pendingInput.Params.Fee
|
feePref := sweeperInput.Params.Fee
|
||||||
requestedFee, ok := feePref.(sweep.FeeEstimateInfo)
|
requestedFee, ok := feePref.(sweep.FeeEstimateInfo)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unknown fee preference type: "+
|
return nil, fmt.Errorf("unknown fee preference type: "+
|
||||||
@ -900,7 +900,7 @@ func (w *WalletKit) PendingSweeps(ctx context.Context,
|
|||||||
BroadcastAttempts: broadcastAttempts,
|
BroadcastAttempts: broadcastAttempts,
|
||||||
RequestedSatPerVbyte: requestedFeeRate,
|
RequestedSatPerVbyte: requestedFeeRate,
|
||||||
RequestedConfTarget: requestedFee.ConfTarget,
|
RequestedConfTarget: requestedFee.ConfTarget,
|
||||||
Force: pendingInput.Params.Force,
|
Force: sweeperInput.Params.Force,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ const (
|
|||||||
type inputCluster struct {
|
type inputCluster struct {
|
||||||
lockTime *uint32
|
lockTime *uint32
|
||||||
sweepFeeRate chainfee.SatPerKWeight
|
sweepFeeRate chainfee.SatPerKWeight
|
||||||
inputs pendingInputs
|
inputs InputsMap
|
||||||
}
|
}
|
||||||
|
|
||||||
// createInputSets goes through the cluster's inputs and constructs sets of
|
// createInputSets goes through the cluster's inputs and constructs sets of
|
||||||
@ -41,7 +41,7 @@ func (c *inputCluster) createInputSets(maxFeeRate chainfee.SatPerKWeight,
|
|||||||
maxInputs uint32) []InputSet {
|
maxInputs uint32) []InputSet {
|
||||||
|
|
||||||
// Turn the inputs into a slice so we can sort them.
|
// Turn the inputs into a slice so we can sort them.
|
||||||
inputList := make([]*pendingInput, 0, len(c.inputs))
|
inputList := make([]*SweeperInput, 0, len(c.inputs))
|
||||||
for _, input := range c.inputs {
|
for _, input := range c.inputs {
|
||||||
inputList = append(inputList, input)
|
inputList = append(inputList, input)
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ func (c *inputCluster) createInputSets(maxFeeRate chainfee.SatPerKWeight,
|
|||||||
//
|
//
|
||||||
// For witness size, the upper limit is taken. The actual size depends
|
// For witness size, the upper limit is taken. The actual size depends
|
||||||
// on the signature length, which is not known yet at this point.
|
// on the signature length, which is not known yet at this point.
|
||||||
calcYield := func(input *pendingInput) int64 {
|
calcYield := func(input *SweeperInput) int64 {
|
||||||
size, _, err := input.WitnessType().SizeUpperBound()
|
size, _, err := input.WitnessType().SizeUpperBound()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to get input weight: %v", err)
|
log.Errorf("Failed to get input weight: %v", err)
|
||||||
@ -123,7 +123,7 @@ func (c *inputCluster) createInputSets(maxFeeRate chainfee.SatPerKWeight,
|
|||||||
type UtxoAggregator interface {
|
type UtxoAggregator interface {
|
||||||
// ClusterInputs takes a list of inputs and groups them into input
|
// ClusterInputs takes a list of inputs and groups them into input
|
||||||
// sets. Each input set will be used to create a sweeping transaction.
|
// sets. Each input set will be used to create a sweeping transaction.
|
||||||
ClusterInputs(pendingInputs) []InputSet
|
ClusterInputs(InputsMap) []InputSet
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimpleAggregator aggregates inputs known by the Sweeper based on each
|
// SimpleAggregator aggregates inputs known by the Sweeper based on each
|
||||||
@ -175,7 +175,7 @@ func NewSimpleUtxoAggregator(estimator chainfee.Estimator,
|
|||||||
// inputs known by the UtxoSweeper. It clusters inputs by
|
// inputs known by the UtxoSweeper. It clusters inputs by
|
||||||
// 1) Required tx locktime
|
// 1) Required tx locktime
|
||||||
// 2) Similar fee rates.
|
// 2) Similar fee rates.
|
||||||
func (s *SimpleAggregator) ClusterInputs(inputs pendingInputs) []InputSet {
|
func (s *SimpleAggregator) ClusterInputs(inputs InputsMap) []InputSet {
|
||||||
// We start by getting the inputs clusters by locktime. Since the
|
// We start by getting the inputs clusters by locktime. Since the
|
||||||
// inputs commit to the locktime, they can only be clustered together
|
// inputs commit to the locktime, they can only be clustered together
|
||||||
// if the locktime is equal.
|
// if the locktime is equal.
|
||||||
@ -212,10 +212,10 @@ func (s *SimpleAggregator) ClusterInputs(inputs pendingInputs) []InputSet {
|
|||||||
// cluster. In addition to the created clusters, inputs that did not specify a
|
// cluster. In addition to the created clusters, inputs that did not specify a
|
||||||
// required locktime are returned.
|
// required locktime are returned.
|
||||||
func (s *SimpleAggregator) clusterByLockTime(
|
func (s *SimpleAggregator) clusterByLockTime(
|
||||||
inputs pendingInputs) ([]inputCluster, pendingInputs) {
|
inputs InputsMap) ([]inputCluster, InputsMap) {
|
||||||
|
|
||||||
locktimes := make(map[uint32]pendingInputs)
|
locktimes := make(map[uint32]InputsMap)
|
||||||
rem := make(pendingInputs)
|
rem := make(InputsMap)
|
||||||
|
|
||||||
// Go through all inputs and check if they require a certain locktime.
|
// Go through all inputs and check if they require a certain locktime.
|
||||||
for op, input := range inputs {
|
for op, input := range inputs {
|
||||||
@ -228,7 +228,7 @@ func (s *SimpleAggregator) clusterByLockTime(
|
|||||||
// Check if we already have inputs with this locktime.
|
// Check if we already have inputs with this locktime.
|
||||||
cluster, ok := locktimes[lt]
|
cluster, ok := locktimes[lt]
|
||||||
if !ok {
|
if !ok {
|
||||||
cluster = make(pendingInputs)
|
cluster = make(InputsMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the fee rate based on the fee preference. If an error is
|
// Get the fee rate based on the fee preference. If an error is
|
||||||
@ -281,7 +281,7 @@ func (s *SimpleAggregator) clusterByLockTime(
|
|||||||
// sweep fee rate, which is determined by calculating the average fee rate of
|
// sweep fee rate, which is determined by calculating the average fee rate of
|
||||||
// all inputs within that cluster.
|
// all inputs within that cluster.
|
||||||
func (s *SimpleAggregator) clusterBySweepFeeRate(
|
func (s *SimpleAggregator) clusterBySweepFeeRate(
|
||||||
inputs pendingInputs) []inputCluster {
|
inputs InputsMap) []inputCluster {
|
||||||
|
|
||||||
bucketInputs := make(map[int]*bucketList)
|
bucketInputs := make(map[int]*bucketList)
|
||||||
inputFeeRates := make(map[wire.OutPoint]chainfee.SatPerKWeight)
|
inputFeeRates := make(map[wire.OutPoint]chainfee.SatPerKWeight)
|
||||||
@ -399,7 +399,7 @@ func mergeClusters(a, b inputCluster) []inputCluster {
|
|||||||
newCluster.sweepFeeRate = b.sweepFeeRate
|
newCluster.sweepFeeRate = b.sweepFeeRate
|
||||||
}
|
}
|
||||||
|
|
||||||
newCluster.inputs = make(pendingInputs)
|
newCluster.inputs = make(InputsMap)
|
||||||
|
|
||||||
for op, in := range a.inputs {
|
for op, in := range a.inputs {
|
||||||
newCluster.inputs[op] = in
|
newCluster.inputs[op] = in
|
||||||
@ -492,7 +492,7 @@ func NewBudgetAggregator(estimator chainfee.Estimator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clusterGroup defines an alias for a set of inputs that are to be grouped.
|
// clusterGroup defines an alias for a set of inputs that are to be grouped.
|
||||||
type clusterGroup map[fn.Option[int32]][]pendingInput
|
type clusterGroup map[fn.Option[int32]][]SweeperInput
|
||||||
|
|
||||||
// ClusterInputs creates a list of input sets from pending inputs.
|
// ClusterInputs creates a list of input sets from pending inputs.
|
||||||
// 1. filter out inputs whose budget cannot cover min relay fee.
|
// 1. filter out inputs whose budget cannot cover min relay fee.
|
||||||
@ -500,7 +500,7 @@ type clusterGroup map[fn.Option[int32]][]pendingInput
|
|||||||
// 3. sort the inputs in each cluster by their budget.
|
// 3. sort the inputs in each cluster by their budget.
|
||||||
// 4. optionally split a cluster if it exceeds the max input limit.
|
// 4. optionally split a cluster if it exceeds the max input limit.
|
||||||
// 5. create input sets from each of the clusters.
|
// 5. create input sets from each of the clusters.
|
||||||
func (b *BudgetAggregator) ClusterInputs(inputs pendingInputs) []InputSet {
|
func (b *BudgetAggregator) ClusterInputs(inputs InputsMap) []InputSet {
|
||||||
// Filter out inputs that have a budget below min relay fee.
|
// Filter out inputs that have a budget below min relay fee.
|
||||||
filteredInputs := b.filterInputs(inputs)
|
filteredInputs := b.filterInputs(inputs)
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ func (b *BudgetAggregator) ClusterInputs(inputs pendingInputs) []InputSet {
|
|||||||
height := input.params.DeadlineHeight
|
height := input.params.DeadlineHeight
|
||||||
cluster, ok := clusters[height]
|
cluster, ok := clusters[height]
|
||||||
if !ok {
|
if !ok {
|
||||||
cluster = make([]pendingInput, 0)
|
cluster = make([]SweeperInput, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster = append(cluster, *input)
|
cluster = append(cluster, *input)
|
||||||
@ -540,12 +540,12 @@ func (b *BudgetAggregator) ClusterInputs(inputs pendingInputs) []InputSet {
|
|||||||
// createInputSet takes a set of inputs which share the same deadline height
|
// createInputSet takes a set of inputs which share the same deadline height
|
||||||
// and turns them into a list of `InputSet`, each set is then used to create a
|
// and turns them into a list of `InputSet`, each set is then used to create a
|
||||||
// sweep transaction.
|
// sweep transaction.
|
||||||
func (b *BudgetAggregator) createInputSets(inputs []pendingInput) []InputSet {
|
func (b *BudgetAggregator) createInputSets(inputs []SweeperInput) []InputSet {
|
||||||
// sets holds the InputSets that we will return.
|
// sets holds the InputSets that we will return.
|
||||||
sets := make([]InputSet, 0)
|
sets := make([]InputSet, 0)
|
||||||
|
|
||||||
// Copy the inputs to a new slice so we can modify it.
|
// Copy the inputs to a new slice so we can modify it.
|
||||||
remainingInputs := make([]pendingInput, len(inputs))
|
remainingInputs := make([]SweeperInput, len(inputs))
|
||||||
copy(remainingInputs, inputs)
|
copy(remainingInputs, inputs)
|
||||||
|
|
||||||
// If the number of inputs is greater than the max inputs allowed, we
|
// If the number of inputs is greater than the max inputs allowed, we
|
||||||
@ -556,7 +556,7 @@ func (b *BudgetAggregator) createInputSets(inputs []pendingInput) []InputSet {
|
|||||||
|
|
||||||
// Copy the inputs to be put into the new set, and update the
|
// Copy the inputs to be put into the new set, and update the
|
||||||
// remaining inputs by removing currentInputs.
|
// remaining inputs by removing currentInputs.
|
||||||
currentInputs := make([]pendingInput, b.maxInputs)
|
currentInputs := make([]SweeperInput, b.maxInputs)
|
||||||
copy(currentInputs, remainingInputs[:b.maxInputs])
|
copy(currentInputs, remainingInputs[:b.maxInputs])
|
||||||
remainingInputs = remainingInputs[b.maxInputs:]
|
remainingInputs = remainingInputs[b.maxInputs:]
|
||||||
|
|
||||||
@ -587,13 +587,13 @@ func (b *BudgetAggregator) createInputSets(inputs []pendingInput) []InputSet {
|
|||||||
|
|
||||||
// filterInputs filters out inputs that have a budget below the min relay fee
|
// filterInputs filters out inputs that have a budget below the min relay fee
|
||||||
// or have a required output that's below the dust.
|
// or have a required output that's below the dust.
|
||||||
func (b *BudgetAggregator) filterInputs(inputs pendingInputs) pendingInputs {
|
func (b *BudgetAggregator) filterInputs(inputs InputsMap) InputsMap {
|
||||||
// Get the current min relay fee for this round.
|
// Get the current min relay fee for this round.
|
||||||
minFeeRate := b.estimator.RelayFeePerKW()
|
minFeeRate := b.estimator.RelayFeePerKW()
|
||||||
|
|
||||||
// filterInputs stores a map of inputs that has a budget that at least
|
// filterInputs stores a map of inputs that has a budget that at least
|
||||||
// can pay the minimal fee.
|
// can pay the minimal fee.
|
||||||
filteredInputs := make(pendingInputs, len(inputs))
|
filteredInputs := make(InputsMap, len(inputs))
|
||||||
|
|
||||||
// Iterate all the inputs and filter out the ones whose budget cannot
|
// Iterate all the inputs and filter out the ones whose budget cannot
|
||||||
// cover the min fee.
|
// cover the min fee.
|
||||||
@ -647,10 +647,10 @@ func (b *BudgetAggregator) filterInputs(inputs pendingInputs) pendingInputs {
|
|||||||
// number of inputs exceeds the maxInputs limit, it requires us to split them
|
// number of inputs exceeds the maxInputs limit, it requires us to split them
|
||||||
// into smaller clusters. In that case, the sorting will make a difference as
|
// into smaller clusters. In that case, the sorting will make a difference as
|
||||||
// the budgets of the clusters will be different.
|
// the budgets of the clusters will be different.
|
||||||
func (b *BudgetAggregator) sortInputs(inputs []pendingInput) []pendingInput {
|
func (b *BudgetAggregator) sortInputs(inputs []SweeperInput) []SweeperInput {
|
||||||
// sortedInputs is the final list of inputs sorted by their economical
|
// sortedInputs is the final list of inputs sorted by their economical
|
||||||
// value.
|
// value.
|
||||||
sortedInputs := make([]pendingInput, 0, len(inputs))
|
sortedInputs := make([]SweeperInput, 0, len(inputs))
|
||||||
|
|
||||||
// Copy the inputs.
|
// Copy the inputs.
|
||||||
sortedInputs = append(sortedInputs, inputs...)
|
sortedInputs = append(sortedInputs, inputs...)
|
||||||
|
@ -19,25 +19,25 @@ import (
|
|||||||
|
|
||||||
//nolint:lll
|
//nolint:lll
|
||||||
var (
|
var (
|
||||||
testInputsA = pendingInputs{
|
testInputsA = InputsMap{
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 0}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 0}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 1}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 1}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 2}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 2}: &SweeperInput{},
|
||||||
}
|
}
|
||||||
|
|
||||||
testInputsB = pendingInputs{
|
testInputsB = InputsMap{
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 10}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 10}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 11}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 11}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 12}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 12}: &SweeperInput{},
|
||||||
}
|
}
|
||||||
|
|
||||||
testInputsC = pendingInputs{
|
testInputsC = InputsMap{
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 0}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 0}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 1}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 1}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 2}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 2}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 10}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 10}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 11}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 11}: &SweeperInput{},
|
||||||
wire.OutPoint{Hash: chainhash.Hash{}, Index: 12}: &pendingInput{},
|
wire.OutPoint{Hash: chainhash.Hash{}, Index: 12}: &SweeperInput{},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ func TestMergeClusters(t *testing.T) {
|
|||||||
func TestZipClusters(t *testing.T) {
|
func TestZipClusters(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
createCluster := func(inp pendingInputs,
|
createCluster := func(inp InputsMap,
|
||||||
f chainfee.SatPerKWeight) inputCluster {
|
f chainfee.SatPerKWeight) inputCluster {
|
||||||
|
|
||||||
return inputCluster{
|
return inputCluster{
|
||||||
@ -275,19 +275,19 @@ func TestClusterByLockTime(t *testing.T) {
|
|||||||
|
|
||||||
// With the inner Input being mocked, we can now create the pending
|
// With the inner Input being mocked, we can now create the pending
|
||||||
// inputs.
|
// inputs.
|
||||||
input1 := &pendingInput{Input: input1LockTime1, params: param}
|
input1 := &SweeperInput{Input: input1LockTime1, params: param}
|
||||||
input2 := &pendingInput{Input: input2LockTime1, params: param}
|
input2 := &SweeperInput{Input: input2LockTime1, params: param}
|
||||||
input3 := &pendingInput{Input: input3LockTime2, params: param}
|
input3 := &SweeperInput{Input: input3LockTime2, params: param}
|
||||||
input4 := &pendingInput{Input: input4LockTime2, params: param}
|
input4 := &SweeperInput{Input: input4LockTime2, params: param}
|
||||||
input5 := &pendingInput{Input: input5NoLockTime, params: param}
|
input5 := &SweeperInput{Input: input5NoLockTime, params: param}
|
||||||
input6 := &pendingInput{Input: input6NoLockTime, params: param}
|
input6 := &SweeperInput{Input: input6NoLockTime, params: param}
|
||||||
|
|
||||||
// Create the pending inputs map, which will be passed to the method
|
// Create the pending inputs map, which will be passed to the method
|
||||||
// under test.
|
// under test.
|
||||||
//
|
//
|
||||||
// NOTE: we don't care the actual outpoint values as long as they are
|
// NOTE: we don't care the actual outpoint values as long as they are
|
||||||
// unique.
|
// unique.
|
||||||
inputs := pendingInputs{
|
inputs := InputsMap{
|
||||||
wire.OutPoint{Index: 1}: input1,
|
wire.OutPoint{Index: 1}: input1,
|
||||||
wire.OutPoint{Index: 2}: input2,
|
wire.OutPoint{Index: 2}: input2,
|
||||||
wire.OutPoint{Index: 3}: input3,
|
wire.OutPoint{Index: 3}: input3,
|
||||||
@ -298,18 +298,18 @@ func TestClusterByLockTime(t *testing.T) {
|
|||||||
|
|
||||||
// Create expected clusters so we can shorten the line length in the
|
// Create expected clusters so we can shorten the line length in the
|
||||||
// test cases below.
|
// test cases below.
|
||||||
cluster1 := pendingInputs{
|
cluster1 := InputsMap{
|
||||||
wire.OutPoint{Index: 1}: input1,
|
wire.OutPoint{Index: 1}: input1,
|
||||||
wire.OutPoint{Index: 2}: input2,
|
wire.OutPoint{Index: 2}: input2,
|
||||||
}
|
}
|
||||||
cluster2 := pendingInputs{
|
cluster2 := InputsMap{
|
||||||
wire.OutPoint{Index: 3}: input3,
|
wire.OutPoint{Index: 3}: input3,
|
||||||
wire.OutPoint{Index: 4}: input4,
|
wire.OutPoint{Index: 4}: input4,
|
||||||
}
|
}
|
||||||
|
|
||||||
// cluster3 should be the remaining inputs since they don't have
|
// cluster3 should be the remaining inputs since they don't have
|
||||||
// locktime.
|
// locktime.
|
||||||
cluster3 := pendingInputs{
|
cluster3 := InputsMap{
|
||||||
wire.OutPoint{Index: 5}: input5,
|
wire.OutPoint{Index: 5}: input5,
|
||||||
wire.OutPoint{Index: 6}: input6,
|
wire.OutPoint{Index: 6}: input6,
|
||||||
}
|
}
|
||||||
@ -332,7 +332,7 @@ func TestClusterByLockTime(t *testing.T) {
|
|||||||
setupMocker func()
|
setupMocker func()
|
||||||
testFeeRate chainfee.SatPerKWeight
|
testFeeRate chainfee.SatPerKWeight
|
||||||
expectedClusters []inputCluster
|
expectedClusters []inputCluster
|
||||||
expectedRemainingInputs pendingInputs
|
expectedRemainingInputs InputsMap
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
// Test a successful case where the locktime clusters
|
// Test a successful case where the locktime clusters
|
||||||
@ -518,33 +518,33 @@ func TestBudgetAggregatorFilterInputs(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Create testing pending inputs.
|
// Create testing pending inputs.
|
||||||
inputs := pendingInputs{
|
inputs := InputsMap{
|
||||||
// The first input will be filtered out due to the error.
|
// The first input will be filtered out due to the error.
|
||||||
opErr: &pendingInput{
|
opErr: &SweeperInput{
|
||||||
Input: inpErr,
|
Input: inpErr,
|
||||||
},
|
},
|
||||||
|
|
||||||
// The second input will be filtered out due to the budget.
|
// The second input will be filtered out due to the budget.
|
||||||
opLow: &pendingInput{
|
opLow: &SweeperInput{
|
||||||
Input: inpLow,
|
Input: inpLow,
|
||||||
params: Params{Budget: budgetLow},
|
params: Params{Budget: budgetLow},
|
||||||
},
|
},
|
||||||
|
|
||||||
// The third input will be included.
|
// The third input will be included.
|
||||||
opEqual: &pendingInput{
|
opEqual: &SweeperInput{
|
||||||
Input: inpEqual,
|
Input: inpEqual,
|
||||||
params: Params{Budget: budgetEqual},
|
params: Params{Budget: budgetEqual},
|
||||||
},
|
},
|
||||||
|
|
||||||
// The fourth input will be included.
|
// The fourth input will be included.
|
||||||
opHigh: &pendingInput{
|
opHigh: &SweeperInput{
|
||||||
Input: inpHigh,
|
Input: inpHigh,
|
||||||
params: Params{Budget: budgetHigh},
|
params: Params{Budget: budgetHigh},
|
||||||
},
|
},
|
||||||
|
|
||||||
// The fifth input will be filtered out due to the dust
|
// The fifth input will be filtered out due to the dust
|
||||||
// required.
|
// required.
|
||||||
opDust: &pendingInput{
|
opDust: &SweeperInput{
|
||||||
Input: inpDust,
|
Input: inpDust,
|
||||||
params: Params{Budget: budgetHigh},
|
params: Params{Budget: budgetHigh},
|
||||||
},
|
},
|
||||||
@ -578,7 +578,7 @@ func TestBudgetAggregatorSortInputs(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Create an input with the low budget but forced.
|
// Create an input with the low budget but forced.
|
||||||
inputLowForce := pendingInput{
|
inputLowForce := SweeperInput{
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budgetLow,
|
Budget: budgetLow,
|
||||||
Force: true,
|
Force: true,
|
||||||
@ -586,14 +586,14 @@ func TestBudgetAggregatorSortInputs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an input with the low budget.
|
// Create an input with the low budget.
|
||||||
inputLow := pendingInput{
|
inputLow := SweeperInput{
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budgetLow,
|
Budget: budgetLow,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an input with the high budget and forced.
|
// Create an input with the high budget and forced.
|
||||||
inputHighForce := pendingInput{
|
inputHighForce := SweeperInput{
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budgetHight,
|
Budget: budgetHight,
|
||||||
Force: true,
|
Force: true,
|
||||||
@ -601,14 +601,14 @@ func TestBudgetAggregatorSortInputs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create an input with the high budget.
|
// Create an input with the high budget.
|
||||||
inputHigh := pendingInput{
|
inputHigh := SweeperInput{
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budgetHight,
|
Budget: budgetHight,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a testing pending inputs.
|
// Create a testing pending inputs.
|
||||||
inputs := []pendingInput{
|
inputs := []SweeperInput{
|
||||||
inputLowForce,
|
inputLowForce,
|
||||||
inputLow,
|
inputLow,
|
||||||
inputHighForce,
|
inputHighForce,
|
||||||
@ -652,25 +652,25 @@ func TestBudgetAggregatorCreateInputSets(t *testing.T) {
|
|||||||
defer mockInput4.AssertExpectations(t)
|
defer mockInput4.AssertExpectations(t)
|
||||||
|
|
||||||
// Create testing pending inputs.
|
// Create testing pending inputs.
|
||||||
pi1 := pendingInput{
|
pi1 := SweeperInput{
|
||||||
Input: mockInput1,
|
Input: mockInput1,
|
||||||
params: Params{
|
params: Params{
|
||||||
DeadlineHeight: fn.Some(int32(1)),
|
DeadlineHeight: fn.Some(int32(1)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pi2 := pendingInput{
|
pi2 := SweeperInput{
|
||||||
Input: mockInput2,
|
Input: mockInput2,
|
||||||
params: Params{
|
params: Params{
|
||||||
DeadlineHeight: fn.Some(int32(1)),
|
DeadlineHeight: fn.Some(int32(1)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pi3 := pendingInput{
|
pi3 := SweeperInput{
|
||||||
Input: mockInput3,
|
Input: mockInput3,
|
||||||
params: Params{
|
params: Params{
|
||||||
DeadlineHeight: fn.Some(int32(1)),
|
DeadlineHeight: fn.Some(int32(1)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pi4 := pendingInput{
|
pi4 := SweeperInput{
|
||||||
Input: mockInput4,
|
Input: mockInput4,
|
||||||
params: Params{
|
params: Params{
|
||||||
// This input has a deadline height that is different
|
// This input has a deadline height that is different
|
||||||
@ -686,7 +686,7 @@ func TestBudgetAggregatorCreateInputSets(t *testing.T) {
|
|||||||
// Create test cases.
|
// Create test cases.
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
inputs []pendingInput
|
inputs []SweeperInput
|
||||||
setupMock func()
|
setupMock func()
|
||||||
expectedNumSets int
|
expectedNumSets int
|
||||||
}{
|
}{
|
||||||
@ -694,7 +694,7 @@ func TestBudgetAggregatorCreateInputSets(t *testing.T) {
|
|||||||
// When the number of inputs is below the max, a single
|
// When the number of inputs is below the max, a single
|
||||||
// input set is returned.
|
// input set is returned.
|
||||||
name: "num inputs below max",
|
name: "num inputs below max",
|
||||||
inputs: []pendingInput{pi1},
|
inputs: []SweeperInput{pi1},
|
||||||
setupMock: func() {
|
setupMock: func() {
|
||||||
// Mock methods used in loggings.
|
// Mock methods used in loggings.
|
||||||
mockInput1.On("WitnessType").Return(
|
mockInput1.On("WitnessType").Return(
|
||||||
@ -708,7 +708,7 @@ func TestBudgetAggregatorCreateInputSets(t *testing.T) {
|
|||||||
// When the number of inputs is equal to the max, a
|
// When the number of inputs is equal to the max, a
|
||||||
// single input set is returned.
|
// single input set is returned.
|
||||||
name: "num inputs equal to max",
|
name: "num inputs equal to max",
|
||||||
inputs: []pendingInput{pi1, pi2},
|
inputs: []SweeperInput{pi1, pi2},
|
||||||
setupMock: func() {
|
setupMock: func() {
|
||||||
// Mock methods used in loggings.
|
// Mock methods used in loggings.
|
||||||
mockInput1.On("WitnessType").Return(
|
mockInput1.On("WitnessType").Return(
|
||||||
@ -727,7 +727,7 @@ func TestBudgetAggregatorCreateInputSets(t *testing.T) {
|
|||||||
// When the number of inputs is above the max, multiple
|
// When the number of inputs is above the max, multiple
|
||||||
// input sets are returned.
|
// input sets are returned.
|
||||||
name: "num inputs above max",
|
name: "num inputs above max",
|
||||||
inputs: []pendingInput{pi1, pi2, pi3},
|
inputs: []SweeperInput{pi1, pi2, pi3},
|
||||||
setupMock: func() {
|
setupMock: func() {
|
||||||
// Mock methods used in loggings.
|
// Mock methods used in loggings.
|
||||||
mockInput1.On("WitnessType").Return(
|
mockInput1.On("WitnessType").Return(
|
||||||
@ -751,7 +751,7 @@ func TestBudgetAggregatorCreateInputSets(t *testing.T) {
|
|||||||
// error is returned from creating the first set, it
|
// error is returned from creating the first set, it
|
||||||
// shouldn't affect the remaining inputs.
|
// shouldn't affect the remaining inputs.
|
||||||
name: "num inputs above max with error",
|
name: "num inputs above max with error",
|
||||||
inputs: []pendingInput{pi1, pi4, pi3},
|
inputs: []SweeperInput{pi1, pi4, pi3},
|
||||||
setupMock: func() {
|
setupMock: func() {
|
||||||
// Mock methods used in loggings.
|
// Mock methods used in loggings.
|
||||||
mockInput1.On("WitnessType").Return(
|
mockInput1.On("WitnessType").Return(
|
||||||
@ -825,7 +825,7 @@ func TestBudgetInputSetClusterInputs(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Create testing pending inputs.
|
// Create testing pending inputs.
|
||||||
inputs := make(pendingInputs)
|
inputs := make(InputsMap)
|
||||||
|
|
||||||
// For each deadline height, create two inputs with different budgets,
|
// For each deadline height, create two inputs with different budgets,
|
||||||
// one below the min fee rate and one above it. We should see the lower
|
// one below the min fee rate and one above it. We should see the lower
|
||||||
@ -879,7 +879,7 @@ func TestBudgetInputSetClusterInputs(t *testing.T) {
|
|||||||
inpHigh2.On("RequiredTxOut").Return(nil)
|
inpHigh2.On("RequiredTxOut").Return(nil)
|
||||||
|
|
||||||
// Add the low input, which should be filtered out.
|
// Add the low input, which should be filtered out.
|
||||||
inputs[opLow] = &pendingInput{
|
inputs[opLow] = &SweeperInput{
|
||||||
Input: inpLow,
|
Input: inpLow,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budgetLow,
|
Budget: budgetLow,
|
||||||
@ -888,14 +888,14 @@ func TestBudgetInputSetClusterInputs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the high inputs, which should be included.
|
// Add the high inputs, which should be included.
|
||||||
inputs[opHigh1] = &pendingInput{
|
inputs[opHigh1] = &SweeperInput{
|
||||||
Input: inpHigh1,
|
Input: inpHigh1,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budgetHigh,
|
Budget: budgetHigh,
|
||||||
DeadlineHeight: deadline,
|
DeadlineHeight: deadline,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
inputs[opHigh2] = &pendingInput{
|
inputs[opHigh2] = &SweeperInput{
|
||||||
Input: inpHigh2,
|
Input: inpHigh2,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budgetHigh,
|
Budget: budgetHigh,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package sweep
|
package sweep
|
||||||
|
|
||||||
// bucket contains a set of inputs that are not mutually exclusive.
|
// bucket contains a set of inputs that are not mutually exclusive.
|
||||||
type bucket pendingInputs
|
type bucket InputsMap
|
||||||
|
|
||||||
// tryAdd tries to add a new input to this bucket.
|
// tryAdd tries to add a new input to this bucket.
|
||||||
func (b bucket) tryAdd(input *pendingInput) bool {
|
func (b bucket) tryAdd(input *SweeperInput) bool {
|
||||||
exclusiveGroup := input.params.ExclusiveGroup
|
exclusiveGroup := input.params.ExclusiveGroup
|
||||||
if exclusiveGroup != nil {
|
if exclusiveGroup != nil {
|
||||||
for _, input := range b {
|
for _, input := range b {
|
||||||
@ -40,7 +40,7 @@ type bucketList struct {
|
|||||||
|
|
||||||
// add adds a new input. If the input is not accepted by any of the existing
|
// add adds a new input. If the input is not accepted by any of the existing
|
||||||
// buckets, a new bucket will be created.
|
// buckets, a new bucket will be created.
|
||||||
func (b *bucketList) add(input *pendingInput) {
|
func (b *bucketList) add(input *SweeperInput) {
|
||||||
for _, existingBucket := range b.buckets {
|
for _, existingBucket := range b.buckets {
|
||||||
if existingBucket.tryAdd(input) {
|
if existingBucket.tryAdd(input) {
|
||||||
return
|
return
|
||||||
|
@ -342,7 +342,7 @@ type mockUtxoAggregator struct {
|
|||||||
var _ UtxoAggregator = (*mockUtxoAggregator)(nil)
|
var _ UtxoAggregator = (*mockUtxoAggregator)(nil)
|
||||||
|
|
||||||
// ClusterInputs takes a list of inputs and groups them into clusters.
|
// ClusterInputs takes a list of inputs and groups them into clusters.
|
||||||
func (m *mockUtxoAggregator) ClusterInputs(inputs pendingInputs) []InputSet {
|
func (m *mockUtxoAggregator) ClusterInputs(inputs InputsMap) []InputSet {
|
||||||
args := m.Called(inputs)
|
args := m.Called(inputs)
|
||||||
|
|
||||||
return args.Get(0).([]InputSet)
|
return args.Get(0).([]InputSet)
|
||||||
|
@ -179,10 +179,10 @@ type RBFInfo struct {
|
|||||||
Fee btcutil.Amount
|
Fee btcutil.Amount
|
||||||
}
|
}
|
||||||
|
|
||||||
// pendingInput is created when an input reaches the main loop for the first
|
// 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
|
// time. It wraps the input and tracks all relevant state that is needed for
|
||||||
// sweeping.
|
// sweeping.
|
||||||
type pendingInput struct {
|
type SweeperInput struct {
|
||||||
input.Input
|
input.Input
|
||||||
|
|
||||||
// state tracks the current state of the input.
|
// state tracks the current state of the input.
|
||||||
@ -212,20 +212,20 @@ type pendingInput struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns a human readable interpretation of the pending input.
|
// String returns a human readable interpretation of the pending input.
|
||||||
func (p *pendingInput) String() string {
|
func (p *SweeperInput) String() string {
|
||||||
return fmt.Sprintf("%v (%v)", p.Input.OutPoint(), p.Input.WitnessType())
|
return fmt.Sprintf("%v (%v)", p.Input.OutPoint(), p.Input.WitnessType())
|
||||||
}
|
}
|
||||||
|
|
||||||
// parameters returns the sweep parameters for this input.
|
// parameters returns the sweep parameters for this input.
|
||||||
//
|
//
|
||||||
// NOTE: Part of the txInput interface.
|
// NOTE: Part of the txInput interface.
|
||||||
func (p *pendingInput) parameters() Params {
|
func (p *SweeperInput) parameters() Params {
|
||||||
return p.params
|
return p.params
|
||||||
}
|
}
|
||||||
|
|
||||||
// terminated returns a boolean indicating whether the input has reached a
|
// terminated returns a boolean indicating whether the input has reached a
|
||||||
// final state.
|
// final state.
|
||||||
func (p *pendingInput) terminated() bool {
|
func (p *SweeperInput) terminated() bool {
|
||||||
switch p.state {
|
switch p.state {
|
||||||
// If the input has reached a final state, that it's either
|
// If the input has reached a final state, that it's either
|
||||||
// been swept, or failed, or excluded, we will remove it from
|
// been swept, or failed, or excluded, we will remove it from
|
||||||
@ -238,20 +238,20 @@ func (p *pendingInput) terminated() bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pendingInputs is a type alias for a set of pending inputs.
|
// InputsMap is a type alias for a set of pending inputs.
|
||||||
type pendingInputs = map[wire.OutPoint]*pendingInput
|
type InputsMap = map[wire.OutPoint]*SweeperInput
|
||||||
|
|
||||||
// pendingSweepsReq is an internal message we'll use to represent an external
|
// pendingSweepsReq is an internal message we'll use to represent an external
|
||||||
// caller's intent to retrieve all of the pending inputs the UtxoSweeper is
|
// caller's intent to retrieve all of the pending inputs the UtxoSweeper is
|
||||||
// attempting to sweep.
|
// attempting to sweep.
|
||||||
type pendingSweepsReq struct {
|
type pendingSweepsReq struct {
|
||||||
respChan chan map[wire.OutPoint]*PendingInput
|
respChan chan map[wire.OutPoint]*PendingInputResponse
|
||||||
errChan chan error
|
errChan chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
// PendingInput contains information about an input that is currently being
|
// PendingInputResponse contains information about an input that is currently
|
||||||
// swept by the UtxoSweeper.
|
// being swept by the UtxoSweeper.
|
||||||
type PendingInput struct {
|
type PendingInputResponse struct {
|
||||||
// OutPoint is the identify outpoint of the input being swept.
|
// OutPoint is the identify outpoint of the input being swept.
|
||||||
OutPoint wire.OutPoint
|
OutPoint wire.OutPoint
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ type UtxoSweeper struct {
|
|||||||
|
|
||||||
// inputs is the total set of inputs the UtxoSweeper has been requested
|
// inputs is the total set of inputs the UtxoSweeper has been requested
|
||||||
// to sweep.
|
// to sweep.
|
||||||
inputs pendingInputs
|
inputs InputsMap
|
||||||
|
|
||||||
currentOutputScript []byte
|
currentOutputScript []byte
|
||||||
|
|
||||||
@ -408,7 +408,7 @@ func New(cfg *UtxoSweeperConfig) *UtxoSweeper {
|
|||||||
updateReqs: make(chan *updateReq),
|
updateReqs: make(chan *updateReq),
|
||||||
pendingSweepsReqs: make(chan *pendingSweepsReq),
|
pendingSweepsReqs: make(chan *pendingSweepsReq),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
inputs: make(pendingInputs),
|
inputs: make(InputsMap),
|
||||||
bumpResultChan: make(chan *BumpResult, 100),
|
bumpResultChan: make(chan *BumpResult, 100),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -768,7 +768,7 @@ func (s *UtxoSweeper) removeExclusiveGroup(group uint64) {
|
|||||||
|
|
||||||
// signalResult notifies the listeners of the final result of the input sweep.
|
// signalResult notifies the listeners of the final result of the input sweep.
|
||||||
// It also cancels any pending spend notification.
|
// It also cancels any pending spend notification.
|
||||||
func (s *UtxoSweeper) signalResult(pi *pendingInput, result Result) {
|
func (s *UtxoSweeper) signalResult(pi *SweeperInput, result Result) {
|
||||||
op := pi.OutPoint()
|
op := pi.OutPoint()
|
||||||
listeners := pi.listeners
|
listeners := pi.listeners
|
||||||
|
|
||||||
@ -1012,8 +1012,10 @@ func (s *UtxoSweeper) monitorSpend(outpoint wire.OutPoint,
|
|||||||
|
|
||||||
// PendingInputs returns the set of inputs that the UtxoSweeper is currently
|
// PendingInputs returns the set of inputs that the UtxoSweeper is currently
|
||||||
// attempting to sweep.
|
// attempting to sweep.
|
||||||
func (s *UtxoSweeper) PendingInputs() (map[wire.OutPoint]*PendingInput, error) {
|
func (s *UtxoSweeper) PendingInputs() (
|
||||||
respChan := make(chan map[wire.OutPoint]*PendingInput, 1)
|
map[wire.OutPoint]*PendingInputResponse, error) {
|
||||||
|
|
||||||
|
respChan := make(chan map[wire.OutPoint]*PendingInputResponse, 1)
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
select {
|
select {
|
||||||
case s.pendingSweepsReqs <- &pendingSweepsReq{
|
case s.pendingSweepsReqs <- &pendingSweepsReq{
|
||||||
@ -1037,26 +1039,26 @@ func (s *UtxoSweeper) PendingInputs() (map[wire.OutPoint]*PendingInput, error) {
|
|||||||
// handlePendingSweepsReq handles a request to retrieve all pending inputs the
|
// handlePendingSweepsReq handles a request to retrieve all pending inputs the
|
||||||
// UtxoSweeper is attempting to sweep.
|
// UtxoSweeper is attempting to sweep.
|
||||||
func (s *UtxoSweeper) handlePendingSweepsReq(
|
func (s *UtxoSweeper) handlePendingSweepsReq(
|
||||||
req *pendingSweepsReq) map[wire.OutPoint]*PendingInput {
|
req *pendingSweepsReq) map[wire.OutPoint]*PendingInputResponse {
|
||||||
|
|
||||||
pendingInputs := make(map[wire.OutPoint]*PendingInput, len(s.inputs))
|
resps := make(map[wire.OutPoint]*PendingInputResponse, len(s.inputs))
|
||||||
for _, pendingInput := range s.inputs {
|
for _, inp := range s.inputs {
|
||||||
// Only the exported fields are set, as we expect the response
|
// Only the exported fields are set, as we expect the response
|
||||||
// to only be consumed externally.
|
// to only be consumed externally.
|
||||||
op := *pendingInput.OutPoint()
|
op := *inp.OutPoint()
|
||||||
pendingInputs[op] = &PendingInput{
|
resps[op] = &PendingInputResponse{
|
||||||
OutPoint: op,
|
OutPoint: op,
|
||||||
WitnessType: pendingInput.WitnessType(),
|
WitnessType: inp.WitnessType(),
|
||||||
Amount: btcutil.Amount(
|
Amount: btcutil.Amount(
|
||||||
pendingInput.SignDesc().Output.Value,
|
inp.SignDesc().Output.Value,
|
||||||
),
|
),
|
||||||
LastFeeRate: pendingInput.lastFeeRate,
|
LastFeeRate: inp.lastFeeRate,
|
||||||
BroadcastAttempts: pendingInput.publishAttempts,
|
BroadcastAttempts: inp.publishAttempts,
|
||||||
Params: pendingInput.params,
|
Params: inp.params,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pendingInputs
|
return resps
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateParams allows updating the sweep parameters of a pending input in the
|
// UpdateParams allows updating the sweep parameters of a pending input in the
|
||||||
@ -1117,30 +1119,30 @@ func (s *UtxoSweeper) handleUpdateReq(req *updateReq) (
|
|||||||
// batched with others which also have a similar fee rate, creating a
|
// batched with others which also have a similar fee rate, creating a
|
||||||
// higher fee rate transaction that replaces the original input's
|
// higher fee rate transaction that replaces the original input's
|
||||||
// sweeping transaction.
|
// sweeping transaction.
|
||||||
pendingInput, ok := s.inputs[req.input]
|
sweeperInput, ok := s.inputs[req.input]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, lnwallet.ErrNotMine
|
return nil, lnwallet.ErrNotMine
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the updated parameters struct. Leave the exclusive group
|
// Create the updated parameters struct. Leave the exclusive group
|
||||||
// unchanged.
|
// unchanged.
|
||||||
newParams := pendingInput.params
|
newParams := sweeperInput.params
|
||||||
newParams.Fee = req.params.Fee
|
newParams.Fee = req.params.Fee
|
||||||
newParams.Force = req.params.Force
|
newParams.Force = req.params.Force
|
||||||
|
|
||||||
log.Debugf("Updating parameters for %v(state=%v) from (%v) to (%v)",
|
log.Debugf("Updating parameters for %v(state=%v) from (%v) to (%v)",
|
||||||
req.input, pendingInput.state, pendingInput.params, newParams)
|
req.input, sweeperInput.state, sweeperInput.params, newParams)
|
||||||
|
|
||||||
pendingInput.params = newParams
|
sweeperInput.params = newParams
|
||||||
|
|
||||||
// We need to reset the state so this input will be attempted again by
|
// We need to reset the state so this input will be attempted again by
|
||||||
// our sweeper.
|
// our sweeper.
|
||||||
//
|
//
|
||||||
// TODO(yy): a dedicated state?
|
// TODO(yy): a dedicated state?
|
||||||
pendingInput.state = Init
|
sweeperInput.state = Init
|
||||||
|
|
||||||
resultChan := make(chan Result, 1)
|
resultChan := make(chan Result, 1)
|
||||||
pendingInput.listeners = append(pendingInput.listeners, resultChan)
|
sweeperInput.listeners = append(sweeperInput.listeners, resultChan)
|
||||||
|
|
||||||
return resultChan, nil
|
return resultChan, nil
|
||||||
}
|
}
|
||||||
@ -1229,7 +1231,7 @@ func (s *UtxoSweeper) handleNewInput(input *sweepInputMessage) {
|
|||||||
// Create a new pendingInput and initialize the listeners slice with
|
// Create a new pendingInput and initialize the listeners slice with
|
||||||
// the passed in result channel. If this input is offered for sweep
|
// the passed in result channel. If this input is offered for sweep
|
||||||
// again, the result channel will be appended to this slice.
|
// again, the result channel will be appended to this slice.
|
||||||
pi = &pendingInput{
|
pi = &SweeperInput{
|
||||||
state: state,
|
state: state,
|
||||||
listeners: []chan Result{input.resultChan},
|
listeners: []chan Result{input.resultChan},
|
||||||
Input: input.input,
|
Input: input.input,
|
||||||
@ -1294,8 +1296,7 @@ func (s *UtxoSweeper) decideStateAndRBFInfo(op wire.OutPoint) (
|
|||||||
|
|
||||||
// If the tx is not found in the store, it means it's not broadcast by
|
// If the tx is not found in the store, it means it's not broadcast by
|
||||||
// us, hence we can't find the fee info. This is fine as, later on when
|
// us, hence we can't find the fee info. This is fine as, later on when
|
||||||
// this tx is confirmed, we will remove the input from our
|
// this tx is confirmed, we will remove the input from our inputs.
|
||||||
// pendingInputs.
|
|
||||||
if errors.Is(err, ErrTxNotFound) {
|
if errors.Is(err, ErrTxNotFound) {
|
||||||
log.Warnf("Spending tx %v not found in sweeper store", txid)
|
log.Warnf("Spending tx %v not found in sweeper store", txid)
|
||||||
return Published, fn.None[RBFInfo]()
|
return Published, fn.None[RBFInfo]()
|
||||||
@ -1322,7 +1323,7 @@ func (s *UtxoSweeper) decideStateAndRBFInfo(op wire.OutPoint) (
|
|||||||
// handleExistingInput processes an input that is already known to the sweeper.
|
// handleExistingInput processes an input that is already known to the sweeper.
|
||||||
// It will overwrite the params of the old input with the new ones.
|
// It will overwrite the params of the old input with the new ones.
|
||||||
func (s *UtxoSweeper) handleExistingInput(input *sweepInputMessage,
|
func (s *UtxoSweeper) handleExistingInput(input *sweepInputMessage,
|
||||||
oldInput *pendingInput) {
|
oldInput *SweeperInput) {
|
||||||
|
|
||||||
// Before updating the input details, check if an exclusive group was
|
// Before updating the input details, check if an exclusive group was
|
||||||
// set. In case the same input is registered again without an exclusive
|
// set. In case the same input is registered again without an exclusive
|
||||||
@ -1412,9 +1413,9 @@ func (s *UtxoSweeper) markInputsSwept(tx *wire.MsgTx, isOurTx bool) {
|
|||||||
outpoint := txIn.PreviousOutPoint
|
outpoint := txIn.PreviousOutPoint
|
||||||
|
|
||||||
// Check if this input is known to us. It could probably be
|
// Check if this input is known to us. It could probably be
|
||||||
// unknown if we canceled the registration, deleted from
|
// unknown if we canceled the registration, deleted from inputs
|
||||||
// pendingInputs but the ntfn was in-flight already. Or this
|
// map but the ntfn was in-flight already. Or this could be not
|
||||||
// could be not one of our inputs.
|
// one of our inputs.
|
||||||
input, ok := s.inputs[outpoint]
|
input, ok := s.inputs[outpoint]
|
||||||
if !ok {
|
if !ok {
|
||||||
// It's very likely that a spending tx contains inputs
|
// It's very likely that a spending tx contains inputs
|
||||||
@ -1460,7 +1461,7 @@ func (s *UtxoSweeper) markInputsSwept(tx *wire.MsgTx, isOurTx bool) {
|
|||||||
|
|
||||||
// markInputFailed marks the given input as failed and won't be retried. It
|
// markInputFailed marks the given input as failed and won't be retried. It
|
||||||
// will also notify all the subscribers of this input.
|
// will also notify all the subscribers of this input.
|
||||||
func (s *UtxoSweeper) markInputFailed(pi *pendingInput, err error) {
|
func (s *UtxoSweeper) markInputFailed(pi *SweeperInput, err error) {
|
||||||
log.Errorf("Failed to sweep input: %v, error: %v", pi, err)
|
log.Errorf("Failed to sweep input: %v, error: %v", pi, err)
|
||||||
|
|
||||||
pi.state = Failed
|
pi.state = Failed
|
||||||
@ -1476,16 +1477,16 @@ func (s *UtxoSweeper) markInputFailed(pi *pendingInput, err error) {
|
|||||||
// updateSweeperInputs updates the sweeper's internal state and returns a map
|
// updateSweeperInputs updates the sweeper's internal state and returns a map
|
||||||
// of inputs to be swept. It will remove the inputs that are in final states,
|
// of inputs to be swept. It will remove the inputs that are in final states,
|
||||||
// and returns a map of inputs that have either state Init or PublishFailed.
|
// and returns a map of inputs that have either state Init or PublishFailed.
|
||||||
func (s *UtxoSweeper) updateSweeperInputs() pendingInputs {
|
func (s *UtxoSweeper) updateSweeperInputs() InputsMap {
|
||||||
// Create a map of inputs to be swept.
|
// Create a map of inputs to be swept.
|
||||||
inputs := make(pendingInputs)
|
inputs := make(InputsMap)
|
||||||
|
|
||||||
// Iterate the pending inputs and update the sweeper's state.
|
// Iterate the pending inputs and update the sweeper's state.
|
||||||
//
|
//
|
||||||
// TODO(yy): sweeper is made to communicate via go channels, so no
|
// TODO(yy): sweeper is made to communicate via go channels, so no
|
||||||
// locks are needed to access the map. However, it'd be safer if we
|
// locks are needed to access the map. However, it'd be safer if we
|
||||||
// turn this pendingInputs into a SyncMap in case we wanna add
|
// turn this inputs map into a SyncMap in case we wanna add concurrent
|
||||||
// concurrent access to the map in the future.
|
// access to the map in the future.
|
||||||
for op, input := range s.inputs {
|
for op, input := range s.inputs {
|
||||||
// If the input has reached a final state, that it's either
|
// If the input has reached a final state, that it's either
|
||||||
// been swept, or failed, or excluded, we will remove it from
|
// been swept, or failed, or excluded, we will remove it from
|
||||||
@ -1524,7 +1525,7 @@ func (s *UtxoSweeper) updateSweeperInputs() pendingInputs {
|
|||||||
|
|
||||||
// sweepPendingInputs is called when the ticker fires. It will create clusters
|
// sweepPendingInputs is called when the ticker fires. It will create clusters
|
||||||
// and attempt to create and publish the sweeping transactions.
|
// and attempt to create and publish the sweeping transactions.
|
||||||
func (s *UtxoSweeper) sweepPendingInputs(inputs pendingInputs) {
|
func (s *UtxoSweeper) sweepPendingInputs(inputs InputsMap) {
|
||||||
// Cluster all of our inputs based on the specific Aggregator.
|
// Cluster all of our inputs based on the specific Aggregator.
|
||||||
sets := s.cfg.Aggregator.ClusterInputs(inputs)
|
sets := s.cfg.Aggregator.ClusterInputs(inputs)
|
||||||
|
|
||||||
|
@ -268,15 +268,15 @@ func (ctx *sweeperTestContext) assertPendingInputs(inputs ...input.Input) {
|
|||||||
inputSet[*input.OutPoint()] = struct{}{}
|
inputSet[*input.OutPoint()] = struct{}{}
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingInputs, err := ctx.sweeper.PendingInputs()
|
inputsMap, err := ctx.sweeper.PendingInputs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.t.Fatal(err)
|
ctx.t.Fatal(err)
|
||||||
}
|
}
|
||||||
if len(pendingInputs) != len(inputSet) {
|
if len(inputsMap) != len(inputSet) {
|
||||||
ctx.t.Fatalf("expected %d pending inputs, got %d",
|
ctx.t.Fatalf("expected %d pending inputs, got %d",
|
||||||
len(inputSet), len(pendingInputs))
|
len(inputSet), len(inputsMap))
|
||||||
}
|
}
|
||||||
for input := range pendingInputs {
|
for input := range inputsMap {
|
||||||
if _, ok := inputSet[input]; !ok {
|
if _, ok := inputSet[input]; !ok {
|
||||||
ctx.t.Fatalf("found unexpected input %v", input)
|
ctx.t.Fatalf("found unexpected input %v", input)
|
||||||
}
|
}
|
||||||
@ -2146,7 +2146,7 @@ func TestMarkInputsPendingPublish(t *testing.T) {
|
|||||||
|
|
||||||
inputInit.On("OutPoint").Return(&wire.OutPoint{Index: 1})
|
inputInit.On("OutPoint").Return(&wire.OutPoint{Index: 1})
|
||||||
|
|
||||||
s.inputs[*inputInit.OutPoint()] = &pendingInput{
|
s.inputs[*inputInit.OutPoint()] = &SweeperInput{
|
||||||
state: Init,
|
state: Init,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2156,7 +2156,7 @@ func TestMarkInputsPendingPublish(t *testing.T) {
|
|||||||
|
|
||||||
inputPendingPublish.On("OutPoint").Return(&wire.OutPoint{Index: 2})
|
inputPendingPublish.On("OutPoint").Return(&wire.OutPoint{Index: 2})
|
||||||
|
|
||||||
s.inputs[*inputPendingPublish.OutPoint()] = &pendingInput{
|
s.inputs[*inputPendingPublish.OutPoint()] = &SweeperInput{
|
||||||
state: PendingPublish,
|
state: PendingPublish,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2166,7 +2166,7 @@ func TestMarkInputsPendingPublish(t *testing.T) {
|
|||||||
|
|
||||||
inputTerminated.On("OutPoint").Return(&wire.OutPoint{Index: 3})
|
inputTerminated.On("OutPoint").Return(&wire.OutPoint{Index: 3})
|
||||||
|
|
||||||
s.inputs[*inputTerminated.OutPoint()] = &pendingInput{
|
s.inputs[*inputTerminated.OutPoint()] = &SweeperInput{
|
||||||
state: Excluded,
|
state: Excluded,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2227,7 +2227,7 @@ func TestMarkInputsPublished(t *testing.T) {
|
|||||||
inputInit := &wire.TxIn{
|
inputInit := &wire.TxIn{
|
||||||
PreviousOutPoint: wire.OutPoint{Index: 2},
|
PreviousOutPoint: wire.OutPoint{Index: 2},
|
||||||
}
|
}
|
||||||
s.inputs[inputInit.PreviousOutPoint] = &pendingInput{
|
s.inputs[inputInit.PreviousOutPoint] = &SweeperInput{
|
||||||
state: Init,
|
state: Init,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2235,7 +2235,7 @@ func TestMarkInputsPublished(t *testing.T) {
|
|||||||
inputPendingPublish := &wire.TxIn{
|
inputPendingPublish := &wire.TxIn{
|
||||||
PreviousOutPoint: wire.OutPoint{Index: 3},
|
PreviousOutPoint: wire.OutPoint{Index: 3},
|
||||||
}
|
}
|
||||||
s.inputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{
|
s.inputs[inputPendingPublish.PreviousOutPoint] = &SweeperInput{
|
||||||
state: PendingPublish,
|
state: PendingPublish,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2307,7 +2307,7 @@ func TestMarkInputsPublishFailed(t *testing.T) {
|
|||||||
inputInit := &wire.TxIn{
|
inputInit := &wire.TxIn{
|
||||||
PreviousOutPoint: wire.OutPoint{Index: 2},
|
PreviousOutPoint: wire.OutPoint{Index: 2},
|
||||||
}
|
}
|
||||||
s.inputs[inputInit.PreviousOutPoint] = &pendingInput{
|
s.inputs[inputInit.PreviousOutPoint] = &SweeperInput{
|
||||||
state: Init,
|
state: Init,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2315,7 +2315,7 @@ func TestMarkInputsPublishFailed(t *testing.T) {
|
|||||||
inputPendingPublish := &wire.TxIn{
|
inputPendingPublish := &wire.TxIn{
|
||||||
PreviousOutPoint: wire.OutPoint{Index: 3},
|
PreviousOutPoint: wire.OutPoint{Index: 3},
|
||||||
}
|
}
|
||||||
s.inputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{
|
s.inputs[inputPendingPublish.PreviousOutPoint] = &SweeperInput{
|
||||||
state: PendingPublish,
|
state: PendingPublish,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2373,7 +2373,7 @@ func TestMarkInputsSwept(t *testing.T) {
|
|||||||
inputInit := &wire.TxIn{
|
inputInit := &wire.TxIn{
|
||||||
PreviousOutPoint: wire.OutPoint{Index: 2},
|
PreviousOutPoint: wire.OutPoint{Index: 2},
|
||||||
}
|
}
|
||||||
s.inputs[inputInit.PreviousOutPoint] = &pendingInput{
|
s.inputs[inputInit.PreviousOutPoint] = &SweeperInput{
|
||||||
state: Init,
|
state: Init,
|
||||||
Input: mockInput,
|
Input: mockInput,
|
||||||
}
|
}
|
||||||
@ -2382,7 +2382,7 @@ func TestMarkInputsSwept(t *testing.T) {
|
|||||||
inputPendingPublish := &wire.TxIn{
|
inputPendingPublish := &wire.TxIn{
|
||||||
PreviousOutPoint: wire.OutPoint{Index: 3},
|
PreviousOutPoint: wire.OutPoint{Index: 3},
|
||||||
}
|
}
|
||||||
s.inputs[inputPendingPublish.PreviousOutPoint] = &pendingInput{
|
s.inputs[inputPendingPublish.PreviousOutPoint] = &SweeperInput{
|
||||||
state: PendingPublish,
|
state: PendingPublish,
|
||||||
Input: mockInput,
|
Input: mockInput,
|
||||||
}
|
}
|
||||||
@ -2391,7 +2391,7 @@ func TestMarkInputsSwept(t *testing.T) {
|
|||||||
inputTerminated := &wire.TxIn{
|
inputTerminated := &wire.TxIn{
|
||||||
PreviousOutPoint: wire.OutPoint{Index: 4},
|
PreviousOutPoint: wire.OutPoint{Index: 4},
|
||||||
}
|
}
|
||||||
s.inputs[inputTerminated.PreviousOutPoint] = &pendingInput{
|
s.inputs[inputTerminated.PreviousOutPoint] = &SweeperInput{
|
||||||
state: Excluded,
|
state: Excluded,
|
||||||
Input: mockInput,
|
Input: mockInput,
|
||||||
}
|
}
|
||||||
@ -2479,17 +2479,17 @@ func TestUpdateSweeperInputs(t *testing.T) {
|
|||||||
s := New(nil)
|
s := New(nil)
|
||||||
|
|
||||||
// Create a list of inputs using all the states.
|
// Create a list of inputs using all the states.
|
||||||
input0 := &pendingInput{state: Init}
|
input0 := &SweeperInput{state: Init}
|
||||||
input1 := &pendingInput{state: PendingPublish}
|
input1 := &SweeperInput{state: PendingPublish}
|
||||||
input2 := &pendingInput{state: Published}
|
input2 := &SweeperInput{state: Published}
|
||||||
input3 := &pendingInput{state: PublishFailed}
|
input3 := &SweeperInput{state: PublishFailed}
|
||||||
input4 := &pendingInput{state: Swept}
|
input4 := &SweeperInput{state: Swept}
|
||||||
input5 := &pendingInput{state: Excluded}
|
input5 := &SweeperInput{state: Excluded}
|
||||||
input6 := &pendingInput{state: Failed}
|
input6 := &SweeperInput{state: Failed}
|
||||||
|
|
||||||
// Add the inputs to the sweeper. After the update, we should see the
|
// Add the inputs to the sweeper. After the update, we should see the
|
||||||
// terminated inputs being removed.
|
// terminated inputs being removed.
|
||||||
s.inputs = map[wire.OutPoint]*pendingInput{
|
s.inputs = map[wire.OutPoint]*SweeperInput{
|
||||||
{Index: 0}: input0,
|
{Index: 0}: input0,
|
||||||
{Index: 1}: input1,
|
{Index: 1}: input1,
|
||||||
{Index: 2}: input2,
|
{Index: 2}: input2,
|
||||||
@ -2501,7 +2501,7 @@ func TestUpdateSweeperInputs(t *testing.T) {
|
|||||||
|
|
||||||
// We expect the inputs with `Swept`, `Excluded`, and `Failed` to be
|
// We expect the inputs with `Swept`, `Excluded`, and `Failed` to be
|
||||||
// removed.
|
// removed.
|
||||||
expectedInputs := map[wire.OutPoint]*pendingInput{
|
expectedInputs := map[wire.OutPoint]*SweeperInput{
|
||||||
{Index: 0}: input0,
|
{Index: 0}: input0,
|
||||||
{Index: 1}: input1,
|
{Index: 1}: input1,
|
||||||
{Index: 2}: input2,
|
{Index: 2}: input2,
|
||||||
@ -2510,7 +2510,7 @@ func TestUpdateSweeperInputs(t *testing.T) {
|
|||||||
|
|
||||||
// We expect only the inputs with `Init` and `PublishFailed` to be
|
// We expect only the inputs with `Init` and `PublishFailed` to be
|
||||||
// returned.
|
// returned.
|
||||||
expectedReturn := map[wire.OutPoint]*pendingInput{
|
expectedReturn := map[wire.OutPoint]*SweeperInput{
|
||||||
{Index: 0}: input0,
|
{Index: 0}: input0,
|
||||||
{Index: 3}: input3,
|
{Index: 3}: input3,
|
||||||
}
|
}
|
||||||
@ -2618,7 +2618,7 @@ func TestMarkInputFailed(t *testing.T) {
|
|||||||
s := New(&UtxoSweeperConfig{})
|
s := New(&UtxoSweeperConfig{})
|
||||||
|
|
||||||
// Create a testing pending input.
|
// Create a testing pending input.
|
||||||
pi := &pendingInput{
|
pi := &SweeperInput{
|
||||||
state: Init,
|
state: Init,
|
||||||
Input: mockInput,
|
Input: mockInput,
|
||||||
}
|
}
|
||||||
@ -2683,7 +2683,7 @@ func TestSweepPendingInputs(t *testing.T) {
|
|||||||
|
|
||||||
// Make pending inputs for testing. We don't need real values here as
|
// Make pending inputs for testing. We don't need real values here as
|
||||||
// the returned clusters are mocked.
|
// the returned clusters are mocked.
|
||||||
pis := make(pendingInputs)
|
pis := make(InputsMap)
|
||||||
|
|
||||||
// Mock the aggregator to return the mocked input sets.
|
// Mock the aggregator to return the mocked input sets.
|
||||||
aggregator.On("ClusterInputs", pis).Return([]InputSet{
|
aggregator.On("ClusterInputs", pis).Return([]InputSet{
|
||||||
@ -2729,10 +2729,10 @@ func TestHandleBumpEventTxFailed(t *testing.T) {
|
|||||||
defer input3.AssertExpectations(t)
|
defer input3.AssertExpectations(t)
|
||||||
|
|
||||||
// Construct the initial state for the sweeper.
|
// Construct the initial state for the sweeper.
|
||||||
s.inputs = pendingInputs{
|
s.inputs = InputsMap{
|
||||||
op1: &pendingInput{Input: input1, state: PendingPublish},
|
op1: &SweeperInput{Input: input1, state: PendingPublish},
|
||||||
op2: &pendingInput{Input: input2, state: PendingPublish},
|
op2: &SweeperInput{Input: input2, state: PendingPublish},
|
||||||
op3: &pendingInput{Input: input3, state: PendingPublish},
|
op3: &SweeperInput{Input: input3, state: PendingPublish},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a testing tx that spends the first two inputs.
|
// Create a testing tx that spends the first two inputs.
|
||||||
@ -2788,8 +2788,8 @@ func TestHandleBumpEventTxReplaced(t *testing.T) {
|
|||||||
defer inp.AssertExpectations(t)
|
defer inp.AssertExpectations(t)
|
||||||
|
|
||||||
// Construct the initial state for the sweeper.
|
// Construct the initial state for the sweeper.
|
||||||
s.inputs = pendingInputs{
|
s.inputs = InputsMap{
|
||||||
op: &pendingInput{Input: inp, state: PendingPublish},
|
op: &SweeperInput{Input: inp, state: PendingPublish},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a testing tx that spends the input.
|
// Create a testing tx that spends the input.
|
||||||
@ -2878,8 +2878,8 @@ func TestHandleBumpEventTxPublished(t *testing.T) {
|
|||||||
defer inp.AssertExpectations(t)
|
defer inp.AssertExpectations(t)
|
||||||
|
|
||||||
// Construct the initial state for the sweeper.
|
// Construct the initial state for the sweeper.
|
||||||
s.inputs = pendingInputs{
|
s.inputs = InputsMap{
|
||||||
op: &pendingInput{Input: inp, state: PendingPublish},
|
op: &SweeperInput{Input: inp, state: PendingPublish},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a testing tx that spends the input.
|
// Create a testing tx that spends the input.
|
||||||
@ -2930,8 +2930,8 @@ func TestMonitorFeeBumpResult(t *testing.T) {
|
|||||||
defer inp.AssertExpectations(t)
|
defer inp.AssertExpectations(t)
|
||||||
|
|
||||||
// Construct the initial state for the sweeper.
|
// Construct the initial state for the sweeper.
|
||||||
s.inputs = pendingInputs{
|
s.inputs = InputsMap{
|
||||||
op: &pendingInput{Input: inp, state: PendingPublish},
|
op: &SweeperInput{Input: inp, state: PendingPublish},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a testing tx that spends the input.
|
// Create a testing tx that spends the input.
|
||||||
|
@ -402,7 +402,7 @@ func (t *txInputSet) add(input input.Input, constraints addConstraints) bool {
|
|||||||
// up the utxo set even if it costs us some fees up front. In the spirit of
|
// up the utxo set even if it costs us some fees up front. In the spirit of
|
||||||
// minimizing any negative externalities we cause for the Bitcoin system as a
|
// minimizing any negative externalities we cause for the Bitcoin system as a
|
||||||
// whole.
|
// whole.
|
||||||
func (t *txInputSet) addPositiveYieldInputs(sweepableInputs []*pendingInput) {
|
func (t *txInputSet) addPositiveYieldInputs(sweepableInputs []*SweeperInput) {
|
||||||
for i, inp := range sweepableInputs {
|
for i, inp := range sweepableInputs {
|
||||||
// Apply relaxed constraints for force sweeps.
|
// Apply relaxed constraints for force sweeps.
|
||||||
constraints := constraintsRegular
|
constraints := constraintsRegular
|
||||||
@ -549,7 +549,7 @@ func createWalletTxInput(utxo *lnwallet.Utxo) (input.Input, error) {
|
|||||||
type BudgetInputSet struct {
|
type BudgetInputSet struct {
|
||||||
// inputs is the set of inputs that have been added to the set after
|
// inputs is the set of inputs that have been added to the set after
|
||||||
// considering their economical contribution.
|
// considering their economical contribution.
|
||||||
inputs []*pendingInput
|
inputs []*SweeperInput
|
||||||
|
|
||||||
// deadlineHeight is the height which the inputs in this set must be
|
// deadlineHeight is the height which the inputs in this set must be
|
||||||
// confirmed by.
|
// confirmed by.
|
||||||
@ -561,7 +561,7 @@ var _ InputSet = (*BudgetInputSet)(nil)
|
|||||||
|
|
||||||
// validateInputs is used when creating new BudgetInputSet to ensure there are
|
// validateInputs is used when creating new BudgetInputSet to ensure there are
|
||||||
// no duplicate inputs and they all share the same deadline heights, if set.
|
// no duplicate inputs and they all share the same deadline heights, if set.
|
||||||
func validateInputs(inputs []pendingInput) error {
|
func validateInputs(inputs []SweeperInput) error {
|
||||||
// Sanity check the input slice to ensure it's non-empty.
|
// Sanity check the input slice to ensure it's non-empty.
|
||||||
if len(inputs) == 0 {
|
if len(inputs) == 0 {
|
||||||
return fmt.Errorf("inputs slice is empty")
|
return fmt.Errorf("inputs slice is empty")
|
||||||
@ -597,7 +597,7 @@ func validateInputs(inputs []pendingInput) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewBudgetInputSet creates a new BudgetInputSet.
|
// NewBudgetInputSet creates a new BudgetInputSet.
|
||||||
func NewBudgetInputSet(inputs []pendingInput) (*BudgetInputSet, error) {
|
func NewBudgetInputSet(inputs []SweeperInput) (*BudgetInputSet, error) {
|
||||||
// Validate the supplied inputs.
|
// Validate the supplied inputs.
|
||||||
if err := validateInputs(inputs); err != nil {
|
if err := validateInputs(inputs); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -611,7 +611,7 @@ func NewBudgetInputSet(inputs []pendingInput) (*BudgetInputSet, error) {
|
|||||||
deadlineHeight := inputs[0].params.DeadlineHeight
|
deadlineHeight := inputs[0].params.DeadlineHeight
|
||||||
bi := &BudgetInputSet{
|
bi := &BudgetInputSet{
|
||||||
deadlineHeight: deadlineHeight,
|
deadlineHeight: deadlineHeight,
|
||||||
inputs: make([]*pendingInput, 0, len(inputs)),
|
inputs: make([]*SweeperInput, 0, len(inputs)),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, input := range inputs {
|
for _, input := range inputs {
|
||||||
@ -640,7 +640,7 @@ func (b *BudgetInputSet) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addInput adds an input to the input set.
|
// addInput adds an input to the input set.
|
||||||
func (b *BudgetInputSet) addInput(input pendingInput) {
|
func (b *BudgetInputSet) addInput(input SweeperInput) {
|
||||||
b.inputs = append(b.inputs, &input)
|
b.inputs = append(b.inputs, &input)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -695,8 +695,8 @@ func (b *BudgetInputSet) NeedWalletInput() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copyInputs returns a copy of the slice of the inputs in the set.
|
// copyInputs returns a copy of the slice of the inputs in the set.
|
||||||
func (b *BudgetInputSet) copyInputs() []*pendingInput {
|
func (b *BudgetInputSet) copyInputs() []*SweeperInput {
|
||||||
inputs := make([]*pendingInput, len(b.inputs))
|
inputs := make([]*SweeperInput, len(b.inputs))
|
||||||
copy(inputs, b.inputs)
|
copy(inputs, b.inputs)
|
||||||
return inputs
|
return inputs
|
||||||
}
|
}
|
||||||
@ -745,7 +745,7 @@ func (b *BudgetInputSet) AddWalletInputs(wallet Wallet) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pi := pendingInput{
|
pi := SweeperInput{
|
||||||
Input: input,
|
Input: input,
|
||||||
params: Params{
|
params: Params{
|
||||||
// Inherit the deadline height from the input
|
// Inherit the deadline height from the input
|
||||||
|
@ -250,7 +250,7 @@ func TestNewBudgetInputSet(t *testing.T) {
|
|||||||
rt := require.New(t)
|
rt := require.New(t)
|
||||||
|
|
||||||
// Pass an empty slice and expect an error.
|
// Pass an empty slice and expect an error.
|
||||||
set, err := NewBudgetInputSet([]pendingInput{})
|
set, err := NewBudgetInputSet([]SweeperInput{})
|
||||||
rt.ErrorContains(err, "inputs slice is empty")
|
rt.ErrorContains(err, "inputs slice is empty")
|
||||||
rt.Nil(set)
|
rt.Nil(set)
|
||||||
|
|
||||||
@ -258,21 +258,21 @@ func TestNewBudgetInputSet(t *testing.T) {
|
|||||||
inp0 := createP2WKHInput(1000)
|
inp0 := createP2WKHInput(1000)
|
||||||
inp1 := createP2WKHInput(1000)
|
inp1 := createP2WKHInput(1000)
|
||||||
inp2 := createP2WKHInput(1000)
|
inp2 := createP2WKHInput(1000)
|
||||||
input0 := pendingInput{
|
input0 := SweeperInput{
|
||||||
Input: inp0,
|
Input: inp0,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: 100,
|
Budget: 100,
|
||||||
DeadlineHeight: fn.None[int32](),
|
DeadlineHeight: fn.None[int32](),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
input1 := pendingInput{
|
input1 := SweeperInput{
|
||||||
Input: inp1,
|
Input: inp1,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: 100,
|
Budget: 100,
|
||||||
DeadlineHeight: fn.Some(int32(1)),
|
DeadlineHeight: fn.Some(int32(1)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
input2 := pendingInput{
|
input2 := SweeperInput{
|
||||||
Input: inp2,
|
Input: inp2,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: 100,
|
Budget: 100,
|
||||||
@ -281,17 +281,17 @@ func TestNewBudgetInputSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pass a slice of inputs with different deadline heights.
|
// Pass a slice of inputs with different deadline heights.
|
||||||
set, err = NewBudgetInputSet([]pendingInput{input1, input2})
|
set, err = NewBudgetInputSet([]SweeperInput{input1, input2})
|
||||||
rt.ErrorContains(err, "inputs have different deadline heights")
|
rt.ErrorContains(err, "inputs have different deadline heights")
|
||||||
rt.Nil(set)
|
rt.Nil(set)
|
||||||
|
|
||||||
// Pass a slice of inputs that only one input has the deadline height.
|
// Pass a slice of inputs that only one input has the deadline height.
|
||||||
set, err = NewBudgetInputSet([]pendingInput{input0, input2})
|
set, err = NewBudgetInputSet([]SweeperInput{input0, input2})
|
||||||
rt.NoError(err)
|
rt.NoError(err)
|
||||||
rt.NotNil(set)
|
rt.NotNil(set)
|
||||||
|
|
||||||
// Pass a slice of inputs that are duplicates.
|
// Pass a slice of inputs that are duplicates.
|
||||||
set, err = NewBudgetInputSet([]pendingInput{input1, input1})
|
set, err = NewBudgetInputSet([]SweeperInput{input1, input1})
|
||||||
rt.ErrorContains(err, "duplicate inputs")
|
rt.ErrorContains(err, "duplicate inputs")
|
||||||
rt.Nil(set)
|
rt.Nil(set)
|
||||||
}
|
}
|
||||||
@ -303,7 +303,7 @@ func TestBudgetInputSetAddInput(t *testing.T) {
|
|||||||
|
|
||||||
// Create a testing input with a budget of 100 satoshis.
|
// Create a testing input with a budget of 100 satoshis.
|
||||||
input := createP2WKHInput(1000)
|
input := createP2WKHInput(1000)
|
||||||
pi := &pendingInput{
|
pi := &SweeperInput{
|
||||||
Input: input,
|
Input: input,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: 100,
|
Budget: 100,
|
||||||
@ -311,7 +311,7 @@ func TestBudgetInputSetAddInput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize an input set, which adds the above input.
|
// Initialize an input set, which adds the above input.
|
||||||
set, err := NewBudgetInputSet([]pendingInput{*pi})
|
set, err := NewBudgetInputSet([]SweeperInput{*pi})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Add the input to the set again.
|
// Add the input to the set again.
|
||||||
@ -345,20 +345,20 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
const budget = 100
|
const budget = 100
|
||||||
|
|
||||||
// Create the pending input that doesn't have a required output.
|
// Create the pending input that doesn't have a required output.
|
||||||
piBudget := &pendingInput{
|
piBudget := &SweeperInput{
|
||||||
Input: mockInput,
|
Input: mockInput,
|
||||||
params: Params{Budget: budget},
|
params: Params{Budget: budget},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the pending input that has a required output.
|
// Create the pending input that has a required output.
|
||||||
piRequireOutput := &pendingInput{
|
piRequireOutput := &SweeperInput{
|
||||||
Input: mockInputRequireOutput,
|
Input: mockInputRequireOutput,
|
||||||
params: Params{Budget: budget},
|
params: Params{Budget: budget},
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
setupInputs func() []*pendingInput
|
setupInputs func() []*SweeperInput
|
||||||
need bool
|
need bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -366,7 +366,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
// wallet input. Technically this should be an invalid
|
// wallet input. Technically this should be an invalid
|
||||||
// state.
|
// state.
|
||||||
name: "no inputs",
|
name: "no inputs",
|
||||||
setupInputs: func() []*pendingInput {
|
setupInputs: func() []*SweeperInput {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
need: false,
|
need: false,
|
||||||
@ -375,7 +375,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
// When there's no required output, we don't need a
|
// When there's no required output, we don't need a
|
||||||
// wallet input.
|
// wallet input.
|
||||||
name: "no required outputs",
|
name: "no required outputs",
|
||||||
setupInputs: func() []*pendingInput {
|
setupInputs: func() []*SweeperInput {
|
||||||
// Create a sign descriptor to be used in the
|
// Create a sign descriptor to be used in the
|
||||||
// pending input when calculating budgets can
|
// pending input when calculating budgets can
|
||||||
// be borrowed.
|
// be borrowed.
|
||||||
@ -386,7 +386,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
mockInput.On("SignDesc").Return(sd).Once()
|
mockInput.On("SignDesc").Return(sd).Once()
|
||||||
|
|
||||||
return []*pendingInput{piBudget}
|
return []*SweeperInput{piBudget}
|
||||||
},
|
},
|
||||||
need: false,
|
need: false,
|
||||||
},
|
},
|
||||||
@ -394,7 +394,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
// When the output value cannot cover the budget, we
|
// When the output value cannot cover the budget, we
|
||||||
// need a wallet input.
|
// need a wallet input.
|
||||||
name: "output value cannot cover budget",
|
name: "output value cannot cover budget",
|
||||||
setupInputs: func() []*pendingInput {
|
setupInputs: func() []*SweeperInput {
|
||||||
// Create a sign descriptor to be used in the
|
// Create a sign descriptor to be used in the
|
||||||
// pending input when calculating budgets can
|
// pending input when calculating budgets can
|
||||||
// be borrowed.
|
// be borrowed.
|
||||||
@ -414,7 +414,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
input.CommitmentAnchor,
|
input.CommitmentAnchor,
|
||||||
).Maybe()
|
).Maybe()
|
||||||
|
|
||||||
return []*pendingInput{piBudget}
|
return []*SweeperInput{piBudget}
|
||||||
},
|
},
|
||||||
need: true,
|
need: true,
|
||||||
},
|
},
|
||||||
@ -422,8 +422,8 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
// When there's only inputs that require outputs, we
|
// When there's only inputs that require outputs, we
|
||||||
// need wallet inputs.
|
// need wallet inputs.
|
||||||
name: "only required outputs",
|
name: "only required outputs",
|
||||||
setupInputs: func() []*pendingInput {
|
setupInputs: func() []*SweeperInput {
|
||||||
return []*pendingInput{piRequireOutput}
|
return []*SweeperInput{piRequireOutput}
|
||||||
},
|
},
|
||||||
need: true,
|
need: true,
|
||||||
},
|
},
|
||||||
@ -432,7 +432,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
// budget cannot cover the required, we need a wallet
|
// budget cannot cover the required, we need a wallet
|
||||||
// input.
|
// input.
|
||||||
name: "not enough budget to be borrowed",
|
name: "not enough budget to be borrowed",
|
||||||
setupInputs: func() []*pendingInput {
|
setupInputs: func() []*SweeperInput {
|
||||||
// Create a sign descriptor to be used in the
|
// Create a sign descriptor to be used in the
|
||||||
// pending input when calculating budgets can
|
// pending input when calculating budgets can
|
||||||
// be borrowed.
|
// be borrowed.
|
||||||
@ -446,7 +446,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
}
|
}
|
||||||
mockInput.On("SignDesc").Return(sd).Once()
|
mockInput.On("SignDesc").Return(sd).Once()
|
||||||
|
|
||||||
return []*pendingInput{
|
return []*SweeperInput{
|
||||||
piBudget, piRequireOutput,
|
piBudget, piRequireOutput,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -457,7 +457,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
// borrowed covers the required, we don't need wallet
|
// borrowed covers the required, we don't need wallet
|
||||||
// inputs.
|
// inputs.
|
||||||
name: "enough budget to be borrowed",
|
name: "enough budget to be borrowed",
|
||||||
setupInputs: func() []*pendingInput {
|
setupInputs: func() []*SweeperInput {
|
||||||
// Create a sign descriptor to be used in the
|
// Create a sign descriptor to be used in the
|
||||||
// pending input when calculating budgets can
|
// pending input when calculating budgets can
|
||||||
// be borrowed.
|
// be borrowed.
|
||||||
@ -472,7 +472,7 @@ func TestNeedWalletInput(t *testing.T) {
|
|||||||
mockInput.On("SignDesc").Return(sd).Once()
|
mockInput.On("SignDesc").Return(sd).Once()
|
||||||
piBudget.Input = mockInput
|
piBudget.Input = mockInput
|
||||||
|
|
||||||
return []*pendingInput{
|
return []*SweeperInput{
|
||||||
piBudget, piRequireOutput,
|
piBudget, piRequireOutput,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -567,7 +567,7 @@ func TestAddWalletInputNotEnoughInputs(t *testing.T) {
|
|||||||
defer mockInput.AssertExpectations(t)
|
defer mockInput.AssertExpectations(t)
|
||||||
|
|
||||||
// Create a pending input that requires 10k satoshis.
|
// Create a pending input that requires 10k satoshis.
|
||||||
pi := &pendingInput{
|
pi := &SweeperInput{
|
||||||
Input: mockInput,
|
Input: mockInput,
|
||||||
params: Params{Budget: budget},
|
params: Params{Budget: budget},
|
||||||
}
|
}
|
||||||
@ -583,7 +583,7 @@ func TestAddWalletInputNotEnoughInputs(t *testing.T) {
|
|||||||
min, max).Return([]*lnwallet.Utxo{utxo}, nil).Once()
|
min, max).Return([]*lnwallet.Utxo{utxo}, nil).Once()
|
||||||
|
|
||||||
// Initialize an input set with the pending input.
|
// Initialize an input set with the pending input.
|
||||||
set := BudgetInputSet{inputs: []*pendingInput{pi}}
|
set := BudgetInputSet{inputs: []*SweeperInput{pi}}
|
||||||
|
|
||||||
// Add wallet inputs to the input set, which should give us an error as
|
// Add wallet inputs to the input set, which should give us an error as
|
||||||
// the wallet cannot cover the budget.
|
// the wallet cannot cover the budget.
|
||||||
@ -617,7 +617,7 @@ func TestAddWalletInputSuccess(t *testing.T) {
|
|||||||
|
|
||||||
// Create a pending input that requires 10k satoshis.
|
// Create a pending input that requires 10k satoshis.
|
||||||
deadline := int32(1000)
|
deadline := int32(1000)
|
||||||
pi := &pendingInput{
|
pi := &SweeperInput{
|
||||||
Input: mockInput,
|
Input: mockInput,
|
||||||
params: Params{
|
params: Params{
|
||||||
Budget: budget,
|
Budget: budget,
|
||||||
@ -643,7 +643,7 @@ func TestAddWalletInputSuccess(t *testing.T) {
|
|||||||
min, max).Return([]*lnwallet.Utxo{utxo, utxo}, nil).Once()
|
min, max).Return([]*lnwallet.Utxo{utxo, utxo}, nil).Once()
|
||||||
|
|
||||||
// Initialize an input set with the pending input.
|
// Initialize an input set with the pending input.
|
||||||
set, err := NewBudgetInputSet([]pendingInput{*pi})
|
set, err := NewBudgetInputSet([]SweeperInput{*pi})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Add wallet inputs to the input set, which should give us an error as
|
// Add wallet inputs to the input set, which should give us an error as
|
||||||
|
Loading…
x
Reference in New Issue
Block a user