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

lightningnetwork / lnd / 15205630088

23 May 2025 08:14AM UTC coverage: 57.45% (-11.5%) from 68.996%
15205630088

Pull #9784

github

web-flow
Merge f8b9f36a3 into c52a6ddeb
Pull Request #9784: [wip] lnwallet+walletrpc: add SubmitPackage and related RPC call

47 of 96 new or added lines in 5 files covered. (48.96%)

30087 existing lines in 459 files now uncovered.

95586 of 166380 relevant lines covered (57.45%)

0.61 hits per line

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

0.0
/lnwallet/mock.go
1
package lnwallet
2

3
import (
4
        "encoding/hex"
5
        "sync/atomic"
6
        "time"
7

8
        "github.com/btcsuite/btcd/btcec/v2"
9
        "github.com/btcsuite/btcd/btcjson"
10
        "github.com/btcsuite/btcd/btcutil"
11
        "github.com/btcsuite/btcd/btcutil/hdkeychain"
12
        "github.com/btcsuite/btcd/btcutil/psbt"
13
        "github.com/btcsuite/btcd/chaincfg"
14
        "github.com/btcsuite/btcd/chaincfg/chainhash"
15
        "github.com/btcsuite/btcd/wire"
16
        "github.com/btcsuite/btcwallet/waddrmgr"
17
        base "github.com/btcsuite/btcwallet/wallet"
18
        "github.com/btcsuite/btcwallet/wallet/txauthor"
19
        "github.com/btcsuite/btcwallet/wtxmgr"
20
        "github.com/lightningnetwork/lnd/chainntnfs"
21
        "github.com/lightningnetwork/lnd/channeldb"
22
        "github.com/lightningnetwork/lnd/fn/v2"
23
        "github.com/lightningnetwork/lnd/lntypes"
24
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
25
        "github.com/lightningnetwork/lnd/tlv"
26
        "github.com/stretchr/testify/mock"
27
)
28

29
var (
30
        CoinPkScript, _ = hex.DecodeString(
31
                "001431df1bde03c074d0cf21ea2529427e1499b8f1de",
32
        )
33
)
34

35
// mockWalletController is a mock implementation of the WalletController
36
// interface. It let's us mock the interaction with the bitcoin network.
37
type mockWalletController struct {
38
        RootKey               *btcec.PrivateKey
39
        PublishedTransactions chan *wire.MsgTx
40
        index                 uint32
41
        Utxos                 []*Utxo
42
}
43

44
// A compile time check to ensure that mockWalletController implements the
45
// WalletController.
46
var _ WalletController = (*mockWalletController)(nil)
47

48
// BackEnd returns "mock" to signify a mock wallet controller.
49
func (w *mockWalletController) BackEnd() string {
×
50
        return "mock"
×
51
}
×
52

53
// FetchOutpointInfo will be called to get info about the inputs to the funding
54
// transaction.
55
func (w *mockWalletController) FetchOutpointInfo(
56
        prevOut *wire.OutPoint) (*Utxo, error) {
×
57

×
58
        utxo := &Utxo{
×
59
                AddressType:   WitnessPubKey,
×
60
                Value:         10 * btcutil.SatoshiPerBitcoin,
×
61
                PkScript:      []byte("dummy"),
×
62
                Confirmations: 1,
×
63
                OutPoint:      *prevOut,
×
64
        }
×
65

×
66
        return utxo, nil
×
67
}
×
68

69
// ScriptForOutput returns the address, witness program and redeem script for a
70
// given UTXO. An error is returned if the UTXO does not belong to our wallet or
71
// it is not a managed pubKey address.
72
func (w *mockWalletController) ScriptForOutput(*wire.TxOut) (
73
        waddrmgr.ManagedPubKeyAddress, []byte, []byte, error) {
×
74

×
75
        return nil, nil, nil, nil
×
76
}
×
77

78
// ConfirmedBalance currently returns dummy values.
79
func (w *mockWalletController) ConfirmedBalance(int32, string) (btcutil.Amount,
80
        error) {
×
81

×
82
        return 0, nil
×
83
}
×
84

85
// NewAddress is called to get new addresses for delivery, change etc.
86
func (w *mockWalletController) NewAddress(AddressType, bool,
87
        string) (btcutil.Address, error) {
×
88

×
89
        addr, _ := btcutil.NewAddressPubKey(
×
90
                w.RootKey.PubKey().SerializeCompressed(),
×
91
                &chaincfg.MainNetParams,
×
92
        )
×
93

×
94
        return addr, nil
×
95
}
×
96

97
// LastUnusedAddress currently returns dummy values.
98
func (w *mockWalletController) LastUnusedAddress(AddressType,
99
        string) (btcutil.Address, error) {
×
100

×
101
        return nil, nil
×
102
}
×
103

104
// IsOurAddress currently returns a dummy value.
105
func (w *mockWalletController) IsOurAddress(btcutil.Address) bool {
×
106
        return false
×
107
}
×
108

109
// AddressInfo currently returns a dummy value.
110
func (w *mockWalletController) AddressInfo(
111
        btcutil.Address) (waddrmgr.ManagedAddress, error) {
×
112

×
113
        return nil, nil
×
114
}
×
115

116
// ListAccounts currently returns a dummy value.
117
func (w *mockWalletController) ListAccounts(string,
118
        *waddrmgr.KeyScope) ([]*waddrmgr.AccountProperties, error) {
×
119

×
120
        return nil, nil
×
121
}
×
122

123
// RequiredReserve currently returns a dummy value.
124
func (w *mockWalletController) RequiredReserve(uint32) btcutil.Amount {
×
125
        return 0
×
126
}
×
127

128
// ListAddresses currently returns a dummy value.
129
func (w *mockWalletController) ListAddresses(string,
130
        bool) (AccountAddressMap, error) {
×
131

×
132
        return nil, nil
×
133
}
×
134

135
// ImportAccount currently returns a dummy value.
136
func (w *mockWalletController) ImportAccount(string, *hdkeychain.ExtendedKey,
137
        uint32, *waddrmgr.AddressType, bool) (*waddrmgr.AccountProperties,
138
        []btcutil.Address, []btcutil.Address, error) {
×
139

×
140
        return nil, nil, nil, nil
×
141
}
×
142

143
// ImportPublicKey currently returns a dummy value.
144
func (w *mockWalletController) ImportPublicKey(*btcec.PublicKey,
145
        waddrmgr.AddressType) error {
×
146

×
147
        return nil
×
148
}
×
149

150
// ImportTaprootScript currently returns a dummy value.
151
func (w *mockWalletController) ImportTaprootScript(waddrmgr.KeyScope,
152
        *waddrmgr.Tapscript) (waddrmgr.ManagedAddress, error) {
×
153

×
154
        return nil, nil
×
155
}
×
156

157
// SendOutputs currently returns dummy values.
158
func (w *mockWalletController) SendOutputs(fn.Set[wire.OutPoint], []*wire.TxOut,
159
        chainfee.SatPerKWeight, int32, string,
160
        base.CoinSelectionStrategy) (*wire.MsgTx, error) {
×
161

×
162
        return nil, nil
×
163
}
×
164

165
// CreateSimpleTx currently returns dummy values.
166
func (w *mockWalletController) CreateSimpleTx(fn.Set[wire.OutPoint],
167
        []*wire.TxOut, chainfee.SatPerKWeight, int32,
168
        base.CoinSelectionStrategy, bool) (*txauthor.AuthoredTx, error) {
×
169

×
170
        return nil, nil
×
171
}
×
172

173
// ListUnspentWitness is called by the wallet when doing coin selection. We just
174
// need one unspent for the funding transaction.
175
func (w *mockWalletController) ListUnspentWitness(int32, int32,
176
        string) ([]*Utxo, error) {
×
177

×
178
        // If the mock already has a list of utxos, return it.
×
179
        if w.Utxos != nil {
×
180
                return w.Utxos, nil
×
181
        }
×
182

183
        // Otherwise create one to return.
184
        utxo := &Utxo{
×
185
                AddressType: WitnessPubKey,
×
186
                Value:       btcutil.Amount(10 * btcutil.SatoshiPerBitcoin),
×
187
                PkScript:    CoinPkScript,
×
188
                OutPoint: wire.OutPoint{
×
189
                        Hash:  chainhash.Hash{},
×
190
                        Index: w.index,
×
191
                },
×
192
        }
×
193
        atomic.AddUint32(&w.index, 1)
×
194
        var ret []*Utxo
×
195
        ret = append(ret, utxo)
×
196

×
197
        return ret, nil
×
198
}
199

200
// ListTransactionDetails currently returns dummy values.
201
func (w *mockWalletController) ListTransactionDetails(int32, int32,
202
        string, uint32, uint32) ([]*TransactionDetail, uint64, uint64, error) {
×
203

×
204
        return nil, 0, 0, nil
×
205
}
×
206

207
// LeaseOutput returns the current time and a nil error.
208
func (w *mockWalletController) LeaseOutput(wtxmgr.LockID, wire.OutPoint,
209
        time.Duration) (time.Time, error) {
×
210

×
211
        return time.Now(), nil
×
212
}
×
213

214
// ReleaseOutput currently does nothing.
215
func (w *mockWalletController) ReleaseOutput(wtxmgr.LockID,
216
        wire.OutPoint) error {
×
217

×
218
        return nil
×
219
}
×
220

221
func (w *mockWalletController) ListLeasedOutputs() (
222
        []*base.ListLeasedOutputResult, error) {
×
223

×
224
        return nil, nil
×
225
}
×
226

227
// FundPsbt currently does nothing.
228
func (w *mockWalletController) FundPsbt(*psbt.Packet, int32,
229
        chainfee.SatPerKWeight, string, *waddrmgr.KeyScope,
230
        base.CoinSelectionStrategy, func(utxo wtxmgr.Credit) bool) (int32,
231
        error) {
×
232

×
233
        return 0, nil
×
234
}
×
235

236
// SignPsbt currently does nothing.
237
func (w *mockWalletController) SignPsbt(*psbt.Packet) ([]uint32, error) {
×
238
        return nil, nil
×
239
}
×
240

241
// FinalizePsbt currently does nothing.
242
func (w *mockWalletController) FinalizePsbt(_ *psbt.Packet, _ string) error {
×
243
        return nil
×
244
}
×
245

246
// DecorateInputs currently does nothing.
247
func (w *mockWalletController) DecorateInputs(*psbt.Packet, bool) error {
×
248
        return nil
×
249
}
×
250

251
// PublishTransaction sends a transaction to the PublishedTransactions chan.
252
func (w *mockWalletController) PublishTransaction(tx *wire.MsgTx,
UNCOV
253
        _ string) error {
×
UNCOV
254

×
UNCOV
255
        w.PublishedTransactions <- tx
×
UNCOV
256
        return nil
×
UNCOV
257
}
×
258

259
// GetTransactionDetails currently does nothing.
260
func (w *mockWalletController) GetTransactionDetails(*chainhash.Hash) (
261
        *TransactionDetail, error) {
×
262

×
263
        return nil, nil
×
264
}
×
265

266
// LabelTransaction currently does nothing.
267
func (w *mockWalletController) LabelTransaction(chainhash.Hash, string,
268
        bool) error {
×
269

×
270
        return nil
×
271
}
×
272

273
// SubscribeTransactions currently does nothing.
274
func (w *mockWalletController) SubscribeTransactions() (TransactionSubscription,
275
        error) {
×
276

×
277
        return nil, nil
×
278
}
×
279

280
// IsSynced currently returns dummy values.
281
func (w *mockWalletController) IsSynced() (bool, int64, error) {
×
282
        return true, int64(0), nil
×
283
}
×
284

285
// GetRecoveryInfo currently returns dummy values.
286
func (w *mockWalletController) GetRecoveryInfo() (bool, float64, error) {
×
287
        return true, float64(1), nil
×
288
}
×
289

290
// Start currently does nothing.
UNCOV
291
func (w *mockWalletController) Start() error {
×
UNCOV
292
        return nil
×
UNCOV
293
}
×
294

295
// Stop currently does nothing.
UNCOV
296
func (w *mockWalletController) Stop() error {
×
UNCOV
297
        return nil
×
UNCOV
298
}
×
299

300
func (w *mockWalletController) FetchTx(chainhash.Hash) (*wire.MsgTx, error) {
×
301
        return nil, nil
×
302
}
×
303

304
func (w *mockWalletController) RemoveDescendants(*wire.MsgTx) error {
×
305
        return nil
×
306
}
×
307

308
// FetchDerivationInfo queries for the wallet's knowledge of the passed
309
// pkScript and constructs the derivation info and returns it.
310
func (w *mockWalletController) FetchDerivationInfo(
311
        pkScript []byte) (*psbt.Bip32Derivation, error) {
×
312

×
313
        return nil, nil
×
314
}
×
315

316
func (w *mockWalletController) CheckMempoolAcceptance(tx *wire.MsgTx) error {
×
317
        return nil
×
318
}
×
319

320
func (w *mockWalletController) SubmitPackage(parents []*wire.MsgTx,
321
        child *wire.MsgTx, maxFeeRate chainfee.SatPerKWeight) (
NEW
322
        *btcjson.SubmitPackageResult, error) {
×
NEW
323

×
NEW
324
        return nil, nil
×
NEW
325
}
×
326

327
// mockChainNotifier is a mock implementation of the ChainNotifier interface.
328
type mockChainNotifier struct {
329
        SpendChan chan *chainntnfs.SpendDetail
330
        EpochChan chan *chainntnfs.BlockEpoch
331
        ConfChan  chan *chainntnfs.TxConfirmation
332
}
333

334
// RegisterConfirmationsNtfn returns a ConfirmationEvent that contains a channel
335
// that the tx confirmation will go over.
336
func (c *mockChainNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
337
        pkScript []byte, numConfs, heightHint uint32,
338
        opts ...chainntnfs.NotifierOption) (*chainntnfs.ConfirmationEvent,
UNCOV
339
        error) {
×
UNCOV
340

×
UNCOV
341
        return &chainntnfs.ConfirmationEvent{
×
UNCOV
342
                Confirmed: c.ConfChan,
×
UNCOV
343
                Cancel:    func() {},
×
344
        }, nil
345
}
346

347
// RegisterSpendNtfn returns a SpendEvent that contains a channel that the spend
348
// details will go over.
349
func (c *mockChainNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
350
        pkScript []byte, heightHint uint32) (*chainntnfs.SpendEvent, error) {
×
351

×
352
        return &chainntnfs.SpendEvent{
×
353
                Spend:  c.SpendChan,
×
354
                Cancel: func() {},
×
355
        }, nil
356
}
357

358
// RegisterBlockEpochNtfn returns a BlockEpochEvent that contains a channel that
359
// block epochs will go over.
360
func (c *mockChainNotifier) RegisterBlockEpochNtfn(
361
        blockEpoch *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent,
362
        error) {
×
363

×
364
        return &chainntnfs.BlockEpochEvent{
×
365
                Epochs: c.EpochChan,
×
366
                Cancel: func() {},
×
367
        }, nil
368
}
369

370
// Start currently returns a dummy value.
371
func (c *mockChainNotifier) Start() error {
×
372
        return nil
×
373
}
×
374

375
// Started currently returns a dummy value.
376
func (c *mockChainNotifier) Started() bool {
×
377
        return true
×
378
}
×
379

380
// Stop currently returns a dummy value.
381
func (c *mockChainNotifier) Stop() error {
×
382
        return nil
×
383
}
×
384

385
type mockChainIO struct{}
386

UNCOV
387
func (*mockChainIO) GetBestBlock() (*chainhash.Hash, int32, error) {
×
UNCOV
388
        return nil, 0, nil
×
UNCOV
389
}
×
390

391
func (*mockChainIO) GetUtxo(op *wire.OutPoint, _ []byte,
392
        heightHint uint32, _ <-chan struct{}) (*wire.TxOut, error) {
×
393

×
394
        return nil, nil
×
395
}
×
396

397
func (*mockChainIO) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
×
398
        return nil, nil
×
399
}
×
400

401
func (*mockChainIO) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock,
402
        error) {
×
403

×
404
        return nil, nil
×
405
}
×
406

407
func (*mockChainIO) GetBlockHeader(
408
        blockHash *chainhash.Hash) (*wire.BlockHeader, error) {
×
409

×
410
        return nil, nil
×
411
}
×
412

413
type MockAuxLeafStore struct{}
414

415
// A compile time check to ensure that MockAuxLeafStore implements the
416
// AuxLeafStore interface.
417
var _ AuxLeafStore = (*MockAuxLeafStore)(nil)
418

419
// FetchLeavesFromView attempts to fetch the auxiliary leaves that
420
// correspond to the passed aux blob, and pending original (unfiltered)
421
// HTLC view.
422
func (*MockAuxLeafStore) FetchLeavesFromView(
423
        _ CommitDiffAuxInput) fn.Result[CommitDiffAuxResult] {
×
424

×
425
        return fn.Ok(CommitDiffAuxResult{})
×
426
}
×
427

428
// FetchLeavesFromCommit attempts to fetch the auxiliary leaves that
429
// correspond to the passed aux blob, and an existing channel
430
// commitment.
431
func (*MockAuxLeafStore) FetchLeavesFromCommit(_ AuxChanState,
432
        _ channeldb.ChannelCommitment, _ CommitmentKeyRing,
UNCOV
433
        _ lntypes.ChannelParty) fn.Result[CommitDiffAuxResult] {
×
UNCOV
434

×
UNCOV
435
        return fn.Ok(CommitDiffAuxResult{})
×
UNCOV
436
}
×
437

438
// FetchLeavesFromRevocation attempts to fetch the auxiliary leaves
439
// from a channel revocation that stores balance + blob information.
440
func (*MockAuxLeafStore) FetchLeavesFromRevocation(
UNCOV
441
        _ *channeldb.RevocationLog) fn.Result[CommitDiffAuxResult] {
×
UNCOV
442

×
UNCOV
443
        return fn.Ok(CommitDiffAuxResult{})
×
UNCOV
444
}
×
445

446
// ApplyHtlcView serves as the state transition function for the custom
447
// channel's blob. Given the old blob, and an HTLC view, then a new
448
// blob should be returned that reflects the pending updates.
449
func (*MockAuxLeafStore) ApplyHtlcView(
450
        _ CommitDiffAuxInput) fn.Result[fn.Option[tlv.Blob]] {
×
451

×
452
        return fn.Ok(fn.None[tlv.Blob]())
×
453
}
×
454

455
// EmptyMockJobHandler is a mock job handler that just sends an empty response
456
// to all jobs.
UNCOV
457
func EmptyMockJobHandler(jobs []AuxSigJob) {
×
UNCOV
458
        for _, sigJob := range jobs {
×
UNCOV
459
                sigJob.Resp <- AuxSigJobResp{}
×
UNCOV
460
        }
×
461
}
462

463
// MockAuxSigner is a mock implementation of the AuxSigner interface.
464
type MockAuxSigner struct {
465
        mock.Mock
466

467
        jobHandlerFunc func([]AuxSigJob)
468
}
469

470
// NewAuxSignerMock creates a new mock aux signer with the given job handler.
UNCOV
471
func NewAuxSignerMock(jobHandler func([]AuxSigJob)) *MockAuxSigner {
×
UNCOV
472
        return &MockAuxSigner{
×
UNCOV
473
                jobHandlerFunc: jobHandler,
×
UNCOV
474
        }
×
UNCOV
475
}
×
476

477
// SubmitSecondLevelSigBatch takes a batch of aux sign jobs and
478
// processes them asynchronously.
479
func (a *MockAuxSigner) SubmitSecondLevelSigBatch(chanState AuxChanState,
UNCOV
480
        tx *wire.MsgTx, jobs []AuxSigJob) error {
×
UNCOV
481

×
UNCOV
482
        args := a.Called(chanState, tx, jobs)
×
UNCOV
483

×
UNCOV
484
        if a.jobHandlerFunc != nil {
×
UNCOV
485
                a.jobHandlerFunc(jobs)
×
UNCOV
486
        }
×
487

UNCOV
488
        return args.Error(0)
×
489
}
490

491
// PackSigs takes a series of aux signatures and packs them into a
492
// single blob that can be sent alongside the CommitSig messages.
493
func (a *MockAuxSigner) PackSigs(
UNCOV
494
        sigs []fn.Option[tlv.Blob]) fn.Result[fn.Option[tlv.Blob]] {
×
UNCOV
495

×
UNCOV
496
        args := a.Called(sigs)
×
UNCOV
497

×
UNCOV
498
        return args.Get(0).(fn.Result[fn.Option[tlv.Blob]])
×
UNCOV
499
}
×
500

501
// UnpackSigs takes a packed blob of signatures and returns the
502
// original signatures for each HTLC, keyed by HTLC index.
503
func (a *MockAuxSigner) UnpackSigs(
UNCOV
504
        sigs fn.Option[tlv.Blob]) fn.Result[[]fn.Option[tlv.Blob]] {
×
UNCOV
505

×
UNCOV
506
        args := a.Called(sigs)
×
UNCOV
507

×
UNCOV
508
        return args.Get(0).(fn.Result[[]fn.Option[tlv.Blob]])
×
UNCOV
509
}
×
510

511
// VerifySecondLevelSigs attempts to synchronously verify a batch of aux
512
// sig jobs.
513
func (a *MockAuxSigner) VerifySecondLevelSigs(chanState AuxChanState,
UNCOV
514
        tx *wire.MsgTx, jobs []AuxVerifyJob) error {
×
UNCOV
515

×
UNCOV
516
        args := a.Called(chanState, tx, jobs)
×
UNCOV
517

×
UNCOV
518
        return args.Error(0)
×
UNCOV
519
}
×
520

521
type MockAuxContractResolver struct{}
522

523
// ResolveContract is called to resolve a contract that needs
524
// additional information to resolve properly. If no extra information
525
// is required, a nil Result error is returned.
526
func (*MockAuxContractResolver) ResolveContract(
UNCOV
527
        ResolutionReq) fn.Result[tlv.Blob] {
×
UNCOV
528

×
UNCOV
529
        return fn.Ok[tlv.Blob](nil)
×
UNCOV
530
}
×
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