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

lightningnetwork / lnd / 13986536491

21 Mar 2025 07:12AM UTC coverage: 68.805% (+9.7%) from 59.126%
13986536491

Pull #9627

github

web-flow
Merge 071ed001a into 5d921723b
Pull Request #9627: Sweep inputs even the budget cannot be covered

113 of 159 new or added lines in 6 files covered. (71.07%)

18 existing lines in 4 files now uncovered.

131503 of 191123 relevant lines covered (68.81%)

23375.23 hits per line

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

0.0
/lntest/harness_miner.go
1
package lntest
2

3
import (
4
        "fmt"
5

6
        "github.com/btcsuite/btcd/blockchain"
7
        "github.com/btcsuite/btcd/btcutil"
8
        "github.com/btcsuite/btcd/chaincfg/chainhash"
9
        "github.com/btcsuite/btcd/wire"
10
        "github.com/lightningnetwork/lnd/lntest/miner"
11
        "github.com/lightningnetwork/lnd/lntest/node"
12
        "github.com/lightningnetwork/lnd/lntest/wait"
13
        "github.com/stretchr/testify/require"
14
)
15

16
// Miner returns the miner instance.
17
//
18
// NOTE: Caller should keep in mind that when using this private instance,
19
// certain states won't be managed by the HarnessTest anymore. For instance,
20
// when mining directly, the nodes managed by the HarnessTest can be out of
21
// sync, and the `HarnessTest.CurrentHeight()` won't be accurate.
22
func (h *HarnessTest) Miner() *miner.HarnessMiner {
×
23
        return h.miner
×
24
}
×
25

26
// MineBlocks mines blocks and asserts all active nodes have synced to the
27
// chain. It assumes no txns are expected in the blocks.
28
//
29
// NOTE: Use `MineBlocksAndAssertNumTxes` if you expect txns in the blocks. Use
30
// `MineEmptyBlocks` if you want to make sure that txns stay unconfirmed.
31
func (h *HarnessTest) MineBlocks(num int) {
×
32
        require.Less(h, num, maxBlocksAllowed, "too many blocks to mine")
×
33

×
34
        // Update the harness's current height.
×
35
        defer h.updateCurrentHeight()
×
36

×
37
        // Mine num of blocks.
×
38
        for i := 0; i < num; i++ {
×
39
                block := h.miner.MineBlocks(1)[0]
×
40

×
41
                // Check the block doesn't have any txns except the coinbase.
×
42
                if len(block.Transactions) <= 1 {
×
43
                        // Make sure all the active nodes are synced.
×
44
                        h.AssertActiveNodesSyncedTo(block.BlockHash())
×
45

×
46
                        // Mine the next block.
×
47
                        continue
×
48
                }
49

50
                // Create a detailed description.
51
                desc := fmt.Sprintf("block %v has %d txns:\n",
×
52
                        block.BlockHash(), len(block.Transactions)-1)
×
53

×
54
                // Print all the txns except the coinbase.
×
55
                for _, tx := range block.Transactions {
×
56
                        if blockchain.IsCoinBaseTx(tx) {
×
57
                                continue
×
58
                        }
59

60
                        desc += fmt.Sprintf("%v\n", tx.TxHash())
×
61
                }
62

63
                desc += "Consider using `MineBlocksAndAssertNumTxes` if you " +
×
64
                        "expect txns, or `MineEmptyBlocks` if you want to " +
×
65
                        "keep the txns unconfirmed."
×
66

×
67
                // Raise an error if the block has txns.
×
68
                require.Fail(h, "MineBlocks", desc)
×
69
        }
70
}
71

72
// MineEmptyBlocks mines a given number of empty blocks.
73
//
74
// NOTE: this differs from miner's `MineEmptyBlocks` as it requires the nodes
75
// to be synced.
76
func (h *HarnessTest) MineEmptyBlocks(num int) []*wire.MsgBlock {
×
77
        require.Less(h, num, maxBlocksAllowed, "too many blocks to mine")
×
78

×
79
        // Update the harness's current height.
×
80
        defer h.updateCurrentHeight()
×
81

×
82
        blocks := h.miner.MineEmptyBlocks(num)
×
83

×
84
        // Finally, make sure all the active nodes are synced.
×
85
        h.AssertActiveNodesSynced()
×
86

×
87
        return blocks
×
88
}
×
89

90
// MineBlocksAndAssertNumTxes mines blocks and asserts the number of
91
// transactions are found in the first block. It also asserts all active nodes
92
// have synced to the chain.
93
//
94
// NOTE: this differs from miner's `MineBlocks` as it requires the nodes to be
95
// synced.
96
func (h *HarnessTest) MineBlocksAndAssertNumTxes(num uint32,
97
        numTxs int) []*wire.MsgBlock {
×
98

×
99
        // Update the harness's current height.
×
100
        defer h.updateCurrentHeight()
×
101

×
102
        // If we expect transactions to be included in the blocks we'll mine,
×
103
        // we wait here until they are seen in the miner's mempool.
×
104
        txids := h.AssertNumTxsInMempool(numTxs)
×
105

×
106
        // Mine blocks.
×
107
        blocks := h.miner.MineBlocks(num)
×
108

×
109
        // Assert that all the transactions were included in the first block.
×
110
        for _, txid := range txids {
×
111
                h.miner.AssertTxInBlock(blocks[0], txid)
×
112
        }
×
113

114
        // Make sure the mempool has been updated.
115
        h.miner.AssertTxnsNotInMempool(txids)
×
116

×
117
        // Finally, make sure all the active nodes are synced.
×
118
        bestBlock := blocks[len(blocks)-1]
×
119
        h.AssertActiveNodesSyncedTo(bestBlock.BlockHash())
×
120

×
121
        return blocks
×
122
}
123

124
// ConnectMiner connects the miner with the chain backend in the network.
125
func (h *HarnessTest) ConnectMiner() {
×
126
        err := h.manager.chainBackend.ConnectMiner()
×
127
        require.NoError(h, err, "failed to connect miner")
×
128
}
×
129

130
// DisconnectMiner removes the connection between the miner and the chain
131
// backend in the network.
132
func (h *HarnessTest) DisconnectMiner() {
×
133
        err := h.manager.chainBackend.DisconnectMiner()
×
134
        require.NoError(h, err, "failed to disconnect miner")
×
135
}
×
136

137
// cleanMempool mines blocks till the mempool is empty and asserts all active
138
// nodes have synced to the chain.
139
func (h *HarnessTest) cleanMempool() {
×
140
        _, startHeight := h.GetBestBlock()
×
141

×
142
        // Mining the blocks slow to give `lnd` more time to sync.
×
143
        var bestBlock *wire.MsgBlock
×
144
        err := wait.NoError(func() error {
×
145
                // If mempool is empty, exit.
×
146
                mem := h.miner.GetRawMempool()
×
147
                if len(mem) == 0 {
×
148
                        _, height := h.GetBestBlock()
×
149
                        h.Logf("Mined %d blocks when cleanup the mempool",
×
150
                                height-startHeight)
×
151

×
152
                        return nil
×
153
                }
×
154

155
                // Otherwise mine a block.
156
                blocks := h.miner.MineBlocksSlow(1)
×
157
                bestBlock = blocks[len(blocks)-1]
×
158

×
159
                // Make sure all the active nodes are synced.
×
160
                h.AssertActiveNodesSyncedTo(bestBlock.BlockHash())
×
161

×
162
                return fmt.Errorf("still have %d txes in mempool", len(mem))
×
163
        }, wait.MinerMempoolTimeout)
164
        require.NoError(h, err, "timeout cleaning up mempool")
×
165
}
166

167
// mineTillForceCloseResolved asserts that the number of pending close channels
168
// are zero. Each time it checks, an empty block is mined, followed by a
169
// mempool check to see if there are any sweeping txns. If found, these txns
170
// are then mined to clean up the mempool.
171
func (h *HarnessTest) mineTillForceCloseResolved(hn *node.HarnessNode) {
×
172
        _, startHeight := h.GetBestBlock()
×
173

×
174
        err := wait.NoError(func() error {
×
175
                resp := hn.RPC.PendingChannels()
×
176
                total := len(resp.PendingForceClosingChannels)
×
177
                if total != 0 {
×
178
                        // Mine an empty block first.
×
179
                        h.MineEmptyBlocks(1)
×
180

×
181
                        // If there are new sweeping txns, mine a block to
×
182
                        // confirm it.
×
183
                        mem := h.GetRawMempool()
×
184
                        if len(mem) != 0 {
×
185
                                h.MineBlocksAndAssertNumTxes(1, len(mem))
×
186
                        }
×
187

188
                        return fmt.Errorf("expected num of pending force " +
×
189
                                "close channel to be zero")
×
190
                }
191

192
                _, height := h.GetBestBlock()
×
193
                h.Logf("Mined %d blocks while waiting for force closed "+
×
194
                        "channel to be resolved", height-startHeight)
×
195

×
196
                return nil
×
197
        }, DefaultTimeout)
198

199
        require.NoErrorf(h, err, "%s: assert force close resolved timeout",
×
200
                hn.Name())
×
201
}
202

203
// AssertTxInMempool asserts a given transaction can be found in the mempool.
204
func (h *HarnessTest) AssertTxInMempool(txid chainhash.Hash) *wire.MsgTx {
×
205
        return h.miner.AssertTxInMempool(txid)
×
206
}
×
207

208
// AssertTxNotInMempool asserts a given transaction cannot be found in the
209
// mempool. It assumes the mempool is not empty.
210
//
211
// NOTE: this should be used after `AssertTxInMempool` to ensure the tx has
212
// entered the mempool before. Otherwise it might give false positive and the
213
// tx may enter the mempool after the check.
214
func (h *HarnessTest) AssertTxNotInMempool(txid chainhash.Hash) {
×
215
        h.miner.AssertTxNotInMempool(txid)
×
216
}
×
217

218
// AssertNumTxsInMempool polls until finding the desired number of transactions
219
// in the provided miner's mempool. It will assert if this number is not met
220
// after the given timeout.
221
func (h *HarnessTest) AssertNumTxsInMempool(n int) []chainhash.Hash {
×
222
        return h.miner.AssertNumTxsInMempool(n)
×
223
}
×
224

225
// AssertOutpointInMempool asserts a given outpoint can be found in the mempool.
226
func (h *HarnessTest) AssertOutpointInMempool(op wire.OutPoint) *wire.MsgTx {
×
227
        return h.miner.AssertOutpointInMempool(op)
×
228
}
×
229

230
// AssertTxInBlock asserts that a given txid can be found in the passed block.
231
func (h *HarnessTest) AssertTxInBlock(block *wire.MsgBlock,
232
        txid chainhash.Hash) {
×
233

×
234
        h.miner.AssertTxInBlock(block, txid)
×
235
}
×
236

237
// GetNumTxsFromMempool polls until finding the desired number of transactions
238
// in the miner's mempool and returns the full transactions to the caller.
239
func (h *HarnessTest) GetNumTxsFromMempool(n int) []*wire.MsgTx {
×
240
        return h.miner.GetNumTxsFromMempool(n)
×
241
}
×
242

243
// GetBestBlock makes a RPC request to miner and asserts.
244
func (h *HarnessTest) GetBestBlock() (*chainhash.Hash, int32) {
×
245
        return h.miner.GetBestBlock()
×
246
}
×
247

248
// MineBlockWithTx mines a single block to include the specifies tx only.
249
func (h *HarnessTest) MineBlockWithTx(tx *wire.MsgTx) *wire.MsgBlock {
×
NEW
250
        // Update the harness's current height.
×
NEW
251
        defer h.updateCurrentHeight()
×
NEW
252

×
NEW
253
        block := h.miner.MineBlockWithTx(tx)
×
NEW
254

×
NEW
255
        // Finally, make sure all the active nodes are synced.
×
NEW
256
        h.AssertActiveNodesSyncedTo(block.BlockHash())
×
NEW
257

×
NEW
258
        return block
×
259
}
×
260

261
// ConnectToMiner connects the miner to a temp miner.
262
func (h *HarnessTest) ConnectToMiner(tempMiner *miner.HarnessMiner) {
×
263
        h.miner.ConnectMiner(tempMiner)
×
264
}
×
265

266
// DisconnectFromMiner disconnects the miner from the temp miner.
267
func (h *HarnessTest) DisconnectFromMiner(tempMiner *miner.HarnessMiner) {
×
268
        h.miner.DisconnectMiner(tempMiner)
×
269
}
×
270

271
// GetRawMempool makes a RPC call to the miner's GetRawMempool and
272
// asserts.
273
func (h *HarnessTest) GetRawMempool() []chainhash.Hash {
×
274
        return h.miner.GetRawMempool()
×
275
}
×
276

277
// GetRawTransaction makes a RPC call to the miner's GetRawTransaction and
278
// asserts.
279
func (h *HarnessTest) GetRawTransaction(txid chainhash.Hash) *btcutil.Tx {
×
280
        return h.miner.GetRawTransaction(txid)
×
281
}
×
282

283
// NewMinerAddress creates a new address for the miner and asserts.
284
func (h *HarnessTest) NewMinerAddress() btcutil.Address {
×
285
        return h.miner.NewMinerAddress()
×
286
}
×
287

288
// SpawnTempMiner creates a temp miner and syncs it with the current miner.
289
// Once miners are synced, the temp miner is disconnected from the original
290
// miner and returned.
291
func (h *HarnessTest) SpawnTempMiner() *miner.HarnessMiner {
×
292
        return h.miner.SpawnTempMiner()
×
293
}
×
294

295
// CreateTransaction uses the miner to create a transaction using the given
296
// outputs using the specified fee rate and returns the transaction.
297
func (h *HarnessTest) CreateTransaction(outputs []*wire.TxOut,
298
        feeRate btcutil.Amount) *wire.MsgTx {
×
299

×
300
        return h.miner.CreateTransaction(outputs, feeRate)
×
301
}
×
302

303
// SendOutputsWithoutChange uses the miner to send the given outputs using the
304
// specified fee rate and returns the txid.
305
func (h *HarnessTest) SendOutputsWithoutChange(outputs []*wire.TxOut,
306
        feeRate btcutil.Amount) *chainhash.Hash {
×
307

×
308
        return h.miner.SendOutputsWithoutChange(outputs, feeRate)
×
309
}
×
310

311
// AssertMinerBlockHeightDelta ensures that tempMiner is 'delta' blocks ahead
312
// of miner.
313
func (h *HarnessTest) AssertMinerBlockHeightDelta(
314
        tempMiner *miner.HarnessMiner, delta int32) {
×
315

×
316
        h.miner.AssertMinerBlockHeightDelta(tempMiner, delta)
×
317
}
×
318

319
// SendRawTransaction submits the encoded transaction to the server which will
320
// then relay it to the network.
321
func (h *HarnessTest) SendRawTransaction(tx *wire.MsgTx,
322
        allowHighFees bool) (chainhash.Hash, error) {
×
323

×
324
        txid, err := h.miner.Client.SendRawTransaction(tx, allowHighFees)
×
325
        require.NoError(h, err)
×
326

×
327
        return *txid, nil
×
328
}
×
329

330
// CurrentHeight returns the current block height.
331
func (h *HarnessTest) CurrentHeight() uint32 {
×
332
        return h.currentHeight
×
333
}
×
334

335
// updateCurrentHeight set the harness's current height to the best known
336
// height.
337
func (h *HarnessTest) updateCurrentHeight() {
×
338
        _, height := h.GetBestBlock()
×
339
        h.currentHeight = uint32(height)
×
340
}
×
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