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

lightningnetwork / lnd / 13536249039

26 Feb 2025 03:42AM UTC coverage: 57.462% (-1.4%) from 58.835%
13536249039

Pull #8453

github

Roasbeef
peer: update chooseDeliveryScript to gen script if needed

In this commit, we update `chooseDeliveryScript` to generate a new
script if needed. This allows us to fold in a few other lines that
always followed this function into this expanded function.

The tests have been updated accordingly.
Pull Request #8453: [4/4] - multi: integrate new rbf coop close FSM into the existing peer flow

275 of 1318 new or added lines in 22 files covered. (20.86%)

19521 existing lines in 257 files now uncovered.

103858 of 180741 relevant lines covered (57.46%)

24750.23 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/lightningnetwork/lnd/channeldb"
22
        "github.com/lightningnetwork/lnd/lnrpc"
23
        "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
24
        "github.com/lightningnetwork/lnd/lnrpc/routerrpc"
25
        "github.com/lightningnetwork/lnd/lnrpc/walletrpc"
26
        "github.com/lightningnetwork/lnd/lntest/miner"
27
        "github.com/lightningnetwork/lnd/lntest/node"
28
        "github.com/lightningnetwork/lnd/lntest/rpc"
29
        "github.com/lightningnetwork/lnd/lntest/wait"
30
        "github.com/lightningnetwork/lnd/lntypes"
31
        "github.com/lightningnetwork/lnd/lnutils"
32
        "github.com/stretchr/testify/require"
33
        "google.golang.org/protobuf/proto"
34
)
35

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

221
                return err
×
222
        }
223

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

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

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

243
// AssertNumEdges checks that an expected number of edges can be found in the
244
// node specified.
245
func (h *HarnessTest) AssertNumEdges(hn *node.HarnessNode,
246
        expected int, includeUnannounced bool) []*lnrpc.ChannelEdge {
×
247

×
248
        var edges []*lnrpc.ChannelEdge
×
249

×
250
        old := hn.State.Edge.Public
×
251
        if includeUnannounced {
×
252
                old = hn.State.Edge.Total
×
253
        }
×
254

255
        err := wait.NoError(func() error {
×
256
                req := &lnrpc.ChannelGraphRequest{
×
257
                        IncludeUnannounced: includeUnannounced,
×
258
                }
×
259
                resp := hn.RPC.DescribeGraph(req)
×
260
                total := len(resp.Edges)
×
261

×
262
                if total-old == expected {
×
263
                        if expected != 0 {
×
264
                                // NOTE: assume edges come in ascending order
×
265
                                // that the old edges are at the front of the
×
266
                                // slice.
×
267
                                edges = resp.Edges[old:]
×
268
                        }
×
269

270
                        return nil
×
271
                }
272

273
                return errNumNotMatched(hn.Name(), "num of channel edges",
×
274
                        expected, total-old, total, old)
×
275
        }, DefaultTimeout)
276

277
        require.NoError(h, err, "timeout while checking for edges")
×
278

×
279
        return edges
×
280
}
281

282
// ReceiveOpenChannelUpdate waits until a message is received on the stream or
283
// the timeout is reached.
284
func (h *HarnessTest) ReceiveOpenChannelUpdate(
285
        stream rpc.OpenChanClient) *lnrpc.OpenStatusUpdate {
×
286

×
287
        update, err := h.receiveOpenChannelUpdate(stream)
×
288
        require.NoError(h, err, "received err from open channel stream")
×
289

×
290
        return update
×
291
}
×
292

293
// ReceiveOpenChannelError waits for the expected error during the open channel
294
// flow from the peer or times out.
295
func (h *HarnessTest) ReceiveOpenChannelError(
296
        stream rpc.OpenChanClient, expectedErr error) {
×
297

×
298
        _, err := h.receiveOpenChannelUpdate(stream)
×
299
        require.Contains(h, err.Error(), expectedErr.Error(),
×
300
                "error not matched")
×
301
}
×
302

303
// receiveOpenChannelUpdate waits until a message or an error is received on
304
// the stream or the timeout is reached.
305
//
306
// TODO(yy): use generics to unify all receiving stream update once go@1.18 is
307
// used.
308
func (h *HarnessTest) receiveOpenChannelUpdate(
309
        stream rpc.OpenChanClient) (*lnrpc.OpenStatusUpdate, error) {
×
310

×
311
        chanMsg := make(chan *lnrpc.OpenStatusUpdate)
×
312
        errChan := make(chan error)
×
313
        go func() {
×
314
                // Consume one message. This will block until the message is
×
315
                // received.
×
316
                resp, err := stream.Recv()
×
317
                if err != nil {
×
318
                        errChan <- err
×
319
                        return
×
320
                }
×
321
                chanMsg <- resp
×
322
        }()
323

324
        select {
×
325
        case <-time.After(DefaultTimeout):
×
326
                require.Fail(h, "timeout", "timeout waiting for open channel "+
×
327
                        "update sent")
×
328
                return nil, nil
×
329

330
        case err := <-errChan:
×
331
                return nil, err
×
332

333
        case updateMsg := <-chanMsg:
×
334
                return updateMsg, nil
×
335
        }
336
}
337

338
// WaitForChannelOpenEvent waits for a notification that a channel is open by
339
// consuming a message from the passed open channel stream.
340
func (h HarnessTest) WaitForChannelOpenEvent(
341
        stream rpc.OpenChanClient) *lnrpc.ChannelPoint {
×
342

×
343
        // Consume one event.
×
344
        event := h.ReceiveOpenChannelUpdate(stream)
×
345

×
346
        resp, ok := event.Update.(*lnrpc.OpenStatusUpdate_ChanOpen)
×
347
        require.Truef(h, ok, "expected channel open update, instead got %v",
×
348
                resp)
×
349

×
350
        return resp.ChanOpen.ChannelPoint
×
351
}
×
352

353
// AssertChannelExists asserts that an active channel identified by the
354
// specified channel point exists from the point-of-view of the node.
355
func (h *HarnessTest) AssertChannelExists(hn *node.HarnessNode,
356
        cp *lnrpc.ChannelPoint) *lnrpc.Channel {
×
357

×
358
        return h.assertChannelStatus(hn, cp, true)
×
359
}
×
360

361
// AssertChannelActive checks if a channel identified by the specified channel
362
// point is active.
363
func (h *HarnessTest) AssertChannelActive(hn *node.HarnessNode,
364
        cp *lnrpc.ChannelPoint) *lnrpc.Channel {
×
365

×
366
        return h.assertChannelStatus(hn, cp, true)
×
367
}
×
368

369
// AssertChannelInactive checks if a channel identified by the specified channel
370
// point is inactive.
371
func (h *HarnessTest) AssertChannelInactive(hn *node.HarnessNode,
372
        cp *lnrpc.ChannelPoint) *lnrpc.Channel {
×
373

×
374
        return h.assertChannelStatus(hn, cp, false)
×
375
}
×
376

377
// assertChannelStatus asserts that a channel identified by the specified
378
// channel point exists from the point-of-view of the node and that it is either
379
// active or inactive depending on the value of the active parameter.
380
func (h *HarnessTest) assertChannelStatus(hn *node.HarnessNode,
381
        cp *lnrpc.ChannelPoint, active bool) *lnrpc.Channel {
×
382

×
383
        var (
×
384
                channel *lnrpc.Channel
×
385
                err     error
×
386
        )
×
387

×
388
        err = wait.NoError(func() error {
×
389
                channel, err = h.findChannel(hn, cp)
×
390
                if err != nil {
×
391
                        return err
×
392
                }
×
393

394
                // Check whether the channel is active, exit early if it is.
395
                if channel.Active == active {
×
396
                        return nil
×
397
                }
×
398

399
                return fmt.Errorf("expected channel_active=%v, got %v",
×
400
                        active, channel.Active)
×
401
        }, DefaultTimeout)
402

403
        require.NoErrorf(h, err, "%s: timeout checking for channel point: %v",
×
404
                hn.Name(), cp)
×
405

×
406
        return channel
×
407
}
408

409
// AssertOutputScriptClass checks that the specified transaction output has the
410
// expected script class.
411
func (h *HarnessTest) AssertOutputScriptClass(tx *btcutil.Tx,
412
        outputIndex uint32, scriptClass txscript.ScriptClass) {
×
413

×
414
        require.Greater(h, len(tx.MsgTx().TxOut), int(outputIndex))
×
415

×
416
        txOut := tx.MsgTx().TxOut[outputIndex]
×
417

×
418
        pkScript, err := txscript.ParsePkScript(txOut.PkScript)
×
419
        require.NoError(h, err)
×
420
        require.Equal(h, scriptClass, pkScript.Class())
×
421
}
×
422

423
// findChannel tries to find a target channel in the node using the given
424
// channel point.
425
func (h *HarnessTest) findChannel(hn *node.HarnessNode,
426
        chanPoint *lnrpc.ChannelPoint,
427
        opts ...ListChannelOption) (*lnrpc.Channel, error) {
×
428

×
429
        // Get the funding point.
×
430
        fp := h.OutPointFromChannelPoint(chanPoint)
×
431

×
432
        req := &lnrpc.ListChannelsRequest{}
×
433

×
434
        for _, opt := range opts {
×
435
                opt(req)
×
436
        }
×
437

438
        channelInfo := hn.RPC.ListChannels(req)
×
439

×
440
        // Find the target channel.
×
441
        for _, channel := range channelInfo.Channels {
×
442
                if channel.ChannelPoint == fp.String() {
×
443
                        return channel, nil
×
444
                }
×
445
        }
446

447
        return nil, fmt.Errorf("%s: channel not found using %s", hn.Name(),
×
448
                fp.String())
×
449
}
450

451
// ReceiveCloseChannelUpdate waits until a message or an error is received on
452
// the subscribe channel close stream or the timeout is reached.
453
func (h *HarnessTest) ReceiveCloseChannelUpdate(
454
        stream rpc.CloseChanClient) (*lnrpc.CloseStatusUpdate, error) {
×
455

×
456
        chanMsg := make(chan *lnrpc.CloseStatusUpdate)
×
457
        errChan := make(chan error)
×
458
        go func() {
×
459
                // Consume one message. This will block until the message is
×
460
                // received.
×
461
                resp, err := stream.Recv()
×
462
                if err != nil {
×
463
                        errChan <- err
×
464
                        return
×
465
                }
×
466
                chanMsg <- resp
×
467
        }()
468

469
        select {
×
470
        case <-time.After(DefaultTimeout):
×
471
                require.Fail(h, "timeout", "timeout waiting for close channel "+
×
472
                        "update sent")
×
473

×
474
                return nil, nil
×
475

476
        case err := <-errChan:
×
477
                return nil, fmt.Errorf("received err from close channel "+
×
478
                        "stream: %v", err)
×
479

480
        case updateMsg := <-chanMsg:
×
481
                return updateMsg, nil
×
482
        }
483
}
484

485
type WaitingCloseChannel *lnrpc.PendingChannelsResponse_WaitingCloseChannel
486

487
// AssertChannelWaitingClose asserts that the given channel found in the node
488
// is waiting close. Returns the WaitingCloseChannel if found.
489
func (h *HarnessTest) AssertChannelWaitingClose(hn *node.HarnessNode,
490
        chanPoint *lnrpc.ChannelPoint) WaitingCloseChannel {
×
491

×
492
        var target WaitingCloseChannel
×
493

×
494
        op := h.OutPointFromChannelPoint(chanPoint)
×
495

×
496
        err := wait.NoError(func() error {
×
497
                resp := hn.RPC.PendingChannels()
×
498

×
499
                for _, waitingClose := range resp.WaitingCloseChannels {
×
500
                        if waitingClose.Channel.ChannelPoint == op.String() {
×
501
                                target = waitingClose
×
502
                                return nil
×
503
                        }
×
504
                }
505

506
                return fmt.Errorf("%v: channel %s not found in waiting close",
×
507
                        hn.Name(), op)
×
508
        }, DefaultTimeout)
509
        require.NoError(h, err, "assert channel waiting close timed out")
×
510

×
511
        return target
×
512
}
513

514
// AssertTopologyChannelClosed asserts a given channel is closed by checking
515
// the graph topology subscription of the specified node. Returns the closed
516
// channel update if found.
517
func (h *HarnessTest) AssertTopologyChannelClosed(hn *node.HarnessNode,
518
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ClosedChannelUpdate {
×
519

×
520
        closedChan, err := hn.Watcher.WaitForChannelClose(chanPoint)
×
521
        require.NoError(h, err, "failed to wait for channel close")
×
522

×
523
        return closedChan
×
524
}
×
525

526
// WaitForChannelCloseEvent waits for a notification that a channel is closed
527
// by consuming a message from the passed close channel stream. Returns the
528
// closing txid if found.
529
func (h HarnessTest) WaitForChannelCloseEvent(
530
        stream rpc.CloseChanClient) chainhash.Hash {
×
531

×
532
        // Consume one event.
×
533
        event, err := h.ReceiveCloseChannelUpdate(stream)
×
534
        require.NoError(h, err)
×
535

×
536
        resp, ok := event.Update.(*lnrpc.CloseStatusUpdate_ChanClose)
×
NEW
537
        require.Truef(h, ok, "expected channel close update, instead got %v",
×
NEW
538
                event.Update)
×
539

×
540
        txid, err := chainhash.NewHash(resp.ChanClose.ClosingTxid)
×
541
        require.NoErrorf(h, err, "wrong format found in closing txid: %v",
×
542
                resp.ChanClose.ClosingTxid)
×
543

×
544
        return *txid
×
545
}
×
546

547
// AssertNumWaitingClose checks that a PendingChannels response from the node
548
// reports the expected number of waiting close channels.
549
func (h *HarnessTest) AssertNumWaitingClose(hn *node.HarnessNode,
550
        num int) []*lnrpc.PendingChannelsResponse_WaitingCloseChannel {
×
551

×
552
        var channels []*lnrpc.PendingChannelsResponse_WaitingCloseChannel
×
553
        oldWaiting := hn.State.CloseChannel.WaitingClose
×
554

×
555
        err := wait.NoError(func() error {
×
556
                resp := hn.RPC.PendingChannels()
×
557
                channels = resp.WaitingCloseChannels
×
558
                total := len(channels)
×
559

×
560
                got := total - oldWaiting
×
561
                if got == num {
×
562
                        return nil
×
563
                }
×
564

565
                return errNumNotMatched(hn.Name(), "waiting close channels",
×
566
                        num, got, total, oldWaiting)
×
567
        }, DefaultTimeout)
568

569
        require.NoErrorf(h, err, "%s: assert waiting close timeout",
×
570
                hn.Name())
×
571

×
572
        return channels
×
573
}
574

575
// AssertNumPendingForceClose checks that a PendingChannels response from the
576
// node reports the expected number of pending force close channels.
577
func (h *HarnessTest) AssertNumPendingForceClose(hn *node.HarnessNode,
578
        num int) []*lnrpc.PendingChannelsResponse_ForceClosedChannel {
×
579

×
580
        var channels []*lnrpc.PendingChannelsResponse_ForceClosedChannel
×
581
        oldForce := hn.State.CloseChannel.PendingForceClose
×
582

×
583
        err := wait.NoError(func() error {
×
584
                // TODO(yy): we should be able to use `hn.RPC.PendingChannels`
×
585
                // here to avoid checking the RPC error. However, we may get a
×
586
                // `unable to find arbitrator` error from the rpc point, due to
×
587
                // a timing issue in rpcserver,
×
588
                // 1. `r.server.chanStateDB.FetchClosedChannels` fetches
×
589
                //    the pending force close channel.
×
590
                // 2. `r.arbitratorPopulateForceCloseResp` relies on the
×
591
                //    channel arbitrator to get the report, and,
×
592
                // 3. the arbitrator may be deleted due to the force close
×
593
                //    channel being resolved.
×
594
                // Somewhere along the line is missing a lock to keep the data
×
595
                // consistent.
×
596
                req := &lnrpc.PendingChannelsRequest{}
×
597
                resp, err := hn.RPC.LN.PendingChannels(h.runCtx, req)
×
598
                if err != nil {
×
599
                        return fmt.Errorf("PendingChannels got: %w", err)
×
600
                }
×
601

602
                channels = resp.PendingForceClosingChannels
×
603
                total := len(channels)
×
604

×
605
                got := total - oldForce
×
606
                if got == num {
×
607
                        return nil
×
608
                }
×
609

610
                return errNumNotMatched(hn.Name(), "pending force close "+
×
611
                        "channels", num, got, total, oldForce)
×
612
        }, DefaultTimeout)
613

614
        require.NoErrorf(h, err, "%s: assert pending force close timeout",
×
615
                hn.Name())
×
616

×
617
        return channels
×
618
}
619

620
// AssertStreamChannelCoopClosed reads an update from the close channel client
621
// stream and asserts that the mempool state and node's topology match a coop
622
// close. In specific,
623
// - assert the channel is waiting close and has the expected ChanStatusFlags.
624
// - assert the mempool has the closing txes and anchor sweeps.
625
// - mine a block and assert the closing txid is mined.
626
// - assert the node has zero waiting close channels.
627
// - assert the node has seen the channel close update.
628
func (h *HarnessTest) AssertStreamChannelCoopClosed(hn *node.HarnessNode,
629
        cp *lnrpc.ChannelPoint, anchors bool,
630
        stream rpc.CloseChanClient) chainhash.Hash {
×
631

×
632
        // Assert the channel is waiting close.
×
633
        resp := h.AssertChannelWaitingClose(hn, cp)
×
634

×
635
        // Assert that the channel is in coop broadcasted.
×
636
        require.Contains(h, resp.Channel.ChanStatusFlags,
×
637
                channeldb.ChanStatusCoopBroadcasted.String(),
×
638
                "channel not coop broadcasted")
×
639

×
640
        // We'll now, generate a single block, wait for the final close status
×
641
        // update, then ensure that the closing transaction was included in the
×
642
        // block. If there are anchors, we also expect an anchor sweep.
×
643
        expectedTxes := 1
×
644
        if anchors {
×
645
                expectedTxes = 2
×
646
        }
×
647
        block := h.MineBlocksAndAssertNumTxes(1, expectedTxes)[0]
×
648

×
649
        // Consume one close event and assert the closing txid can be found in
×
650
        // the block.
×
651
        closingTxid := h.WaitForChannelCloseEvent(stream)
×
652
        h.AssertTxInBlock(block, closingTxid)
×
653

×
654
        // We should see zero waiting close channels now.
×
655
        h.AssertNumWaitingClose(hn, 0)
×
656

×
657
        // Finally, check that the node's topology graph has seen this channel
×
658
        // closed if it's a public channel.
×
659
        if !resp.Channel.Private {
×
660
                h.AssertTopologyChannelClosed(hn, cp)
×
661
        }
×
662

663
        return closingTxid
×
664
}
665

666
// AssertStreamChannelForceClosed reads an update from the close channel client
667
// stream and asserts that the mempool state and node's topology match a local
668
// force close. In specific,
669
//   - assert the channel is waiting close and has the expected ChanStatusFlags.
670
//   - assert the mempool has the closing txes.
671
//   - mine a block and assert the closing txid is mined.
672
//   - assert the channel is pending force close.
673
//   - assert the node has seen the channel close update.
674
//   - assert there's a pending anchor sweep request once the force close tx is
675
//     confirmed.
676
func (h *HarnessTest) AssertStreamChannelForceClosed(hn *node.HarnessNode,
677
        cp *lnrpc.ChannelPoint, anchorSweep bool,
678
        stream rpc.CloseChanClient) chainhash.Hash {
×
679

×
680
        // Assert the channel is waiting close.
×
681
        resp := h.AssertChannelWaitingClose(hn, cp)
×
682

×
683
        // Assert that the channel is in local force broadcasted.
×
684
        require.Contains(h, resp.Channel.ChanStatusFlags,
×
685
                channeldb.ChanStatusLocalCloseInitiator.String(),
×
686
                "channel not coop broadcasted")
×
687

×
688
        // Get the closing txid.
×
689
        closeTxid, err := chainhash.NewHashFromStr(resp.ClosingTxid)
×
690
        require.NoError(h, err)
×
691

×
692
        // We'll now, generate a single block, wait for the final close status
×
693
        // update, then ensure that the closing transaction was included in the
×
694
        // block.
×
695
        closeTx := h.AssertTxInMempool(*closeTxid)
×
696
        h.MineBlockWithTx(closeTx)
×
697

×
698
        // Consume one close event and assert the closing txid can be found in
×
699
        // the block.
×
700
        closingTxid := h.WaitForChannelCloseEvent(stream)
×
701

×
702
        // We should see zero waiting close channels and 1 pending force close
×
703
        // channels now.
×
704
        h.AssertNumWaitingClose(hn, 0)
×
705
        h.AssertNumPendingForceClose(hn, 1)
×
706

×
707
        // Finally, check that the node's topology graph has seen this channel
×
708
        // closed if it's a public channel.
×
709
        if !resp.Channel.Private {
×
710
                h.AssertTopologyChannelClosed(hn, cp)
×
711
        }
×
712

713
        // Assert there's a pending anchor sweep.
714
        if anchorSweep {
×
715
                h.AssertNumPendingSweeps(hn, 1)
×
716
        }
×
717

718
        return closingTxid
×
719
}
720

721
// AssertChannelPolicyUpdate checks that the required policy update has
722
// happened on the given node.
723
func (h *HarnessTest) AssertChannelPolicyUpdate(hn *node.HarnessNode,
724
        advertisingNode *node.HarnessNode, policy *lnrpc.RoutingPolicy,
725
        chanPoint *lnrpc.ChannelPoint, includeUnannounced bool) {
×
726

×
727
        require.NoError(
×
728
                h, hn.Watcher.WaitForChannelPolicyUpdate(
×
729
                        advertisingNode, policy,
×
730
                        chanPoint, includeUnannounced,
×
731
                ), "%s: error while waiting for channel update", hn.Name(),
×
732
        )
×
733
}
×
734

735
// WaitForGraphSync waits until the node is synced to graph or times out.
736
func (h *HarnessTest) WaitForGraphSync(hn *node.HarnessNode) {
×
737
        err := wait.NoError(func() error {
×
738
                resp := hn.RPC.GetInfo()
×
739
                if resp.SyncedToGraph {
×
740
                        return nil
×
741
                }
×
742

743
                return fmt.Errorf("node not synced to graph")
×
744
        }, DefaultTimeout)
745
        require.NoError(h, err, "%s: timeout while sync to graph", hn.Name())
×
746
}
747

748
// AssertNumUTXOsWithConf waits for the given number of UTXOs with the
749
// specified confirmations range to be available or fails if that isn't the
750
// case before the default timeout.
751
//
752
// NOTE: for standby nodes(Alice and Bob), this method takes account of the
753
// previous state of the node's UTXOs. The previous state is snapshotted when
754
// finishing a previous test case via the cleanup function in `Subtest`. In
755
// other words, this assertion only checks the new changes made in the current
756
// test.
757
func (h *HarnessTest) AssertNumUTXOsWithConf(hn *node.HarnessNode,
758
        expectedUtxos int, max, min int32) []*lnrpc.Utxo {
×
759

×
760
        var unconfirmed bool
×
761

×
762
        old := hn.State.UTXO.Confirmed
×
763
        if max == 0 {
×
764
                old = hn.State.UTXO.Unconfirmed
×
765
                unconfirmed = true
×
766
        }
×
767

768
        var utxos []*lnrpc.Utxo
×
769
        err := wait.NoError(func() error {
×
770
                req := &walletrpc.ListUnspentRequest{
×
771
                        Account:         "",
×
772
                        MaxConfs:        max,
×
773
                        MinConfs:        min,
×
774
                        UnconfirmedOnly: unconfirmed,
×
775
                }
×
776
                resp := hn.RPC.ListUnspent(req)
×
777
                total := len(resp.Utxos)
×
778

×
779
                if total-old == expectedUtxos {
×
780
                        utxos = resp.Utxos[old:]
×
781

×
782
                        return nil
×
783
                }
×
784

785
                desc := "has UTXOs:\n"
×
786
                for _, utxo := range resp.Utxos {
×
787
                        desc += fmt.Sprintf("%v\n", utxo)
×
788
                }
×
789

790
                return errNumNotMatched(hn.Name(), "num of UTXOs",
×
791
                        expectedUtxos, total-old, total, old, desc)
×
792
        }, DefaultTimeout)
793
        require.NoError(h, err, "timeout waiting for UTXOs")
×
794

×
795
        return utxos
×
796
}
797

798
// AssertNumUTXOsUnconfirmed asserts the expected num of unconfirmed utxos are
799
// seen.
800
//
801
// NOTE: for standby nodes(Alice and Bob), this method takes account of the
802
// previous state of the node's UTXOs. Check `AssertNumUTXOsWithConf` for
803
// details.
804
func (h *HarnessTest) AssertNumUTXOsUnconfirmed(hn *node.HarnessNode,
805
        num int) []*lnrpc.Utxo {
×
806

×
807
        return h.AssertNumUTXOsWithConf(hn, num, 0, 0)
×
808
}
×
809

810
// AssertNumUTXOsConfirmed asserts the expected num of confirmed utxos are
811
// seen, which means the returned utxos have at least one confirmation.
812
//
813
// NOTE: for standby nodes(Alice and Bob), this method takes account of the
814
// previous state of the node's UTXOs. Check `AssertNumUTXOsWithConf` for
815
// details.
816
func (h *HarnessTest) AssertNumUTXOsConfirmed(hn *node.HarnessNode,
817
        num int) []*lnrpc.Utxo {
×
818

×
819
        return h.AssertNumUTXOsWithConf(hn, num, math.MaxInt32, 1)
×
820
}
×
821

822
// AssertNumUTXOs asserts the expected num of utxos are seen, including
823
// confirmed and unconfirmed outputs.
824
//
825
// NOTE: for standby nodes(Alice and Bob), this method takes account of the
826
// previous state of the node's UTXOs. Check `AssertNumUTXOsWithConf` for
827
// details.
828
func (h *HarnessTest) AssertNumUTXOs(hn *node.HarnessNode,
829
        num int) []*lnrpc.Utxo {
×
830

×
831
        return h.AssertNumUTXOsWithConf(hn, num, math.MaxInt32, 0)
×
832
}
×
833

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

×
839
        var unconfirmed bool
×
840

×
841
        if max == 0 {
×
842
                unconfirmed = true
×
843
        }
×
844

845
        req := &walletrpc.ListUnspentRequest{
×
846
                Account:         account,
×
847
                MaxConfs:        max,
×
848
                MinConfs:        min,
×
849
                UnconfirmedOnly: unconfirmed,
×
850
        }
×
851
        resp := hn.RPC.ListUnspent(req)
×
852

×
853
        return resp.Utxos
×
854
}
855

856
// GetUTXOs returns all the UTXOs for the given node's account, including
857
// confirmed and unconfirmed.
858
func (h *HarnessTest) GetUTXOs(hn *node.HarnessNode,
859
        account string) []*lnrpc.Utxo {
×
860

×
861
        return h.getUTXOs(hn, account, math.MaxInt32, 0)
×
862
}
×
863

864
// GetUTXOsConfirmed returns the confirmed UTXOs for the given node's account.
865
func (h *HarnessTest) GetUTXOsConfirmed(hn *node.HarnessNode,
866
        account string) []*lnrpc.Utxo {
×
867

×
868
        return h.getUTXOs(hn, account, math.MaxInt32, 1)
×
869
}
×
870

871
// GetUTXOsUnconfirmed returns the unconfirmed UTXOs for the given node's
872
// account.
873
func (h *HarnessTest) GetUTXOsUnconfirmed(hn *node.HarnessNode,
874
        account string) []*lnrpc.Utxo {
×
875

×
876
        return h.getUTXOs(hn, account, 0, 0)
×
877
}
×
878

879
// WaitForBalanceConfirmed waits until the node sees the expected confirmed
880
// balance in its wallet.
881
func (h *HarnessTest) WaitForBalanceConfirmed(hn *node.HarnessNode,
882
        expected btcutil.Amount) {
×
883

×
884
        var lastBalance btcutil.Amount
×
885
        err := wait.NoError(func() error {
×
886
                resp := hn.RPC.WalletBalance()
×
887

×
888
                lastBalance = btcutil.Amount(resp.ConfirmedBalance)
×
889
                if lastBalance == expected {
×
890
                        return nil
×
891
                }
×
892

893
                return fmt.Errorf("expected %v, only have %v", expected,
×
894
                        lastBalance)
×
895
        }, DefaultTimeout)
896

897
        require.NoError(h, err, "timeout waiting for confirmed balances")
×
898
}
899

900
// WaitForBalanceUnconfirmed waits until the node sees the expected unconfirmed
901
// balance in its wallet.
902
func (h *HarnessTest) WaitForBalanceUnconfirmed(hn *node.HarnessNode,
903
        expected btcutil.Amount) {
×
904

×
905
        var lastBalance btcutil.Amount
×
906
        err := wait.NoError(func() error {
×
907
                resp := hn.RPC.WalletBalance()
×
908

×
909
                lastBalance = btcutil.Amount(resp.UnconfirmedBalance)
×
910
                if lastBalance == expected {
×
911
                        return nil
×
912
                }
×
913

914
                return fmt.Errorf("expected %v, only have %v", expected,
×
915
                        lastBalance)
×
916
        }, DefaultTimeout)
917

918
        require.NoError(h, err, "timeout waiting for unconfirmed balances")
×
919
}
920

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

×
926
        _, err := rand.Read(randBuf)
×
927
        require.NoErrorf(h, err, "internal error, cannot generate random bytes")
×
928

×
929
        return randBuf
×
930
}
×
931

932
// RandomPreimage generates a random preimage which can be used as a payment
933
// preimage.
934
func (h *HarnessTest) RandomPreimage() lntypes.Preimage {
×
935
        var preimage lntypes.Preimage
×
936
        copy(preimage[:], h.Random32Bytes())
×
937

×
938
        return preimage
×
939
}
×
940

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

×
946
        return resp
×
947
}
×
948

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

×
955
        return addrScript
×
956
}
×
957

958
// AssertChannelBalanceResp makes a ChannelBalance request and checks the
959
// returned response matches the expected.
960
func (h *HarnessTest) AssertChannelBalanceResp(hn *node.HarnessNode,
961
        expected *lnrpc.ChannelBalanceResponse) {
×
962

×
963
        resp := hn.RPC.ChannelBalance()
×
964

×
965
        // Ignore custom channel data of both expected and actual responses.
×
966
        expected.CustomChannelData = nil
×
967
        resp.CustomChannelData = nil
×
968

×
969
        require.True(h, proto.Equal(expected, resp), "balance is incorrect "+
×
970
                "got: %v, want: %v", resp, expected)
×
971
}
×
972

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

×
978
        channel, err := h.findChannel(hn, chanPoint)
×
979
        require.NoErrorf(h, err, "channel not found using %v", chanPoint)
×
980

×
981
        return channel
×
982
}
×
983

984
// GetChannelCommitType retrieves the active channel commitment type for the
985
// given chan point.
986
func (h *HarnessTest) GetChannelCommitType(hn *node.HarnessNode,
987
        chanPoint *lnrpc.ChannelPoint) lnrpc.CommitmentType {
×
988

×
989
        c := h.GetChannelByChanPoint(hn, chanPoint)
×
990

×
991
        return c.CommitmentType
×
992
}
×
993

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

×
999
        var channels []*lnrpc.PendingChannelsResponse_PendingOpenChannel
×
1000

×
1001
        oldNum := hn.State.OpenChannel.Pending
×
1002

×
1003
        err := wait.NoError(func() error {
×
1004
                resp := hn.RPC.PendingChannels()
×
1005
                channels = resp.PendingOpenChannels
×
1006
                total := len(channels)
×
1007

×
1008
                numChans := total - oldNum
×
1009

×
1010
                if numChans != expected {
×
1011
                        return errNumNotMatched(hn.Name(),
×
1012
                                "pending open channels", expected,
×
1013
                                numChans, total, oldNum)
×
1014
                }
×
1015

1016
                return nil
×
1017
        }, DefaultTimeout)
1018

1019
        require.NoError(h, err, "num of pending open channels not match")
×
1020

×
1021
        return channels
×
1022
}
1023

1024
// AssertNodesNumPendingOpenChannels asserts that both of the nodes have the
1025
// expected number of pending open channels.
1026
func (h *HarnessTest) AssertNodesNumPendingOpenChannels(a, b *node.HarnessNode,
1027
        expected int) {
×
1028

×
1029
        h.AssertNumPendingOpenChannels(a, expected)
×
1030
        h.AssertNumPendingOpenChannels(b, expected)
×
1031
}
×
1032

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

×
1039
        return h.assertPaymentStatusWithTimeout(
×
1040
                stream, status, wait.PaymentTimeout,
×
1041
        )
×
1042
}
×
1043

1044
// AssertPaymentSucceedWithTimeout asserts that a payment is succeeded within
1045
// the specified timeout.
1046
func (h *HarnessTest) AssertPaymentSucceedWithTimeout(stream rpc.PaymentClient,
1047
        timeout time.Duration) *lnrpc.Payment {
×
1048

×
1049
        return h.assertPaymentStatusWithTimeout(
×
1050
                stream, lnrpc.Payment_SUCCEEDED, timeout,
×
1051
        )
×
1052
}
×
1053

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

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

1073
                // Return if the desired payment state is reached.
1074
                if payment.Status == status {
×
1075
                        target = payment
×
1076

×
1077
                        return nil
×
1078
                }
×
1079

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

1086
        require.NoError(h, err, "timeout while waiting payment")
×
1087

×
1088
        return target
×
1089
}
1090

1091
// ReceivePaymentUpdate waits until a message is received on the payment client
1092
// stream or the timeout is reached.
1093
func (h *HarnessTest) ReceivePaymentUpdate(
1094
        stream rpc.PaymentClient) (*lnrpc.Payment, error) {
×
1095

×
1096
        return h.receivePaymentUpdateWithTimeout(stream, DefaultTimeout)
×
1097
}
×
1098

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

×
1104
        chanMsg := make(chan *lnrpc.Payment, 1)
×
1105
        errChan := make(chan error, 1)
×
1106

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

×
1114
                        return
×
1115
                }
×
1116
                chanMsg <- resp
×
1117
        }()
1118

1119
        select {
×
1120
        case <-time.After(timeout):
×
1121
                require.Fail(h, "timeout", "timeout waiting for payment update")
×
1122
                return nil, nil
×
1123

1124
        case err := <-errChan:
×
1125
                return nil, err
×
1126

1127
        case updateMsg := <-chanMsg:
×
1128
                return updateMsg, nil
×
1129
        }
1130
}
1131

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

×
1141
        err := wait.NoError(func() error {
×
1142
                invoice := hn.RPC.LookupInvoiceV2(msg)
×
1143
                if invoice.State == lnrpc.Invoice_SETTLED {
×
1144
                        return nil
×
1145
                }
×
1146

1147
                return fmt.Errorf("%s: invoice with payment address %x not "+
×
1148
                        "settled", hn.Name(), addr)
×
1149
        }, DefaultTimeout)
1150
        require.NoError(h, err, "timeout waiting for invoice settled state")
×
1151
}
1152

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

×
1158
        // Get the total number of channels.
×
1159
        old := hn.State.OpenChannel.Active + hn.State.OpenChannel.Inactive
×
1160

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

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

1174
                return nil
×
1175
        }, DefaultTimeout)
1176

1177
        require.NoError(h, err, "timeout checking node's num of channels")
×
1178
}
1179

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

×
1185
        var result *lnrpc.Channel
×
1186

×
1187
        // Get the funding point.
×
1188
        err := wait.NoError(func() error {
×
1189
                // Find the target channel first.
×
1190
                target, err := h.findChannel(hn, cp)
×
1191

×
1192
                // Exit early if the channel is not found.
×
1193
                if err != nil {
×
1194
                        return fmt.Errorf("check balance failed: %w", err)
×
1195
                }
×
1196

1197
                result = target
×
1198

×
1199
                // Check local balance.
×
1200
                if target.LocalBalance == balance {
×
1201
                        return nil
×
1202
                }
×
1203

1204
                return fmt.Errorf("balance is incorrect, got %v, expected %v",
×
1205
                        target.LocalBalance, balance)
×
1206
        }, DefaultTimeout)
1207

1208
        require.NoError(h, err, "timeout while checking for balance")
×
1209

×
1210
        return result
×
1211
}
1212

1213
// AssertChannelNumUpdates checks the num of updates is expected from the given
1214
// channel.
1215
func (h *HarnessTest) AssertChannelNumUpdates(hn *node.HarnessNode,
1216
        num uint64, cp *lnrpc.ChannelPoint) {
×
1217

×
1218
        old := int(hn.State.OpenChannel.NumUpdates)
×
1219

×
1220
        // Find the target channel first.
×
1221
        target, err := h.findChannel(hn, cp)
×
1222
        require.NoError(h, err, "unable to find channel")
×
1223

×
1224
        err = wait.NoError(func() error {
×
1225
                total := int(target.NumUpdates)
×
1226
                if total-old == int(num) {
×
1227
                        return nil
×
1228
                }
×
1229

1230
                return errNumNotMatched(hn.Name(), "channel updates",
×
1231
                        int(num), total-old, total, old)
×
1232
        }, DefaultTimeout)
1233
        require.NoError(h, err, "timeout while checking for num of updates")
×
1234
}
1235

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

×
1241
        err := wait.NoError(func() error {
×
1242
                // We require the RPC call to be succeeded and won't wait for
×
1243
                // it as it's an unexpected behavior.
×
1244
                req := &lnrpc.ListChannelsRequest{}
×
1245
                nodeChans := hn.RPC.ListChannels(req)
×
1246

×
1247
                total := 0
×
1248
                for _, channel := range nodeChans.Channels {
×
1249
                        total += len(channel.PendingHtlcs)
×
1250
                }
×
1251
                if total-old != num {
×
1252
                        return errNumNotMatched(hn.Name(), "active HTLCs",
×
1253
                                num, total-old, total, old)
×
1254
                }
×
1255

1256
                return nil
×
1257
        }, DefaultTimeout)
1258

1259
        require.NoErrorf(h, err, "%s timeout checking num active htlcs",
×
1260
                hn.Name())
×
1261
}
1262

1263
// AssertIncomingHTLCActive asserts the node has a pending incoming HTLC in the
1264
// given channel. Returns the HTLC if found and active.
1265
func (h *HarnessTest) AssertIncomingHTLCActive(hn *node.HarnessNode,
1266
        cp *lnrpc.ChannelPoint, payHash []byte) *lnrpc.HTLC {
×
1267

×
1268
        return h.assertHTLCActive(hn, cp, payHash, true)
×
1269
}
×
1270

1271
// AssertOutgoingHTLCActive asserts the node has a pending outgoing HTLC in the
1272
// given channel. Returns the HTLC if found and active.
1273
func (h *HarnessTest) AssertOutgoingHTLCActive(hn *node.HarnessNode,
1274
        cp *lnrpc.ChannelPoint, payHash []byte) *lnrpc.HTLC {
×
1275

×
1276
        return h.assertHTLCActive(hn, cp, payHash, false)
×
1277
}
×
1278

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

×
1284
        var result *lnrpc.HTLC
×
1285
        target := hex.EncodeToString(payHash)
×
1286

×
1287
        err := wait.NoError(func() error {
×
1288
                // We require the RPC call to be succeeded and won't wait for
×
1289
                // it as it's an unexpected behavior.
×
1290
                ch := h.GetChannelByChanPoint(hn, cp)
×
1291

×
1292
                // Check all payment hashes active for this channel.
×
1293
                for _, htlc := range ch.PendingHtlcs {
×
1294
                        h := hex.EncodeToString(htlc.HashLock)
×
1295
                        if h != target {
×
1296
                                continue
×
1297
                        }
1298

1299
                        // If the payment hash is found, check the incoming
1300
                        // field.
1301
                        if htlc.Incoming == incoming {
×
1302
                                // Found it and return.
×
1303
                                result = htlc
×
1304
                                return nil
×
1305
                        }
×
1306

1307
                        // Otherwise we do have the HTLC but its direction is
1308
                        // not right.
1309
                        have, want := "outgoing", "incoming"
×
1310
                        if htlc.Incoming {
×
1311
                                have, want = "incoming", "outgoing"
×
1312
                        }
×
1313

1314
                        return fmt.Errorf("node[%s] have htlc(%v), want: %s, "+
×
1315
                                "have: %s", hn.Name(), payHash, want, have)
×
1316
                }
1317

1318
                return fmt.Errorf("node [%s:%x] didn't have: the payHash %x",
×
1319
                        hn.Name(), hn.PubKey[:], payHash)
×
1320
        }, DefaultTimeout)
1321
        require.NoError(h, err, "timeout checking pending HTLC")
×
1322

×
1323
        return result
×
1324
}
1325

1326
// AssertHLTCNotActive asserts the node doesn't have a pending HTLC in the
1327
// given channel, which mean either the HTLC never exists, or it was pending
1328
// and now settled. Returns the HTLC if found and active.
1329
//
1330
// NOTE: to check a pending HTLC becoming settled, first use AssertHLTCActive
1331
// then follow this check.
1332
func (h *HarnessTest) AssertHTLCNotActive(hn *node.HarnessNode,
1333
        cp *lnrpc.ChannelPoint, payHash []byte) *lnrpc.HTLC {
×
1334

×
1335
        var result *lnrpc.HTLC
×
1336
        target := hex.EncodeToString(payHash)
×
1337

×
1338
        err := wait.NoError(func() error {
×
1339
                // We require the RPC call to be succeeded and won't wait for
×
1340
                // it as it's an unexpected behavior.
×
1341
                ch := h.GetChannelByChanPoint(hn, cp)
×
1342

×
1343
                // Check all payment hashes active for this channel.
×
1344
                for _, htlc := range ch.PendingHtlcs {
×
1345
                        h := hex.EncodeToString(htlc.HashLock)
×
1346

×
1347
                        // Break if found the htlc.
×
1348
                        if h == target {
×
1349
                                result = htlc
×
1350
                                break
×
1351
                        }
1352
                }
1353

1354
                // If we've found nothing, we're done.
1355
                if result == nil {
×
1356
                        return nil
×
1357
                }
×
1358

1359
                // Otherwise return an error.
1360
                return fmt.Errorf("node [%s:%x] still has: the payHash %x",
×
1361
                        hn.Name(), hn.PubKey[:], payHash)
×
1362
        }, DefaultTimeout)
1363
        require.NoError(h, err, "timeout checking pending HTLC")
×
1364

×
1365
        return result
×
1366
}
1367

1368
// ReceiveSingleInvoice waits until a message is received on the subscribe
1369
// single invoice stream or the timeout is reached.
1370
func (h *HarnessTest) ReceiveSingleInvoice(
1371
        stream rpc.SingleInvoiceClient) *lnrpc.Invoice {
×
1372

×
1373
        chanMsg := make(chan *lnrpc.Invoice, 1)
×
1374
        errChan := make(chan error, 1)
×
1375
        go func() {
×
1376
                // Consume one message. This will block until the message is
×
1377
                // received.
×
1378
                resp, err := stream.Recv()
×
1379
                if err != nil {
×
1380
                        errChan <- err
×
1381

×
1382
                        return
×
1383
                }
×
1384
                chanMsg <- resp
×
1385
        }()
1386

1387
        select {
×
1388
        case <-time.After(DefaultTimeout):
×
1389
                require.Fail(h, "timeout", "timeout receiving single invoice")
×
1390

1391
        case err := <-errChan:
×
1392
                require.Failf(h, "err from stream",
×
1393
                        "received err from stream: %v", err)
×
1394

1395
        case updateMsg := <-chanMsg:
×
1396
                return updateMsg
×
1397
        }
1398

1399
        return nil
×
1400
}
1401

1402
// AssertInvoiceState takes a single invoice subscription stream and asserts
1403
// that a given invoice has became the desired state before timeout and returns
1404
// the invoice found.
1405
func (h *HarnessTest) AssertInvoiceState(stream rpc.SingleInvoiceClient,
1406
        state lnrpc.Invoice_InvoiceState) *lnrpc.Invoice {
×
1407

×
1408
        var invoice *lnrpc.Invoice
×
1409

×
1410
        err := wait.NoError(func() error {
×
1411
                invoice = h.ReceiveSingleInvoice(stream)
×
1412
                if invoice.State == state {
×
1413
                        return nil
×
1414
                }
×
1415

1416
                return fmt.Errorf("mismatched invoice state, want %v, got %v",
×
1417
                        state, invoice.State)
×
1418
        }, DefaultTimeout)
1419
        require.NoError(h, err, "timeout waiting for invoice state: %v", state)
×
1420

×
1421
        return invoice
×
1422
}
1423

1424
// assertAllTxesSpendFrom asserts that all txes in the list spend from the
1425
// given tx.
1426
func (h *HarnessTest) AssertAllTxesSpendFrom(txes []*wire.MsgTx,
1427
        prevTxid chainhash.Hash) {
×
1428

×
1429
        for _, tx := range txes {
×
1430
                if tx.TxIn[0].PreviousOutPoint.Hash != prevTxid {
×
1431
                        require.Failf(h, "", "tx %v did not spend from %v",
×
1432
                                tx.TxHash(), prevTxid)
×
1433
                }
×
1434
        }
1435
}
1436

1437
// AssertTxSpendFrom asserts that a given tx is spent from a previous tx.
1438
func (h *HarnessTest) AssertTxSpendFrom(tx *wire.MsgTx,
1439
        prevTxid chainhash.Hash) {
×
1440

×
1441
        if tx.TxIn[0].PreviousOutPoint.Hash != prevTxid {
×
1442
                require.Failf(h, "", "tx %v did not spend from %v",
×
1443
                        tx.TxHash(), prevTxid)
×
1444
        }
×
1445
}
1446

1447
type PendingForceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel
1448

1449
// AssertChannelPendingForceClose asserts that the given channel found in the
1450
// node is pending force close. Returns the PendingForceClose if found.
1451
func (h *HarnessTest) AssertChannelPendingForceClose(hn *node.HarnessNode,
1452
        chanPoint *lnrpc.ChannelPoint) PendingForceClose {
×
1453

×
1454
        var target PendingForceClose
×
1455

×
1456
        op := h.OutPointFromChannelPoint(chanPoint)
×
1457

×
1458
        err := wait.NoError(func() error {
×
1459
                resp := hn.RPC.PendingChannels()
×
1460

×
1461
                forceCloseChans := resp.PendingForceClosingChannels
×
1462
                for _, ch := range forceCloseChans {
×
1463
                        if ch.Channel.ChannelPoint == op.String() {
×
1464
                                target = ch
×
1465

×
1466
                                return nil
×
1467
                        }
×
1468
                }
1469

1470
                return fmt.Errorf("%v: channel %s not found in pending "+
×
1471
                        "force close", hn.Name(), chanPoint)
×
1472
        }, DefaultTimeout)
1473
        require.NoError(h, err, "assert pending force close timed out")
×
1474

×
1475
        return target
×
1476
}
1477

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

×
1483
        // Get the channel output point.
×
1484
        cp := h.OutPointFromChannelPoint(chanPoint)
×
1485

×
1486
        var target PendingForceClose
×
1487
        checkStage := func() error {
×
1488
                resp := hn.RPC.PendingChannels()
×
1489
                if len(resp.PendingForceClosingChannels) == 0 {
×
1490
                        return fmt.Errorf("zero pending force closing channels")
×
1491
                }
×
1492

1493
                for _, ch := range resp.PendingForceClosingChannels {
×
1494
                        if ch.Channel.ChannelPoint == cp.String() {
×
1495
                                target = ch
×
1496

×
1497
                                break
×
1498
                        }
1499
                }
1500

1501
                if target == nil {
×
1502
                        return fmt.Errorf("cannot find pending force closing "+
×
1503
                                "channel using %v", cp)
×
1504
                }
×
1505

1506
                if target.LimboBalance == 0 {
×
1507
                        return fmt.Errorf("zero limbo balance")
×
1508
                }
×
1509

1510
                if len(target.PendingHtlcs) != num {
×
1511
                        return fmt.Errorf("got %d pending htlcs, want %d, %s",
×
1512
                                len(target.PendingHtlcs), num,
×
1513
                                lnutils.SpewLogClosure(target.PendingHtlcs)())
×
1514
                }
×
1515

1516
                for _, htlc := range target.PendingHtlcs {
×
1517
                        if htlc.Stage == stage {
×
1518
                                continue
×
1519
                        }
1520

1521
                        return fmt.Errorf("HTLC %s got stage: %v, "+
×
1522
                                "want stage: %v", htlc.Outpoint, htlc.Stage,
×
1523
                                stage)
×
1524
                }
1525

1526
                return nil
×
1527
        }
1528

1529
        require.NoErrorf(h, wait.NoError(checkStage, DefaultTimeout),
×
1530
                "timeout waiting for htlc stage")
×
1531
}
1532

1533
// findPayment queries the payment from the node's ListPayments which matches
1534
// the specified preimage hash.
1535
func (h *HarnessTest) findPayment(hn *node.HarnessNode,
1536
        paymentHash string) (*lnrpc.Payment, error) {
×
1537

×
1538
        req := &lnrpc.ListPaymentsRequest{IncludeIncomplete: true}
×
1539
        paymentsResp := hn.RPC.ListPayments(req)
×
1540

×
1541
        for _, p := range paymentsResp.Payments {
×
1542
                if p.PaymentHash == paymentHash {
×
1543
                        return p, nil
×
1544
                }
×
1545
        }
1546

1547
        return nil, fmt.Errorf("payment %v cannot be found", paymentHash)
×
1548
}
1549

1550
// PaymentCheck is a function that checks a payment for a specific condition.
1551
type PaymentCheck func(*lnrpc.Payment) error
1552

1553
// AssertPaymentStatus asserts that the given node list a payment with the
1554
// given preimage has the expected status. It also checks that the payment has
1555
// the expected preimage, which is empty when it's not settled and matches the
1556
// given preimage when it's succeeded.
1557
func (h *HarnessTest) AssertPaymentStatus(hn *node.HarnessNode,
1558
        preimage lntypes.Preimage, status lnrpc.Payment_PaymentStatus,
1559
        checks ...PaymentCheck) *lnrpc.Payment {
×
1560

×
1561
        var target *lnrpc.Payment
×
1562
        payHash := preimage.Hash()
×
1563

×
1564
        err := wait.NoError(func() error {
×
1565
                p, err := h.findPayment(hn, payHash.String())
×
1566
                if err != nil {
×
1567
                        return err
×
1568
                }
×
1569

1570
                if status == p.Status {
×
1571
                        target = p
×
1572
                        return nil
×
1573
                }
×
1574

1575
                return fmt.Errorf("payment: %v status not match, want %s "+
×
1576
                        "got %s", payHash, status, p.Status)
×
1577
        }, DefaultTimeout)
1578
        require.NoError(h, err, "timeout checking payment status")
×
1579

×
1580
        switch status {
×
1581
        // If this expected status is SUCCEEDED, we expect the final
1582
        // preimage.
1583
        case lnrpc.Payment_SUCCEEDED:
×
1584
                require.Equal(h, preimage.String(), target.PaymentPreimage,
×
1585
                        "preimage not match")
×
1586

1587
        // Otherwise we expect an all-zero preimage.
1588
        default:
×
1589
                require.Equal(h, (lntypes.Preimage{}).String(),
×
1590
                        target.PaymentPreimage, "expected zero preimage")
×
1591
        }
1592

1593
        // Perform any additional checks on the payment.
1594
        for _, check := range checks {
×
1595
                require.NoError(h, check(target))
×
1596
        }
×
1597

1598
        return target
×
1599
}
1600

1601
// AssertPaymentFailureReason asserts that the given node lists a payment with
1602
// the given preimage which has the expected failure reason.
1603
func (h *HarnessTest) AssertPaymentFailureReason(
1604
        hn *node.HarnessNode, preimage lntypes.Preimage,
1605
        reason lnrpc.PaymentFailureReason) *lnrpc.Payment {
×
1606

×
1607
        var payment *lnrpc.Payment
×
1608

×
1609
        payHash := preimage.Hash()
×
1610
        err := wait.NoError(func() error {
×
1611
                p, err := h.findPayment(hn, payHash.String())
×
1612
                if err != nil {
×
1613
                        return err
×
1614
                }
×
1615

1616
                payment = p
×
1617

×
1618
                if reason == p.FailureReason {
×
1619
                        return nil
×
1620
                }
×
1621

1622
                return fmt.Errorf("payment: %v failure reason not match, "+
×
1623
                        "want %s(%d) got %s(%d)", payHash, reason, reason,
×
1624
                        p.FailureReason, p.FailureReason)
×
1625
        }, DefaultTimeout)
1626
        require.NoError(h, err, "timeout checking payment failure reason")
×
1627

×
1628
        return payment
×
1629
}
1630

1631
// AssertActiveNodesSynced asserts all active nodes have synced to the chain.
1632
func (h *HarnessTest) AssertActiveNodesSynced() {
×
1633
        for _, node := range h.manager.activeNodes {
×
1634
                h.WaitForBlockchainSync(node)
×
1635
        }
×
1636
}
1637

1638
// AssertActiveNodesSyncedTo asserts all active nodes have synced to the
1639
// provided bestBlock.
1640
func (h *HarnessTest) AssertActiveNodesSyncedTo(bestBlock chainhash.Hash) {
×
1641
        for _, node := range h.manager.activeNodes {
×
1642
                h.WaitForBlockchainSyncTo(node, bestBlock)
×
1643
        }
×
1644
}
1645

1646
// AssertPeerNotConnected asserts that the given node b is not connected to a.
1647
func (h *HarnessTest) AssertPeerNotConnected(a, b *node.HarnessNode) {
×
1648
        err := wait.NoError(func() error {
×
1649
                // We require the RPC call to be succeeded and won't wait for
×
1650
                // it as it's an unexpected behavior.
×
1651
                resp := a.RPC.ListPeers()
×
1652

×
1653
                // If node B is seen in the ListPeers response from node A,
×
1654
                // then we return false as the connection has been fully
×
1655
                // established.
×
1656
                for _, peer := range resp.Peers {
×
1657
                        if peer.PubKey == b.PubKeyStr {
×
1658
                                return fmt.Errorf("peers %s and %s still "+
×
1659
                                        "connected", a.Name(), b.Name())
×
1660
                        }
×
1661
                }
1662

1663
                return nil
×
1664
        }, DefaultTimeout)
1665
        require.NoError(h, err, "timeout checking peers not connected")
×
1666
}
1667

1668
// AssertNotConnected asserts that two peers are not connected.
1669
func (h *HarnessTest) AssertNotConnected(a, b *node.HarnessNode) {
×
1670
        h.AssertPeerNotConnected(a, b)
×
1671
        h.AssertPeerNotConnected(b, a)
×
1672
}
×
1673

1674
// AssertConnected asserts that two peers are connected.
1675
func (h *HarnessTest) AssertConnected(a, b *node.HarnessNode) {
×
1676
        h.AssertPeerConnected(a, b)
×
1677
        h.AssertPeerConnected(b, a)
×
1678
}
×
1679

1680
// AssertAmountPaid checks that the ListChannels command of the provided
1681
// node list the total amount sent and received as expected for the
1682
// provided channel.
1683
func (h *HarnessTest) AssertAmountPaid(channelName string, hn *node.HarnessNode,
1684
        chanPoint *lnrpc.ChannelPoint, amountSent, amountReceived int64) {
×
1685

×
1686
        checkAmountPaid := func() error {
×
1687
                // Find the targeted channel.
×
1688
                channel, err := h.findChannel(hn, chanPoint)
×
1689
                if err != nil {
×
1690
                        return fmt.Errorf("assert amount failed: %w", err)
×
1691
                }
×
1692

1693
                if channel.TotalSatoshisSent != amountSent {
×
1694
                        return fmt.Errorf("%v: incorrect amount"+
×
1695
                                " sent: %v != %v", channelName,
×
1696
                                channel.TotalSatoshisSent,
×
1697
                                amountSent)
×
1698
                }
×
1699
                if channel.TotalSatoshisReceived !=
×
1700
                        amountReceived {
×
1701

×
1702
                        return fmt.Errorf("%v: incorrect amount"+
×
1703
                                " received: %v != %v",
×
1704
                                channelName,
×
1705
                                channel.TotalSatoshisReceived,
×
1706
                                amountReceived)
×
1707
                }
×
1708

1709
                return nil
×
1710
        }
1711

1712
        // As far as HTLC inclusion in commitment transaction might be
1713
        // postponed we will try to check the balance couple of times,
1714
        // and then if after some period of time we receive wrong
1715
        // balance return the error.
1716
        err := wait.NoError(checkAmountPaid, DefaultTimeout)
×
1717
        require.NoError(h, err, "timeout while checking amount paid")
×
1718
}
1719

1720
// AssertLastHTLCError checks that the last sent HTLC of the last payment sent
1721
// by the given node failed with the expected failure code.
1722
func (h *HarnessTest) AssertLastHTLCError(hn *node.HarnessNode,
1723
        code lnrpc.Failure_FailureCode) {
×
1724

×
1725
        // Use -1 to specify the last HTLC.
×
1726
        h.assertHTLCError(hn, code, -1)
×
1727
}
×
1728

1729
// AssertFirstHTLCError checks that the first HTLC of the last payment sent
1730
// by the given node failed with the expected failure code.
1731
func (h *HarnessTest) AssertFirstHTLCError(hn *node.HarnessNode,
1732
        code lnrpc.Failure_FailureCode) {
×
1733

×
1734
        // Use 0 to specify the first HTLC.
×
1735
        h.assertHTLCError(hn, code, 0)
×
1736
}
×
1737

1738
// assertLastHTLCError checks that the HTLC at the specified index of the last
1739
// payment sent by the given node failed with the expected failure code.
1740
func (h *HarnessTest) assertHTLCError(hn *node.HarnessNode,
1741
        code lnrpc.Failure_FailureCode, index int) {
×
1742

×
1743
        req := &lnrpc.ListPaymentsRequest{
×
1744
                IncludeIncomplete: true,
×
1745
        }
×
1746

×
1747
        err := wait.NoError(func() error {
×
1748
                paymentsResp := hn.RPC.ListPayments(req)
×
1749

×
1750
                payments := paymentsResp.Payments
×
1751
                if len(payments) == 0 {
×
1752
                        return fmt.Errorf("no payments found")
×
1753
                }
×
1754

1755
                payment := payments[len(payments)-1]
×
1756
                htlcs := payment.Htlcs
×
1757
                if len(htlcs) == 0 {
×
1758
                        return fmt.Errorf("no htlcs found")
×
1759
                }
×
1760

1761
                // If the index is greater than 0, check we have enough htlcs.
1762
                if index > 0 && len(htlcs) <= index {
×
1763
                        return fmt.Errorf("not enough htlcs")
×
1764
                }
×
1765

1766
                // If index is less than or equal to 0, we will read the last
1767
                // htlc.
1768
                if index <= 0 {
×
1769
                        index = len(htlcs) - 1
×
1770
                }
×
1771

1772
                htlc := htlcs[index]
×
1773

×
1774
                // The htlc must have a status of failed.
×
1775
                if htlc.Status != lnrpc.HTLCAttempt_FAILED {
×
1776
                        return fmt.Errorf("htlc should be failed")
×
1777
                }
×
1778
                // The failure field must not be empty.
1779
                if htlc.Failure == nil {
×
1780
                        return fmt.Errorf("expected htlc failure")
×
1781
                }
×
1782

1783
                // Exit if the expected code is found.
1784
                if htlc.Failure.Code == code {
×
1785
                        return nil
×
1786
                }
×
1787

1788
                return fmt.Errorf("unexpected failure code")
×
1789
        }, DefaultTimeout)
1790

1791
        require.NoError(h, err, "timeout checking HTLC error")
×
1792
}
1793

1794
// AssertZombieChannel asserts that a given channel found using the chanID is
1795
// marked as zombie.
1796
func (h *HarnessTest) AssertZombieChannel(hn *node.HarnessNode, chanID uint64) {
×
1797
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
1798
        defer cancel()
×
1799

×
1800
        err := wait.NoError(func() error {
×
1801
                _, err := hn.RPC.LN.GetChanInfo(
×
1802
                        ctxt, &lnrpc.ChanInfoRequest{ChanId: chanID},
×
1803
                )
×
1804
                if err == nil {
×
1805
                        return fmt.Errorf("expected error but got nil")
×
1806
                }
×
1807

1808
                if !strings.Contains(err.Error(), "marked as zombie") {
×
1809
                        return fmt.Errorf("expected error to contain '%s' but "+
×
1810
                                "was '%v'", "marked as zombie", err)
×
1811
                }
×
1812

1813
                return nil
×
1814
        }, DefaultTimeout)
1815
        require.NoError(h, err, "timeout while checking zombie channel")
×
1816
}
1817

1818
// AssertNotInGraph asserts that a given channel is either not found at all in
1819
// the graph or that it has been marked as a zombie.
1820
func (h *HarnessTest) AssertNotInGraph(hn *node.HarnessNode, chanID uint64) {
×
1821
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
1822
        defer cancel()
×
1823

×
1824
        err := wait.NoError(func() error {
×
1825
                _, err := hn.RPC.LN.GetChanInfo(
×
1826
                        ctxt, &lnrpc.ChanInfoRequest{ChanId: chanID},
×
1827
                )
×
1828
                if err == nil {
×
1829
                        return fmt.Errorf("expected error but got nil")
×
1830
                }
×
1831

1832
                switch {
×
1833
                case strings.Contains(err.Error(), "marked as zombie"):
×
1834
                        return nil
×
1835

1836
                case strings.Contains(err.Error(), "edge not found"):
×
1837
                        return nil
×
1838

1839
                default:
×
1840
                        return fmt.Errorf("expected error to contain either "+
×
1841
                                "'%s' or '%s' but was: '%v'", "marked as i"+
×
1842
                                "zombie", "edge not found", err)
×
1843
                }
1844
        }, DefaultTimeout)
1845
        require.NoError(h, err, "timeout while checking that channel is not "+
×
1846
                "found in graph")
×
1847
}
1848

1849
// AssertChannelInGraphDB asserts that a given channel is found in the graph db.
1850
func (h *HarnessTest) AssertChannelInGraphDB(hn *node.HarnessNode,
1851
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelEdge {
×
1852

×
1853
        ctxt, cancel := context.WithCancel(h.runCtx)
×
1854
        defer cancel()
×
1855

×
1856
        var edge *lnrpc.ChannelEdge
×
1857

×
1858
        op := h.OutPointFromChannelPoint(chanPoint)
×
1859
        err := wait.NoError(func() error {
×
1860
                resp, err := hn.RPC.LN.GetChanInfo(
×
1861
                        ctxt, &lnrpc.ChanInfoRequest{
×
1862
                                ChanPoint: op.String(),
×
1863
                        },
×
1864
                )
×
1865
                if err != nil {
×
1866
                        return fmt.Errorf("channel %s not found in graph: %w",
×
1867
                                op, err)
×
1868
                }
×
1869

1870
                // Make sure the policies are populated, otherwise this edge
1871
                // cannot be used for routing.
1872
                if resp.Node1Policy == nil {
×
1873
                        return fmt.Errorf("channel %s has no policy1", op)
×
1874
                }
×
1875

1876
                if resp.Node2Policy == nil {
×
1877
                        return fmt.Errorf("channel %s has no policy2", op)
×
1878
                }
×
1879

1880
                edge = resp
×
1881

×
1882
                return nil
×
1883
        }, DefaultTimeout)
1884

1885
        require.NoError(h, err, "%s: timeout finding channel in graph",
×
1886
                hn.Name())
×
1887

×
1888
        return edge
×
1889
}
1890

1891
// AssertChannelInGraphCache asserts a given channel is found in the graph
1892
// cache.
1893
func (h *HarnessTest) AssertChannelInGraphCache(hn *node.HarnessNode,
1894
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelEdge {
×
1895

×
1896
        var edge *lnrpc.ChannelEdge
×
1897

×
1898
        req := &lnrpc.ChannelGraphRequest{IncludeUnannounced: true}
×
1899
        cpStr := channelPointStr(chanPoint)
×
1900

×
1901
        err := wait.NoError(func() error {
×
1902
                chanGraph := hn.RPC.DescribeGraph(req)
×
1903

×
1904
                // Iterate all the known edges, and make sure the edge policies
×
1905
                // are populated when a matched edge is found.
×
1906
                for _, e := range chanGraph.Edges {
×
1907
                        if e.ChanPoint != cpStr {
×
1908
                                continue
×
1909
                        }
1910

1911
                        if e.Node1Policy == nil {
×
1912
                                return fmt.Errorf("no policy for node1 %v",
×
1913
                                        e.Node1Pub)
×
1914
                        }
×
1915

1916
                        if e.Node2Policy == nil {
×
1917
                                return fmt.Errorf("no policy for node2 %v",
×
1918
                                        e.Node1Pub)
×
1919
                        }
×
1920

1921
                        edge = e
×
1922

×
1923
                        return nil
×
1924
                }
1925

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

1931
        require.NoError(h, err, "%s: timeout finding channel %v in graph cache",
×
1932
                cpStr, hn.Name())
×
1933

×
1934
        return edge
×
1935
}
1936

1937
// AssertChannelInGraphDB asserts that a given channel is found both in the
1938
// graph db (GetChanInfo) and the graph cache (DescribeGraph).
1939
func (h *HarnessTest) AssertChannelInGraph(hn *node.HarnessNode,
1940
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelEdge {
×
1941

×
1942
        // Make sure the channel is found in the db first.
×
1943
        h.AssertChannelInGraphDB(hn, chanPoint)
×
1944

×
1945
        // Assert the channel is also found in the graph cache, which refreshes
×
1946
        // every `--caches.rpc-graph-cache-duration`.
×
1947
        return h.AssertChannelInGraphCache(hn, chanPoint)
×
1948
}
×
1949

1950
// AssertTxAtHeight gets all of the transactions that a node's wallet has a
1951
// record of at the target height, and finds and returns the tx with the target
1952
// txid, failing if it is not found.
1953
func (h *HarnessTest) AssertTxAtHeight(hn *node.HarnessNode, height int32,
1954
        txid *chainhash.Hash) *lnrpc.Transaction {
×
1955

×
1956
        req := &lnrpc.GetTransactionsRequest{
×
1957
                StartHeight: height,
×
1958
                EndHeight:   height,
×
1959
        }
×
1960
        txns := hn.RPC.GetTransactions(req)
×
1961

×
1962
        for _, tx := range txns.Transactions {
×
1963
                if tx.TxHash == txid.String() {
×
1964
                        return tx
×
1965
                }
×
1966
        }
1967

1968
        require.Failf(h, "fail to find tx", "tx:%v not found at height:%v",
×
1969
                txid, height)
×
1970

×
1971
        return nil
×
1972
}
1973

1974
// getChannelPolicies queries the channel graph and retrieves the current edge
1975
// policies for the provided channel point.
1976
func (h *HarnessTest) getChannelPolicies(hn *node.HarnessNode,
1977
        advertisingNode string,
1978
        cp *lnrpc.ChannelPoint) (*lnrpc.RoutingPolicy, error) {
×
1979

×
1980
        req := &lnrpc.ChannelGraphRequest{IncludeUnannounced: true}
×
1981
        chanGraph := hn.RPC.DescribeGraph(req)
×
1982

×
1983
        cpStr := channelPointStr(cp)
×
1984
        for _, e := range chanGraph.Edges {
×
1985
                if e.ChanPoint != cpStr {
×
1986
                        continue
×
1987
                }
1988

1989
                if e.Node1Pub == advertisingNode {
×
1990
                        return e.Node1Policy, nil
×
1991
                }
×
1992

1993
                return e.Node2Policy, nil
×
1994
        }
1995

1996
        // If we've iterated over all the known edges and we weren't
1997
        // able to find this specific one, then we'll fail.
1998
        return nil, fmt.Errorf("did not find edge with advertisingNode: %s"+
×
1999
                ", channel point: %s", advertisingNode, cpStr)
×
2000
}
2001

2002
// AssertChannelPolicy asserts that the passed node's known channel policy for
2003
// the passed chanPoint is consistent with the expected policy values.
2004
func (h *HarnessTest) AssertChannelPolicy(hn *node.HarnessNode,
2005
        advertisingNode string, expectedPolicy *lnrpc.RoutingPolicy,
2006
        chanPoint *lnrpc.ChannelPoint) {
×
2007

×
2008
        policy, err := h.getChannelPolicies(hn, advertisingNode, chanPoint)
×
2009
        require.NoErrorf(h, err, "%s: failed to find policy", hn.Name())
×
2010

×
2011
        err = node.CheckChannelPolicy(policy, expectedPolicy)
×
2012
        require.NoErrorf(h, err, "%s: check policy failed", hn.Name())
×
2013
}
×
2014

2015
// AssertNumPolicyUpdates asserts that a given number of channel policy updates
2016
// has been seen in the specified node.
2017
func (h *HarnessTest) AssertNumPolicyUpdates(hn *node.HarnessNode,
2018
        chanPoint *lnrpc.ChannelPoint,
2019
        advertisingNode *node.HarnessNode, num int) {
×
2020

×
2021
        op := h.OutPointFromChannelPoint(chanPoint)
×
2022

×
2023
        var policies []*node.PolicyUpdateInfo
×
2024

×
2025
        err := wait.NoError(func() error {
×
2026
                policyMap := hn.Watcher.GetPolicyUpdates(op)
×
2027
                nodePolicy, ok := policyMap[advertisingNode.PubKeyStr]
×
2028
                if ok {
×
2029
                        policies = nodePolicy
×
2030
                }
×
2031

2032
                if len(policies) == num {
×
2033
                        return nil
×
2034
                }
×
2035

2036
                p, err := json.MarshalIndent(policies, "", "\t")
×
2037
                require.NoError(h, err, "encode policy err")
×
2038

×
2039
                return fmt.Errorf("expected to find %d policy updates, "+
×
2040
                        "instead got: %d, chanPoint: %v, "+
×
2041
                        "advertisingNode: %s:%s, policy: %s", num,
×
2042
                        len(policies), op, advertisingNode.Name(),
×
2043
                        advertisingNode.PubKeyStr, p)
×
2044
        }, DefaultTimeout)
2045

2046
        require.NoError(h, err, "%s: timeout waiting for num of policy updates",
×
2047
                hn.Name())
×
2048
}
2049

2050
// AssertNumPayments asserts that the number of payments made within the test
2051
// scope is as expected, including the incomplete ones.
2052
func (h *HarnessTest) AssertNumPayments(hn *node.HarnessNode,
2053
        num int) []*lnrpc.Payment {
×
2054

×
2055
        // Get the number of payments we already have from the previous test.
×
2056
        have := hn.State.Payment.Total
×
2057

×
2058
        req := &lnrpc.ListPaymentsRequest{
×
2059
                IncludeIncomplete: true,
×
2060
                IndexOffset:       hn.State.Payment.LastIndexOffset,
×
2061
        }
×
2062

×
2063
        var payments []*lnrpc.Payment
×
2064
        err := wait.NoError(func() error {
×
2065
                resp := hn.RPC.ListPayments(req)
×
2066

×
2067
                payments = resp.Payments
×
2068
                if len(payments) == num {
×
2069
                        return nil
×
2070
                }
×
2071

2072
                return errNumNotMatched(hn.Name(), "num of payments",
×
2073
                        num, len(payments), have+len(payments), have)
×
2074
        }, DefaultTimeout)
2075
        require.NoError(h, err, "%s: timeout checking num of payments",
×
2076
                hn.Name())
×
2077

×
2078
        return payments
×
2079
}
2080

2081
// AssertNumNodeAnns asserts that a given number of node announcements has been
2082
// seen in the specified node.
2083
func (h *HarnessTest) AssertNumNodeAnns(hn *node.HarnessNode,
2084
        pubkey string, num int) []*lnrpc.NodeUpdate {
×
2085

×
2086
        // We will get the current number of channel updates first and add it
×
2087
        // to our expected number of newly created channel updates.
×
2088
        anns, err := hn.Watcher.WaitForNumNodeUpdates(pubkey, num)
×
2089
        require.NoError(h, err, "%s: failed to assert num of node anns",
×
2090
                hn.Name())
×
2091

×
2092
        return anns
×
2093
}
×
2094

2095
// AssertNumChannelUpdates asserts that a given number of channel updates has
2096
// been seen in the specified node's network topology.
2097
func (h *HarnessTest) AssertNumChannelUpdates(hn *node.HarnessNode,
2098
        chanPoint *lnrpc.ChannelPoint, num int) {
×
2099

×
2100
        op := h.OutPointFromChannelPoint(chanPoint)
×
2101
        err := hn.Watcher.WaitForNumChannelUpdates(op, num)
×
2102
        require.NoError(h, err, "%s: failed to assert num of channel updates",
×
2103
                hn.Name())
×
2104
}
×
2105

2106
// CreateBurnAddr creates a random burn address of the given type.
2107
func (h *HarnessTest) CreateBurnAddr(addrType lnrpc.AddressType) ([]byte,
2108
        btcutil.Address) {
×
2109

×
2110
        randomPrivKey, err := btcec.NewPrivateKey()
×
2111
        require.NoError(h, err)
×
2112

×
2113
        randomKeyBytes := randomPrivKey.PubKey().SerializeCompressed()
×
2114
        harnessNetParams := miner.HarnessNetParams
×
2115

×
2116
        var addr btcutil.Address
×
2117
        switch addrType {
×
2118
        case lnrpc.AddressType_WITNESS_PUBKEY_HASH:
×
2119
                addr, err = btcutil.NewAddressWitnessPubKeyHash(
×
2120
                        btcutil.Hash160(randomKeyBytes), harnessNetParams,
×
2121
                )
×
2122

2123
        case lnrpc.AddressType_TAPROOT_PUBKEY:
×
2124
                taprootKey := txscript.ComputeTaprootKeyNoScript(
×
2125
                        randomPrivKey.PubKey(),
×
2126
                )
×
2127
                addr, err = btcutil.NewAddressPubKey(
×
2128
                        schnorr.SerializePubKey(taprootKey), harnessNetParams,
×
2129
                )
×
2130

2131
        case lnrpc.AddressType_NESTED_PUBKEY_HASH:
×
2132
                var witnessAddr btcutil.Address
×
2133
                witnessAddr, err = btcutil.NewAddressWitnessPubKeyHash(
×
2134
                        btcutil.Hash160(randomKeyBytes), harnessNetParams,
×
2135
                )
×
2136
                require.NoError(h, err)
×
2137

×
2138
                addr, err = btcutil.NewAddressScriptHash(
×
2139
                        h.PayToAddrScript(witnessAddr), harnessNetParams,
×
2140
                )
×
2141

2142
        default:
×
2143
                h.Fatalf("Unsupported burn address type: %v", addrType)
×
2144
        }
2145
        require.NoError(h, err)
×
2146

×
2147
        return h.PayToAddrScript(addr), addr
×
2148
}
2149

2150
// ReceiveTrackPayment waits until a message is received on the track payment
2151
// stream or the timeout is reached.
2152
func (h *HarnessTest) ReceiveTrackPayment(
2153
        stream rpc.TrackPaymentClient) *lnrpc.Payment {
×
2154

×
2155
        chanMsg := make(chan *lnrpc.Payment)
×
2156
        errChan := make(chan error)
×
2157
        go func() {
×
2158
                // Consume one message. This will block until the message is
×
2159
                // received.
×
2160
                resp, err := stream.Recv()
×
2161
                if err != nil {
×
2162
                        errChan <- err
×
2163
                        return
×
2164
                }
×
2165
                chanMsg <- resp
×
2166
        }()
2167

2168
        select {
×
2169
        case <-time.After(DefaultTimeout):
×
2170
                require.Fail(h, "timeout", "timeout trakcing payment")
×
2171

2172
        case err := <-errChan:
×
2173
                require.Failf(h, "err from stream",
×
2174
                        "received err from stream: %v", err)
×
2175

2176
        case updateMsg := <-chanMsg:
×
2177
                return updateMsg
×
2178
        }
2179

2180
        return nil
×
2181
}
2182

2183
// ReceiveHtlcEvent waits until a message is received on the subscribe
2184
// htlc event stream or the timeout is reached.
2185
func (h *HarnessTest) ReceiveHtlcEvent(
2186
        stream rpc.HtlcEventsClient) *routerrpc.HtlcEvent {
×
2187

×
2188
        chanMsg := make(chan *routerrpc.HtlcEvent)
×
2189
        errChan := make(chan error)
×
2190
        go func() {
×
2191
                // Consume one message. This will block until the message is
×
2192
                // received.
×
2193
                resp, err := stream.Recv()
×
2194
                if err != nil {
×
2195
                        errChan <- err
×
2196
                        return
×
2197
                }
×
2198
                chanMsg <- resp
×
2199
        }()
2200

2201
        select {
×
2202
        case <-time.After(DefaultTimeout):
×
2203
                require.Fail(h, "timeout", "timeout receiving htlc "+
×
2204
                        "event update")
×
2205

2206
        case err := <-errChan:
×
2207
                require.Failf(h, "err from stream",
×
2208
                        "received err from stream: %v", err)
×
2209

2210
        case updateMsg := <-chanMsg:
×
2211
                return updateMsg
×
2212
        }
2213

2214
        return nil
×
2215
}
2216

2217
// AssertHtlcEventType consumes one event from a client and asserts the event
2218
// type is matched.
2219
func (h *HarnessTest) AssertHtlcEventType(client rpc.HtlcEventsClient,
2220
        userType routerrpc.HtlcEvent_EventType) *routerrpc.HtlcEvent {
×
2221

×
2222
        event := h.ReceiveHtlcEvent(client)
×
2223
        require.Equalf(h, userType, event.EventType, "wrong event type, "+
×
2224
                "want %v got %v", userType, event.EventType)
×
2225

×
2226
        return event
×
2227
}
×
2228

2229
// HtlcEvent maps the series of event types used in `*routerrpc.HtlcEvent_*`.
2230
type HtlcEvent int
2231

2232
const (
2233
        HtlcEventForward HtlcEvent = iota
2234
        HtlcEventForwardFail
2235
        HtlcEventSettle
2236
        HtlcEventLinkFail
2237
        HtlcEventFinal
2238
)
2239

2240
// AssertHtlcEventType consumes one event from a client and asserts both the
2241
// user event type the event.Event type is matched.
2242
func (h *HarnessTest) AssertHtlcEventTypes(client rpc.HtlcEventsClient,
2243
        userType routerrpc.HtlcEvent_EventType,
2244
        eventType HtlcEvent) *routerrpc.HtlcEvent {
×
2245

×
2246
        event := h.ReceiveHtlcEvent(client)
×
2247
        require.Equalf(h, userType, event.EventType, "wrong event type, "+
×
2248
                "want %v got %v", userType, event.EventType)
×
2249

×
2250
        var ok bool
×
2251

×
2252
        switch eventType {
×
2253
        case HtlcEventForward:
×
2254
                _, ok = event.Event.(*routerrpc.HtlcEvent_ForwardEvent)
×
2255

2256
        case HtlcEventForwardFail:
×
2257
                _, ok = event.Event.(*routerrpc.HtlcEvent_ForwardFailEvent)
×
2258

2259
        case HtlcEventSettle:
×
2260
                _, ok = event.Event.(*routerrpc.HtlcEvent_SettleEvent)
×
2261

2262
        case HtlcEventLinkFail:
×
2263
                _, ok = event.Event.(*routerrpc.HtlcEvent_LinkFailEvent)
×
2264

2265
        case HtlcEventFinal:
×
2266
                _, ok = event.Event.(*routerrpc.HtlcEvent_FinalHtlcEvent)
×
2267
        }
2268

2269
        require.Truef(h, ok, "wrong event type: %T, want %T", event.Event,
×
2270
                eventType)
×
2271

×
2272
        return event
×
2273
}
2274

2275
// AssertFeeReport checks that the fee report from the given node has the
2276
// desired day, week, and month sum values.
2277
func (h *HarnessTest) AssertFeeReport(hn *node.HarnessNode,
2278
        day, week, month int) {
×
2279

×
2280
        err := wait.NoError(func() error {
×
2281
                feeReport, err := hn.RPC.LN.FeeReport(
×
2282
                        h.runCtx, &lnrpc.FeeReportRequest{},
×
2283
                )
×
2284
                require.NoError(h, err, "unable to query for fee report")
×
2285

×
2286
                if uint64(day) != feeReport.DayFeeSum {
×
2287
                        return fmt.Errorf("day fee mismatch, want %d, got %d",
×
2288
                                day, feeReport.DayFeeSum)
×
2289
                }
×
2290

2291
                if uint64(week) != feeReport.WeekFeeSum {
×
2292
                        return fmt.Errorf("week fee mismatch, want %d, got %d",
×
2293
                                week, feeReport.WeekFeeSum)
×
2294
                }
×
2295
                if uint64(month) != feeReport.MonthFeeSum {
×
2296
                        return fmt.Errorf("month fee mismatch, want %d, got %d",
×
2297
                                month, feeReport.MonthFeeSum)
×
2298
                }
×
2299

2300
                return nil
×
2301
        }, wait.DefaultTimeout)
2302
        require.NoErrorf(h, err, "%s: time out checking fee report", hn.Name())
×
2303
}
2304

2305
// AssertHtlcEvents consumes events from a client and ensures that they are of
2306
// the expected type and contain the expected number of forwards, forward
2307
// failures and settles.
2308
//
2309
// TODO(yy): needs refactor to reduce its complexity.
2310
func (h *HarnessTest) AssertHtlcEvents(client rpc.HtlcEventsClient,
2311
        fwdCount, fwdFailCount, settleCount, linkFailCount int,
2312
        userType routerrpc.HtlcEvent_EventType) []*routerrpc.HtlcEvent {
×
2313

×
2314
        var forwards, forwardFails, settles, linkFails int
×
2315

×
2316
        numEvents := fwdCount + fwdFailCount + settleCount + linkFailCount
×
2317
        events := make([]*routerrpc.HtlcEvent, 0)
×
2318

×
2319
        // It's either the userType or the unknown type.
×
2320
        //
×
2321
        // TODO(yy): maybe the FinalHtlcEvent shouldn't be in UNKNOWN type?
×
2322
        eventTypes := []routerrpc.HtlcEvent_EventType{
×
2323
                userType, routerrpc.HtlcEvent_UNKNOWN,
×
2324
        }
×
2325

×
2326
        for i := 0; i < numEvents; i++ {
×
2327
                event := h.ReceiveHtlcEvent(client)
×
2328

×
2329
                require.Containsf(h, eventTypes, event.EventType,
×
2330
                        "wrong event type, got %v", userType, event.EventType)
×
2331

×
2332
                events = append(events, event)
×
2333

×
2334
                switch e := event.Event.(type) {
×
2335
                case *routerrpc.HtlcEvent_ForwardEvent:
×
2336
                        forwards++
×
2337

2338
                case *routerrpc.HtlcEvent_ForwardFailEvent:
×
2339
                        forwardFails++
×
2340

2341
                case *routerrpc.HtlcEvent_SettleEvent:
×
2342
                        settles++
×
2343

2344
                case *routerrpc.HtlcEvent_FinalHtlcEvent:
×
2345
                        if e.FinalHtlcEvent.Settled {
×
2346
                                settles++
×
2347
                        }
×
2348

2349
                case *routerrpc.HtlcEvent_LinkFailEvent:
×
2350
                        linkFails++
×
2351

2352
                default:
×
2353
                        require.Fail(h, "assert event fail",
×
2354
                                "unexpected event: %T", event.Event)
×
2355
                }
2356
        }
2357

2358
        require.Equal(h, fwdCount, forwards, "num of forwards mismatch")
×
2359
        require.Equal(h, fwdFailCount, forwardFails,
×
2360
                "num of forward fails mismatch")
×
2361
        require.Equal(h, settleCount, settles, "num of settles mismatch")
×
2362
        require.Equal(h, linkFailCount, linkFails, "num of link fails mismatch")
×
2363

×
2364
        return events
×
2365
}
2366

2367
// AssertTransactionInWallet asserts a given txid can be found in the node's
2368
// wallet.
2369
func (h *HarnessTest) AssertTransactionInWallet(hn *node.HarnessNode,
2370
        txid chainhash.Hash) {
×
2371

×
2372
        req := &lnrpc.GetTransactionsRequest{}
×
2373
        err := wait.NoError(func() error {
×
2374
                txResp := hn.RPC.GetTransactions(req)
×
2375
                for _, txn := range txResp.Transactions {
×
2376
                        if txn.TxHash == txid.String() {
×
2377
                                return nil
×
2378
                        }
×
2379
                }
2380

2381
                return fmt.Errorf("%s: expected txid=%v not found in wallet",
×
2382
                        hn.Name(), txid)
×
2383
        }, DefaultTimeout)
2384

2385
        require.NoError(h, err, "failed to find tx")
×
2386
}
2387

2388
// AssertTransactionNotInWallet asserts a given txid can NOT be found in the
2389
// node's wallet.
2390
func (h *HarnessTest) AssertTransactionNotInWallet(hn *node.HarnessNode,
2391
        txid chainhash.Hash) {
×
2392

×
2393
        req := &lnrpc.GetTransactionsRequest{}
×
2394
        err := wait.NoError(func() error {
×
2395
                txResp := hn.RPC.GetTransactions(req)
×
2396
                for _, txn := range txResp.Transactions {
×
2397
                        if txn.TxHash == txid.String() {
×
2398
                                return fmt.Errorf("expected txid=%v to be "+
×
2399
                                        "not found", txid)
×
2400
                        }
×
2401
                }
2402

2403
                return nil
×
2404
        }, DefaultTimeout)
2405

2406
        require.NoErrorf(h, err, "%s: failed to assert tx not found", hn.Name())
×
2407
}
2408

2409
// WaitForNodeBlockHeight queries the node for its current block height until
2410
// it reaches the passed height.
2411
func (h *HarnessTest) WaitForNodeBlockHeight(hn *node.HarnessNode,
2412
        height int32) {
×
2413

×
2414
        err := wait.NoError(func() error {
×
2415
                info := hn.RPC.GetInfo()
×
2416
                if int32(info.BlockHeight) != height {
×
2417
                        return fmt.Errorf("expected block height to "+
×
2418
                                "be %v, was %v", height, info.BlockHeight)
×
2419
                }
×
2420

2421
                return nil
×
2422
        }, DefaultTimeout)
2423

2424
        require.NoErrorf(h, err, "%s: timeout while waiting for height",
×
2425
                hn.Name())
×
2426
}
2427

2428
// AssertChannelCommitHeight asserts the given channel for the node has the
2429
// expected commit height(`NumUpdates`).
2430
func (h *HarnessTest) AssertChannelCommitHeight(hn *node.HarnessNode,
2431
        cp *lnrpc.ChannelPoint, height int) {
×
2432

×
2433
        err := wait.NoError(func() error {
×
2434
                c, err := h.findChannel(hn, cp)
×
2435
                if err != nil {
×
2436
                        return err
×
2437
                }
×
2438

2439
                if int(c.NumUpdates) == height {
×
2440
                        return nil
×
2441
                }
×
2442

2443
                return fmt.Errorf("expected commit height to be %v, was %v",
×
2444
                        height, c.NumUpdates)
×
2445
        }, DefaultTimeout)
2446

2447
        require.NoError(h, err, "timeout while waiting for commit height")
×
2448
}
2449

2450
// AssertNumInvoices asserts that the number of invoices made within the test
2451
// scope is as expected.
2452
func (h *HarnessTest) AssertNumInvoices(hn *node.HarnessNode,
2453
        num int) []*lnrpc.Invoice {
×
2454

×
2455
        have := hn.State.Invoice.Total
×
2456
        req := &lnrpc.ListInvoiceRequest{
×
2457
                NumMaxInvoices: math.MaxUint64,
×
2458
                IndexOffset:    hn.State.Invoice.LastIndexOffset,
×
2459
        }
×
2460

×
2461
        var invoices []*lnrpc.Invoice
×
2462
        err := wait.NoError(func() error {
×
2463
                resp := hn.RPC.ListInvoices(req)
×
2464

×
2465
                invoices = resp.Invoices
×
2466
                if len(invoices) == num {
×
2467
                        return nil
×
2468
                }
×
2469

2470
                return errNumNotMatched(hn.Name(), "num of invoices",
×
2471
                        num, len(invoices), have+len(invoices), have)
×
2472
        }, DefaultTimeout)
2473
        require.NoError(h, err, "timeout checking num of invoices")
×
2474

×
2475
        return invoices
×
2476
}
2477

2478
// ReceiveSendToRouteUpdate waits until a message is received on the
2479
// SendToRoute client stream or the timeout is reached.
2480
func (h *HarnessTest) ReceiveSendToRouteUpdate(
2481
        stream rpc.SendToRouteClient) (*lnrpc.SendResponse, error) {
×
2482

×
2483
        chanMsg := make(chan *lnrpc.SendResponse, 1)
×
2484
        errChan := make(chan error, 1)
×
2485
        go func() {
×
2486
                // Consume one message. This will block until the message is
×
2487
                // received.
×
2488
                resp, err := stream.Recv()
×
2489
                if err != nil {
×
2490
                        errChan <- err
×
2491

×
2492
                        return
×
2493
                }
×
2494
                chanMsg <- resp
×
2495
        }()
2496

2497
        select {
×
2498
        case <-time.After(DefaultTimeout):
×
2499
                require.Fail(h, "timeout", "timeout waiting for send resp")
×
2500
                return nil, nil
×
2501

2502
        case err := <-errChan:
×
2503
                return nil, err
×
2504

2505
        case updateMsg := <-chanMsg:
×
2506
                return updateMsg, nil
×
2507
        }
2508
}
2509

2510
// AssertInvoiceEqual asserts that two lnrpc.Invoices are equivalent. A custom
2511
// comparison function is defined for these tests, since proto message returned
2512
// from unary and streaming RPCs (as of protobuf 1.23.0 and grpc 1.29.1) aren't
2513
// consistent with the private fields set on the messages. As a result, we
2514
// avoid using require.Equal and test only the actual data members.
2515
func (h *HarnessTest) AssertInvoiceEqual(a, b *lnrpc.Invoice) {
×
2516
        // Ensure the HTLCs are sorted properly before attempting to compare.
×
2517
        sort.Slice(a.Htlcs, func(i, j int) bool {
×
2518
                return a.Htlcs[i].ChanId < a.Htlcs[j].ChanId
×
2519
        })
×
2520
        sort.Slice(b.Htlcs, func(i, j int) bool {
×
2521
                return b.Htlcs[i].ChanId < b.Htlcs[j].ChanId
×
2522
        })
×
2523

2524
        require.Equal(h, a.Memo, b.Memo)
×
2525
        require.Equal(h, a.RPreimage, b.RPreimage)
×
2526
        require.Equal(h, a.RHash, b.RHash)
×
2527
        require.Equal(h, a.Value, b.Value)
×
2528
        require.Equal(h, a.ValueMsat, b.ValueMsat)
×
2529
        require.Equal(h, a.CreationDate, b.CreationDate)
×
2530
        require.Equal(h, a.SettleDate, b.SettleDate)
×
2531
        require.Equal(h, a.PaymentRequest, b.PaymentRequest)
×
2532
        require.Equal(h, a.DescriptionHash, b.DescriptionHash)
×
2533
        require.Equal(h, a.Expiry, b.Expiry)
×
2534
        require.Equal(h, a.FallbackAddr, b.FallbackAddr)
×
2535
        require.Equal(h, a.CltvExpiry, b.CltvExpiry)
×
2536
        require.Equal(h, a.RouteHints, b.RouteHints)
×
2537
        require.Equal(h, a.Private, b.Private)
×
2538
        require.Equal(h, a.AddIndex, b.AddIndex)
×
2539
        require.Equal(h, a.SettleIndex, b.SettleIndex)
×
2540
        require.Equal(h, a.AmtPaidSat, b.AmtPaidSat)
×
2541
        require.Equal(h, a.AmtPaidMsat, b.AmtPaidMsat)
×
2542
        require.Equal(h, a.State, b.State)
×
2543
        require.Equal(h, a.Features, b.Features)
×
2544
        require.Equal(h, a.IsKeysend, b.IsKeysend)
×
2545
        require.Equal(h, a.PaymentAddr, b.PaymentAddr)
×
2546
        require.Equal(h, a.IsAmp, b.IsAmp)
×
2547

×
2548
        require.Equal(h, len(a.Htlcs), len(b.Htlcs))
×
2549
        for i := range a.Htlcs {
×
2550
                htlcA, htlcB := a.Htlcs[i], b.Htlcs[i]
×
2551
                require.Equal(h, htlcA.ChanId, htlcB.ChanId)
×
2552
                require.Equal(h, htlcA.HtlcIndex, htlcB.HtlcIndex)
×
2553
                require.Equal(h, htlcA.AmtMsat, htlcB.AmtMsat)
×
2554
                require.Equal(h, htlcA.AcceptHeight, htlcB.AcceptHeight)
×
2555
                require.Equal(h, htlcA.AcceptTime, htlcB.AcceptTime)
×
2556
                require.Equal(h, htlcA.ResolveTime, htlcB.ResolveTime)
×
2557
                require.Equal(h, htlcA.ExpiryHeight, htlcB.ExpiryHeight)
×
2558
                require.Equal(h, htlcA.State, htlcB.State)
×
2559
                require.Equal(h, htlcA.CustomRecords, htlcB.CustomRecords)
×
2560
                require.Equal(h, htlcA.MppTotalAmtMsat, htlcB.MppTotalAmtMsat)
×
2561
                require.Equal(h, htlcA.Amp, htlcB.Amp)
×
2562
        }
×
2563
}
2564

2565
// AssertUTXOInWallet asserts that a given UTXO can be found in the node's
2566
// wallet.
2567
func (h *HarnessTest) AssertUTXOInWallet(hn *node.HarnessNode,
2568
        op *lnrpc.OutPoint, account string) {
×
2569

×
2570
        err := wait.NoError(func() error {
×
2571
                utxos := h.GetUTXOs(hn, account)
×
2572

×
2573
                err := fmt.Errorf("tx with hash %x not found", op.TxidBytes)
×
2574
                for _, utxo := range utxos {
×
2575
                        if !bytes.Equal(utxo.Outpoint.TxidBytes, op.TxidBytes) {
×
2576
                                continue
×
2577
                        }
2578

2579
                        err = fmt.Errorf("tx with output index %v not found",
×
2580
                                op.OutputIndex)
×
2581
                        if utxo.Outpoint.OutputIndex != op.OutputIndex {
×
2582
                                continue
×
2583
                        }
2584

2585
                        return nil
×
2586
                }
2587

2588
                return err
×
2589
        }, DefaultTimeout)
2590

2591
        require.NoErrorf(h, err, "outpoint %v not found in %s's wallet",
×
2592
                op, hn.Name())
×
2593
}
2594

2595
// AssertWalletAccountBalance asserts that the unconfirmed and confirmed
2596
// balance for the given account is satisfied by the WalletBalance and
2597
// ListUnspent RPCs. The unconfirmed balance is not checked for neutrino nodes.
2598
func (h *HarnessTest) AssertWalletAccountBalance(hn *node.HarnessNode,
2599
        account string, confirmedBalance, unconfirmedBalance int64) {
×
2600

×
2601
        err := wait.NoError(func() error {
×
2602
                balanceResp := hn.RPC.WalletBalance()
×
2603
                require.Contains(h, balanceResp.AccountBalance, account)
×
2604
                accountBalance := balanceResp.AccountBalance[account]
×
2605

×
2606
                // Check confirmed balance.
×
2607
                if accountBalance.ConfirmedBalance != confirmedBalance {
×
2608
                        return fmt.Errorf("expected confirmed balance %v, "+
×
2609
                                "got %v", confirmedBalance,
×
2610
                                accountBalance.ConfirmedBalance)
×
2611
                }
×
2612

2613
                utxos := h.GetUTXOsConfirmed(hn, account)
×
2614
                var totalConfirmedVal int64
×
2615
                for _, utxo := range utxos {
×
2616
                        totalConfirmedVal += utxo.AmountSat
×
2617
                }
×
2618
                if totalConfirmedVal != confirmedBalance {
×
2619
                        return fmt.Errorf("expected total confirmed utxo "+
×
2620
                                "balance %v, got %v", confirmedBalance,
×
2621
                                totalConfirmedVal)
×
2622
                }
×
2623

2624
                // Skip unconfirmed balance checks for neutrino nodes.
2625
                if h.IsNeutrinoBackend() {
×
2626
                        return nil
×
2627
                }
×
2628

2629
                // Check unconfirmed balance.
2630
                if accountBalance.UnconfirmedBalance != unconfirmedBalance {
×
2631
                        return fmt.Errorf("expected unconfirmed balance %v, "+
×
2632
                                "got %v", unconfirmedBalance,
×
2633
                                accountBalance.UnconfirmedBalance)
×
2634
                }
×
2635

2636
                utxos = h.GetUTXOsUnconfirmed(hn, account)
×
2637
                var totalUnconfirmedVal int64
×
2638
                for _, utxo := range utxos {
×
2639
                        totalUnconfirmedVal += utxo.AmountSat
×
2640
                }
×
2641
                if totalUnconfirmedVal != unconfirmedBalance {
×
2642
                        return fmt.Errorf("expected total unconfirmed utxo "+
×
2643
                                "balance %v, got %v", unconfirmedBalance,
×
2644
                                totalUnconfirmedVal)
×
2645
                }
×
2646

2647
                return nil
×
2648
        }, DefaultTimeout)
2649
        require.NoError(h, err, "timeout checking wallet account balance")
×
2650
}
2651

2652
// AssertClosingTxInMempool assert that the closing transaction of the given
2653
// channel point can be found in the mempool. If the channel has anchors, it
2654
// will assert the anchor sweep tx is also in the mempool.
2655
func (h *HarnessTest) AssertClosingTxInMempool(cp *lnrpc.ChannelPoint,
2656
        c lnrpc.CommitmentType) *wire.MsgTx {
×
2657

×
2658
        // Get expected number of txes to be found in the mempool.
×
2659
        expectedTxes := 1
×
2660
        hasAnchors := CommitTypeHasAnchors(c)
×
2661
        if hasAnchors {
×
2662
                expectedTxes = 2
×
2663
        }
×
2664

2665
        // Wait for the expected txes to be found in the mempool.
2666
        h.AssertNumTxsInMempool(expectedTxes)
×
2667

×
2668
        // Get the closing tx from the mempool.
×
2669
        op := h.OutPointFromChannelPoint(cp)
×
2670
        closeTx := h.AssertOutpointInMempool(op)
×
2671

×
2672
        return closeTx
×
2673
}
2674

2675
// AssertClosingTxInMempool assert that the closing transaction of the given
2676
// channel point can be found in the mempool. If the channel has anchors, it
2677
// will assert the anchor sweep tx is also in the mempool.
2678
func (h *HarnessTest) MineClosingTx(cp *lnrpc.ChannelPoint) *wire.MsgTx {
×
2679
        // Wait for the expected txes to be found in the mempool.
×
2680
        h.AssertNumTxsInMempool(1)
×
2681

×
2682
        // Get the closing tx from the mempool.
×
2683
        op := h.OutPointFromChannelPoint(cp)
×
2684
        closeTx := h.AssertOutpointInMempool(op)
×
2685

×
2686
        // Mine a block to confirm the closing transaction and potential anchor
×
2687
        // sweep.
×
2688
        h.MineBlocksAndAssertNumTxes(1, 1)
×
2689

×
2690
        return closeTx
×
2691
}
×
2692

2693
// AssertWalletLockedBalance asserts the expected amount has been marked as
2694
// locked in the node's WalletBalance response.
2695
func (h *HarnessTest) AssertWalletLockedBalance(hn *node.HarnessNode,
2696
        balance int64) {
×
2697

×
2698
        err := wait.NoError(func() error {
×
2699
                balanceResp := hn.RPC.WalletBalance()
×
2700
                got := balanceResp.LockedBalance
×
2701

×
2702
                if got != balance {
×
2703
                        return fmt.Errorf("want %d, got %d", balance, got)
×
2704
                }
×
2705

2706
                return nil
×
2707
        }, wait.DefaultTimeout)
2708
        require.NoError(h, err, "%s: timeout checking locked balance",
×
2709
                hn.Name())
×
2710
}
2711

2712
// AssertNumPendingSweeps asserts the number of pending sweeps for the given
2713
// node.
2714
func (h *HarnessTest) AssertNumPendingSweeps(hn *node.HarnessNode,
2715
        n int) []*walletrpc.PendingSweep {
×
2716

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

×
2719
        err := wait.NoError(func() error {
×
2720
                resp := hn.RPC.PendingSweeps()
×
2721
                num := len(resp.PendingSweeps)
×
2722

×
2723
                numDesc := "\n"
×
2724
                for _, s := range resp.PendingSweeps {
×
2725
                        desc := fmt.Sprintf("op=%v:%v, amt=%v, type=%v, "+
×
2726
                                "deadline=%v\n", s.Outpoint.TxidStr,
×
2727
                                s.Outpoint.OutputIndex, s.AmountSat,
×
2728
                                s.WitnessType, s.DeadlineHeight)
×
2729
                        numDesc += desc
×
2730

×
2731
                        // The deadline height must be set, otherwise the
×
2732
                        // pending input response is not update-to-date.
×
2733
                        if s.DeadlineHeight == 0 {
×
2734
                                return fmt.Errorf("input not updated: %s", desc)
×
2735
                        }
×
2736
                }
2737

2738
                if num == n {
×
2739
                        results = resp.PendingSweeps
×
2740
                        return nil
×
2741
                }
×
2742

2743
                return fmt.Errorf("want %d , got %d, sweeps: %s", n, num,
×
2744
                        numDesc)
×
2745
        }, DefaultTimeout)
2746

2747
        require.NoErrorf(h, err, "%s: check pending sweeps timeout", hn.Name())
×
2748

×
2749
        return results
×
2750
}
2751

2752
// FindSweepingTxns asserts the expected number of sweeping txns are found in
2753
// the txns specified and return them.
2754
func (h *HarnessTest) FindSweepingTxns(txns []*wire.MsgTx,
2755
        expectedNumSweeps int, closeTxid chainhash.Hash) []*wire.MsgTx {
×
2756

×
2757
        var sweepTxns []*wire.MsgTx
×
2758

×
2759
        for _, tx := range txns {
×
2760
                if tx.TxIn[0].PreviousOutPoint.Hash == closeTxid {
×
2761
                        sweepTxns = append(sweepTxns, tx)
×
2762
                }
×
2763
        }
2764
        require.Len(h, sweepTxns, expectedNumSweeps, "unexpected num of sweeps")
×
2765

×
2766
        return sweepTxns
×
2767
}
2768

2769
// AssertForceCloseAndAnchorTxnsInMempool asserts that the force close and
2770
// anchor sweep txns are found in the mempool and returns the force close tx
2771
// and the anchor sweep tx.
2772
func (h *HarnessTest) AssertForceCloseAndAnchorTxnsInMempool() (*wire.MsgTx,
2773
        *wire.MsgTx) {
×
2774

×
2775
        // Assert there are two txns in the mempool.
×
2776
        txns := h.GetNumTxsFromMempool(2)
×
2777

×
2778
        // isParentAndChild checks whether there is an input used in the
×
2779
        // assumed child tx by checking every input's previous outpoint against
×
2780
        // the assumed parentTxid.
×
2781
        isParentAndChild := func(parent, child *wire.MsgTx) bool {
×
2782
                parentTxid := parent.TxHash()
×
2783

×
2784
                for _, inp := range child.TxIn {
×
2785
                        if inp.PreviousOutPoint.Hash == parentTxid {
×
2786
                                // Found a match, this is indeed the anchor
×
2787
                                // sweeping tx so we return it here.
×
2788
                                return true
×
2789
                        }
×
2790
                }
2791

2792
                return false
×
2793
        }
2794

2795
        switch {
×
2796
        // Assume the first one is the closing tx and the second one is the
2797
        // anchor sweeping tx.
2798
        case isParentAndChild(txns[0], txns[1]):
×
2799
                return txns[0], txns[1]
×
2800

2801
        // Assume the first one is the anchor sweeping tx and the second one is
2802
        // the closing tx.
2803
        case isParentAndChild(txns[1], txns[0]):
×
2804
                return txns[1], txns[0]
×
2805

2806
        // Unrelated txns found, fail the test.
2807
        default:
×
2808
                h.Fatalf("the two txns not related: %v", txns)
×
2809

×
2810
                return nil, nil
×
2811
        }
2812
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc