sweep: create add constraints
This refactor prepares for the addition of specific constraints for force sweep inputs.
This commit is contained in:
parent
16832cefa3
commit
14237f5fd4
|
@ -13,6 +13,19 @@ import (
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// addConstraints defines the constraints to apply when adding an input.
|
||||||
|
type addConstraints uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// constraintsRegular is for regular input sweeps that should have a positive
|
||||||
|
// yield.
|
||||||
|
constraintsRegular addConstraints = iota
|
||||||
|
|
||||||
|
// constraintsWallet is for wallet inputs that are only added to bring up the tx
|
||||||
|
// output value.
|
||||||
|
constraintsWallet
|
||||||
|
)
|
||||||
|
|
||||||
// txInputSet is an object that accumulates tx inputs and keeps running counters
|
// txInputSet is an object that accumulates tx inputs and keeps running counters
|
||||||
// on various properties of the tx.
|
// on various properties of the tx.
|
||||||
type txInputSet struct {
|
type txInputSet struct {
|
||||||
|
@ -78,10 +91,12 @@ func (t *txInputSet) dustLimitReached() bool {
|
||||||
// add adds a new input to the set. It returns a bool indicating whether the
|
// add adds a new input to the set. It returns a bool indicating whether the
|
||||||
// input was added to the set. An input is rejected if it decreases the tx
|
// input was added to the set. An input is rejected if it decreases the tx
|
||||||
// output value after paying fees.
|
// output value after paying fees.
|
||||||
func (t *txInputSet) add(input input.Input, fromWallet bool) bool {
|
func (t *txInputSet) add(input input.Input, constraints addConstraints) bool {
|
||||||
// Stop if max inputs is reached. Do not count additional wallet inputs,
|
// Stop if max inputs is reached. Do not count additional wallet inputs,
|
||||||
// because we don't know in advance how many we may need.
|
// because we don't know in advance how many we may need.
|
||||||
if !fromWallet && len(t.inputs) >= t.maxInputs {
|
if constraints != constraintsWallet &&
|
||||||
|
len(t.inputs) >= t.maxInputs {
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,19 +123,33 @@ func (t *txInputSet) add(input input.Input, fromWallet bool) bool {
|
||||||
// added to the set.
|
// added to the set.
|
||||||
newOutputValue := newInputTotal - fee
|
newOutputValue := newInputTotal - fee
|
||||||
|
|
||||||
// If adding this input makes the total output value of the set
|
// Initialize new wallet total with the current wallet total. This is
|
||||||
// decrease, this is a negative yield input. We don't add the input to
|
// updated below if this input is a wallet input.
|
||||||
// the set and return the outcome.
|
newWalletTotal := t.walletInputTotal
|
||||||
if newOutputValue <= t.outputValue {
|
|
||||||
return false
|
// Calculate the yield of this input from the change in tx output value.
|
||||||
}
|
inputYield := newOutputValue - t.outputValue
|
||||||
|
|
||||||
|
switch constraints {
|
||||||
|
|
||||||
|
// Don't sweep inputs that cost us more to sweep than they give us.
|
||||||
|
case constraintsRegular:
|
||||||
|
if inputYield <= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are attaching a wallet input to raise the tx output value above
|
||||||
|
// the dust limit.
|
||||||
|
case constraintsWallet:
|
||||||
|
// Skip this wallet input if adding it would lower the output
|
||||||
|
// value.
|
||||||
|
if inputYield <= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// If this input comes from the wallet, verify that we still gain
|
|
||||||
// something with this transaction.
|
|
||||||
if fromWallet {
|
|
||||||
// Calculate the total value that we spend in this tx from the
|
// Calculate the total value that we spend in this tx from the
|
||||||
// wallet if we'd add this wallet input.
|
// wallet if we'd add this wallet input.
|
||||||
newWalletTotal := t.walletInputTotal + value
|
newWalletTotal += value
|
||||||
|
|
||||||
// In any case, we don't want to lose money by sweeping. If we
|
// In any case, we don't want to lose money by sweeping. If we
|
||||||
// don't get more out of the tx then we put in ourselves, do not
|
// don't get more out of the tx then we put in ourselves, do not
|
||||||
|
@ -142,10 +171,6 @@ func (t *txInputSet) add(input input.Input, fromWallet bool) bool {
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've decided to add the wallet input. Increment the total
|
|
||||||
// wallet funds that go into this tx.
|
|
||||||
t.walletInputTotal = newWalletTotal
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update running values.
|
// Update running values.
|
||||||
|
@ -153,6 +178,7 @@ func (t *txInputSet) add(input input.Input, fromWallet bool) bool {
|
||||||
t.outputValue = newOutputValue
|
t.outputValue = newOutputValue
|
||||||
t.inputs = append(t.inputs, input)
|
t.inputs = append(t.inputs, input)
|
||||||
t.weightEstimate = newWeightEstimate
|
t.weightEstimate = newWeightEstimate
|
||||||
|
t.walletInputTotal = newWalletTotal
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -171,7 +197,7 @@ func (t *txInputSet) addPositiveYieldInputs(sweepableInputs []txInput) {
|
||||||
// succeed because it wouldn't increase the output value,
|
// succeed because it wouldn't increase the output value,
|
||||||
// return. Assuming inputs are sorted by yield, any further
|
// return. Assuming inputs are sorted by yield, any further
|
||||||
// inputs wouldn't increase the output value either.
|
// inputs wouldn't increase the output value either.
|
||||||
if !t.add(input, false) {
|
if !t.add(input, constraintsRegular) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +228,7 @@ func (t *txInputSet) tryAddWalletInputsIfNeeded() error {
|
||||||
|
|
||||||
// If the wallet input isn't positively-yielding at this fee
|
// If the wallet input isn't positively-yielding at this fee
|
||||||
// rate, skip it.
|
// rate, skip it.
|
||||||
if !t.add(input, true) {
|
if !t.add(input, constraintsWallet) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,13 +24,13 @@ func TestTxInputSet(t *testing.T) {
|
||||||
// Create a 300 sat input. The fee to sweep this input to a P2WKH output
|
// Create a 300 sat input. The fee to sweep this input to a P2WKH output
|
||||||
// is 439 sats. That means that this input yields -139 sats and we
|
// is 439 sats. That means that this input yields -139 sats and we
|
||||||
// expect it not to be added.
|
// expect it not to be added.
|
||||||
if set.add(createP2WKHInput(300), false) {
|
if set.add(createP2WKHInput(300), constraintsRegular) {
|
||||||
t.Fatal("expected add of negatively yielding input to fail")
|
t.Fatal("expected add of negatively yielding input to fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
// A 700 sat input should be accepted into the set, because it yields
|
// A 700 sat input should be accepted into the set, because it yields
|
||||||
// positively.
|
// positively.
|
||||||
if !set.add(createP2WKHInput(700), false) {
|
if !set.add(createP2WKHInput(700), constraintsRegular) {
|
||||||
t.Fatal("expected add of positively yielding input to succeed")
|
t.Fatal("expected add of positively yielding input to succeed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func TestTxInputSet(t *testing.T) {
|
||||||
|
|
||||||
// Add a 1000 sat input. This increases the tx fee to 712 sats. The tx
|
// Add a 1000 sat input. This increases the tx fee to 712 sats. The tx
|
||||||
// output should now be 1000+700 - 712 = 988 sats.
|
// output should now be 1000+700 - 712 = 988 sats.
|
||||||
if !set.add(createP2WKHInput(1000), false) {
|
if !set.add(createP2WKHInput(1000), constraintsRegular) {
|
||||||
t.Fatal("expected add of positively yielding input to succeed")
|
t.Fatal("expected add of positively yielding input to succeed")
|
||||||
}
|
}
|
||||||
if set.outputValue != 988 {
|
if set.outputValue != 988 {
|
||||||
|
@ -70,7 +70,7 @@ func TestTxInputSetFromWallet(t *testing.T) {
|
||||||
|
|
||||||
// Add a 700 sat input to the set. It yields positively, but doesn't
|
// Add a 700 sat input to the set. It yields positively, but doesn't
|
||||||
// reach the output dust limit.
|
// reach the output dust limit.
|
||||||
if !set.add(createP2WKHInput(700), false) {
|
if !set.add(createP2WKHInput(700), constraintsRegular) {
|
||||||
t.Fatal("expected add of positively yielding input to succeed")
|
t.Fatal("expected add of positively yielding input to succeed")
|
||||||
}
|
}
|
||||||
if set.dustLimitReached() {
|
if set.dustLimitReached() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user