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

lightningnetwork / lnd / 12425886916

20 Dec 2024 05:06AM UTC coverage: 49.675% (-7.9%) from 57.578%
12425886916

Pull #9227

github

yyforyongyu
lntest+itest: export `DeriveFundingShim`
Pull Request #9227: Beat [5/4]: fix itests for `blockbeat`

45 of 49 new or added lines in 8 files covered. (91.84%)

26491 existing lines in 430 files now uncovered.

101120 of 203562 relevant lines covered (49.68%)

2.06 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 {
4✔
28

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

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

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

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

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

4✔
52
        // If there is no parent, there is nothing to add.
4✔
53
        if unconfParent == nil {
8✔
54
                return
4✔
55
        }
4✔
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
4✔
61
        if _, ok := w.parents[parentHash]; ok {
4✔
62
                return
×
63
        }
×
64

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

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

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

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

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

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

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

105
// weight gets the estimated weight of the transaction.
106
func (w *weightEstimator) weight() lntypes.WeightUnit {
4✔
107
        return w.estimator.Weight()
4✔
108
}
4✔
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 {
4✔
114
        // Calculate the weight of the transaction.
4✔
115
        weight := w.estimator.Weight()
4✔
116

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

4✔
120
        return fee
4✔
121
}
4✔
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 {
4✔
126
        // Calculate fee and weight for just this tx.
4✔
127
        childWeight := w.estimator.Weight()
4✔
128

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

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

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

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

147
        // Clamp the fee to the max fee rate.
148
        maxFee := w.maxFeeRate.FeeForWeight(childWeight)
4✔
149
        if fee > maxFee {
4✔
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
4✔
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