mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
138 lines
5.5 KiB
Go
138 lines
5.5 KiB
Go
package contractcourt
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
|
)
|
|
|
|
const (
|
|
// MinBudgetValue is the minimal budget that we allow when configuring
|
|
// the budget used in sweeping outputs. The actual budget can be lower
|
|
// if the user decides to NOT set this value.
|
|
//
|
|
// NOTE: This value is chosen so the linear fee function can increase
|
|
// at least 1 sat/kw per block.
|
|
MinBudgetValue btcutil.Amount = 1008
|
|
|
|
// MinBudgetRatio is the minimal ratio that we allow when configuring
|
|
// the budget ratio used in sweeping outputs.
|
|
MinBudgetRatio = 0.001
|
|
|
|
// DefaultBudgetRatio defines a default budget ratio to be used when
|
|
// sweeping inputs. This is a large value, which is fine as the final
|
|
// fee rate is capped at the max fee rate configured.
|
|
DefaultBudgetRatio = 0.5
|
|
)
|
|
|
|
// BudgetConfig is a struct that holds the configuration when offering outputs
|
|
// to the sweeper.
|
|
//
|
|
//nolint:lll
|
|
type BudgetConfig struct {
|
|
ToLocal btcutil.Amount `long:"tolocal" description:"The amount in satoshis to allocate as the budget to pay fees when sweeping the to_local output. If set, the budget calculated using the ratio (if set) will be capped at this value."`
|
|
ToLocalRatio float64 `long:"tolocalratio" description:"The ratio of the value in to_local output to allocate as the budget to pay fees when sweeping it."`
|
|
|
|
AnchorCPFP btcutil.Amount `long:"anchorcpfp" description:"The amount in satoshis to allocate as the budget to pay fees when CPFPing a force close tx using the anchor output. If set, the budget calculated using the ratio (if set) will be capped at this value."`
|
|
AnchorCPFPRatio float64 `long:"anchorcpfpratio" description:"The ratio of a special value to allocate as the budget to pay fees when CPFPing a force close tx using the anchor output. The special value is the sum of all time-sensitive HTLCs on this commitment subtracted by their budgets."`
|
|
|
|
DeadlineHTLC btcutil.Amount `long:"deadlinehtlc" description:"The amount in satoshis to allocate as the budget to pay fees when sweeping a time-sensitive (first-level) HTLC. If set, the budget calculated using the ratio (if set) will be capped at this value."`
|
|
DeadlineHTLCRatio float64 `long:"deadlinehtlcratio" description:"The ratio of the value in a time-sensitive (first-level) HTLC to allocate as the budget to pay fees when sweeping it."`
|
|
|
|
NoDeadlineHTLC btcutil.Amount `long:"nodeadlinehtlc" description:"The amount in satoshis to allocate as the budget to pay fees when sweeping a non-time-sensitive (second-level) HTLC. If set, the budget calculated using the ratio (if set) will be capped at this value."`
|
|
NoDeadlineHTLCRatio float64 `long:"nodeadlinehtlcratio" description:"The ratio of the value in a non-time-sensitive (second-level) HTLC to allocate as the budget to pay fees when sweeping it."`
|
|
}
|
|
|
|
// Validate checks the budget configuration for any invalid values.
|
|
func (b *BudgetConfig) Validate() error {
|
|
// Exit early if no budget config is set.
|
|
if b == nil {
|
|
return fmt.Errorf("no budget config set")
|
|
}
|
|
|
|
// Sanity check all fields.
|
|
if b.ToLocal != 0 && b.ToLocal < MinBudgetValue {
|
|
return fmt.Errorf("tolocal must be at least %v",
|
|
MinBudgetValue)
|
|
}
|
|
if b.ToLocalRatio != 0 && b.ToLocalRatio < MinBudgetRatio {
|
|
return fmt.Errorf("tolocalratio must be at least %v",
|
|
MinBudgetRatio)
|
|
}
|
|
|
|
if b.AnchorCPFP != 0 && b.AnchorCPFP < MinBudgetValue {
|
|
return fmt.Errorf("anchorcpfp must be at least %v",
|
|
MinBudgetValue)
|
|
}
|
|
if b.AnchorCPFPRatio != 0 && b.AnchorCPFPRatio < MinBudgetRatio {
|
|
return fmt.Errorf("anchorcpfpratio must be at least %v",
|
|
MinBudgetRatio)
|
|
}
|
|
|
|
if b.DeadlineHTLC != 0 && b.DeadlineHTLC < MinBudgetValue {
|
|
return fmt.Errorf("deadlinehtlc must be at least %v",
|
|
MinBudgetValue)
|
|
}
|
|
if b.DeadlineHTLCRatio != 0 && b.DeadlineHTLCRatio < MinBudgetRatio {
|
|
return fmt.Errorf("deadlinehtlcratio must be at least %v",
|
|
MinBudgetRatio)
|
|
}
|
|
|
|
if b.NoDeadlineHTLC != 0 && b.NoDeadlineHTLC < MinBudgetValue {
|
|
return fmt.Errorf("nodeadlinehtlc must be at least %v",
|
|
MinBudgetValue)
|
|
}
|
|
if b.NoDeadlineHTLCRatio != 0 &&
|
|
b.NoDeadlineHTLCRatio < MinBudgetRatio {
|
|
|
|
return fmt.Errorf("nodeadlinehtlcratio must be at least %v",
|
|
MinBudgetRatio)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// String returns a human-readable description of the budget configuration.
|
|
func (b *BudgetConfig) String() string {
|
|
return fmt.Sprintf("tolocal=%v tolocalratio=%v anchorcpfp=%v "+
|
|
"anchorcpfpratio=%v deadlinehtlc=%v deadlinehtlcratio=%v "+
|
|
"nodeadlinehtlc=%v nodeadlinehtlcratio=%v",
|
|
b.ToLocal, b.ToLocalRatio, b.AnchorCPFP, b.AnchorCPFPRatio,
|
|
b.DeadlineHTLC, b.DeadlineHTLCRatio, b.NoDeadlineHTLC,
|
|
b.NoDeadlineHTLCRatio)
|
|
}
|
|
|
|
// DefaultSweeperConfig returns the default configuration for the sweeper.
|
|
func DefaultBudgetConfig() *BudgetConfig {
|
|
return &BudgetConfig{
|
|
ToLocalRatio: DefaultBudgetRatio,
|
|
AnchorCPFPRatio: DefaultBudgetRatio,
|
|
DeadlineHTLCRatio: 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
|
|
}
|