• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 11170835610

03 Oct 2024 10:41PM UTC coverage: 49.188% (-9.6%) from 58.738%
11170835610

push

github

web-flow
Merge pull request #9154 from ziggie1984/master

multi: bump btcd version.

3 of 6 new or added lines in 6 files covered. (50.0%)

26110 existing lines in 428 files now uncovered.

97359 of 197934 relevant lines covered (49.19%)

1.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.16
/sweep/weight_estimator.go
1
package sweep
2

3
import (
4
        "github.com/btcsuite/btcd/btcutil"
5
        "github.com/btcsuite/btcd/chaincfg/chainhash"
6
        "github.com/btcsuite/btcd/wire"
7
        "github.com/lightningnetwork/lnd/input"
8
        "github.com/lightningnetwork/lnd/lntypes"
9
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
10
)
11

12
// weightEstimator wraps a standard weight estimator instance and adds to that
13
// support for child-pays-for-parent.
14
type weightEstimator struct {
15
        estimator     input.TxWeightEstimator
16
        feeRate       chainfee.SatPerKWeight
17
        parents       map[chainhash.Hash]struct{}
18
        parentsFee    btcutil.Amount
19
        parentsWeight lntypes.WeightUnit
20

21
        // maxFeeRate is the max allowed fee rate configured by the user.
22
        maxFeeRate chainfee.SatPerKWeight
23
}
24

25
// newWeightEstimator instantiates a new sweeper weight estimator.
26
func newWeightEstimator(
27
        feeRate, maxFeeRate chainfee.SatPerKWeight) *weightEstimator {
2✔
28

2✔
29
        return &weightEstimator{
2✔
30
                feeRate:    feeRate,
2✔
31
                maxFeeRate: maxFeeRate,
2✔
32
                parents:    make(map[chainhash.Hash]struct{}),
2✔
33
        }
2✔
34
}
2✔
35

36
// add adds the weight of the given input to the weight estimate.
37
func (w *weightEstimator) add(inp input.Input) error {
2✔
38
        // If there is a parent tx, add the parent's fee and weight.
2✔
39
        w.tryAddParent(inp)
2✔
40

2✔
41
        wt := inp.WitnessType()
2✔
42

2✔
43
        return wt.AddWeightEstimation(&w.estimator)
2✔
44
}
2✔
45

46
// tryAddParent examines the input and updates parent tx totals if required for
47
// cpfp.
48
func (w *weightEstimator) tryAddParent(inp input.Input) {
2✔
49
        // Get unconfirmed parent info from the input.
2✔
50
        unconfParent := inp.UnconfParent()
2✔
51

2✔
52
        // If there is no parent, there is nothing to add.
2✔
53
        if unconfParent == nil {
4✔
54
                return
2✔
55
        }
2✔
56

57
        // If we've already accounted for the parent tx, don't do it
58
        // again. This can happens when two outputs of the parent tx are
59
        // included in the same sweep tx.
60
        parentHash := inp.OutPoint().Hash
2✔
61
        if _, ok := w.parents[parentHash]; ok {
2✔
62
                return
×
63
        }
×
64

65
        // Calculate parent fee rate.
66
        parentFeeRate := chainfee.SatPerKWeight(unconfParent.Fee) * 1000 /
2✔
67
                chainfee.SatPerKWeight(unconfParent.Weight)
2✔
68

2✔
69
        // Ignore parents that pay at least the fee rate of this transaction.
2✔
70
        // Parent pays for child is not happening.
2✔
71
        if parentFeeRate >= w.feeRate {
4✔
72
                return
2✔
73
        }
2✔
74

75
        // Include parent.
76
        w.parents[parentHash] = struct{}{}
2✔
77
        w.parentsFee += unconfParent.Fee
2✔
78
        w.parentsWeight += unconfParent.Weight
2✔
79
}
80

81
// addP2WKHOutput updates the weight estimate to account for an additional
82
// native P2WKH output.
83
func (w *weightEstimator) addP2WKHOutput() {
2✔
84
        w.estimator.AddP2WKHOutput()
2✔
85
}
2✔
86

87
// addP2TROutput updates the weight estimate to account for an additional native
88
// SegWit v1 P2TR output.
89
func (w *weightEstimator) addP2TROutput() {
2✔
90
        w.estimator.AddP2TROutput()
2✔
91
}
2✔
92

93
// addP2WSHOutput updates the weight estimate to account for an additional
94
// segwit v0 P2WSH output.
95
func (w *weightEstimator) addP2WSHOutput() {
2✔
96
        w.estimator.AddP2WSHOutput()
2✔
97
}
2✔
98

99
// addOutput updates the weight estimate to account for the known
100
// output given.
101
func (w *weightEstimator) addOutput(txOut *wire.TxOut) {
2✔
102
        w.estimator.AddTxOutput(txOut)
2✔
103
}
2✔
104

105
// weight gets the estimated weight of the transaction.
106
func (w *weightEstimator) weight() lntypes.WeightUnit {
2✔
107
        return w.estimator.Weight()
2✔
108
}
2✔
109

110
// fee returns the tx fee to use for the aggregated inputs and outputs, which
111
// is different from feeWithParent as it doesn't take into account unconfirmed
112
// parent transactions.
113
func (w *weightEstimator) fee() btcutil.Amount {
2✔
114
        // Calculate the weight of the transaction.
2✔
115
        weight := w.estimator.Weight()
2✔
116

2✔
117
        // Calculate the fee.
2✔
118
        fee := w.feeRate.FeeForWeight(weight)
2✔
119

2✔
120
        return fee
2✔
121
}
2✔
122

123
// feeWithParent returns the tx fee to use for the aggregated inputs and
124
// outputs, taking into account unconfirmed parent transactions (cpfp).
125
func (w *weightEstimator) feeWithParent() btcutil.Amount {
2✔
126
        // Calculate fee and weight for just this tx.
2✔
127
        childWeight := w.estimator.Weight()
2✔
128

2✔
129
        // Add combined weight of unconfirmed parent txes.
2✔
130
        totalWeight := childWeight + w.parentsWeight
2✔
131

2✔
132
        // Subtract fee already paid by parents.
2✔
133
        fee := w.feeRate.FeeForWeight(totalWeight) - w.parentsFee
2✔
134

2✔
135
        // Clamp the fee to what would be required if no parent txes were paid
2✔
136
        // for. This is to make sure no rounding errors can get us into trouble.
2✔
137
        childFee := w.feeRate.FeeForWeight(childWeight)
2✔
138
        if childFee > fee {
2✔
139
                fee = childFee
×
140
        }
×
141

142
        // Exit early if maxFeeRate is not set.
143
        if w.maxFeeRate == 0 {
2✔
UNCOV
144
                return fee
×
UNCOV
145
        }
×
146

147
        // Clamp the fee to the max fee rate.
148
        maxFee := w.maxFeeRate.FeeForWeight(childWeight)
2✔
149
        if fee > maxFee {
2✔
UNCOV
150
                // Calculate the effective fee rate for logging.
×
UNCOV
151
                childFeeRate := chainfee.SatPerKWeight(
×
UNCOV
152
                        fee * 1000 / btcutil.Amount(childWeight),
×
UNCOV
153
                )
×
UNCOV
154
                log.Warnf("Child fee rate %v exceeds max allowed fee rate %v, "+
×
UNCOV
155
                        "returning fee %v instead of %v", childFeeRate,
×
UNCOV
156
                        w.maxFeeRate, maxFee, fee)
×
UNCOV
157

×
UNCOV
158
                fee = maxFee
×
UNCOV
159
        }
×
160

161
        return fee
2✔
162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc