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

lightningnetwork / lnd / 21485572389

29 Jan 2026 04:09PM UTC coverage: 65.247% (+0.2%) from 65.074%
21485572389

Pull #10089

github

web-flow
Merge 22d34d15e into 19b2ad797
Pull Request #10089: Onion message forwarding

1152 of 1448 new or added lines in 23 files covered. (79.56%)

4109 existing lines in 29 files now uncovered.

139515 of 213825 relevant lines covered (65.25%)

20529.09 hits per line

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

0.0
/lntest/harness_assertion.go
1
package lntest
2

3
import (
4
        "bytes"
5
        "context"
6
        "crypto/rand"
7
        "encoding/hex"
8
        "encoding/json"
9
        "fmt"
10
        "math"
11
        "sort"
12
        "strings"
13
        "time"
14

15
        "github.com/btcsuite/btcd/btcec/v2"
16
        "github.com/btcsuite/btcd/btcec/v2/schnorr"
17
        "github.com/btcsuite/btcd/btcutil"
18
        "github.com/btcsuite/btcd/chaincfg/chainhash"
19
        "github.com/btcsuite/btcd/txscript"
20
        "github.com/btcsuite/btcd/wire"
21
        "github.com/davecgh/go-spew/spew"
22
        "github.com/lightningnetwork/lnd/channeldb"
23
        "github.com/lightningnetwork/lnd/lnrpc"
24
        "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
25
        "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
26
        "github.com/lightningnetwork/lnd/lnrpc/walletrpc"
27
        "github.com/lightningnetwork/lnd/lntest/miner"
28
        "github.com/lightningnetwork/lnd/lntest/node"
29
        "github.com/lightningnetwork/lnd/lntest/rpc"
30
        "github.com/lightningnetwork/lnd/lntest/wait"
31
        "github.com/lightningnetwork/lnd/lntypes"
32
        "github.com/lightningnetwork/lnd/lnutils"
33
        "github.com/stretchr/testify/require"
34
        "google.golang.org/protobuf/proto"
35
)
36

37
// FindChannelOption is a functional type for an option that modifies a
38
// ListChannelsRequest.
39
type ListChannelOption func(r *lnrpc.ListChannelsRequest)
40

41
// WithPeerAliasLookup is an option for setting the peer alias lookup flag on a
42
// ListChannelsRequest.
43
func WithPeerAliasLookup() ListChannelOption {
×
44
        return func(r *lnrpc.ListChannelsRequest) {
×
45
                r.PeerAliasLookup = true
×
UNCOV
46
        }
×
47
}
48

49
// WaitForBlockchainSync waits until the node is synced to chain.
50
func (h *HarnessTest) WaitForBlockchainSync(hn *node.HarnessNode) {
×
51
        err := wait.NoError(func() error {
×
52
                resp := hn.RPC.GetInfo()
×
53
                if resp.SyncedToChain {
×
54
                        return nil
×
UNCOV
55
                }
×
56

UNCOV
57
                return fmt.Errorf("%s is not synced to chain", hn.Name())
×
58
        }, DefaultTimeout)
59

UNCOV
60
        require.NoError(h, err, "timeout waiting for blockchain sync")
×
61
}
62

63
// WaitForBlockchainSyncTo waits until the node is synced to bestBlock.
64
func (h *HarnessTest) WaitForBlockchainSyncTo(hn *node.HarnessNode,
65
        bestBlock chainhash.Hash) {
×
66

×
67
        bestBlockHash := bestBlock.String()
×
68
        err := wait.NoError(func() error {
×
69
                resp := hn.RPC.GetInfo()
×
70
                if resp.SyncedToChain {
×
71
                        if resp.BlockHash == bestBlockHash {
×
72
                                return nil
×
UNCOV
73
                        }
×
74

75
                        return fmt.Errorf("%s's backend is synced to the "+
×
76
                                "wrong block (expected=%s, actual=%s)",
×
UNCOV
77
                                hn.Name(), bestBlockHash, resp.BlockHash)
×
78
                }
79

UNCOV
80
                return fmt.Errorf("%s is not synced to chain", hn.Name())
×
81
        }, DefaultTimeout)
82

UNCOV
83
        require.NoError(h, err, "timeout waiting for blockchain sync")
×
84
}
85

86
// AssertPeerConnected asserts that the given node b is connected to a.
87
func (h *HarnessTest) AssertPeerConnected(a, b *node.HarnessNode) {
×
88
        err := wait.NoError(func() error {
×
89
                // We require the RPC call to be succeeded and won't wait for
×
90
                // it as it's an unexpected behavior.
×
91
                resp := a.RPC.ListPeers()
×
92

×
93
                // If node B is seen in the ListPeers response from node A,
×
94
                // then we can return true as the connection has been fully
×
95
                // established.
×
96
                for _, peer := range resp.Peers {
×
97
                        if peer.PubKey == b.PubKeyStr {
×
98
                                return nil
×
UNCOV
99
                        }
×
100
                }
101

102
                return fmt.Errorf("%s not found in %s's ListPeers",
×
UNCOV
103
                        b.Name(), a.Name())
×
104
        }, DefaultTimeout)
105

106
        require.NoError(h, err, "unable to connect %s to %s, got error: "+
×
107
                "peers not connected within %v seconds",
×
UNCOV
108
                a.Name(), b.Name(), DefaultTimeout)
×
109
}
110

111
// ConnectNodes creates a connection between the two nodes and asserts the
112
// connection is succeeded.
113
func (h *HarnessTest) ConnectNodes(a, b *node.HarnessNode) {
×
114
        bobInfo := b.RPC.GetInfo()
×
115

×
116
        req := &lnrpc.ConnectPeerRequest{
×
117
                Addr: &lnrpc.LightningAddress{
×
118
                        Pubkey: bobInfo.IdentityPubkey,
×
119
                        Host:   b.Cfg.P2PAddr(),
×
120
                },
×
121
        }
×
122
        a.RPC.ConnectPeer(req)
×
123
        h.AssertConnected(a, b)
×
UNCOV
124
}
×
125

126
// ConnectNodesPerm creates a persistent connection between the two nodes and
127
// asserts the connection is succeeded.
128
func (h *HarnessTest) ConnectNodesPerm(a, b *node.HarnessNode) {
×
129
        bobInfo := b.RPC.GetInfo()
×
130

×
131
        req := &lnrpc.ConnectPeerRequest{
×
132
                Addr: &lnrpc.LightningAddress{
×
133
                        Pubkey: bobInfo.IdentityPubkey,
×
134
                        Host:   b.Cfg.P2PAddr(),
×
135
                },
×
136
                Perm: true,
×
137
        }
×
138
        a.RPC.ConnectPeer(req)
×
139
        h.AssertPeerConnected(a, b)
×
UNCOV
140
}
×
141

142
// DisconnectNodes disconnects the given two nodes and asserts the
143
// disconnection is succeeded. The request is made from node a and sent to node
144
// b.
145
func (h *HarnessTest) DisconnectNodes(a, b *node.HarnessNode) {
×
146
        bobInfo := b.RPC.GetInfo()
×
147
        a.RPC.DisconnectPeer(bobInfo.IdentityPubkey)
×
148

×
149
        // Assert disconnected.
×
150
        h.AssertPeerNotConnected(a, b)
×
UNCOV
151
}
×
152

153
// EnsureConnected will try to connect to two nodes, returning no error if they
154
// are already connected. If the nodes were not connected previously, this will
155
// behave the same as ConnectNodes. If a pending connection request has already
156
// been made, the method will block until the two nodes appear in each other's
157
// peers list, or until the DefaultTimeout expires.
158
func (h *HarnessTest) EnsureConnected(a, b *node.HarnessNode) {
×
159
        // errConnectionRequested is used to signal that a connection was
×
160
        // requested successfully, which is distinct from already being
×
161
        // connected to the peer.
×
162
        errConnectionRequested := "connection request in progress"
×
163

×
164
        // windowsErr is an error we've seen from windows build where
×
165
        // connecting to an already connected node gives such error from the
×
166
        // receiver side.
×
167
        windowsErr := "An established connection was aborted by the software " +
×
168
                "in your host machine."
×
169

×
170
        tryConnect := func(a, b *node.HarnessNode) error {
×
171
                bInfo := b.RPC.GetInfo()
×
172

×
173
                req := &lnrpc.ConnectPeerRequest{
×
174
                        Addr: &lnrpc.LightningAddress{
×
175
                                Pubkey: bInfo.IdentityPubkey,
×
176
                                Host:   b.Cfg.P2PAddr(),
×
177
                        },
×
178
                }
×
179

×
180
                ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
181
                defer cancel()
×
182

×
183
                _, err := a.RPC.LN.ConnectPeer(ctxt, req)
×
184

×
185
                // Request was successful.
×
186
                if err == nil {
×
187
                        return nil
×
UNCOV
188
                }
×
189

190
                // If the two are already connected, we return early with no
191
                // error.
192
                if strings.Contains(err.Error(), "already connected to peer") {
×
193
                        return nil
×
UNCOV
194
                }
×
195

196
                // Otherwise we log the error to console.
197
                h.Logf("EnsureConnected %s=>%s got err: %v", a.Name(),
×
198
                        b.Name(), err)
×
199

×
200
                // If the connection is in process, we return no error.
×
201
                if strings.Contains(err.Error(), errConnectionRequested) {
×
202
                        return nil
×
UNCOV
203
                }
×
204

205
                // We may get connection refused error if we happens to be in
206
                // the middle of a previous node disconnection, e.g., a restart
207
                // from one of the nodes.
208
                if strings.Contains(err.Error(), "connection refused") {
×
209
                        return nil
×
UNCOV
210
                }
×
211

212
                // Check for windows error. If Alice connects to Bob, Alice
213
                // will throw "i/o timeout" and Bob will give windowsErr.
214
                if strings.Contains(err.Error(), windowsErr) {
×
215
                        return nil
×
UNCOV
216
                }
×
217

218
                if strings.Contains(err.Error(), "i/o timeout") {
×
219
                        return nil
×
UNCOV
220
                }
×
221

UNCOV
222
                return err
×
223
        }
224

225
        // Return any critical errors returned by either alice or bob.
226
        require.NoError(h, tryConnect(a, b), "connection failed between %s "+
×
227
                "and %s", a.Cfg.Name, b.Cfg.Name)
×
228

×
229
        // When Alice and Bob each makes a connection to the other side at the
×
230
        // same time, it's likely neither connections could succeed. Bob's
×
231
        // connection will be canceled by Alice since she has an outbound
×
232
        // connection to Bob already, and same happens to Alice's. Thus the two
×
233
        // connections cancel each other out.
×
234
        // TODO(yy): move this back when the above issue is fixed.
×
235
        // require.NoError(h, tryConnect(b, a), "connection failed between %s "+
×
236
        //         "and %s", a.Cfg.Name, b.Cfg.Name)
×
237

×
238
        // Otherwise one or both requested a connection, so we wait for the
×
239
        // peers lists to reflect the connection.
×
240
        h.AssertPeerConnected(a, b)
×
UNCOV
241
        h.AssertPeerConnected(b, a)
×
242
}
243

244
// ConnectNodesNoAssert creates a connection from node A to node B.
245
func (h *HarnessTest) ConnectNodesNoAssert(a, b *node.HarnessNode) (
246
        *lnrpc.ConnectPeerResponse, error) {
×
247

×
248
        bobInfo := b.RPC.GetInfo()
×
249

×
250
        req := &lnrpc.ConnectPeerRequest{
×
251
                Addr: &lnrpc.LightningAddress{
×
252
                        Pubkey: bobInfo.IdentityPubkey,
×
253
                        Host:   b.Cfg.P2PAddr(),
×
254
                },
×
255
        }
×
256
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
257
        defer cancel()
×
258

×
259
        return a.RPC.LN.ConnectPeer(ctxt, req)
×
UNCOV
260
}
×
261

262
// AssertNumEdges checks that an expected number of edges can be found in the
263
// node specified.
264
func (h *HarnessTest) AssertNumEdges(hn *node.HarnessNode,
265
        expected int, includeUnannounced bool) []*lnrpc.ChannelEdge {
×
266

×
267
        var edges []*lnrpc.ChannelEdge
×
268

×
269
        old := hn.State.Edge.Public
×
270
        if includeUnannounced {
×
271
                old = hn.State.Edge.Total
×
UNCOV
272
        }
×
273

274
        err := wait.NoError(func() error {
×
275
                req := &lnrpc.ChannelGraphRequest{
×
276
                        IncludeUnannounced: includeUnannounced,
×
277
                }
×
278
                resp := hn.RPC.DescribeGraph(req)
×
279
                total := len(resp.Edges)
×
280

×
281
                if total-old == expected {
×
282
                        if expected != 0 {
×
283
                                // NOTE: assume edges come in ascending order
×
284
                                // that the old edges are at the front of the
×
285
                                // slice.
×
286
                                edges = resp.Edges[old:]
×
UNCOV
287
                        }
×
288

UNCOV
289
                        return nil
×
290
                }
291

292
                return errNumNotMatched(hn.Name(), "num of channel edges",
×
UNCOV
293
                        expected, total-old, total, old)
×
294
        }, DefaultTimeout)
295

296
        require.NoError(h, err, "timeout while checking for edges")
×
297

×
UNCOV
298
        return edges
×
299
}
300

301
// ReceiveOpenChannelUpdate waits until a message is received on the stream or
302
// the timeout is reached.
303
func (h *HarnessTest) ReceiveOpenChannelUpdate(
304
        stream rpc.OpenChanClient) *lnrpc.OpenStatusUpdate {
×
305

×
306
        update, err := h.receiveOpenChannelUpdate(stream)
×
307
        require.NoError(h, err, "received err from open channel stream")
×
308

×
309
        return update
×
UNCOV
310
}
×
311

312
// ReceiveOpenChannelError waits for the expected error during the open channel
313
// flow from the peer or times out.
314
func (h *HarnessTest) ReceiveOpenChannelError(
315
        stream rpc.OpenChanClient, expectedErr error) {
×
316

×
317
        _, err := h.receiveOpenChannelUpdate(stream)
×
318
        require.Contains(h, err.Error(), expectedErr.Error(),
×
319
                "error not matched")
×
UNCOV
320
}
×
321

322
// receiveOpenChannelUpdate waits until a message or an error is received on
323
// the stream or the timeout is reached.
324
//
325
// TODO(yy): use generics to unify all receiving stream update once go@1.18 is
326
// used.
327
func (h *HarnessTest) receiveOpenChannelUpdate(
328
        stream rpc.OpenChanClient) (*lnrpc.OpenStatusUpdate, error) {
×
329

×
330
        chanMsg := make(chan *lnrpc.OpenStatusUpdate)
×
331
        errChan := make(chan error)
×
332
        go func() {
×
333
                // Consume one message. This will block until the message is
×
334
                // received.
×
335
                resp, err := stream.Recv()
×
336
                if err != nil {
×
337
                        errChan <- err
×
338
                        return
×
339
                }
×
UNCOV
340
                chanMsg <- resp
×
341
        }()
342

343
        select {
×
344
        case <-time.After(DefaultTimeout):
×
345
                require.Fail(h, "timeout", "timeout waiting for open channel "+
×
346
                        "update sent")
×
UNCOV
347
                return nil, nil
×
348

349
        case err := <-errChan:
×
UNCOV
350
                return nil, err
×
351

352
        case updateMsg := <-chanMsg:
×
UNCOV
353
                return updateMsg, nil
×
354
        }
355
}
356

357
// WaitForChannelOpenEvent waits for a notification that a channel is open by
358
// consuming a message from the passed open channel stream.
359
func (h HarnessTest) WaitForChannelOpenEvent(
360
        stream rpc.OpenChanClient) *lnrpc.ChannelPoint {
×
361

×
362
        // Consume one event.
×
363
        event := h.ReceiveOpenChannelUpdate(stream)
×
364

×
365
        resp, ok := event.Update.(*lnrpc.OpenStatusUpdate_ChanOpen)
×
366
        require.Truef(h, ok, "expected channel open update, instead got %v",
×
367
                resp)
×
368

×
369
        return resp.ChanOpen.ChannelPoint
×
UNCOV
370
}
×
371

372
// AssertChannelExists asserts that an active channel identified by the
373
// specified channel point exists from the point-of-view of the node.
374
func (h *HarnessTest) AssertChannelExists(hn *node.HarnessNode,
375
        cp *lnrpc.ChannelPoint) *lnrpc.Channel {
×
376

×
377
        return h.assertChannelStatus(hn, cp, true)
×
UNCOV
378
}
×
379

380
// AssertChannelActive checks if a channel identified by the specified channel
381
// point is active.
382
func (h *HarnessTest) AssertChannelActive(hn *node.HarnessNode,
383
        cp *lnrpc.ChannelPoint) *lnrpc.Channel {
×
384

×
385
        return h.assertChannelStatus(hn, cp, true)
×
UNCOV
386
}
×
387

388
// AssertChannelInactive checks if a channel identified by the specified channel
389
// point is inactive.
390
func (h *HarnessTest) AssertChannelInactive(hn *node.HarnessNode,
391
        cp *lnrpc.ChannelPoint) *lnrpc.Channel {
×
392

×
393
        return h.assertChannelStatus(hn, cp, false)
×
UNCOV
394
}
×
395

396
// assertChannelStatus asserts that a channel identified by the specified
397
// channel point exists from the point-of-view of the node and that it is either
398
// active or inactive depending on the value of the active parameter.
399
func (h *HarnessTest) assertChannelStatus(hn *node.HarnessNode,
400
        cp *lnrpc.ChannelPoint, active bool) *lnrpc.Channel {
×
401

×
402
        var (
×
403
                channel *lnrpc.Channel
×
404
                err     error
×
405
        )
×
406

×
407
        err = wait.NoError(func() error {
×
408
                channel, err = h.findChannel(hn, cp)
×
409
                if err != nil {
×
410
                        return err
×
UNCOV
411
                }
×
412

413
                // Check whether the channel is active, exit early if it is.
414
                if channel.Active == active {
×
415
                        return nil
×
UNCOV
416
                }
×
417

418
                return fmt.Errorf("expected channel_active=%v, got %v",
×
UNCOV
419
                        active, channel.Active)
×
420
        }, DefaultTimeout)
421

422
        require.NoErrorf(h, err, "%s: timeout checking for channel point: %v",
×
423
                hn.Name(), h.OutPointFromChannelPoint(cp))
×
424

×
UNCOV
425
        return channel
×
426
}
427

428
// AssertOutputScriptClass checks that the specified transaction output has the
429
// expected script class.
430
func (h *HarnessTest) AssertOutputScriptClass(tx *btcutil.Tx,
431
        outputIndex uint32, scriptClass txscript.ScriptClass) {
×
432

×
433
        require.Greater(h, len(tx.MsgTx().TxOut), int(outputIndex))
×
434

×
435
        txOut := tx.MsgTx().TxOut[outputIndex]
×
436

×
437
        pkScript, err := txscript.ParsePkScript(txOut.PkScript)
×
438
        require.NoError(h, err)
×
439
        require.Equal(h, scriptClass, pkScript.Class())
×
UNCOV
440
}
×
441

442
// findChannel tries to find a target channel in the node using the given
443
// channel point.
444
func (h *HarnessTest) findChannel(hn *node.HarnessNode,
445
        chanPoint *lnrpc.ChannelPoint,
446
        opts ...ListChannelOption) (*lnrpc.Channel, error) {
×
447

×
448
        // Get the funding point.
×
449
        fp := h.OutPointFromChannelPoint(chanPoint)
×
450

×
451
        req := &lnrpc.ListChannelsRequest{}
×
452

×
453
        for _, opt := range opts {
×
454
                opt(req)
×
UNCOV
455
        }
×
456

457
        channelInfo := hn.RPC.ListChannels(req)
×
458

×
459
        // Find the target channel.
×
460
        for _, channel := range channelInfo.Channels {
×
461
                if channel.ChannelPoint == fp.String() {
×
462
                        return channel, nil
×
UNCOV
463
                }
×
464
        }
465

466
        return nil, fmt.Errorf("%s: channel not found using %s", hn.Name(),
×
UNCOV
467
                fp.String())
×
468
}
469

470
// ReceiveCloseChannelUpdate waits until a message or an error is received on
471
// the subscribe channel close stream or the timeout is reached.
472
func (h *HarnessTest) ReceiveCloseChannelUpdate(
473
        stream rpc.CloseChanClient) (*lnrpc.CloseStatusUpdate, error) {
×
474

×
475
        chanMsg := make(chan *lnrpc.CloseStatusUpdate)
×
476
        errChan := make(chan error)
×
477
        go func() {
×
478
                // Consume one message. This will block until the message is
×
479
                // received.
×
480
                resp, err := stream.Recv()
×
481
                if err != nil {
×
482
                        errChan <- err
×
483
                        return
×
484
                }
×
UNCOV
485
                chanMsg <- resp
×
486
        }()
487

488
        select {
×
489
        case <-time.After(DefaultTimeout):
×
490
                require.Fail(h, "timeout", "timeout waiting for close channel "+
×
491
                        "update sent")
×
492

×
UNCOV
493
                return nil, nil
×
494

495
        case err := <-errChan:
×
496
                return nil, fmt.Errorf("received err from close channel "+
×
UNCOV
497
                        "stream: %v", err)
×
498

499
        case updateMsg := <-chanMsg:
×
UNCOV
500
                return updateMsg, nil
×
501
        }
502
}
503

504
type WaitingCloseChannel *lnrpc.PendingChannelsResponse_WaitingCloseChannel
505

506
// AssertChannelWaitingClose asserts that the given channel found in the node
507
// is waiting close. Returns the WaitingCloseChannel if found.
508
func (h *HarnessTest) AssertChannelWaitingClose(hn *node.HarnessNode,
509
        chanPoint *lnrpc.ChannelPoint) WaitingCloseChannel {
×
510

×
511
        var target WaitingCloseChannel
×
512

×
513
        op := h.OutPointFromChannelPoint(chanPoint)
×
514

×
515
        err := wait.NoError(func() error {
×
516
                resp := hn.RPC.PendingChannels()
×
517

×
518
                for _, waitingClose := range resp.WaitingCloseChannels {
×
519
                        if waitingClose.Channel.ChannelPoint == op.String() {
×
520
                                target = waitingClose
×
521
                                return nil
×
UNCOV
522
                        }
×
523
                }
524

525
                return fmt.Errorf("%v: channel %s not found in waiting close",
×
UNCOV
526
                        hn.Name(), op)
×
527
        }, DefaultTimeout)
528
        require.NoError(h, err, "assert channel waiting close timed out")
×
529

×
UNCOV
530
        return target
×
531
}
532

533
// AssertTopologyChannelClosed asserts a given channel is closed by checking
534
// the graph topology subscription of the specified node. Returns the closed
535
// channel update if found.
536
func (h *HarnessTest) AssertTopologyChannelClosed(hn *node.HarnessNode,
537
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ClosedChannelUpdate {
×
538

×
539
        closedChan, err := hn.Watcher.WaitForChannelClose(chanPoint)
×
540
        require.NoError(h, err, "failed to wait for channel close")
×
541

×
542
        return closedChan
×
UNCOV
543
}
×
544

545
// WaitForChannelCloseEvent waits for a notification that a channel is closed
546
// by consuming a message from the passed close channel stream. Returns the
547
// closing txid if found.
548
func (h HarnessTest) WaitForChannelCloseEvent(
549
        stream rpc.CloseChanClient) chainhash.Hash {
×
550

×
551
        // Consume one event.
×
552
        event, err := h.ReceiveCloseChannelUpdate(stream)
×
553
        require.NoError(h, err)
×
554

×
555
        resp, ok := event.Update.(*lnrpc.CloseStatusUpdate_ChanClose)
×
556
        require.Truef(
×
557
                h, ok, "expected channel close update, instead got %T: %v",
×
558
                event.Update, spew.Sdump(event.Update),
×
559
        )
×
560

×
561
        txid, err := chainhash.NewHash(resp.ChanClose.ClosingTxid)
×
562
        require.NoErrorf(h, err, "wrong format found in closing txid: %v",
×
563
                resp.ChanClose.ClosingTxid)
×
UNCOV
564

×
UNCOV
565
        return *txid
×
UNCOV
566
}
×
567

568
// AssertNumWaitingClose checks that a PendingChannels response from the node
569
// reports the expected number of waiting close channels.
570
func (h *HarnessTest) AssertNumWaitingClose(hn *node.HarnessNode,
571
        num int) []*lnrpc.PendingChannelsResponse_WaitingCloseChannel {
×
572

×
573
        var channels []*lnrpc.PendingChannelsResponse_WaitingCloseChannel
×
574
        oldWaiting := hn.State.CloseChannel.WaitingClose
×
575

×
576
        err := wait.NoError(func() error {
×
577
                resp := hn.RPC.PendingChannels()
×
578
                channels = resp.WaitingCloseChannels
×
579
                total := len(channels)
×
580

×
581
                got := total - oldWaiting
×
UNCOV
582
                if got == num {
×
583
                        return nil
×
584
                }
×
585

UNCOV
586
                return errNumNotMatched(hn.Name(), "waiting close channels",
×
587
                        num, got, total, oldWaiting)
×
588
        }, DefaultTimeout)
589

590
        require.NoErrorf(h, err, "%s: assert waiting close timeout",
×
UNCOV
591
                hn.Name())
×
UNCOV
592

×
UNCOV
593
        return channels
×
594
}
595

596
// AssertNumPendingForceClose checks that a PendingChannels response from the
597
// node reports the expected number of pending force close channels.
598
func (h *HarnessTest) AssertNumPendingForceClose(hn *node.HarnessNode,
599
        num int) []*lnrpc.PendingChannelsResponse_ForceClosedChannel {
×
600

×
601
        var channels []*lnrpc.PendingChannelsResponse_ForceClosedChannel
×
602
        oldForce := hn.State.CloseChannel.PendingForceClose
×
603

×
604
        err := wait.NoError(func() error {
×
605
                // TODO(yy): we should be able to use `hn.RPC.PendingChannels`
×
606
                // here to avoid checking the RPC error. However, we may get a
×
607
                // `unable to find arbitrator` error from the rpc point, due to
×
608
                // a timing issue in rpcserver,
×
609
                // 1. `r.server.chanStateDB.FetchClosedChannels` fetches
×
610
                //    the pending force close channel.
×
611
                // 2. `r.arbitratorPopulateForceCloseResp` relies on the
×
612
                //    channel arbitrator to get the report, and,
×
613
                // 3. the arbitrator may be deleted due to the force close
×
614
                //    channel being resolved.
×
615
                // Somewhere along the line is missing a lock to keep the data
×
616
                // consistent.
×
617
                req := &lnrpc.PendingChannelsRequest{}
×
618
                resp, err := hn.RPC.LN.PendingChannels(h.runCtx, req)
×
UNCOV
619
                if err != nil {
×
620
                        return fmt.Errorf("PendingChannels got: %w", err)
×
621
                }
×
622

623
                channels = resp.PendingForceClosingChannels
×
624
                total := len(channels)
×
625

×
626
                got := total - oldForce
×
UNCOV
627
                if got == num {
×
628
                        return nil
×
629
                }
×
630

UNCOV
631
                return errNumNotMatched(hn.Name(), "pending force close "+
×
632
                        "channels", num, got, total, oldForce)
×
633
        }, DefaultTimeout)
634

635
        require.NoErrorf(h, err, "%s: assert pending force close timeout",
×
UNCOV
636
                hn.Name())
×
UNCOV
637

×
UNCOV
638
        return channels
×
639
}
640

641
// AssertStreamChannelCoopClosed reads an update from the close channel client
642
// stream and asserts that the mempool state and node's topology match a coop
643
// close. In specific,
644
// - assert the channel is waiting close and has the expected ChanStatusFlags.
645
// - assert the mempool has the closing txes and anchor sweeps.
646
// - mine a block and assert the closing txid is mined.
647
// - assert the node has zero waiting close channels.
648
// - assert the node has seen the channel close update.
649
func (h *HarnessTest) AssertStreamChannelCoopClosed(hn *node.HarnessNode,
650
        cp *lnrpc.ChannelPoint, anchors bool,
651
        stream rpc.CloseChanClient) chainhash.Hash {
×
652

×
653
        // Assert the channel is waiting close.
×
654
        resp := h.AssertChannelWaitingClose(hn, cp)
×
655

×
656
        // Assert that the channel is in coop broadcasted.
×
657
        require.Contains(h, resp.Channel.ChanStatusFlags,
×
658
                channeldb.ChanStatusCoopBroadcasted.String(),
×
659
                "channel not coop broadcasted")
×
660

×
661
        // We'll now, generate a single block, wait for the final close status
×
662
        // update, then ensure that the closing transaction was included in the
×
663
        // block. If there are anchors, we also expect an anchor sweep.
×
664
        expectedTxes := 1
×
665
        if anchors {
×
666
                expectedTxes = 2
×
667
        }
×
668
        block := h.MineBlocksAndAssertNumTxes(1, expectedTxes)[0]
×
669

×
670
        // Consume one close event and assert the closing txid can be found in
×
671
        // the block.
×
672
        closingTxid := h.WaitForChannelCloseEvent(stream)
×
673
        h.AssertTxInBlock(block, closingTxid)
×
674

×
675
        // We should see zero waiting close channels now.
×
676
        h.AssertNumWaitingClose(hn, 0)
×
677

×
678
        // Finally, check that the node's topology graph has seen this channel
×
679
        // closed if it's a public channel.
×
UNCOV
680
        if !resp.Channel.Private {
×
681
                h.AssertTopologyChannelClosed(hn, cp)
×
UNCOV
682
        }
×
683

UNCOV
684
        return closingTxid
×
685
}
686

687
// AssertStreamChannelForceClosed reads an update from the close channel client
688
// stream and asserts that the mempool state and node's topology match a local
689
// force close. In specific,
690
//   - assert the channel is waiting close and has the expected ChanStatusFlags.
691
//   - assert the mempool has the closing txes.
692
//   - mine a block and assert the closing txid is mined.
693
//   - assert the channel is pending force close.
694
//   - assert the node has seen the channel close update.
695
//   - assert there's a pending anchor sweep request once the force close tx is
696
//     confirmed.
697
func (h *HarnessTest) AssertStreamChannelForceClosed(hn *node.HarnessNode,
698
        cp *lnrpc.ChannelPoint, anchorSweep bool,
699
        stream rpc.CloseChanClient) chainhash.Hash {
×
700

×
701
        // Assert the channel is waiting close.
×
702
        resp := h.AssertChannelWaitingClose(hn, cp)
×
703

×
704
        // Assert that the channel is in local force broadcasted.
×
705
        require.Contains(h, resp.Channel.ChanStatusFlags,
×
706
                channeldb.ChanStatusLocalCloseInitiator.String(),
×
707
                "channel not coop broadcasted")
×
708

×
709
        // Get the closing txid.
×
710
        closeTxid, err := chainhash.NewHashFromStr(resp.ClosingTxid)
×
711
        require.NoError(h, err)
×
712

×
713
        // We'll now, generate a single block, wait for the final close status
×
714
        // update, then ensure that the closing transaction was included in the
×
715
        // block.
×
716
        closeTx := h.AssertTxInMempool(*closeTxid)
×
717
        h.MineBlockWithTx(closeTx)
×
718

×
719
        // Consume one close event and assert the closing txid can be found in
×
720
        // the block.
×
721
        closingTxid := h.WaitForChannelCloseEvent(stream)
×
722

×
723
        // We should see zero waiting close channels and 1 pending force close
×
724
        // channels now.
×
725
        h.AssertNumWaitingClose(hn, 0)
×
726
        h.AssertNumPendingForceClose(hn, 1)
×
727

×
728
        // Finally, check that the node's topology graph has seen this channel
×
729
        // closed if it's a public channel.
×
UNCOV
730
        if !resp.Channel.Private {
×
UNCOV
731
                h.AssertTopologyChannelClosed(hn, cp)
×
UNCOV
732
        }
×
733

734
        // Assert there's a pending anchor sweep.
735
        //
736
        // NOTE: We may have a local sweep here, that's why we use
737
        // AssertAtLeastNumPendingSweeps instead of AssertNumPendingSweeps.
UNCOV
738
        if anchorSweep {
×
739
                h.AssertAtLeastNumPendingSweeps(hn, 1)
×
UNCOV
740
        }
×
741

UNCOV
742
        return closingTxid
×
743
}
744

745
// AssertChannelPolicyUpdate checks that the required policy update has
746
// happened on the given node.
747
func (h *HarnessTest) AssertChannelPolicyUpdate(hn *node.HarnessNode,
748
        advertisingNode *node.HarnessNode, policy *lnrpc.RoutingPolicy,
749
        chanPoint *lnrpc.ChannelPoint, includeUnannounced bool) {
×
750

×
751
        require.NoError(
×
752
                h, hn.Watcher.WaitForChannelPolicyUpdate(
×
753
                        advertisingNode, policy,
×
754
                        chanPoint, includeUnannounced,
×
UNCOV
755
                ), "%s: error while waiting for channel update", hn.Name(),
×
UNCOV
756
        )
×
757
}
×
758

759
// WaitForGraphSync waits until the node is synced to graph or times out.
760
func (h *HarnessTest) WaitForGraphSync(hn *node.HarnessNode) {
×
761
        err := wait.NoError(func() error {
×
762
                resp := hn.RPC.GetInfo()
×
UNCOV
763
                if resp.SyncedToGraph {
×
764
                        return nil
×
UNCOV
765
                }
×
766

UNCOV
767
                return fmt.Errorf("node not synced to graph")
×
768
        }, DefaultTimeout)
UNCOV
769
        require.NoError(h, err, "%s: timeout while sync to graph", hn.Name())
×
770
}
771

772
// AssertNumUTXOsWithConf waits for the given number of UTXOs with the
773
// specified confirmations range to be available or fails if that isn't the
774
// case before the default timeout.
775
func (h *HarnessTest) AssertNumUTXOsWithConf(hn *node.HarnessNode,
776
        expectedUtxos int, max, min int32) []*lnrpc.Utxo {
×
777

×
778
        var unconfirmed bool
×
779

×
UNCOV
780
        if max == 0 {
×
781
                unconfirmed = true
×
782
        }
×
783

784
        var utxos []*lnrpc.Utxo
×
785
        err := wait.NoError(func() error {
×
786
                req := &walletrpc.ListUnspentRequest{
×
787
                        Account:         "",
×
788
                        MaxConfs:        max,
×
789
                        MinConfs:        min,
×
790
                        UnconfirmedOnly: unconfirmed,
×
791
                }
×
792
                resp := hn.RPC.ListUnspent(req)
×
793
                total := len(resp.Utxos)
×
794

×
795
                if total == expectedUtxos {
×
796
                        utxos = resp.Utxos
×
UNCOV
797

×
798
                        return nil
×
799
                }
×
800

801
                desc := "has UTXOs:\n"
×
UNCOV
802
                for _, utxo := range resp.Utxos {
×
803
                        desc += fmt.Sprintf("%v\n", utxo)
×
804
                }
×
805

806
                return fmt.Errorf("%s: assert num of UTXOs failed: want %d, "+
×
807
                        "got: %d, %s", hn.Name(), expectedUtxos, total, desc)
×
808
        }, DefaultTimeout)
UNCOV
809
        require.NoError(h, err, "timeout waiting for UTXOs")
×
UNCOV
810

×
UNCOV
811
        return utxos
×
812
}
813

814
// AssertNumUTXOsUnconfirmed asserts the expected num of unconfirmed utxos are
815
// seen.
816
func (h *HarnessTest) AssertNumUTXOsUnconfirmed(hn *node.HarnessNode,
817
        num int) []*lnrpc.Utxo {
×
UNCOV
818

×
UNCOV
819
        return h.AssertNumUTXOsWithConf(hn, num, 0, 0)
×
UNCOV
820
}
×
821

822
// AssertNumUTXOsConfirmed asserts the expected num of confirmed utxos are
823
// seen, which means the returned utxos have at least one confirmation.
824
func (h *HarnessTest) AssertNumUTXOsConfirmed(hn *node.HarnessNode,
825
        num int) []*lnrpc.Utxo {
×
UNCOV
826

×
UNCOV
827
        return h.AssertNumUTXOsWithConf(hn, num, math.MaxInt32, 1)
×
UNCOV
828
}
×
829

830
// AssertNumUTXOs asserts the expected num of utxos are seen, including
831
// confirmed and unconfirmed outputs.
832
func (h *HarnessTest) AssertNumUTXOs(hn *node.HarnessNode,
833
        num int) []*lnrpc.Utxo {
×
UNCOV
834

×
UNCOV
835
        return h.AssertNumUTXOsWithConf(hn, num, math.MaxInt32, 0)
×
UNCOV
836
}
×
837

838
// getUTXOs gets the number of newly created UTOXs within the current test
839
// scope.
840
func (h *HarnessTest) getUTXOs(hn *node.HarnessNode, account string,
841
        max, min int32) []*lnrpc.Utxo {
×
842

×
843
        var unconfirmed bool
×
844

×
UNCOV
845
        if max == 0 {
×
846
                unconfirmed = true
×
847
        }
×
848

849
        req := &walletrpc.ListUnspentRequest{
×
850
                Account:         account,
×
851
                MaxConfs:        max,
×
852
                MinConfs:        min,
×
853
                UnconfirmedOnly: unconfirmed,
×
854
        }
×
UNCOV
855
        resp := hn.RPC.ListUnspent(req)
×
UNCOV
856

×
UNCOV
857
        return resp.Utxos
×
858
}
859

860
// GetUTXOs returns all the UTXOs for the given node's account, including
861
// confirmed and unconfirmed.
862
func (h *HarnessTest) GetUTXOs(hn *node.HarnessNode,
863
        account string) []*lnrpc.Utxo {
×
UNCOV
864

×
UNCOV
865
        return h.getUTXOs(hn, account, math.MaxInt32, 0)
×
UNCOV
866
}
×
867

868
// GetUTXOsConfirmed returns the confirmed UTXOs for the given node's account.
869
func (h *HarnessTest) GetUTXOsConfirmed(hn *node.HarnessNode,
870
        account string) []*lnrpc.Utxo {
×
UNCOV
871

×
UNCOV
872
        return h.getUTXOs(hn, account, math.MaxInt32, 1)
×
UNCOV
873
}
×
874

875
// GetUTXOsUnconfirmed returns the unconfirmed UTXOs for the given node's
876
// account.
877
func (h *HarnessTest) GetUTXOsUnconfirmed(hn *node.HarnessNode,
878
        account string) []*lnrpc.Utxo {
×
UNCOV
879

×
UNCOV
880
        return h.getUTXOs(hn, account, 0, 0)
×
UNCOV
881
}
×
882

883
// WaitForBalanceConfirmed waits until the node sees the expected confirmed
884
// balance in its wallet.
885
func (h *HarnessTest) WaitForBalanceConfirmed(hn *node.HarnessNode,
886
        expected btcutil.Amount) {
×
887

×
888
        var lastBalance btcutil.Amount
×
889
        err := wait.NoError(func() error {
×
890
                resp := hn.RPC.WalletBalance()
×
891

×
892
                lastBalance = btcutil.Amount(resp.ConfirmedBalance)
×
UNCOV
893
                if lastBalance == expected {
×
894
                        return nil
×
895
                }
×
896

UNCOV
897
                return fmt.Errorf("expected %v, only have %v", expected,
×
898
                        lastBalance)
×
899
        }, DefaultTimeout)
900

UNCOV
901
        require.NoError(h, err, "timeout waiting for confirmed balances")
×
902
}
903

904
// WaitForBalanceUnconfirmed waits until the node sees the expected unconfirmed
905
// balance in its wallet.
906
func (h *HarnessTest) WaitForBalanceUnconfirmed(hn *node.HarnessNode,
907
        expected btcutil.Amount) {
×
908

×
909
        var lastBalance btcutil.Amount
×
910
        err := wait.NoError(func() error {
×
911
                resp := hn.RPC.WalletBalance()
×
912

×
913
                lastBalance = btcutil.Amount(resp.UnconfirmedBalance)
×
UNCOV
914
                if lastBalance == expected {
×
915
                        return nil
×
916
                }
×
917

UNCOV
918
                return fmt.Errorf("expected %v, only have %v", expected,
×
919
                        lastBalance)
×
920
        }, DefaultTimeout)
921

UNCOV
922
        require.NoError(h, err, "timeout waiting for unconfirmed balances")
×
923
}
924

925
// Random32Bytes generates a random 32 bytes which can be used as a pay hash,
926
// preimage, etc.
927
func (h *HarnessTest) Random32Bytes() []byte {
×
928
        randBuf := make([]byte, lntypes.HashSize)
×
929

×
930
        _, err := rand.Read(randBuf)
×
931
        require.NoErrorf(h, err, "internal error, cannot generate random bytes")
×
UNCOV
932

×
UNCOV
933
        return randBuf
×
UNCOV
934
}
×
935

936
// RandomPreimage generates a random preimage which can be used as a payment
937
// preimage.
938
func (h *HarnessTest) RandomPreimage() lntypes.Preimage {
×
939
        var preimage lntypes.Preimage
×
940
        copy(preimage[:], h.Random32Bytes())
×
UNCOV
941

×
UNCOV
942
        return preimage
×
943
}
×
944

945
// DecodeAddress decodes a given address and asserts there's no error.
946
func (h *HarnessTest) DecodeAddress(addr string) btcutil.Address {
×
947
        resp, err := btcutil.DecodeAddress(addr, miner.HarnessNetParams)
×
948
        require.NoError(h, err, "DecodeAddress failed")
×
UNCOV
949

×
UNCOV
950
        return resp
×
UNCOV
951
}
×
952

953
// PayToAddrScript creates a new script from the given address and asserts
954
// there's no error.
955
func (h *HarnessTest) PayToAddrScript(addr btcutil.Address) []byte {
×
956
        addrScript, err := txscript.PayToAddrScript(addr)
×
957
        require.NoError(h, err, "PayToAddrScript failed")
×
UNCOV
958

×
UNCOV
959
        return addrScript
×
UNCOV
960
}
×
961

962
// AssertChannelBalanceResp makes a ChannelBalance request and checks the
963
// returned response matches the expected.
964
func (h *HarnessTest) AssertChannelBalanceResp(hn *node.HarnessNode,
965
        expected *lnrpc.ChannelBalanceResponse) {
×
966

×
967
        resp := hn.RPC.ChannelBalance()
×
968

×
969
        // Ignore custom channel data of both expected and actual responses.
×
970
        expected.CustomChannelData = nil
×
971
        resp.CustomChannelData = nil
×
972

×
UNCOV
973
        require.True(h, proto.Equal(expected, resp), "balance is incorrect "+
×
UNCOV
974
                "got: %v, want: %v", resp, expected)
×
UNCOV
975
}
×
976

977
// GetChannelByChanPoint tries to find a channel matching the channel point and
978
// asserts. It returns the channel found.
979
func (h *HarnessTest) GetChannelByChanPoint(hn *node.HarnessNode,
980
        chanPoint *lnrpc.ChannelPoint) *lnrpc.Channel {
×
981

×
982
        channel, err := h.findChannel(hn, chanPoint)
×
983
        require.NoErrorf(h, err, "channel not found using %v", chanPoint)
×
UNCOV
984

×
UNCOV
985
        return channel
×
UNCOV
986
}
×
987

988
// GetChannelCommitType retrieves the active channel commitment type for the
989
// given chan point.
990
func (h *HarnessTest) GetChannelCommitType(hn *node.HarnessNode,
991
        chanPoint *lnrpc.ChannelPoint) lnrpc.CommitmentType {
×
992

×
993
        c := h.GetChannelByChanPoint(hn, chanPoint)
×
UNCOV
994

×
UNCOV
995
        return c.CommitmentType
×
UNCOV
996
}
×
997

998
// AssertNumPendingOpenChannels asserts that a given node have the expected
999
// number of pending open channels.
1000
func (h *HarnessTest) AssertNumPendingOpenChannels(hn *node.HarnessNode,
1001
        expected int) []*lnrpc.PendingChannelsResponse_PendingOpenChannel {
×
1002

×
1003
        var channels []*lnrpc.PendingChannelsResponse_PendingOpenChannel
×
1004

×
1005
        oldNum := hn.State.OpenChannel.Pending
×
1006

×
1007
        err := wait.NoError(func() error {
×
1008
                resp := hn.RPC.PendingChannels()
×
1009
                channels = resp.PendingOpenChannels
×
1010
                total := len(channels)
×
1011

×
1012
                numChans := total - oldNum
×
1013

×
1014
                if numChans != expected {
×
1015
                        return errNumNotMatched(hn.Name(),
×
UNCOV
1016
                                "pending open channels", expected,
×
1017
                                numChans, total, oldNum)
×
UNCOV
1018
                }
×
1019

1020
                return nil
×
1021
        }, DefaultTimeout)
1022

UNCOV
1023
        require.NoError(h, err, "num of pending open channels not match")
×
UNCOV
1024

×
UNCOV
1025
        return channels
×
1026
}
1027

1028
// AssertNodesNumPendingOpenChannels asserts that both of the nodes have the
1029
// expected number of pending open channels.
1030
func (h *HarnessTest) AssertNodesNumPendingOpenChannels(a, b *node.HarnessNode,
1031
        expected int) {
×
1032

×
UNCOV
1033
        h.AssertNumPendingOpenChannels(a, expected)
×
UNCOV
1034
        h.AssertNumPendingOpenChannels(b, expected)
×
UNCOV
1035
}
×
1036

1037
// AssertPaymentStatusFromStream takes a client stream and asserts the payment
1038
// is in desired status before default timeout. The payment found is returned
1039
// once succeeded.
1040
func (h *HarnessTest) AssertPaymentStatusFromStream(stream rpc.PaymentClient,
1041
        status lnrpc.Payment_PaymentStatus) *lnrpc.Payment {
×
1042

×
1043
        return h.assertPaymentStatusWithTimeout(
×
UNCOV
1044
                stream, status, wait.PaymentTimeout,
×
UNCOV
1045
        )
×
UNCOV
1046
}
×
1047

1048
// AssertPaymentSucceedWithTimeout asserts that a payment is succeeded within
1049
// the specified timeout.
1050
func (h *HarnessTest) AssertPaymentSucceedWithTimeout(stream rpc.PaymentClient,
1051
        timeout time.Duration) *lnrpc.Payment {
×
1052

×
1053
        return h.assertPaymentStatusWithTimeout(
×
UNCOV
1054
                stream, lnrpc.Payment_SUCCEEDED, timeout,
×
UNCOV
1055
        )
×
UNCOV
1056
}
×
1057

1058
// assertPaymentStatusWithTimeout takes a client stream and asserts the payment
1059
// is in desired status before the specified timeout. The payment found is
1060
// returned once succeeded.
1061
func (h *HarnessTest) assertPaymentStatusWithTimeout(stream rpc.PaymentClient,
1062
        status lnrpc.Payment_PaymentStatus,
1063
        timeout time.Duration) *lnrpc.Payment {
×
1064

×
1065
        var target *lnrpc.Payment
×
1066
        err := wait.NoError(func() error {
×
1067
                // Consume one message. This will raise an error if the message
×
1068
                // is not received within DefaultTimeout.
×
1069
                payment, err := h.receivePaymentUpdateWithTimeout(
×
1070
                        stream, timeout,
×
1071
                )
×
1072
                if err != nil {
×
UNCOV
1073
                        return fmt.Errorf("received error from payment "+
×
UNCOV
1074
                                "stream: %s", err)
×
1075
                }
×
1076

1077
                // Return if the desired payment state is reached.
1078
                if payment.Status == status {
×
1079
                        target = payment
×
UNCOV
1080

×
UNCOV
1081
                        return nil
×
UNCOV
1082
                }
×
1083

1084
                // Return the err so that it can be used for debugging when
1085
                // timeout is reached.
UNCOV
1086
                return fmt.Errorf("payment %v status, got %v, want %v",
×
1087
                        payment.PaymentHash, payment.Status, status)
×
1088
        }, timeout)
1089

UNCOV
1090
        require.NoError(h, err, "timeout while waiting payment")
×
UNCOV
1091

×
UNCOV
1092
        return target
×
1093
}
1094

1095
// ReceivePaymentUpdate waits until a message is received on the payment client
1096
// stream or the timeout is reached.
1097
func (h *HarnessTest) ReceivePaymentUpdate(
1098
        stream rpc.PaymentClient) (*lnrpc.Payment, error) {
×
UNCOV
1099

×
UNCOV
1100
        return h.receivePaymentUpdateWithTimeout(stream, DefaultTimeout)
×
UNCOV
1101
}
×
1102

1103
// receivePaymentUpdateWithTimeout waits until a message is received on the
1104
// payment client stream or the timeout is reached.
1105
func (h *HarnessTest) receivePaymentUpdateWithTimeout(stream rpc.PaymentClient,
1106
        timeout time.Duration) (*lnrpc.Payment, error) {
×
1107

×
1108
        chanMsg := make(chan *lnrpc.Payment, 1)
×
1109
        errChan := make(chan error, 1)
×
1110

×
1111
        go func() {
×
1112
                // Consume one message. This will block until the message is
×
1113
                // received.
×
1114
                resp, err := stream.Recv()
×
1115
                if err != nil {
×
1116
                        errChan <- err
×
1117

×
UNCOV
1118
                        return
×
UNCOV
1119
                }
×
1120
                chanMsg <- resp
×
1121
        }()
1122

1123
        select {
×
UNCOV
1124
        case <-time.After(timeout):
×
1125
                require.Fail(h, "timeout", "timeout waiting for payment update")
×
1126
                return nil, nil
×
1127

1128
        case err := <-errChan:
×
1129
                return nil, err
×
1130

UNCOV
1131
        case updateMsg := <-chanMsg:
×
UNCOV
1132
                return updateMsg, nil
×
1133
        }
1134
}
1135

1136
// AssertInvoiceSettled asserts a given invoice specified by its payment
1137
// address is settled.
1138
func (h *HarnessTest) AssertInvoiceSettled(hn *node.HarnessNode, addr []byte) {
×
1139
        msg := &invoicesrpc.LookupInvoiceMsg{
×
1140
                InvoiceRef: &invoicesrpc.LookupInvoiceMsg_PaymentAddr{
×
1141
                        PaymentAddr: addr,
×
1142
                },
×
1143
        }
×
1144

×
1145
        err := wait.NoError(func() error {
×
1146
                invoice := hn.RPC.LookupInvoiceV2(msg)
×
UNCOV
1147
                if invoice.State == lnrpc.Invoice_SETTLED {
×
1148
                        return nil
×
1149
                }
×
1150

1151
                return fmt.Errorf("%s: invoice with payment address %x not "+
×
UNCOV
1152
                        "settled", hn.Name(), addr)
×
1153
        }, DefaultTimeout)
UNCOV
1154
        require.NoError(h, err, "timeout waiting for invoice settled state")
×
1155
}
1156

1157
// AssertNodeNumChannels polls the provided node's list channels rpc until it
1158
// reaches the desired number of total channels.
1159
func (h *HarnessTest) AssertNodeNumChannels(hn *node.HarnessNode,
1160
        numChannels int) {
×
1161

×
1162
        // Get the total number of channels.
×
1163
        old := hn.State.OpenChannel.Active + hn.State.OpenChannel.Inactive
×
1164

×
1165
        err := wait.NoError(func() error {
×
1166
                // We require the RPC call to be succeeded and won't wait for
×
1167
                // it as it's an unexpected behavior.
×
1168
                chanInfo := hn.RPC.ListChannels(&lnrpc.ListChannelsRequest{})
×
1169

×
1170
                // Return true if the query returned the expected number of
×
1171
                // channels.
×
1172
                num := len(chanInfo.Channels) - old
×
1173
                if num != numChannels {
×
UNCOV
1174
                        return fmt.Errorf("expected %v channels, got %v",
×
1175
                                numChannels, num)
×
UNCOV
1176
                }
×
1177

1178
                return nil
×
1179
        }, DefaultTimeout)
1180

UNCOV
1181
        require.NoError(h, err, "timeout checking node's num of channels")
×
1182
}
1183

1184
// AssertChannelLocalBalance checks the local balance of the given channel is
1185
// expected. The channel found using the specified channel point is returned.
1186
func (h *HarnessTest) AssertChannelLocalBalance(hn *node.HarnessNode,
1187
        cp *lnrpc.ChannelPoint, balance int64) *lnrpc.Channel {
×
1188

×
1189
        var result *lnrpc.Channel
×
1190

×
1191
        // Get the funding point.
×
1192
        err := wait.NoError(func() error {
×
1193
                // Find the target channel first.
×
1194
                target, err := h.findChannel(hn, cp)
×
1195

×
1196
                // Exit early if the channel is not found.
×
UNCOV
1197
                if err != nil {
×
1198
                        return fmt.Errorf("check balance failed: %w", err)
×
1199
                }
×
1200

1201
                result = target
×
1202

×
1203
                // Check local balance.
×
UNCOV
1204
                if target.LocalBalance == balance {
×
1205
                        return nil
×
1206
                }
×
1207

UNCOV
1208
                return fmt.Errorf("balance is incorrect, got %v, expected %v",
×
1209
                        target.LocalBalance, balance)
×
1210
        }, DefaultTimeout)
1211

UNCOV
1212
        require.NoError(h, err, "timeout while checking for balance")
×
UNCOV
1213

×
UNCOV
1214
        return result
×
1215
}
1216

1217
// AssertChannelNumUpdates checks the num of updates is expected from the given
1218
// channel.
1219
func (h *HarnessTest) AssertChannelNumUpdates(hn *node.HarnessNode,
1220
        num uint64, cp *lnrpc.ChannelPoint) {
×
1221

×
1222
        old := int(hn.State.OpenChannel.NumUpdates)
×
1223

×
1224
        // Find the target channel first.
×
1225
        target, err := h.findChannel(hn, cp)
×
1226
        require.NoError(h, err, "unable to find channel")
×
1227

×
1228
        err = wait.NoError(func() error {
×
1229
                total := int(target.NumUpdates)
×
UNCOV
1230
                if total-old == int(num) {
×
1231
                        return nil
×
1232
                }
×
1233

1234
                return errNumNotMatched(hn.Name(), "channel updates",
×
UNCOV
1235
                        int(num), total-old, total, old)
×
1236
        }, DefaultTimeout)
UNCOV
1237
        require.NoError(h, err, "timeout while checking for num of updates")
×
1238
}
1239

1240
// AssertNumActiveHtlcs asserts that a given number of HTLCs are seen in the
1241
// node's channels.
1242
func (h *HarnessTest) AssertNumActiveHtlcs(hn *node.HarnessNode, num int) {
×
1243
        old := hn.State.HTLC
×
1244

×
1245
        err := wait.NoError(func() error {
×
1246
                // pendingHTLCs is used to print unacked HTLCs, if found.
×
1247
                var pendingHTLCs []string
×
1248

×
1249
                // We require the RPC call to be succeeded and won't wait for
×
1250
                // it as it's an unexpected behavior.
×
1251
                req := &lnrpc.ListChannelsRequest{}
×
1252
                nodeChans := hn.RPC.ListChannels(req)
×
1253

×
1254
                total := 0
×
1255
                for _, channel := range nodeChans.Channels {
×
1256
                        for _, htlc := range channel.PendingHtlcs {
×
UNCOV
1257
                                if htlc.LockedIn {
×
1258
                                        total++
×
1259
                                }
×
1260

UNCOV
1261
                                rHash := fmt.Sprintf("%x", htlc.HashLock)
×
1262
                                pendingHTLCs = append(pendingHTLCs, rHash)
×
1263
                        }
1264
                }
1265
                if total-old != num {
×
1266
                        desc := fmt.Sprintf("active HTLCs: unacked HTLCs: %v",
×
1267
                                pendingHTLCs)
×
1268

×
UNCOV
1269
                        return errNumNotMatched(hn.Name(), desc,
×
1270
                                num, total-old, total, old)
×
UNCOV
1271
                }
×
1272

1273
                return nil
×
1274
        }, DefaultTimeout)
1275

UNCOV
1276
        require.NoErrorf(h, err, "%s timeout checking num active htlcs",
×
UNCOV
1277
                hn.Name())
×
1278
}
1279

1280
// AssertIncomingHTLCActive asserts the node has a pending incoming HTLC in the
1281
// given channel. Returns the HTLC if found and active.
1282
func (h *HarnessTest) AssertIncomingHTLCActive(hn *node.HarnessNode,
1283
        cp *lnrpc.ChannelPoint, payHash []byte) *lnrpc.HTLC {
×
UNCOV
1284

×
UNCOV
1285
        return h.assertHTLCActive(hn, cp, payHash, true)
×
UNCOV
1286
}
×
1287

1288
// AssertOutgoingHTLCActive asserts the node has a pending outgoing HTLC in the
1289
// given channel. Returns the HTLC if found and active.
1290
func (h *HarnessTest) AssertOutgoingHTLCActive(hn *node.HarnessNode,
1291
        cp *lnrpc.ChannelPoint, payHash []byte) *lnrpc.HTLC {
×
UNCOV
1292

×
UNCOV
1293
        return h.assertHTLCActive(hn, cp, payHash, false)
×
UNCOV
1294
}
×
1295

1296
// assertHLTCActive asserts the node has a pending HTLC in the given channel.
1297
// Returns the HTLC if found and active.
1298
func (h *HarnessTest) assertHTLCActive(hn *node.HarnessNode,
1299
        cp *lnrpc.ChannelPoint, payHash []byte, incoming bool) *lnrpc.HTLC {
×
1300

×
1301
        var result *lnrpc.HTLC
×
1302
        target := hex.EncodeToString(payHash)
×
1303

×
1304
        err := wait.NoError(func() error {
×
1305
                // We require the RPC call to be succeeded and won't wait for
×
1306
                // it as it's an unexpected behavior.
×
1307
                ch := h.GetChannelByChanPoint(hn, cp)
×
1308

×
1309
                // Check all payment hashes active for this channel.
×
1310
                for _, htlc := range ch.PendingHtlcs {
×
UNCOV
1311
                        rHash := hex.EncodeToString(htlc.HashLock)
×
UNCOV
1312
                        if rHash != target {
×
UNCOV
1313
                                continue
×
1314
                        }
1315

1316
                        // If the payment hash is found, check the incoming
1317
                        // field.
1318
                        if htlc.Incoming == incoming {
×
1319
                                // Return the result if it's locked in.
×
1320
                                if htlc.LockedIn {
×
UNCOV
1321
                                        result = htlc
×
1322
                                        return nil
×
1323
                                }
×
1324

UNCOV
1325
                                return fmt.Errorf("htlc(%x) not locked in",
×
UNCOV
1326
                                        payHash)
×
1327
                        }
1328

1329
                        // Otherwise we do have the HTLC but its direction is
1330
                        // not right.
1331
                        have, want := "outgoing", "incoming"
×
UNCOV
1332
                        if htlc.Incoming {
×
1333
                                have, want = "incoming", "outgoing"
×
1334
                        }
×
1335

UNCOV
1336
                        return fmt.Errorf("htlc(%x) has wrong direction - "+
×
1337
                                "want: %s, have: %s", payHash, want, have)
×
1338
                }
1339

1340
                return fmt.Errorf("htlc not found using payHash %x", payHash)
×
1341
        }, DefaultTimeout)
UNCOV
1342
        require.NoError(h, err, "%s: timeout checking pending HTLC", hn.Name())
×
UNCOV
1343

×
UNCOV
1344
        return result
×
1345
}
1346

1347
// AssertHLTCNotActive asserts the node doesn't have a pending HTLC in the
1348
// given channel, which mean either the HTLC never exists, or it was pending
1349
// and now settled. Returns the HTLC if found and active.
1350
//
1351
// NOTE: to check a pending HTLC becoming settled, first use AssertHLTCActive
1352
// then follow this check.
1353
func (h *HarnessTest) AssertHTLCNotActive(hn *node.HarnessNode,
1354
        cp *lnrpc.ChannelPoint, payHash []byte) *lnrpc.HTLC {
×
1355

×
1356
        var result *lnrpc.HTLC
×
1357
        target := hex.EncodeToString(payHash)
×
1358

×
1359
        err := wait.NoError(func() error {
×
1360
                // We require the RPC call to be succeeded and won't wait for
×
1361
                // it as it's an unexpected behavior.
×
1362
                ch := h.GetChannelByChanPoint(hn, cp)
×
1363

×
1364
                // Check all payment hashes active for this channel.
×
1365
                for _, htlc := range ch.PendingHtlcs {
×
1366
                        h := hex.EncodeToString(htlc.HashLock)
×
1367

×
1368
                        // Break if found the htlc.
×
UNCOV
1369
                        if h == target {
×
UNCOV
1370
                                result = htlc
×
UNCOV
1371
                                break
×
1372
                        }
1373
                }
1374

1375
                // If we've found nothing, we're done.
UNCOV
1376
                if result == nil {
×
UNCOV
1377
                        return nil
×
1378
                }
×
1379

1380
                // Otherwise return an error.
1381
                return fmt.Errorf("node [%s:%x] still has: the payHash %x",
×
1382
                        hn.Name(), hn.PubKey[:], payHash)
×
1383
        }, DefaultTimeout)
UNCOV
1384
        require.NoError(h, err, "timeout checking pending HTLC")
×
UNCOV
1385

×
UNCOV
1386
        return result
×
1387
}
1388

1389
// ReceiveSingleInvoice waits until a message is received on the subscribe
1390
// single invoice stream or the timeout is reached.
1391
func (h *HarnessTest) ReceiveSingleInvoice(
1392
        stream rpc.SingleInvoiceClient) *lnrpc.Invoice {
×
1393

×
1394
        chanMsg := make(chan *lnrpc.Invoice, 1)
×
1395
        errChan := make(chan error, 1)
×
1396
        go func() {
×
1397
                // Consume one message. This will block until the message is
×
1398
                // received.
×
1399
                resp, err := stream.Recv()
×
1400
                if err != nil {
×
1401
                        errChan <- err
×
1402

×
UNCOV
1403
                        return
×
UNCOV
1404
                }
×
1405
                chanMsg <- resp
×
1406
        }()
1407

UNCOV
1408
        select {
×
1409
        case <-time.After(DefaultTimeout):
×
1410
                require.Fail(h, "timeout", "timeout receiving single invoice")
×
1411

UNCOV
1412
        case err := <-errChan:
×
1413
                require.Failf(h, "err from stream",
×
1414
                        "received err from stream: %v", err)
×
1415

UNCOV
1416
        case updateMsg := <-chanMsg:
×
1417
                return updateMsg
×
1418
        }
1419

UNCOV
1420
        return nil
×
1421
}
1422

1423
// AssertInvoiceState takes a single invoice subscription stream and asserts
1424
// that a given invoice has became the desired state before timeout and returns
1425
// the invoice found.
1426
func (h *HarnessTest) AssertInvoiceState(stream rpc.SingleInvoiceClient,
1427
        state lnrpc.Invoice_InvoiceState) *lnrpc.Invoice {
×
1428

×
1429
        var invoice *lnrpc.Invoice
×
1430

×
1431
        err := wait.NoError(func() error {
×
1432
                invoice = h.ReceiveSingleInvoice(stream)
×
UNCOV
1433
                if invoice.State == state {
×
1434
                        return nil
×
1435
                }
×
1436

1437
                return fmt.Errorf("mismatched invoice state, want %v, got %v",
×
1438
                        state, invoice.State)
×
1439
        }, DefaultTimeout)
UNCOV
1440
        require.NoError(h, err, "timeout waiting for invoice state: %v", state)
×
UNCOV
1441

×
UNCOV
1442
        return invoice
×
1443
}
1444

1445
// assertAllTxesSpendFrom asserts that all txes in the list spend from the
1446
// given tx.
1447
func (h *HarnessTest) AssertAllTxesSpendFrom(txes []*wire.MsgTx,
1448
        prevTxid chainhash.Hash) {
×
1449

×
1450
        for _, tx := range txes {
×
1451
                if tx.TxIn[0].PreviousOutPoint.Hash != prevTxid {
×
UNCOV
1452
                        require.Failf(h, "", "tx %v did not spend from %v",
×
UNCOV
1453
                                tx.TxHash(), prevTxid)
×
UNCOV
1454
                }
×
1455
        }
1456
}
1457

1458
// AssertTxSpendFrom asserts that a given tx is spent from a previous tx.
1459
func (h *HarnessTest) AssertTxSpendFrom(tx *wire.MsgTx,
1460
        prevTxid chainhash.Hash) {
×
1461

×
1462
        if tx.TxIn[0].PreviousOutPoint.Hash != prevTxid {
×
UNCOV
1463
                require.Failf(h, "", "tx %v did not spend from %v",
×
UNCOV
1464
                        tx.TxHash(), prevTxid)
×
UNCOV
1465
        }
×
1466
}
1467

1468
type PendingForceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel
1469

1470
// AssertChannelPendingForceClose asserts that the given channel found in the
1471
// node is pending force close. Returns the PendingForceClose if found.
1472
func (h *HarnessTest) AssertChannelPendingForceClose(hn *node.HarnessNode,
1473
        chanPoint *lnrpc.ChannelPoint) PendingForceClose {
×
1474

×
1475
        var target PendingForceClose
×
1476

×
1477
        op := h.OutPointFromChannelPoint(chanPoint)
×
1478

×
1479
        err := wait.NoError(func() error {
×
1480
                resp := hn.RPC.PendingChannels()
×
1481

×
1482
                forceCloseChans := resp.PendingForceClosingChannels
×
1483
                for _, ch := range forceCloseChans {
×
1484
                        if ch.Channel.ChannelPoint == op.String() {
×
1485
                                target = ch
×
UNCOV
1486

×
UNCOV
1487
                                return nil
×
1488
                        }
×
1489
                }
1490

1491
                return fmt.Errorf("%v: channel %s not found in pending "+
×
1492
                        "force close", hn.Name(), chanPoint)
×
1493
        }, DefaultTimeout)
UNCOV
1494
        require.NoError(h, err, "assert pending force close timed out")
×
UNCOV
1495

×
UNCOV
1496
        return target
×
1497
}
1498

1499
// AssertNumHTLCsAndStage takes a pending force close channel's channel point
1500
// and asserts the expected number of pending HTLCs and HTLC stage are matched.
1501
func (h *HarnessTest) AssertNumHTLCsAndStage(hn *node.HarnessNode,
1502
        chanPoint *lnrpc.ChannelPoint, num int, stage uint32) {
×
1503

×
1504
        // Get the channel output point.
×
1505
        cp := h.OutPointFromChannelPoint(chanPoint)
×
1506

×
1507
        var target PendingForceClose
×
1508
        checkStage := func() error {
×
1509
                resp := hn.RPC.PendingChannels()
×
UNCOV
1510
                if len(resp.PendingForceClosingChannels) == 0 {
×
1511
                        return fmt.Errorf("zero pending force closing channels")
×
1512
                }
×
1513

1514
                for _, ch := range resp.PendingForceClosingChannels {
×
1515
                        if ch.Channel.ChannelPoint == cp.String() {
×
UNCOV
1516
                                target = ch
×
UNCOV
1517

×
UNCOV
1518
                                break
×
1519
                        }
1520
                }
1521

1522
                if target == nil {
×
UNCOV
1523
                        return fmt.Errorf("cannot find pending force closing "+
×
1524
                                "channel using %v", cp)
×
1525
                }
×
1526

UNCOV
1527
                if target.LimboBalance == 0 {
×
1528
                        return fmt.Errorf("zero limbo balance")
×
1529
                }
×
1530

1531
                if len(target.PendingHtlcs) != num {
×
1532
                        return fmt.Errorf("got %d pending htlcs, want %d, %s",
×
UNCOV
1533
                                len(target.PendingHtlcs), num,
×
1534
                                lnutils.SpewLogClosure(target.PendingHtlcs)())
×
1535
                }
×
1536

UNCOV
1537
                for _, htlc := range target.PendingHtlcs {
×
UNCOV
1538
                        if htlc.Stage == stage {
×
1539
                                continue
×
1540
                        }
1541

UNCOV
1542
                        return fmt.Errorf("HTLC %s got stage: %v, "+
×
UNCOV
1543
                                "want stage: %v", htlc.Outpoint, htlc.Stage,
×
1544
                                stage)
×
1545
                }
1546

1547
                return nil
×
1548
        }
1549

UNCOV
1550
        require.NoErrorf(h, wait.NoError(checkStage, DefaultTimeout),
×
UNCOV
1551
                "timeout waiting for htlc stage")
×
1552
}
1553

1554
// findPayment queries the payment from the node's ListPayments which matches
1555
// the specified preimage hash.
1556
func (h *HarnessTest) findPayment(hn *node.HarnessNode,
1557
        paymentHash string) (*lnrpc.Payment, error) {
×
1558

×
1559
        req := &lnrpc.ListPaymentsRequest{IncludeIncomplete: true}
×
1560
        paymentsResp := hn.RPC.ListPayments(req)
×
1561

×
1562
        for _, p := range paymentsResp.Payments {
×
UNCOV
1563
                if p.PaymentHash == paymentHash {
×
UNCOV
1564
                        return p, nil
×
1565
                }
×
1566
        }
1567

UNCOV
1568
        return nil, fmt.Errorf("payment %v cannot be found", paymentHash)
×
1569
}
1570

1571
// PaymentCheck is a function that checks a payment for a specific condition.
1572
type PaymentCheck func(*lnrpc.Payment) error
1573

1574
// AssertPaymentStatus asserts that the given node list a payment with the given
1575
// payment hash has the expected status. It also checks that the payment has the
1576
// expected preimage, which is empty when it's not settled and matches the given
1577
// preimage when it's succeeded.
1578
func (h *HarnessTest) AssertPaymentStatus(hn *node.HarnessNode,
1579
        payHash lntypes.Hash, status lnrpc.Payment_PaymentStatus,
1580
        checks ...PaymentCheck) *lnrpc.Payment {
×
1581

×
1582
        var target *lnrpc.Payment
×
1583

×
1584
        err := wait.NoError(func() error {
×
1585
                p, err := h.findPayment(hn, payHash.String())
×
UNCOV
1586
                if err != nil {
×
1587
                        return err
×
1588
                }
×
1589

1590
                if status == p.Status {
×
UNCOV
1591
                        target = p
×
1592
                        return nil
×
1593
                }
×
1594

1595
                return fmt.Errorf("payment: %v status not match, want %s "+
×
1596
                        "got %s", payHash, status, p.Status)
×
1597
        }, DefaultTimeout)
UNCOV
1598
        require.NoError(h, err, "timeout checking payment status")
×
UNCOV
1599

×
1600
        switch status {
×
1601
        // If this expected status is SUCCEEDED, we expect the final
1602
        // preimage.
1603
        case lnrpc.Payment_SUCCEEDED:
×
1604
                preimage, err := lntypes.MakePreimageFromStr(
×
1605
                        target.PaymentPreimage,
×
UNCOV
1606
                )
×
UNCOV
1607
                require.NoError(h, err, "fail to make preimage")
×
1608
                require.Equal(h, payHash, preimage.Hash(), "preimage not match")
×
1609

1610
        // Otherwise we expect an all-zero preimage.
UNCOV
1611
        default:
×
UNCOV
1612
                require.Equal(h, (lntypes.Preimage{}).String(),
×
UNCOV
1613
                        target.PaymentPreimage, "expected zero preimage")
×
1614
        }
1615

1616
        // Perform any additional checks on the payment.
UNCOV
1617
        for _, check := range checks {
×
1618
                require.NoError(h, check(target))
×
UNCOV
1619
        }
×
1620

UNCOV
1621
        return target
×
1622
}
1623

1624
// AssertPaymentFailureReason asserts that the given node lists a payment with
1625
// the given preimage which has the expected failure reason.
1626
func (h *HarnessTest) AssertPaymentFailureReason(
1627
        hn *node.HarnessNode, preimage lntypes.Preimage,
1628
        reason lnrpc.PaymentFailureReason) *lnrpc.Payment {
×
1629

×
1630
        var payment *lnrpc.Payment
×
1631

×
1632
        payHash := preimage.Hash()
×
1633
        err := wait.NoError(func() error {
×
1634
                p, err := h.findPayment(hn, payHash.String())
×
UNCOV
1635
                if err != nil {
×
1636
                        return err
×
1637
                }
×
1638

1639
                payment = p
×
1640

×
UNCOV
1641
                if reason == p.FailureReason {
×
1642
                        return nil
×
1643
                }
×
1644

UNCOV
1645
                return fmt.Errorf("payment: %v failure reason not match, "+
×
1646
                        "want %s(%d) got %s(%d)", payHash, reason, reason,
×
1647
                        p.FailureReason, p.FailureReason)
×
1648
        }, DefaultTimeout)
UNCOV
1649
        require.NoError(h, err, "timeout checking payment failure reason")
×
UNCOV
1650

×
UNCOV
1651
        return payment
×
1652
}
1653

1654
// AssertPaymentFailureReasonAny asserts that the given node lists a payment
1655
// with the given preimage which has one of the expected failure reasons.
1656
func (h *HarnessTest) AssertPaymentFailureReasonAny(
1657
        hn *node.HarnessNode, preimage lntypes.Preimage,
1658
        reasons ...lnrpc.PaymentFailureReason) *lnrpc.Payment {
×
1659

×
1660
        var payment *lnrpc.Payment
×
1661

×
1662
        payHash := preimage.Hash()
×
1663
        err := wait.NoError(func() error {
×
1664
                p, err := h.findPayment(hn, payHash.String())
×
UNCOV
1665
                if err != nil {
×
1666
                        return err
×
1667
                }
×
1668

1669
                payment = p
×
1670

×
1671
                // Check if the payment failure reason matches any of the
×
1672
                // expected reasons.
×
1673
                for _, reason := range reasons {
×
UNCOV
1674
                        if reason == p.FailureReason {
×
UNCOV
1675
                                return nil
×
1676
                        }
×
1677
                }
1678

UNCOV
1679
                return fmt.Errorf("payment: %v failure reason not match, "+
×
1680
                        "want one of %v, got %s(%d)", payHash, reasons,
×
1681
                        p.FailureReason, p.FailureReason)
×
1682
        }, DefaultTimeout)
UNCOV
1683
        require.NoError(h, err, "timeout checking payment failure reason")
×
UNCOV
1684

×
UNCOV
1685
        return payment
×
1686
}
1687

1688
// AssertActiveNodesSynced asserts all active nodes have synced to the chain.
1689
func (h *HarnessTest) AssertActiveNodesSynced() {
×
UNCOV
1690
        for _, node := range h.manager.activeNodes {
×
UNCOV
1691
                h.WaitForBlockchainSync(node)
×
UNCOV
1692
        }
×
1693
}
1694

1695
// AssertActiveNodesSyncedTo asserts all active nodes have synced to the
1696
// provided bestBlock.
1697
func (h *HarnessTest) AssertActiveNodesSyncedTo(bestBlock chainhash.Hash) {
×
UNCOV
1698
        for _, node := range h.manager.activeNodes {
×
UNCOV
1699
                h.WaitForBlockchainSyncTo(node, bestBlock)
×
UNCOV
1700
        }
×
1701
}
1702

1703
// AssertPeerNotConnected asserts that the given node b is not connected to a.
1704
func (h *HarnessTest) AssertPeerNotConnected(a, b *node.HarnessNode) {
×
1705
        err := wait.NoError(func() error {
×
1706
                // We require the RPC call to be succeeded and won't wait for
×
1707
                // it as it's an unexpected behavior.
×
1708
                resp := a.RPC.ListPeers()
×
1709

×
1710
                // If node B is seen in the ListPeers response from node A,
×
1711
                // then we return false as the connection has been fully
×
1712
                // established.
×
1713
                for _, peer := range resp.Peers {
×
1714
                        if peer.PubKey == b.PubKeyStr {
×
UNCOV
1715
                                return fmt.Errorf("peers %s and %s still "+
×
UNCOV
1716
                                        "connected", a.Name(), b.Name())
×
1717
                        }
×
1718
                }
1719

UNCOV
1720
                return nil
×
1721
        }, DefaultTimeout)
UNCOV
1722
        require.NoError(h, err, "timeout checking peers not connected")
×
1723
}
1724

1725
// AssertNotConnected asserts that two peers are not connected.
1726
func (h *HarnessTest) AssertNotConnected(a, b *node.HarnessNode) {
×
1727
        // Sleep one second before the assertion to make sure that when there's
×
1728
        // a RPC call to connect, that RPC call is finished before the
×
1729
        // assertion.
×
1730
        time.Sleep(1 * time.Second)
×
1731

×
UNCOV
1732
        h.AssertPeerNotConnected(a, b)
×
UNCOV
1733
        h.AssertPeerNotConnected(b, a)
×
1734
}
×
1735

1736
// AssertConnected asserts that two peers are connected.
1737
func (h *HarnessTest) AssertConnected(a, b *node.HarnessNode) {
×
UNCOV
1738
        h.AssertPeerConnected(a, b)
×
UNCOV
1739
        h.AssertPeerConnected(b, a)
×
UNCOV
1740
}
×
1741

1742
// AssertAmountPaid checks that the ListChannels command of the provided
1743
// node list the total amount sent and received as expected for the
1744
// provided channel.
1745
func (h *HarnessTest) AssertAmountPaid(channelName string, hn *node.HarnessNode,
1746
        chanPoint *lnrpc.ChannelPoint, amountSent, amountReceived int64) {
×
1747

×
1748
        checkAmountPaid := func() error {
×
1749
                // Find the targeted channel.
×
1750
                channel, err := h.findChannel(hn, chanPoint)
×
UNCOV
1751
                if err != nil {
×
1752
                        return fmt.Errorf("assert amount failed: %w", err)
×
1753
                }
×
1754

1755
                if channel.TotalSatoshisSent != amountSent {
×
1756
                        return fmt.Errorf("%v: incorrect amount"+
×
1757
                                " sent: %v != %v", channelName,
×
1758
                                channel.TotalSatoshisSent,
×
1759
                                amountSent)
×
1760
                }
×
1761
                if channel.TotalSatoshisReceived !=
×
1762
                        amountReceived {
×
1763

×
1764
                        return fmt.Errorf("%v: incorrect amount"+
×
1765
                                " received: %v != %v",
×
1766
                                channelName,
×
UNCOV
1767
                                channel.TotalSatoshisReceived,
×
1768
                                amountReceived)
×
UNCOV
1769
                }
×
1770

UNCOV
1771
                return nil
×
1772
        }
1773

1774
        // As far as HTLC inclusion in commitment transaction might be
1775
        // postponed we will try to check the balance couple of times,
1776
        // and then if after some period of time we receive wrong
1777
        // balance return the error.
UNCOV
1778
        err := wait.NoError(checkAmountPaid, DefaultTimeout)
×
UNCOV
1779
        require.NoError(h, err, "timeout while checking amount paid")
×
1780
}
1781

1782
// AssertLastHTLCError checks that the last sent HTLC of the last payment sent
1783
// by the given node failed with the expected failure code.
1784
func (h *HarnessTest) AssertLastHTLCError(hn *node.HarnessNode,
1785
        code lnrpc.Failure_FailureCode) {
×
1786

×
UNCOV
1787
        // Use -1 to specify the last HTLC.
×
UNCOV
1788
        h.assertHTLCError(hn, code, -1)
×
UNCOV
1789
}
×
1790

1791
// AssertFirstHTLCError checks that the first HTLC of the last payment sent
1792
// by the given node failed with the expected failure code.
1793
func (h *HarnessTest) AssertFirstHTLCError(hn *node.HarnessNode,
1794
        code lnrpc.Failure_FailureCode) {
×
1795

×
UNCOV
1796
        // Use 0 to specify the first HTLC.
×
UNCOV
1797
        h.assertHTLCError(hn, code, 0)
×
UNCOV
1798
}
×
1799

1800
// assertLastHTLCError checks that the HTLC at the specified index of the last
1801
// payment sent by the given node failed with the expected failure code.
1802
func (h *HarnessTest) assertHTLCError(hn *node.HarnessNode,
1803
        code lnrpc.Failure_FailureCode, index int) {
×
1804

×
1805
        req := &lnrpc.ListPaymentsRequest{
×
1806
                IncludeIncomplete: true,
×
1807
        }
×
1808

×
1809
        err := wait.NoError(func() error {
×
1810
                paymentsResp := hn.RPC.ListPayments(req)
×
1811

×
1812
                payments := paymentsResp.Payments
×
UNCOV
1813
                if len(payments) == 0 {
×
1814
                        return fmt.Errorf("no payments found")
×
1815
                }
×
1816

1817
                payment := payments[len(payments)-1]
×
1818
                htlcs := payment.Htlcs
×
UNCOV
1819
                if len(htlcs) == 0 {
×
UNCOV
1820
                        return fmt.Errorf("no htlcs found")
×
1821
                }
×
1822

1823
                // If the index is greater than 0, check we have enough htlcs.
UNCOV
1824
                if index > 0 && len(htlcs) <= index {
×
UNCOV
1825
                        return fmt.Errorf("not enough htlcs")
×
UNCOV
1826
                }
×
1827

1828
                // If index is less than or equal to 0, we will read the last
1829
                // htlc.
UNCOV
1830
                if index <= 0 {
×
1831
                        index = len(htlcs) - 1
×
1832
                }
×
1833

1834
                htlc := htlcs[index]
×
1835

×
1836
                // The htlc must have a status of failed.
×
UNCOV
1837
                if htlc.Status != lnrpc.HTLCAttempt_FAILED {
×
1838
                        return fmt.Errorf("htlc should be failed")
×
1839
                }
×
1840
                // The failure field must not be empty.
UNCOV
1841
                if htlc.Failure == nil {
×
UNCOV
1842
                        return fmt.Errorf("expected htlc failure")
×
1843
                }
×
1844

1845
                // Exit if the expected code is found.
UNCOV
1846
                if htlc.Failure.Code == code {
×
1847
                        return nil
×
UNCOV
1848
                }
×
1849

1850
                return fmt.Errorf("unexpected failure code")
×
1851
        }, DefaultTimeout)
1852

UNCOV
1853
        require.NoError(h, err, "timeout checking HTLC error")
×
1854
}
1855

1856
// AssertZombieChannel asserts that a given channel found using the chanID is
1857
// marked as zombie.
1858
func (h *HarnessTest) AssertZombieChannel(hn *node.HarnessNode, chanID uint64) {
×
1859
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
1860
        defer cancel()
×
1861

×
1862
        err := wait.NoError(func() error {
×
1863
                _, err := hn.RPC.LN.GetChanInfo(
×
1864
                        ctxt, &lnrpc.ChanInfoRequest{ChanId: chanID},
×
1865
                )
×
UNCOV
1866
                if err == nil {
×
1867
                        return fmt.Errorf("expected error but got nil")
×
1868
                }
×
1869

1870
                if !strings.Contains(err.Error(), "marked as zombie") {
×
UNCOV
1871
                        return fmt.Errorf("expected error to contain '%s' but "+
×
1872
                                "was '%v'", "marked as zombie", err)
×
UNCOV
1873
                }
×
1874

UNCOV
1875
                return nil
×
1876
        }, DefaultTimeout)
UNCOV
1877
        require.NoError(h, err, "timeout while checking zombie channel")
×
1878
}
1879

1880
// AssertNotInGraph asserts that a given channel is either not found at all in
1881
// the graph or that it has been marked as a zombie.
1882
func (h *HarnessTest) AssertNotInGraph(hn *node.HarnessNode, chanID uint64) {
×
1883
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
1884
        defer cancel()
×
1885

×
1886
        err := wait.NoError(func() error {
×
1887
                _, err := hn.RPC.LN.GetChanInfo(
×
1888
                        ctxt, &lnrpc.ChanInfoRequest{ChanId: chanID},
×
1889
                )
×
UNCOV
1890
                if err == nil {
×
1891
                        return fmt.Errorf("expected error but got nil")
×
1892
                }
×
1893

UNCOV
1894
                switch {
×
1895
                case strings.Contains(err.Error(), "marked as zombie"):
×
1896
                        return nil
×
1897

1898
                case strings.Contains(err.Error(), "edge not found"):
×
1899
                        return nil
×
1900

1901
                default:
×
UNCOV
1902
                        return fmt.Errorf("expected error to contain either "+
×
UNCOV
1903
                                "'%s' or '%s' but was: '%v'", "marked as i"+
×
1904
                                "zombie", "edge not found", err)
×
1905
                }
1906
        }, DefaultTimeout)
UNCOV
1907
        require.NoError(h, err, "timeout while checking that channel is not "+
×
UNCOV
1908
                "found in graph")
×
1909
}
1910

1911
// AssertChannelInGraphDB asserts that a given channel is found in the graph db.
1912
func (h *HarnessTest) AssertChannelInGraphDB(hn *node.HarnessNode,
1913
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelEdge {
×
1914

×
1915
        ctxt, cancel := context.WithCancel(h.runCtx)
×
1916
        defer cancel()
×
1917

×
1918
        var edge *lnrpc.ChannelEdge
×
1919

×
1920
        op := h.OutPointFromChannelPoint(chanPoint)
×
1921
        err := wait.NoError(func() error {
×
1922
                resp, err := hn.RPC.LN.GetChanInfo(
×
1923
                        ctxt, &lnrpc.ChanInfoRequest{
×
1924
                                ChanPoint: op.String(),
×
1925
                        },
×
1926
                )
×
1927
                if err != nil {
×
UNCOV
1928
                        return fmt.Errorf("channel %s not found in graph: %w",
×
UNCOV
1929
                                op, err)
×
UNCOV
1930
                }
×
1931

1932
                // Make sure the policies are populated, otherwise this edge
1933
                // cannot be used for routing.
UNCOV
1934
                if resp.Node1Policy == nil {
×
1935
                        return fmt.Errorf("channel %s has no policy1", op)
×
1936
                }
×
1937

UNCOV
1938
                if resp.Node2Policy == nil {
×
1939
                        return fmt.Errorf("channel %s has no policy2", op)
×
1940
                }
×
1941

UNCOV
1942
                edge = resp
×
UNCOV
1943

×
1944
                return nil
×
1945
        }, DefaultTimeout)
1946

1947
        require.NoError(h, err, "%s: timeout finding channel in graph",
×
UNCOV
1948
                hn.Name())
×
UNCOV
1949

×
UNCOV
1950
        return edge
×
1951
}
1952

1953
// AssertChannelInGraphCache asserts a given channel is found in the graph
1954
// cache.
1955
func (h *HarnessTest) AssertChannelInGraphCache(hn *node.HarnessNode,
1956
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelEdge {
×
1957

×
1958
        var edge *lnrpc.ChannelEdge
×
1959

×
1960
        req := &lnrpc.ChannelGraphRequest{IncludeUnannounced: true}
×
1961
        cpStr := channelPointStr(chanPoint)
×
1962

×
1963
        err := wait.NoError(func() error {
×
1964
                chanGraph := hn.RPC.DescribeGraph(req)
×
1965

×
1966
                // Iterate all the known edges, and make sure the edge policies
×
1967
                // are populated when a matched edge is found.
×
UNCOV
1968
                for _, e := range chanGraph.Edges {
×
UNCOV
1969
                        if e.ChanPoint != cpStr {
×
1970
                                continue
×
1971
                        }
1972

1973
                        if e.Node1Policy == nil {
×
UNCOV
1974
                                return fmt.Errorf("no policy for node1 %v",
×
1975
                                        e.Node1Pub)
×
1976
                        }
×
1977

1978
                        if e.Node2Policy == nil {
×
UNCOV
1979
                                return fmt.Errorf("no policy for node2 %v",
×
1980
                                        e.Node1Pub)
×
1981
                        }
×
1982

UNCOV
1983
                        edge = e
×
UNCOV
1984

×
UNCOV
1985
                        return nil
×
1986
                }
1987

1988
                // If we've iterated over all the known edges and we weren't
1989
                // able to find this specific one, then we'll fail.
1990
                return fmt.Errorf("no edge found for channel point: %s", cpStr)
×
1991
        }, DefaultTimeout)
1992

1993
        require.NoError(h, err, "%s: timeout finding channel %v in graph cache",
×
UNCOV
1994
                cpStr, hn.Name())
×
UNCOV
1995

×
UNCOV
1996
        return edge
×
1997
}
1998

1999
// AssertChannelInGraphDB asserts that a given channel is found both in the
2000
// graph db (GetChanInfo) and the graph cache (DescribeGraph).
2001
func (h *HarnessTest) AssertChannelInGraph(hn *node.HarnessNode,
2002
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelEdge {
×
2003

×
2004
        // Make sure the channel is found in the db first.
×
2005
        h.AssertChannelInGraphDB(hn, chanPoint)
×
2006

×
2007
        // Assert the channel is also found in the graph cache, which refreshes
×
UNCOV
2008
        // every `--caches.rpc-graph-cache-duration`.
×
UNCOV
2009
        return h.AssertChannelInGraphCache(hn, chanPoint)
×
UNCOV
2010
}
×
2011

2012
// AssertTxAtHeight gets all of the transactions that a node's wallet has a
2013
// record of at the target height, and finds and returns the tx with the target
2014
// txid, failing if it is not found.
2015
func (h *HarnessTest) AssertTxAtHeight(hn *node.HarnessNode, height int32,
2016
        txid *chainhash.Hash) *lnrpc.Transaction {
×
2017

×
2018
        req := &lnrpc.GetTransactionsRequest{
×
2019
                StartHeight: height,
×
2020
                EndHeight:   height,
×
2021
        }
×
2022
        txns := hn.RPC.GetTransactions(req)
×
2023

×
2024
        for _, tx := range txns.Transactions {
×
UNCOV
2025
                if tx.TxHash == txid.String() {
×
UNCOV
2026
                        return tx
×
2027
                }
×
2028
        }
2029

2030
        require.Failf(h, "fail to find tx", "tx:%v not found at height:%v",
×
UNCOV
2031
                txid, height)
×
UNCOV
2032

×
UNCOV
2033
        return nil
×
2034
}
2035

2036
// getChannelPolicies queries the channel graph and retrieves the current edge
2037
// policies for the provided channel point.
2038
func (h *HarnessTest) getChannelPolicies(hn *node.HarnessNode,
2039
        advertisingNode string,
2040
        cp *lnrpc.ChannelPoint) (*lnrpc.RoutingPolicy, error) {
×
2041

×
2042
        req := &lnrpc.ChannelGraphRequest{IncludeUnannounced: true}
×
2043
        chanGraph := hn.RPC.DescribeGraph(req)
×
2044

×
2045
        cpStr := channelPointStr(cp)
×
UNCOV
2046
        for _, e := range chanGraph.Edges {
×
UNCOV
2047
                if e.ChanPoint != cpStr {
×
2048
                        continue
×
2049
                }
2050

UNCOV
2051
                if e.Node1Pub == advertisingNode {
×
2052
                        return e.Node1Policy, nil
×
UNCOV
2053
                }
×
2054

UNCOV
2055
                return e.Node2Policy, nil
×
2056
        }
2057

2058
        // If we've iterated over all the known edges and we weren't
2059
        // able to find this specific one, then we'll fail.
UNCOV
2060
        return nil, fmt.Errorf("did not find edge with advertisingNode: %s"+
×
UNCOV
2061
                ", channel point: %s", advertisingNode, cpStr)
×
2062
}
2063

2064
// AssertChannelPolicy asserts that the passed node's known channel policy for
2065
// the passed chanPoint is consistent with the expected policy values.
2066
func (h *HarnessTest) AssertChannelPolicy(hn *node.HarnessNode,
2067
        advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy,
2068
        chanPoint *lnrpc.ChannelPoint) {
×
2069

×
2070
        policy, err := h.getChannelPolicies(hn, advertisingNode, chanPoint)
×
2071
        require.NoErrorf(h, err, "%s: failed to find policy", hn.Name())
×
2072

×
UNCOV
2073
        err = node.CheckChannelPolicy(policy, expectedPolicy)
×
UNCOV
2074
        require.NoErrorf(h, err, "%s: check policy failed", hn.Name())
×
UNCOV
2075
}
×
2076

2077
// AssertNumPolicyUpdates asserts that a given number of channel policy updates
2078
// has been seen in the specified node.
2079
func (h *HarnessTest) AssertNumPolicyUpdates(hn *node.HarnessNode,
2080
        chanPoint *lnrpc.ChannelPoint,
2081
        advertisingNode *node.HarnessNode, num int) {
×
2082

×
2083
        op := h.OutPointFromChannelPoint(chanPoint)
×
2084

×
2085
        var policies []*node.PolicyUpdateInfo
×
2086

×
2087
        err := wait.NoError(func() error {
×
2088
                policyMap := hn.Watcher.GetPolicyUpdates(op)
×
2089
                nodePolicy, ok := policyMap[advertisingNode.PubKeyStr]
×
UNCOV
2090
                if ok {
×
2091
                        policies = nodePolicy
×
2092
                }
×
2093

UNCOV
2094
                if len(policies) == num {
×
2095
                        return nil
×
2096
                }
×
2097

2098
                p, err := json.MarshalIndent(policies, "", "\t")
×
2099
                require.NoError(h, err, "encode policy err")
×
2100

×
2101
                return fmt.Errorf("expected to find %d policy updates, "+
×
2102
                        "instead got: %d, chanPoint: %v, "+
×
UNCOV
2103
                        "advertisingNode: %s:%s, policy: %s", num,
×
UNCOV
2104
                        len(policies), op, advertisingNode.Name(),
×
2105
                        advertisingNode.PubKeyStr, p)
×
2106
        }, DefaultTimeout)
2107

UNCOV
2108
        require.NoError(h, err, "%s: timeout waiting for num of policy updates",
×
UNCOV
2109
                hn.Name())
×
2110
}
2111

2112
// AssertNumPayments asserts that the number of payments made within the test
2113
// scope is as expected, including the incomplete ones.
2114
func (h *HarnessTest) AssertNumPayments(hn *node.HarnessNode,
2115
        num int) []*lnrpc.Payment {
×
2116

×
2117
        // Get the number of payments we already have from the previous test.
×
2118
        have := hn.State.Payment.Total
×
2119

×
2120
        req := &lnrpc.ListPaymentsRequest{
×
2121
                IncludeIncomplete: true,
×
2122
                IndexOffset:       hn.State.Payment.LastIndexOffset,
×
2123
        }
×
2124

×
2125
        var payments []*lnrpc.Payment
×
2126
        err := wait.NoError(func() error {
×
2127
                resp := hn.RPC.ListPayments(req)
×
2128

×
2129
                payments = resp.Payments
×
UNCOV
2130
                if len(payments) == num {
×
2131
                        return nil
×
2132
                }
×
2133

2134
                return errNumNotMatched(hn.Name(), "num of payments",
×
2135
                        num, len(payments), have+len(payments), have)
×
2136
        }, DefaultTimeout)
2137
        require.NoError(h, err, "%s: timeout checking num of payments",
×
UNCOV
2138
                hn.Name())
×
UNCOV
2139

×
UNCOV
2140
        return payments
×
2141
}
2142

2143
// AssertNumNodeAnns asserts that a given number of node announcements has been
2144
// seen in the specified node.
2145
func (h *HarnessTest) AssertNumNodeAnns(hn *node.HarnessNode,
2146
        pubkey string, num int) []*lnrpc.NodeUpdate {
×
2147

×
2148
        // We will get the current number of channel updates first and add it
×
2149
        // to our expected number of newly created channel updates.
×
2150
        anns, err := hn.Watcher.WaitForNumNodeUpdates(pubkey, num)
×
2151
        require.NoError(h, err, "%s: failed to assert num of node anns",
×
2152
                hn.Name())
×
UNCOV
2153

×
UNCOV
2154
        return anns
×
UNCOV
2155
}
×
2156

2157
// AssertNumChannelUpdates asserts that a given number of channel updates has
2158
// been seen in the specified node's network topology.
2159
func (h *HarnessTest) AssertNumChannelUpdates(hn *node.HarnessNode,
2160
        chanPoint *lnrpc.ChannelPoint, num int) {
×
2161

×
2162
        op := h.OutPointFromChannelPoint(chanPoint)
×
2163
        err := hn.Watcher.WaitForNumChannelUpdates(op, num)
×
UNCOV
2164
        require.NoError(h, err, "%s: failed to assert num of channel updates",
×
UNCOV
2165
                hn.Name())
×
UNCOV
2166
}
×
2167

2168
// CreateBurnAddr creates a random burn address of the given type.
2169
func (h *HarnessTest) CreateBurnAddr(addrType lnrpc.AddressType) ([]byte,
2170
        btcutil.Address) {
×
2171

×
2172
        randomPrivKey, err := btcec.NewPrivateKey()
×
2173
        require.NoError(h, err)
×
2174

×
2175
        randomKeyBytes := randomPrivKey.PubKey().SerializeCompressed()
×
2176
        harnessNetParams := miner.HarnessNetParams
×
2177

×
2178
        var addr btcutil.Address
×
2179
        switch addrType {
×
2180
        case lnrpc.AddressType_WITNESS_PUBKEY_HASH:
×
UNCOV
2181
                addr, err = btcutil.NewAddressWitnessPubKeyHash(
×
2182
                        btcutil.Hash160(randomKeyBytes), harnessNetParams,
×
2183
                )
×
2184

2185
        case lnrpc.AddressType_TAPROOT_PUBKEY:
×
2186
                taprootKey := txscript.ComputeTaprootKeyNoScript(
×
2187
                        randomPrivKey.PubKey(),
×
2188
                )
×
UNCOV
2189
                addr, err = btcutil.NewAddressPubKey(
×
2190
                        schnorr.SerializePubKey(taprootKey), harnessNetParams,
×
2191
                )
×
2192

2193
        case lnrpc.AddressType_NESTED_PUBKEY_HASH:
×
2194
                var witnessAddr btcutil.Address
×
2195
                witnessAddr, err = btcutil.NewAddressWitnessPubKeyHash(
×
2196
                        btcutil.Hash160(randomKeyBytes), harnessNetParams,
×
2197
                )
×
2198
                require.NoError(h, err)
×
2199

×
UNCOV
2200
                addr, err = btcutil.NewAddressScriptHash(
×
2201
                        h.PayToAddrScript(witnessAddr), harnessNetParams,
×
2202
                )
×
2203

2204
        default:
×
2205
                h.Fatalf("Unsupported burn address type: %v", addrType)
×
2206
        }
UNCOV
2207
        require.NoError(h, err)
×
UNCOV
2208

×
UNCOV
2209
        return h.PayToAddrScript(addr), addr
×
2210
}
2211

2212
// ReceiveTrackPayment waits until a message is received on the track payment
2213
// stream or the timeout is reached.
2214
func (h *HarnessTest) ReceiveTrackPayment(
2215
        stream rpc.TrackPaymentClient) *lnrpc.Payment {
×
2216

×
2217
        chanMsg := make(chan *lnrpc.Payment)
×
2218
        errChan := make(chan error)
×
2219
        go func() {
×
2220
                // Consume one message. This will block until the message is
×
2221
                // received.
×
2222
                resp, err := stream.Recv()
×
2223
                if err != nil {
×
2224
                        errChan <- err
×
UNCOV
2225
                        return
×
UNCOV
2226
                }
×
2227
                chanMsg <- resp
×
2228
        }()
2229

UNCOV
2230
        select {
×
2231
        case <-time.After(DefaultTimeout):
×
2232
                require.Fail(h, "timeout", "timeout trakcing payment")
×
2233

UNCOV
2234
        case err := <-errChan:
×
2235
                require.Failf(h, "err from stream",
×
2236
                        "received err from stream: %v", err)
×
2237

UNCOV
2238
        case updateMsg := <-chanMsg:
×
2239
                return updateMsg
×
2240
        }
2241

UNCOV
2242
        return nil
×
2243
}
2244

2245
// ReceiveHtlcEvent waits until a message is received on the subscribe
2246
// htlc event stream or the timeout is reached.
2247
func (h *HarnessTest) ReceiveHtlcEvent(
2248
        stream rpc.HtlcEventsClient) *routerrpc.HtlcEvent {
×
2249

×
2250
        chanMsg := make(chan *routerrpc.HtlcEvent)
×
2251
        errChan := make(chan error)
×
2252
        go func() {
×
2253
                // Consume one message. This will block until the message is
×
2254
                // received.
×
2255
                resp, err := stream.Recv()
×
2256
                if err != nil {
×
2257
                        errChan <- err
×
UNCOV
2258
                        return
×
UNCOV
2259
                }
×
2260
                chanMsg <- resp
×
2261
        }()
2262

2263
        select {
×
UNCOV
2264
        case <-time.After(DefaultTimeout):
×
2265
                require.Fail(h, "timeout", "timeout receiving htlc "+
×
2266
                        "event update")
×
2267

UNCOV
2268
        case err := <-errChan:
×
2269
                require.Failf(h, "err from stream",
×
2270
                        "received err from stream: %v", err)
×
2271

UNCOV
2272
        case updateMsg := <-chanMsg:
×
2273
                return updateMsg
×
2274
        }
2275

UNCOV
2276
        return nil
×
2277
}
2278

2279
// AssertHtlcEventType consumes one event from a client and asserts the event
2280
// type is matched.
2281
func (h *HarnessTest) AssertHtlcEventType(client rpc.HtlcEventsClient,
2282
        userType routerrpc.HtlcEvent_EventType) *routerrpc.HtlcEvent {
×
2283

×
2284
        event := h.ReceiveHtlcEvent(client)
×
2285
        require.Equalf(h, userType, event.EventType, "wrong event type, "+
×
2286
                "want %v got %v", userType, event.EventType)
×
UNCOV
2287

×
UNCOV
2288
        return event
×
UNCOV
2289
}
×
2290

2291
// HtlcEvent maps the series of event types used in `*routerrpc.HtlcEvent_*`.
2292
type HtlcEvent int
2293

2294
const (
2295
        HtlcEventForward HtlcEvent = iota
2296
        HtlcEventForwardFail
2297
        HtlcEventSettle
2298
        HtlcEventLinkFail
2299
        HtlcEventFinal
2300
)
2301

2302
// AssertHtlcEventType consumes one event from a client and asserts both the
2303
// user event type the event.Event type is matched.
2304
func (h *HarnessTest) AssertHtlcEventTypes(client rpc.HtlcEventsClient,
2305
        userType routerrpc.HtlcEvent_EventType,
2306
        eventType HtlcEvent) *routerrpc.HtlcEvent {
×
2307

×
2308
        event := h.ReceiveHtlcEvent(client)
×
2309
        require.Equalf(h, userType, event.EventType, "wrong event type, "+
×
2310
                "want %v got %v", userType, event.EventType)
×
2311

×
2312
        var ok bool
×
2313

×
UNCOV
2314
        switch eventType {
×
2315
        case HtlcEventForward:
×
2316
                _, ok = event.Event.(*routerrpc.HtlcEvent_ForwardEvent)
×
2317

2318
        case HtlcEventForwardFail:
×
2319
                _, ok = event.Event.(*routerrpc.HtlcEvent_ForwardFailEvent)
×
2320

2321
        case HtlcEventSettle:
×
2322
                _, ok = event.Event.(*routerrpc.HtlcEvent_SettleEvent)
×
2323

2324
        case HtlcEventLinkFail:
×
2325
                _, ok = event.Event.(*routerrpc.HtlcEvent_LinkFailEvent)
×
2326

UNCOV
2327
        case HtlcEventFinal:
×
2328
                _, ok = event.Event.(*routerrpc.HtlcEvent_FinalHtlcEvent)
×
2329
        }
2330

2331
        require.Truef(h, ok, "wrong event type: %T, want %T", event.Event,
×
UNCOV
2332
                eventType)
×
UNCOV
2333

×
UNCOV
2334
        return event
×
2335
}
2336

2337
// AssertFeeReport checks that the fee report from the given node has the
2338
// desired day, week, and month sum values.
2339
func (h *HarnessTest) AssertFeeReport(hn *node.HarnessNode,
2340
        day, week, month int) {
×
2341

×
2342
        err := wait.NoError(func() error {
×
2343
                feeReport, err := hn.RPC.LN.FeeReport(
×
2344
                        h.runCtx, &lnrpc.FeeReportRequest{},
×
2345
                )
×
2346
                require.NoError(h, err, "unable to query for fee report")
×
2347

×
2348
                if uint64(day) != feeReport.DayFeeSum {
×
UNCOV
2349
                        return fmt.Errorf("day fee mismatch, want %d, got %d",
×
2350
                                day, feeReport.DayFeeSum)
×
2351
                }
×
2352

2353
                if uint64(week) != feeReport.WeekFeeSum {
×
2354
                        return fmt.Errorf("week fee mismatch, want %d, got %d",
×
2355
                                week, feeReport.WeekFeeSum)
×
2356
                }
×
2357
                if uint64(month) != feeReport.MonthFeeSum {
×
UNCOV
2358
                        return fmt.Errorf("month fee mismatch, want %d, got %d",
×
2359
                                month, feeReport.MonthFeeSum)
×
UNCOV
2360
                }
×
2361

UNCOV
2362
                return nil
×
2363
        }, wait.DefaultTimeout)
UNCOV
2364
        require.NoErrorf(h, err, "%s: time out checking fee report", hn.Name())
×
2365
}
2366

2367
// AssertHtlcEvents consumes events from a client and ensures that they are of
2368
// the expected type and contain the expected number of forwards, forward
2369
// failures and settles.
2370
//
2371
// TODO(yy): needs refactor to reduce its complexity.
2372
func (h *HarnessTest) AssertHtlcEvents(client rpc.HtlcEventsClient,
2373
        fwdCount, fwdFailCount, settleCount, linkFailCount int,
2374
        userType routerrpc.HtlcEvent_EventType) []*routerrpc.HtlcEvent {
×
2375

×
2376
        var forwards, forwardFails, settles, linkFails int
×
2377

×
2378
        numEvents := fwdCount + fwdFailCount + settleCount + linkFailCount
×
2379
        events := make([]*routerrpc.HtlcEvent, 0)
×
2380

×
2381
        // It's either the userType or the unknown type.
×
2382
        //
×
2383
        // TODO(yy): maybe the FinalHtlcEvent shouldn't be in UNKNOWN type?
×
2384
        eventTypes := []routerrpc.HtlcEvent_EventType{
×
2385
                userType, routerrpc.HtlcEvent_UNKNOWN,
×
2386
        }
×
2387

×
2388
        for i := 0; i < numEvents; i++ {
×
2389
                event := h.ReceiveHtlcEvent(client)
×
2390

×
2391
                require.Containsf(h, eventTypes, event.EventType,
×
2392
                        "wrong event type, want %v, got %v", userType,
×
2393
                        event.EventType)
×
2394

×
2395
                events = append(events, event)
×
2396

×
UNCOV
2397
                switch e := event.Event.(type) {
×
2398
                case *routerrpc.HtlcEvent_ForwardEvent:
×
2399
                        forwards++
×
2400

2401
                case *routerrpc.HtlcEvent_ForwardFailEvent:
×
2402
                        forwardFails++
×
2403

2404
                case *routerrpc.HtlcEvent_SettleEvent:
×
2405
                        settles++
×
2406

2407
                case *routerrpc.HtlcEvent_FinalHtlcEvent:
×
UNCOV
2408
                        if e.FinalHtlcEvent.Settled {
×
2409
                                settles++
×
2410
                        }
×
2411

2412
                case *routerrpc.HtlcEvent_LinkFailEvent:
×
2413
                        linkFails++
×
2414

UNCOV
2415
                default:
×
UNCOV
2416
                        require.Fail(h, "assert event fail",
×
UNCOV
2417
                                "unexpected event: %T", event.Event)
×
2418
                }
2419
        }
2420

2421
        require.Equal(h, fwdCount, forwards, "num of forwards mismatch")
×
2422
        require.Equal(h, fwdFailCount, forwardFails,
×
2423
                "num of forward fails mismatch")
×
2424
        require.Equal(h, settleCount, settles, "num of settles mismatch")
×
UNCOV
2425
        require.Equal(h, linkFailCount, linkFails, "num of link fails mismatch")
×
UNCOV
2426

×
UNCOV
2427
        return events
×
2428
}
2429

2430
// AssertTransactionInWallet asserts a given txid can be found in the node's
2431
// wallet.
2432
func (h *HarnessTest) AssertTransactionInWallet(hn *node.HarnessNode,
2433
        txid chainhash.Hash) {
×
2434

×
2435
        req := &lnrpc.GetTransactionsRequest{}
×
2436
        err := wait.NoError(func() error {
×
2437
                txResp := hn.RPC.GetTransactions(req)
×
2438
                for _, txn := range txResp.Transactions {
×
UNCOV
2439
                        if txn.TxHash == txid.String() {
×
UNCOV
2440
                                return nil
×
2441
                        }
×
2442
                }
2443

UNCOV
2444
                return fmt.Errorf("%s: expected txid=%v not found in wallet",
×
2445
                        hn.Name(), txid)
×
2446
        }, DefaultTimeout)
2447

UNCOV
2448
        require.NoError(h, err, "failed to find tx")
×
2449
}
2450

2451
// AssertTransactionNotInWallet asserts a given txid can NOT be found in the
2452
// node's wallet.
2453
func (h *HarnessTest) AssertTransactionNotInWallet(hn *node.HarnessNode,
2454
        txid chainhash.Hash) {
×
2455

×
2456
        req := &lnrpc.GetTransactionsRequest{}
×
2457
        err := wait.NoError(func() error {
×
2458
                txResp := hn.RPC.GetTransactions(req)
×
2459
                for _, txn := range txResp.Transactions {
×
2460
                        if txn.TxHash == txid.String() {
×
UNCOV
2461
                                return fmt.Errorf("expected txid=%v to be "+
×
UNCOV
2462
                                        "not found", txid)
×
2463
                        }
×
2464
                }
2465

2466
                return nil
×
2467
        }, DefaultTimeout)
2468

UNCOV
2469
        require.NoErrorf(h, err, "%s: failed to assert tx not found", hn.Name())
×
2470
}
2471

2472
// WaitForNodeBlockHeight queries the node for its current block height until
2473
// it reaches the passed height.
2474
func (h *HarnessTest) WaitForNodeBlockHeight(hn *node.HarnessNode,
2475
        height int32) {
×
2476

×
2477
        err := wait.NoError(func() error {
×
2478
                info := hn.RPC.GetInfo()
×
2479
                if int32(info.BlockHeight) != height {
×
UNCOV
2480
                        return fmt.Errorf("expected block height to "+
×
2481
                                "be %v, was %v", height, info.BlockHeight)
×
UNCOV
2482
                }
×
2483

2484
                return nil
×
2485
        }, DefaultTimeout)
2486

UNCOV
2487
        require.NoErrorf(h, err, "%s: timeout while waiting for height",
×
UNCOV
2488
                hn.Name())
×
2489
}
2490

2491
// AssertChannelCommitHeight asserts the given channel for the node has the
2492
// expected commit height(`NumUpdates`).
2493
func (h *HarnessTest) AssertChannelCommitHeight(hn *node.HarnessNode,
2494
        cp *lnrpc.ChannelPoint, height int) {
×
2495

×
2496
        err := wait.NoError(func() error {
×
2497
                c, err := h.findChannel(hn, cp)
×
UNCOV
2498
                if err != nil {
×
2499
                        return err
×
2500
                }
×
2501

UNCOV
2502
                if int(c.NumUpdates) == height {
×
2503
                        return nil
×
2504
                }
×
2505

UNCOV
2506
                return fmt.Errorf("expected commit height to be %v, was %v",
×
2507
                        height, c.NumUpdates)
×
2508
        }, DefaultTimeout)
2509

UNCOV
2510
        require.NoError(h, err, "timeout while waiting for commit height")
×
2511
}
2512

2513
// AssertNumInvoices asserts that the number of invoices made within the test
2514
// scope is as expected.
2515
func (h *HarnessTest) AssertNumInvoices(hn *node.HarnessNode,
2516
        num int) []*lnrpc.Invoice {
×
2517

×
2518
        have := hn.State.Invoice.Total
×
2519
        req := &lnrpc.ListInvoiceRequest{
×
2520
                NumMaxInvoices: math.MaxUint64,
×
2521
                IndexOffset:    hn.State.Invoice.LastIndexOffset,
×
2522
        }
×
2523

×
2524
        var invoices []*lnrpc.Invoice
×
2525
        err := wait.NoError(func() error {
×
2526
                resp := hn.RPC.ListInvoices(req)
×
2527

×
2528
                invoices = resp.Invoices
×
UNCOV
2529
                if len(invoices) == num {
×
2530
                        return nil
×
2531
                }
×
2532

2533
                return errNumNotMatched(hn.Name(), "num of invoices",
×
2534
                        num, len(invoices), have+len(invoices), have)
×
2535
        }, DefaultTimeout)
UNCOV
2536
        require.NoError(h, err, "timeout checking num of invoices")
×
UNCOV
2537

×
UNCOV
2538
        return invoices
×
2539
}
2540

2541
// ReceiveSendToRouteUpdate waits until a message is received on the
2542
// SendToRoute client stream or the timeout is reached.
2543
func (h *HarnessTest) ReceiveSendToRouteUpdate(
2544
        stream rpc.SendToRouteClient) (*lnrpc.SendResponse, error) {
×
2545

×
2546
        chanMsg := make(chan *lnrpc.SendResponse, 1)
×
2547
        errChan := make(chan error, 1)
×
2548
        go func() {
×
2549
                // Consume one message. This will block until the message is
×
2550
                // received.
×
2551
                resp, err := stream.Recv()
×
2552
                if err != nil {
×
2553
                        errChan <- err
×
2554

×
UNCOV
2555
                        return
×
UNCOV
2556
                }
×
2557
                chanMsg <- resp
×
2558
        }()
2559

2560
        select {
×
UNCOV
2561
        case <-time.After(DefaultTimeout):
×
2562
                require.Fail(h, "timeout", "timeout waiting for send resp")
×
2563
                return nil, nil
×
2564

2565
        case err := <-errChan:
×
2566
                return nil, err
×
2567

UNCOV
2568
        case updateMsg := <-chanMsg:
×
UNCOV
2569
                return updateMsg, nil
×
2570
        }
2571
}
2572

2573
// AssertInvoiceEqual asserts that two lnrpc.Invoices are equivalent. A custom
2574
// comparison function is defined for these tests, since proto message returned
2575
// from unary and streaming RPCs (as of protobuf 1.23.0 and grpc 1.29.1) aren't
2576
// consistent with the private fields set on the messages. As a result, we
2577
// avoid using require.Equal and test only the actual data members.
2578
func (h *HarnessTest) AssertInvoiceEqual(a, b *lnrpc.Invoice) {
×
2579
        // Ensure the HTLCs are sorted properly before attempting to compare.
×
2580
        sort.Slice(a.Htlcs, func(i, j int) bool {
×
2581
                return a.Htlcs[i].ChanId < a.Htlcs[j].ChanId
×
2582
        })
×
UNCOV
2583
        sort.Slice(b.Htlcs, func(i, j int) bool {
×
2584
                return b.Htlcs[i].ChanId < b.Htlcs[j].ChanId
×
2585
        })
×
2586

2587
        require.Equal(h, a.Memo, b.Memo)
×
2588
        require.Equal(h, a.RPreimage, b.RPreimage)
×
2589
        require.Equal(h, a.RHash, b.RHash)
×
2590
        require.Equal(h, a.Value, b.Value)
×
2591
        require.Equal(h, a.ValueMsat, b.ValueMsat)
×
2592
        require.Equal(h, a.CreationDate, b.CreationDate)
×
2593
        require.Equal(h, a.SettleDate, b.SettleDate)
×
2594
        require.Equal(h, a.PaymentRequest, b.PaymentRequest)
×
2595
        require.Equal(h, a.DescriptionHash, b.DescriptionHash)
×
2596
        require.Equal(h, a.Expiry, b.Expiry)
×
2597
        require.Equal(h, a.FallbackAddr, b.FallbackAddr)
×
2598
        require.Equal(h, a.CltvExpiry, b.CltvExpiry)
×
2599
        require.Equal(h, a.RouteHints, b.RouteHints)
×
2600
        require.Equal(h, a.Private, b.Private)
×
2601
        require.Equal(h, a.AddIndex, b.AddIndex)
×
2602
        require.Equal(h, a.SettleIndex, b.SettleIndex)
×
2603
        require.Equal(h, a.AmtPaidSat, b.AmtPaidSat)
×
2604
        require.Equal(h, a.AmtPaidMsat, b.AmtPaidMsat)
×
2605
        require.Equal(h, a.State, b.State)
×
2606
        require.Equal(h, a.Features, b.Features)
×
2607
        require.Equal(h, a.IsKeysend, b.IsKeysend)
×
2608
        require.Equal(h, a.PaymentAddr, b.PaymentAddr)
×
2609
        require.Equal(h, a.IsAmp, b.IsAmp)
×
2610

×
2611
        require.Equal(h, len(a.Htlcs), len(b.Htlcs))
×
2612
        for i := range a.Htlcs {
×
2613
                htlcA, htlcB := a.Htlcs[i], b.Htlcs[i]
×
2614
                require.Equal(h, htlcA.ChanId, htlcB.ChanId)
×
2615
                require.Equal(h, htlcA.HtlcIndex, htlcB.HtlcIndex)
×
2616
                require.Equal(h, htlcA.AmtMsat, htlcB.AmtMsat)
×
2617
                require.Equal(h, htlcA.AcceptHeight, htlcB.AcceptHeight)
×
2618
                require.Equal(h, htlcA.AcceptTime, htlcB.AcceptTime)
×
2619
                require.Equal(h, htlcA.ResolveTime, htlcB.ResolveTime)
×
2620
                require.Equal(h, htlcA.ExpiryHeight, htlcB.ExpiryHeight)
×
2621
                require.Equal(h, htlcA.State, htlcB.State)
×
2622
                require.Equal(h, htlcA.CustomRecords, htlcB.CustomRecords)
×
UNCOV
2623
                require.Equal(h, htlcA.MppTotalAmtMsat, htlcB.MppTotalAmtMsat)
×
UNCOV
2624
                require.Equal(h, htlcA.Amp, htlcB.Amp)
×
UNCOV
2625
        }
×
2626
}
2627

2628
// AssertUTXOInWallet asserts that a given UTXO can be found in the node's
2629
// wallet.
2630
func (h *HarnessTest) AssertUTXOInWallet(hn *node.HarnessNode,
2631
        op *lnrpc.OutPoint, account string) {
×
2632

×
2633
        err := wait.NoError(func() error {
×
2634
                utxos := h.GetUTXOs(hn, account)
×
2635

×
2636
                err := fmt.Errorf("tx with hash %x not found", op.TxidBytes)
×
UNCOV
2637
                for _, utxo := range utxos {
×
UNCOV
2638
                        if !bytes.Equal(utxo.Outpoint.TxidBytes, op.TxidBytes) {
×
2639
                                continue
×
2640
                        }
2641

2642
                        err = fmt.Errorf("tx with output index %v not found",
×
UNCOV
2643
                                op.OutputIndex)
×
UNCOV
2644
                        if utxo.Outpoint.OutputIndex != op.OutputIndex {
×
2645
                                continue
×
2646
                        }
2647

2648
                        return nil
×
2649
                }
2650

2651
                return err
×
2652
        }, DefaultTimeout)
2653

UNCOV
2654
        require.NoErrorf(h, err, "outpoint %v not found in %s's wallet",
×
UNCOV
2655
                op, hn.Name())
×
2656
}
2657

2658
// AssertWalletAccountBalance asserts that the unconfirmed and confirmed
2659
// balance for the given account is satisfied by the WalletBalance and
2660
// ListUnspent RPCs. The unconfirmed balance is not checked for neutrino nodes.
2661
func (h *HarnessTest) AssertWalletAccountBalance(hn *node.HarnessNode,
2662
        account string, confirmedBalance, unconfirmedBalance int64) {
×
2663

×
2664
        err := wait.NoError(func() error {
×
2665
                balanceResp := hn.RPC.WalletBalance()
×
2666
                require.Contains(h, balanceResp.AccountBalance, account)
×
2667
                accountBalance := balanceResp.AccountBalance[account]
×
2668

×
2669
                // Check confirmed balance.
×
2670
                if accountBalance.ConfirmedBalance != confirmedBalance {
×
2671
                        return fmt.Errorf("expected confirmed balance %v, "+
×
UNCOV
2672
                                "got %v", confirmedBalance,
×
2673
                                accountBalance.ConfirmedBalance)
×
2674
                }
×
2675

2676
                utxos := h.GetUTXOsConfirmed(hn, account)
×
2677
                var totalConfirmedVal int64
×
2678
                for _, utxo := range utxos {
×
2679
                        totalConfirmedVal += utxo.AmountSat
×
2680
                }
×
2681
                if totalConfirmedVal != confirmedBalance {
×
2682
                        return fmt.Errorf("expected total confirmed utxo "+
×
UNCOV
2683
                                "balance %v, got %v", confirmedBalance,
×
UNCOV
2684
                                totalConfirmedVal)
×
2685
                }
×
2686

2687
                // Skip unconfirmed balance checks for neutrino nodes.
UNCOV
2688
                if h.IsNeutrinoBackend() {
×
UNCOV
2689
                        return nil
×
2690
                }
×
2691

2692
                // Check unconfirmed balance.
2693
                if accountBalance.UnconfirmedBalance != unconfirmedBalance {
×
2694
                        return fmt.Errorf("expected unconfirmed balance %v, "+
×
UNCOV
2695
                                "got %v", unconfirmedBalance,
×
2696
                                accountBalance.UnconfirmedBalance)
×
2697
                }
×
2698

2699
                utxos = h.GetUTXOsUnconfirmed(hn, account)
×
2700
                var totalUnconfirmedVal int64
×
2701
                for _, utxo := range utxos {
×
2702
                        totalUnconfirmedVal += utxo.AmountSat
×
2703
                }
×
2704
                if totalUnconfirmedVal != unconfirmedBalance {
×
2705
                        return fmt.Errorf("expected total unconfirmed utxo "+
×
UNCOV
2706
                                "balance %v, got %v", unconfirmedBalance,
×
2707
                                totalUnconfirmedVal)
×
UNCOV
2708
                }
×
2709

UNCOV
2710
                return nil
×
2711
        }, DefaultTimeout)
UNCOV
2712
        require.NoError(h, err, "timeout checking wallet account balance")
×
2713
}
2714

2715
// AssertClosingTxInMempool assert that the closing transaction of the given
2716
// channel point can be found in the mempool. If the channel has anchors, it
2717
// will assert the anchor sweep tx is also in the mempool.
2718
func (h *HarnessTest) AssertClosingTxInMempool(cp *lnrpc.ChannelPoint,
2719
        c lnrpc.CommitmentType) *wire.MsgTx {
×
2720

×
2721
        // Get expected number of txes to be found in the mempool.
×
2722
        expectedTxes := 1
×
2723
        hasAnchors := CommitTypeHasAnchors(c)
×
UNCOV
2724
        if hasAnchors {
×
UNCOV
2725
                expectedTxes = 2
×
2726
        }
×
2727

2728
        // Wait for the expected txes to be found in the mempool.
2729
        h.AssertNumTxsInMempool(expectedTxes)
×
2730

×
2731
        // Get the closing tx from the mempool.
×
2732
        op := h.OutPointFromChannelPoint(cp)
×
UNCOV
2733
        closeTx := h.AssertOutpointInMempool(op)
×
UNCOV
2734

×
UNCOV
2735
        return closeTx
×
2736
}
2737

2738
// AssertClosingTxInMempool assert that the closing transaction of the given
2739
// channel point can be found in the mempool. If the channel has anchors, it
2740
// will assert the anchor sweep tx is also in the mempool.
2741
func (h *HarnessTest) MineClosingTx(cp *lnrpc.ChannelPoint) *wire.MsgTx {
×
2742
        // Wait for the expected txes to be found in the mempool.
×
2743
        h.AssertNumTxsInMempool(1)
×
2744

×
2745
        // Get the closing tx from the mempool.
×
2746
        op := h.OutPointFromChannelPoint(cp)
×
2747
        closeTx := h.AssertOutpointInMempool(op)
×
2748

×
2749
        // Mine a block to confirm the closing transaction and potential anchor
×
2750
        // sweep.
×
2751
        h.MineBlocksAndAssertNumTxes(1, 1)
×
UNCOV
2752

×
UNCOV
2753
        return closeTx
×
UNCOV
2754
}
×
2755

2756
// AssertWalletLockedBalance asserts the expected amount has been marked as
2757
// locked in the node's WalletBalance response.
2758
func (h *HarnessTest) AssertWalletLockedBalance(hn *node.HarnessNode,
2759
        balance int64) {
×
2760

×
2761
        err := wait.NoError(func() error {
×
2762
                balanceResp := hn.RPC.WalletBalance()
×
2763
                got := balanceResp.LockedBalance
×
2764

×
UNCOV
2765
                if got != balance {
×
2766
                        return fmt.Errorf("want %d, got %d", balance, got)
×
UNCOV
2767
                }
×
2768

2769
                return nil
×
2770
        }, wait.DefaultTimeout)
UNCOV
2771
        require.NoError(h, err, "%s: timeout checking locked balance",
×
UNCOV
2772
                hn.Name())
×
2773
}
2774

2775
// AssertNumPendingSweeps asserts the number of pending sweeps for the given
2776
// node.
2777
func (h *HarnessTest) AssertNumPendingSweeps(hn *node.HarnessNode,
2778
        n int) []*walletrpc.PendingSweep {
×
2779

×
2780
        results := make([]*walletrpc.PendingSweep, 0, n)
×
2781

×
2782
        err := wait.NoError(func() error {
×
2783
                resp := hn.RPC.PendingSweeps()
×
2784
                num := len(resp.PendingSweeps)
×
2785

×
2786
                numDesc := "\n"
×
2787
                for _, s := range resp.PendingSweeps {
×
2788
                        desc := fmt.Sprintf("op=%v:%v, amt=%v, type=%v, "+
×
2789
                                "deadline=%v, maturityHeight=%v\n",
×
2790
                                s.Outpoint.TxidStr, s.Outpoint.OutputIndex,
×
2791
                                s.AmountSat, s.WitnessType, s.DeadlineHeight,
×
2792
                                s.MaturityHeight)
×
2793
                        numDesc += desc
×
2794

×
2795
                        // The deadline height must be set, otherwise the
×
2796
                        // pending input response is not update-to-date.
×
UNCOV
2797
                        if s.DeadlineHeight == 0 {
×
UNCOV
2798
                                return fmt.Errorf("input not updated: %s", desc)
×
2799
                        }
×
2800
                }
2801

2802
                if num == n {
×
UNCOV
2803
                        results = resp.PendingSweeps
×
2804
                        return nil
×
2805
                }
×
2806

UNCOV
2807
                return fmt.Errorf("want %d , got %d, sweeps: %s", n, num,
×
2808
                        numDesc)
×
2809
        }, DefaultTimeout)
2810

UNCOV
2811
        require.NoErrorf(h, err, "%s: check pending sweeps timeout", hn.Name())
×
UNCOV
2812

×
UNCOV
2813
        return results
×
2814
}
2815

2816
// AssertAtLeastNumPendingSweeps asserts there are at least n pending sweeps for
2817
// the given node.
2818
func (h *HarnessTest) AssertAtLeastNumPendingSweeps(hn *node.HarnessNode,
2819
        n int) []*walletrpc.PendingSweep {
×
2820

×
2821
        results := make([]*walletrpc.PendingSweep, 0, n)
×
2822

×
2823
        err := wait.NoError(func() error {
×
2824
                resp := hn.RPC.PendingSweeps()
×
2825
                num := len(resp.PendingSweeps)
×
2826

×
2827
                numDesc := "\n"
×
2828
                for _, s := range resp.PendingSweeps {
×
2829
                        desc := fmt.Sprintf("op=%v:%v, amt=%v, type=%v, "+
×
2830
                                "deadline=%v, maturityHeight=%v\n",
×
2831
                                s.Outpoint.TxidStr, s.Outpoint.OutputIndex,
×
2832
                                s.AmountSat, s.WitnessType, s.DeadlineHeight,
×
2833
                                s.MaturityHeight)
×
2834
                        numDesc += desc
×
2835

×
2836
                        // The deadline height must be set, otherwise the
×
2837
                        // pending input response is not update-to-date.
×
UNCOV
2838
                        if s.DeadlineHeight == 0 {
×
UNCOV
2839
                                return fmt.Errorf("input not updated: %s", desc)
×
2840
                        }
×
2841
                }
2842

2843
                if num >= n {
×
UNCOV
2844
                        results = resp.PendingSweeps
×
2845
                        return nil
×
2846
                }
×
2847

UNCOV
2848
                return fmt.Errorf("want %d , got %d, sweeps: %s", n, num,
×
2849
                        numDesc)
×
2850
        }, DefaultTimeout)
2851

UNCOV
2852
        require.NoErrorf(h, err, "%s: check pending sweeps timeout", hn.Name())
×
UNCOV
2853

×
UNCOV
2854
        return results
×
2855
}
2856

2857
// AssertNumSweeps asserts the number of sweeps for the given node.
2858
func (h *HarnessTest) AssertNumSweeps(hn *node.HarnessNode,
2859
        req *walletrpc.ListSweepsRequest,
2860
        n int) *walletrpc.ListSweepsResponse {
×
2861

×
2862
        var result *walletrpc.ListSweepsResponse
×
2863

×
2864
        // The ListSweeps call is wrapped in wait.NoError to handle potential
×
2865
        // timing issues. Sweep transactions might not be immediately reflected
×
2866
        // or processed by the node after an event (e.g., channel closure or
×
2867
        // block mining) due to propagation or processing delays. This ensures
×
2868
        // the system retries the call until the expected sweep is found,
×
2869
        // preventing test flakes caused by race conditions.
×
2870
        err := wait.NoError(func() error {
×
2871
                resp := hn.RPC.ListSweeps(req)
×
2872

×
2873
                var txIDs []string
×
2874
                if req.Verbose {
×
2875
                        details := resp.GetTransactionDetails()
×
2876
                        if details != nil {
×
UNCOV
2877
                                for _, tx := range details.Transactions {
×
2878
                                        txIDs = append(txIDs, tx.TxHash)
×
2879
                                }
×
2880
                        }
2881
                } else {
×
2882
                        ids := resp.GetTransactionIds()
×
UNCOV
2883
                        if ids != nil {
×
UNCOV
2884
                                txIDs = ids.TransactionIds
×
2885
                        }
×
2886
                }
2887

2888
                num := len(txIDs)
×
2889

×
2890
                // Exit early if the num matches.
×
2891
                if num == n {
×
UNCOV
2892
                        result = resp
×
2893
                        return nil
×
2894
                }
×
2895

UNCOV
2896
                return fmt.Errorf("want %d, got %d, sweeps: %v, req: %v", n,
×
2897
                        num, txIDs, req)
×
2898
        }, DefaultTimeout)
2899

UNCOV
2900
        require.NoErrorf(h, err, "%s: check num of sweeps timeout", hn.Name())
×
UNCOV
2901

×
UNCOV
2902
        return result
×
2903
}
2904

2905
// FindSweepingTxns asserts the expected number of sweeping txns are found in
2906
// the txns specified and return them.
2907
func (h *HarnessTest) FindSweepingTxns(txns []*wire.MsgTx,
2908
        expectedNumSweeps int, closeTxid chainhash.Hash) []*wire.MsgTx {
×
2909

×
2910
        var sweepTxns []*wire.MsgTx
×
2911

×
2912
        for _, tx := range txns {
×
UNCOV
2913
                if tx.TxIn[0].PreviousOutPoint.Hash == closeTxid {
×
2914
                        sweepTxns = append(sweepTxns, tx)
×
2915
                }
×
2916
        }
UNCOV
2917
        require.Len(h, sweepTxns, expectedNumSweeps, "unexpected num of sweeps")
×
UNCOV
2918

×
UNCOV
2919
        return sweepTxns
×
2920
}
2921

2922
// AssertForceCloseAndAnchorTxnsInMempool asserts that the force close and
2923
// anchor sweep txns are found in the mempool and returns the force close tx
2924
// and the anchor sweep tx.
2925
func (h *HarnessTest) AssertForceCloseAndAnchorTxnsInMempool() (*wire.MsgTx,
2926
        *wire.MsgTx) {
×
2927

×
2928
        // Assert there are two txns in the mempool.
×
2929
        txns := h.GetNumTxsFromMempool(2)
×
2930

×
2931
        // isParentAndChild checks whether there is an input used in the
×
2932
        // assumed child tx by checking every input's previous outpoint against
×
2933
        // the assumed parentTxid.
×
2934
        isParentAndChild := func(parent, child *wire.MsgTx) bool {
×
2935
                parentTxid := parent.TxHash()
×
2936

×
2937
                for _, inp := range child.TxIn {
×
2938
                        if inp.PreviousOutPoint.Hash == parentTxid {
×
2939
                                // Found a match, this is indeed the anchor
×
UNCOV
2940
                                // sweeping tx so we return it here.
×
UNCOV
2941
                                return true
×
2942
                        }
×
2943
                }
2944

2945
                return false
×
2946
        }
2947

2948
        switch {
×
2949
        // Assume the first one is the closing tx and the second one is the
2950
        // anchor sweeping tx.
UNCOV
2951
        case isParentAndChild(txns[0], txns[1]):
×
UNCOV
2952
                return txns[0], txns[1]
×
2953

2954
        // Assume the first one is the anchor sweeping tx and the second one is
2955
        // the closing tx.
UNCOV
2956
        case isParentAndChild(txns[1], txns[0]):
×
2957
                return txns[1], txns[0]
×
2958

2959
        // Unrelated txns found, fail the test.
2960
        default:
×
UNCOV
2961
                h.Fatalf("the two txns not related: %v", txns)
×
UNCOV
2962

×
UNCOV
2963
                return nil, nil
×
2964
        }
2965
}
2966

2967
// ReceiveSendToRouteUpdate waits until a message is received on the
2968
// PeerEventsClient stream or the timeout is reached.
2969
func (h *HarnessTest) ReceivePeerEvent(
2970
        stream rpc.PeerEventsClient) (*lnrpc.PeerEvent, error) {
×
2971

×
2972
        eventChan := make(chan *lnrpc.PeerEvent, 1)
×
2973
        errChan := make(chan error, 1)
×
2974
        go func() {
×
2975
                // Consume one message. This will block until the message is
×
2976
                // received.
×
2977
                resp, err := stream.Recv()
×
2978
                if err != nil {
×
2979
                        errChan <- err
×
2980

×
UNCOV
2981
                        return
×
UNCOV
2982
                }
×
2983
                eventChan <- resp
×
2984
        }()
2985

2986
        select {
×
UNCOV
2987
        case <-time.After(DefaultTimeout):
×
2988
                require.Fail(h, "timeout", "timeout waiting for peer event")
×
2989
                return nil, nil
×
2990

2991
        case err := <-errChan:
×
2992
                return nil, err
×
2993

UNCOV
2994
        case event := <-eventChan:
×
UNCOV
2995
                return event, nil
×
2996
        }
2997
}
2998

2999
// AssertPeerOnlineEvent reads an event from the PeerEventsClient stream and
3000
// asserts it's an online event.
3001
func (h HarnessTest) AssertPeerOnlineEvent(stream rpc.PeerEventsClient) {
×
3002
        event, err := h.ReceivePeerEvent(stream)
×
3003
        require.NoError(h, err)
×
UNCOV
3004

×
UNCOV
3005
        require.Equal(h, lnrpc.PeerEvent_PEER_ONLINE, event.Type)
×
UNCOV
3006
}
×
3007

3008
// AssertPeerOfflineEvent reads an event from the PeerEventsClient stream and
3009
// asserts it's an offline event.
3010
func (h HarnessTest) AssertPeerOfflineEvent(stream rpc.PeerEventsClient) {
×
3011
        event, err := h.ReceivePeerEvent(stream)
×
3012
        require.NoError(h, err)
×
UNCOV
3013

×
UNCOV
3014
        require.Equal(h, lnrpc.PeerEvent_PEER_OFFLINE, event.Type)
×
UNCOV
3015
}
×
3016

3017
// AssertPeerReconnected reads two events from the PeerEventsClient stream. The
3018
// first event must be an offline event, and the second event must be an online
3019
// event. This is a typical reconnection scenario, where the peer is
3020
// disconnected then connected again.
3021
//
3022
// NOTE: It's important to make the subscription before the disconnection
3023
// happens, otherwise the events can be missed.
3024
func (h HarnessTest) AssertPeerReconnected(stream rpc.PeerEventsClient) {
×
UNCOV
3025
        h.AssertPeerOfflineEvent(stream)
×
UNCOV
3026
        h.AssertPeerOnlineEvent(stream)
×
UNCOV
3027
}
×
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

© 2026 Coveralls, Inc