mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 01:43:16 +01:00
contractcourt: specify deadline and budget for commit sweep
This commit is contained in:
parent
aa44197f88
commit
01fd4e5642
@ -13,17 +13,12 @@ import (
|
|||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/fn"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/sweep"
|
"github.com/lightningnetwork/lnd/sweep"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// commitOutputConfTarget is the default confirmation target we'll use
|
|
||||||
// for sweeps of commit outputs that belong to us.
|
|
||||||
commitOutputConfTarget = 6
|
|
||||||
)
|
|
||||||
|
|
||||||
// commitSweepResolver is a resolver that will attempt to sweep the commitment
|
// commitSweepResolver is a resolver that will attempt to sweep the commitment
|
||||||
// output paying to us, in the case that the remote party broadcasts their
|
// output paying to us, in the case that the remote party broadcasts their
|
||||||
// version of the commitment transaction. We can sweep this output immediately,
|
// version of the commitment transaction. We can sweep this output immediately,
|
||||||
@ -347,12 +342,23 @@ func (c *commitSweepResolver) Resolve() (ContractResolver, error) {
|
|||||||
// TODO(roasbeef): instead of ading ctrl block to the sign desc, make
|
// TODO(roasbeef): instead of ading ctrl block to the sign desc, make
|
||||||
// new input type, have sweeper set it?
|
// new input type, have sweeper set it?
|
||||||
|
|
||||||
// With our input constructed, we'll now offer it to the
|
// Calculate the budget for the sweeping this input.
|
||||||
// sweeper.
|
budget := calculateBudget(
|
||||||
c.log.Infof("sweeping commit output")
|
btcutil.Amount(inp.SignDesc().Output.Value),
|
||||||
|
c.Budget.ToLocalRatio, c.Budget.ToLocal,
|
||||||
|
)
|
||||||
|
c.log.Infof("Sweeping commit output using budget=%v", budget)
|
||||||
|
|
||||||
feePref := sweep.FeeEstimateInfo{ConfTarget: commitOutputConfTarget}
|
// With our input constructed, we'll now offer it to the sweeper.
|
||||||
resultChan, err := c.Sweeper.SweepInput(inp, sweep.Params{Fee: feePref})
|
resultChan, err := c.Sweeper.SweepInput(
|
||||||
|
inp, sweep.Params{
|
||||||
|
Budget: budget,
|
||||||
|
|
||||||
|
// Specify a nil deadline here as there's no time
|
||||||
|
// pressure.
|
||||||
|
DeadlineHeight: fn.None[int32](),
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.log.Errorf("unable to sweep input: %v", err)
|
c.log.Errorf("unable to sweep input: %v", err)
|
||||||
|
|
||||||
|
@ -129,16 +129,19 @@ func (s *mockSweeper) SweepInput(input input.Input, params sweep.Params) (
|
|||||||
|
|
||||||
s.sweptInputs <- input
|
s.sweptInputs <- input
|
||||||
|
|
||||||
// TODO(yy): use `mock.Mock` to avoid the conversion.
|
// TODO(yy): replace mockSweeper with `mock.Mock`.
|
||||||
|
if params.Fee != nil {
|
||||||
fee, ok := params.Fee.(sweep.FeeEstimateInfo)
|
fee, ok := params.Fee.(sweep.FeeEstimateInfo)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected fee type: %T", params.Fee)
|
return nil, fmt.Errorf("unexpected fee type: %T",
|
||||||
|
params.Fee)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the deadlines used if it's set.
|
// Update the deadlines used if it's set.
|
||||||
if fee.ConfTarget != 0 {
|
if fee.ConfTarget != 0 {
|
||||||
s.deadlines = append(s.deadlines, int(fee.ConfTarget))
|
s.deadlines = append(s.deadlines, int(fee.ConfTarget))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result := make(chan sweep.Result, 1)
|
result := make(chan sweep.Result, 1)
|
||||||
result <- sweep.Result{
|
result <- sweep.Result{
|
||||||
|
@ -111,3 +111,27 @@ func DefaultBudgetConfig() *BudgetConfig {
|
|||||||
NoDeadlineHTLCRatio: DefaultBudgetRatio,
|
NoDeadlineHTLCRatio: DefaultBudgetRatio,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calculateBudget takes an output value, a configured ratio and budget value,
|
||||||
|
// and returns the budget to use for sweeping the output. If the budget value
|
||||||
|
// is set, it will be used as cap.
|
||||||
|
func calculateBudget(value btcutil.Amount, ratio float64,
|
||||||
|
max btcutil.Amount) btcutil.Amount {
|
||||||
|
|
||||||
|
// If ratio is not set, using the default value.
|
||||||
|
if ratio == 0 {
|
||||||
|
ratio = DefaultBudgetRatio
|
||||||
|
}
|
||||||
|
|
||||||
|
budget := value.MulF64(ratio)
|
||||||
|
|
||||||
|
log.Tracef("Calculated budget=%v using value=%v, ratio=%v, cap=%v",
|
||||||
|
budget, value, ratio, max)
|
||||||
|
|
||||||
|
if max != 0 && budget > max {
|
||||||
|
log.Debugf("Calculated budget=%v is capped at %v", budget, max)
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
|
||||||
|
return budget
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ package contractcourt
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -81,3 +82,51 @@ func TestBudgetConfigValidate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestCalculateBudget checks that the budget calculation works as expected.
|
||||||
|
func TestCalculateBudget(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
value btcutil.Amount
|
||||||
|
ratio float64
|
||||||
|
max btcutil.Amount
|
||||||
|
expected btcutil.Amount
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// When the ratio is not specified, the default 0.5
|
||||||
|
// should be used.
|
||||||
|
name: "use default ratio",
|
||||||
|
value: btcutil.Amount(1000),
|
||||||
|
ratio: 0,
|
||||||
|
max: 0,
|
||||||
|
expected: btcutil.Amount(500),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// When the ratio is specified, the default is not
|
||||||
|
// used.
|
||||||
|
name: "use specified ratio",
|
||||||
|
value: btcutil.Amount(1000),
|
||||||
|
ratio: 0.1,
|
||||||
|
max: 0,
|
||||||
|
expected: btcutil.Amount(100),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// When the max is specified, the budget should be
|
||||||
|
// capped at that value.
|
||||||
|
name: "budget capped at max",
|
||||||
|
value: btcutil.Amount(1000),
|
||||||
|
ratio: 0.1,
|
||||||
|
max: btcutil.Amount(1),
|
||||||
|
expected: btcutil.Amount(1),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
budget := calculateBudget(tc.value, tc.ratio, tc.max)
|
||||||
|
require.Equal(t, tc.expected, budget)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user