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

lightningnetwork / lnd / 15778860361

20 Jun 2025 12:23PM UTC coverage: 68.208% (+0.07%) from 68.143%
15778860361

Pull #9752

github

web-flow
Merge 831fefef7 into 7857d2c6a
Pull Request #9752: routerrpc: reject payment to invoice that don't have payment secret or blinded paths

10 of 14 new or added lines in 2 files covered. (71.43%)

2644 existing lines in 29 files now uncovered.

134706 of 197494 relevant lines covered (68.21%)

22122.25 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.
UNCOV
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
        }
×
UNCOV
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
                        }
×
UNCOV
269

×
270
                        return nil
×
UNCOV
271
                }
×
272

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

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

×
279
        return edges
×
UNCOV
280
}
×
UNCOV
281

×
UNCOV
282
// ReceiveOpenChannelUpdate waits until a message is received on the stream or
×
UNCOV
283
// the timeout is reached.
×
UNCOV
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
}
×
UNCOV
292

×
293
// ReceiveOpenChannelError waits for the expected error during the open channel
294
// flow from the peer or times out.
UNCOV
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

UNCOV
303
// receiveOpenChannelUpdate waits until a message or an error is received on
×
UNCOV
304
// the stream or the timeout is reached.
×
UNCOV
305
//
×
UNCOV
306
// TODO(yy): use generics to unify all receiving stream update once go@1.18 is
×
UNCOV
307
// used.
×
UNCOV
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
×
UNCOV
329

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

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

×
UNCOV
338
// WaitForChannelOpenEvent waits for a notification that a channel is open by
×
UNCOV
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
}
×
UNCOV
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
}
×
UNCOV
360

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

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

×
UNCOV
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
}
×
UNCOV
376

×
UNCOV
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
                }
×
UNCOV
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)
×
UNCOV
401
        }, DefaultTimeout)
×
UNCOV
402

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

×
406
        return channel
×
UNCOV
407
}
×
UNCOV
408

×
UNCOV
409
// AssertOutputScriptClass checks that the specified transaction output has the
×
UNCOV
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
}
×
UNCOV
422

×
UNCOV
423
// findChannel tries to find a target channel in the node using the given
×
UNCOV
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
        }
×
UNCOV
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
                }
UNCOV
445
        }
×
UNCOV
446

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

×
UNCOV
451
// ReceiveCloseChannelUpdate waits until a message or an error is received on
×
UNCOV
452
// the subscribe channel close stream or the timeout is reached.
×
UNCOV
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
×
UNCOV
475

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

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

×
485
type WaitingCloseChannel *lnrpc.PendingChannelsResponse_WaitingCloseChannel
486

UNCOV
487
// AssertChannelWaitingClose asserts that the given channel found in the node
×
UNCOV
488
// is waiting close. Returns the WaitingCloseChannel if found.
×
UNCOV
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)
UNCOV
508
        }, DefaultTimeout)
×
509
        require.NoError(h, err, "assert channel waiting close timed out")
×
510

×
511
        return target
×
UNCOV
512
}
×
UNCOV
513

×
UNCOV
514
// AssertTopologyChannelClosed asserts a given channel is closed by checking
×
UNCOV
515
// the graph topology subscription of the specified node. Returns the closed
×
UNCOV
516
// channel update if found.
×
UNCOV
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
}
×
UNCOV
525

×
526
// WaitForChannelCloseEvent waits for a notification that a channel is closed
UNCOV
527
// by consuming a message from the passed close channel stream. Returns the
×
UNCOV
528
// closing txid if found.
×
UNCOV
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)
×
537
        require.Truef(h, ok, "expected channel close update, instead got %v",
×
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
UNCOV
548
// reports the expected number of waiting close channels.
×
UNCOV
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)
UNCOV
568

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

×
572
        return channels
×
UNCOV
573
}
×
UNCOV
574

×
UNCOV
575
// AssertNumPendingForceClose checks that a PendingChannels response from the
×
UNCOV
576
// node reports the expected number of pending force close channels.
×
UNCOV
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
                }
×
UNCOV
601

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

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

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

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

×
617
        return channels
×
UNCOV
618
}
×
619

UNCOV
620
// AssertStreamChannelCoopClosed reads an update from the close channel client
×
UNCOV
621
// stream and asserts that the mempool state and node's topology match a coop
×
UNCOV
622
// close. In specific,
×
UNCOV
623
// - assert the channel is waiting close and has the expected ChanStatusFlags.
×
UNCOV
624
// - assert the mempool has the closing txes and anchor sweeps.
×
UNCOV
625
// - mine a block and assert the closing txid is mined.
×
UNCOV
626
// - assert the node has zero waiting close channels.
×
627
// - assert the node has seen the channel close update.
UNCOV
628
func (h *HarnessTest) AssertStreamChannelCoopClosed(hn *node.HarnessNode,
×
UNCOV
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
        }
×
UNCOV
662

×
663
        return closingTxid
×
UNCOV
664
}
×
UNCOV
665

×
UNCOV
666
// AssertStreamChannelForceClosed reads an update from the close channel client
×
UNCOV
667
// stream and asserts that the mempool state and node's topology match a local
×
UNCOV
668
// force close. In specific,
×
UNCOV
669
//   - assert the channel is waiting close and has the expected ChanStatusFlags.
×
UNCOV
670
//   - assert the mempool has the closing txes.
×
UNCOV
671
//   - mine a block and assert the closing txid is mined.
×
UNCOV
672
//   - assert the channel is pending force close.
×
UNCOV
673
//   - assert the node has seen the channel close update.
×
UNCOV
674
//   - assert there's a pending anchor sweep request once the force close tx is
×
UNCOV
675
//     confirmed.
×
UNCOV
676
func (h *HarnessTest) AssertStreamChannelForceClosed(hn *node.HarnessNode,
×
UNCOV
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
        }
×
UNCOV
712

×
UNCOV
713
        // Assert there's a pending anchor sweep.
×
UNCOV
714
        //
×
UNCOV
715
        // NOTE: We may have a local sweep here, that's why we use
×
UNCOV
716
        // AssertAtLeastNumPendingSweeps instead of AssertNumPendingSweeps.
×
717
        if anchorSweep {
×
718
                h.AssertAtLeastNumPendingSweeps(hn, 1)
×
719
        }
×
UNCOV
720

×
721
        return closingTxid
×
UNCOV
722
}
×
UNCOV
723

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

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

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

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

×
UNCOV
751
// AssertNumUTXOsWithConf waits for the given number of UTXOs with the
×
UNCOV
752
// specified confirmations range to be available or fails if that isn't the
×
UNCOV
753
// case before the default timeout.
×
UNCOV
754
func (h *HarnessTest) AssertNumUTXOsWithConf(hn *node.HarnessNode,
×
755
        expectedUtxos int, max, min int32) []*lnrpc.Utxo {
756

757
        var unconfirmed bool
×
758

×
759
        if max == 0 {
×
760
                unconfirmed = true
×
761
        }
×
UNCOV
762

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

×
774
                if total == expectedUtxos {
×
775
                        utxos = resp.Utxos
×
776

×
777
                        return nil
×
778
                }
×
UNCOV
779

×
780
                desc := "has UTXOs:\n"
781
                for _, utxo := range resp.Utxos {
×
782
                        desc += fmt.Sprintf("%v\n", utxo)
×
783
                }
×
UNCOV
784

×
785
                return fmt.Errorf("%s: assert num of UTXOs failed: want %d, "+
×
786
                        "got: %d, %s", hn.Name(), expectedUtxos, total, desc)
×
UNCOV
787
        }, DefaultTimeout)
×
788
        require.NoError(h, err, "timeout waiting for UTXOs")
×
789

×
790
        return utxos
×
UNCOV
791
}
×
UNCOV
792

×
UNCOV
793
// AssertNumUTXOsUnconfirmed asserts the expected num of unconfirmed utxos are
×
UNCOV
794
// seen.
×
UNCOV
795
func (h *HarnessTest) AssertNumUTXOsUnconfirmed(hn *node.HarnessNode,
×
796
        num int) []*lnrpc.Utxo {
×
797

798
        return h.AssertNumUTXOsWithConf(hn, num, 0, 0)
×
799
}
×
UNCOV
800

×
UNCOV
801
// AssertNumUTXOsConfirmed asserts the expected num of confirmed utxos are
×
802
// seen, which means the returned utxos have at least one confirmation.
UNCOV
803
func (h *HarnessTest) AssertNumUTXOsConfirmed(hn *node.HarnessNode,
×
804
        num int) []*lnrpc.Utxo {
×
805

806
        return h.AssertNumUTXOsWithConf(hn, num, math.MaxInt32, 1)
×
807
}
×
UNCOV
808

×
809
// AssertNumUTXOs asserts the expected num of utxos are seen, including
810
// confirmed and unconfirmed outputs.
811
func (h *HarnessTest) AssertNumUTXOs(hn *node.HarnessNode,
812
        num int) []*lnrpc.Utxo {
813

814
        return h.AssertNumUTXOsWithConf(hn, num, math.MaxInt32, 0)
×
815
}
×
UNCOV
816

×
UNCOV
817
// getUTXOs gets the number of newly created UTOXs within the current test
×
818
// scope.
819
func (h *HarnessTest) getUTXOs(hn *node.HarnessNode, account string,
820
        max, min int32) []*lnrpc.Utxo {
821

822
        var unconfirmed bool
×
823

×
824
        if max == 0 {
×
825
                unconfirmed = true
×
826
        }
827

828
        req := &walletrpc.ListUnspentRequest{
829
                Account:         account,
830
                MaxConfs:        max,
×
831
                MinConfs:        min,
×
832
                UnconfirmedOnly: unconfirmed,
×
833
        }
×
834
        resp := hn.RPC.ListUnspent(req)
835

836
        return resp.Utxos
837
}
UNCOV
838

×
UNCOV
839
// GetUTXOs returns all the UTXOs for the given node's account, including
×
UNCOV
840
// confirmed and unconfirmed.
×
UNCOV
841
func (h *HarnessTest) GetUTXOs(hn *node.HarnessNode,
×
842
        account string) []*lnrpc.Utxo {
×
843

×
844
        return h.getUTXOs(hn, account, math.MaxInt32, 0)
×
845
}
UNCOV
846

×
UNCOV
847
// GetUTXOsConfirmed returns the confirmed UTXOs for the given node's account.
×
UNCOV
848
func (h *HarnessTest) GetUTXOsConfirmed(hn *node.HarnessNode,
×
849
        account string) []*lnrpc.Utxo {
×
850

×
851
        return h.getUTXOs(hn, account, math.MaxInt32, 1)
×
852
}
×
UNCOV
853

×
UNCOV
854
// GetUTXOsUnconfirmed returns the unconfirmed UTXOs for the given node's
×
855
// account.
856
func (h *HarnessTest) GetUTXOsUnconfirmed(hn *node.HarnessNode,
857
        account string) []*lnrpc.Utxo {
858

859
        return h.getUTXOs(hn, account, 0, 0)
860
}
×
UNCOV
861

×
UNCOV
862
// WaitForBalanceConfirmed waits until the node sees the expected confirmed
×
UNCOV
863
// balance in its wallet.
×
864
func (h *HarnessTest) WaitForBalanceConfirmed(hn *node.HarnessNode,
865
        expected btcutil.Amount) {
866

867
        var lastBalance btcutil.Amount
×
868
        err := wait.NoError(func() error {
×
869
                resp := hn.RPC.WalletBalance()
×
870

×
871
                lastBalance = btcutil.Amount(resp.ConfirmedBalance)
872
                if lastBalance == expected {
873
                        return nil
874
                }
UNCOV
875

×
876
                return fmt.Errorf("expected %v, only have %v", expected,
×
877
                        lastBalance)
×
UNCOV
878
        }, DefaultTimeout)
×
879

880
        require.NoError(h, err, "timeout waiting for confirmed balances")
881
}
882

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

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

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

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

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

UNCOV
904
// Random32Bytes generates a random 32 bytes which can be used as a pay hash,
×
UNCOV
905
// preimage, etc.
×
906
func (h *HarnessTest) Random32Bytes() []byte {
×
907
        randBuf := make([]byte, lntypes.HashSize)
×
908

×
909
        _, err := rand.Read(randBuf)
×
910
        require.NoErrorf(h, err, "internal error, cannot generate random bytes")
×
911

×
912
        return randBuf
×
913
}
×
914

UNCOV
915
// RandomPreimage generates a random preimage which can be used as a payment
×
UNCOV
916
// preimage.
×
917
func (h *HarnessTest) RandomPreimage() lntypes.Preimage {
918
        var preimage lntypes.Preimage
919
        copy(preimage[:], h.Random32Bytes())
×
920

921
        return preimage
922
}
923

UNCOV
924
// DecodeAddress decodes a given address and asserts there's no error.
×
925
func (h *HarnessTest) DecodeAddress(addr string) btcutil.Address {
×
926
        resp, err := btcutil.DecodeAddress(addr, miner.HarnessNetParams)
×
927
        require.NoError(h, err, "DecodeAddress failed")
×
928

×
929
        return resp
×
930
}
×
UNCOV
931

×
932
// PayToAddrScript creates a new script from the given address and asserts
933
// there's no error.
934
func (h *HarnessTest) PayToAddrScript(addr btcutil.Address) []byte {
935
        addrScript, err := txscript.PayToAddrScript(addr)
×
936
        require.NoError(h, err, "PayToAddrScript failed")
×
937

×
938
        return addrScript
×
939
}
×
UNCOV
940

×
941
// AssertChannelBalanceResp makes a ChannelBalance request and checks the
942
// returned response matches the expected.
UNCOV
943
func (h *HarnessTest) AssertChannelBalanceResp(hn *node.HarnessNode,
×
944
        expected *lnrpc.ChannelBalanceResponse) {
×
945

×
946
        resp := hn.RPC.ChannelBalance()
×
947

×
948
        // Ignore custom channel data of both expected and actual responses.
×
949
        expected.CustomChannelData = nil
950
        resp.CustomChannelData = nil
951

952
        require.True(h, proto.Equal(expected, resp), "balance is incorrect "+
×
953
                "got: %v, want: %v", resp, expected)
×
954
}
×
UNCOV
955

×
UNCOV
956
// GetChannelByChanPoint tries to find a channel matching the channel point and
×
UNCOV
957
// asserts. It returns the channel found.
×
958
func (h *HarnessTest) GetChannelByChanPoint(hn *node.HarnessNode,
959
        chanPoint *lnrpc.ChannelPoint) *lnrpc.Channel {
960

961
        channel, err := h.findChannel(hn, chanPoint)
962
        require.NoErrorf(h, err, "channel not found using %v", chanPoint)
×
963

×
964
        return channel
×
965
}
×
UNCOV
966

×
UNCOV
967
// GetChannelCommitType retrieves the active channel commitment type for the
×
UNCOV
968
// given chan point.
×
UNCOV
969
func (h *HarnessTest) GetChannelCommitType(hn *node.HarnessNode,
×
970
        chanPoint *lnrpc.ChannelPoint) lnrpc.CommitmentType {
×
971

×
972
        c := h.GetChannelByChanPoint(hn, chanPoint)
×
973

974
        return c.CommitmentType
975
}
976

UNCOV
977
// AssertNumPendingOpenChannels asserts that a given node have the expected
×
UNCOV
978
// number of pending open channels.
×
UNCOV
979
func (h *HarnessTest) AssertNumPendingOpenChannels(hn *node.HarnessNode,
×
980
        expected int) []*lnrpc.PendingChannelsResponse_PendingOpenChannel {
×
981

×
982
        var channels []*lnrpc.PendingChannelsResponse_PendingOpenChannel
×
983

×
984
        oldNum := hn.State.OpenChannel.Pending
985

986
        err := wait.NoError(func() error {
987
                resp := hn.RPC.PendingChannels()
988
                channels = resp.PendingOpenChannels
×
989
                total := len(channels)
×
990

×
991
                numChans := total - oldNum
×
992

×
993
                if numChans != expected {
×
994
                        return errNumNotMatched(hn.Name(),
995
                                "pending open channels", expected,
996
                                numChans, total, oldNum)
997
                }
UNCOV
998

×
999
                return nil
×
UNCOV
1000
        }, DefaultTimeout)
×
UNCOV
1001

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

×
1004
        return channels
×
UNCOV
1005
}
×
UNCOV
1006

×
UNCOV
1007
// AssertNodesNumPendingOpenChannels asserts that both of the nodes have the
×
UNCOV
1008
// expected number of pending open channels.
×
UNCOV
1009
func (h *HarnessTest) AssertNodesNumPendingOpenChannels(a, b *node.HarnessNode,
×
1010
        expected int) {
×
1011

×
1012
        h.AssertNumPendingOpenChannels(a, expected)
×
1013
        h.AssertNumPendingOpenChannels(b, expected)
×
1014
}
×
UNCOV
1015

×
1016
// AssertPaymentStatusFromStream takes a client stream and asserts the payment
UNCOV
1017
// is in desired status before default timeout. The payment found is returned
×
1018
// once succeeded.
1019
func (h *HarnessTest) AssertPaymentStatusFromStream(stream rpc.PaymentClient,
1020
        status lnrpc.Payment_PaymentStatus) *lnrpc.Payment {
×
1021

×
1022
        return h.assertPaymentStatusWithTimeout(
×
1023
                stream, status, wait.PaymentTimeout,
1024
        )
1025
}
1026

1027
// AssertPaymentSucceedWithTimeout asserts that a payment is succeeded within
UNCOV
1028
// the specified timeout.
×
UNCOV
1029
func (h *HarnessTest) AssertPaymentSucceedWithTimeout(stream rpc.PaymentClient,
×
1030
        timeout time.Duration) *lnrpc.Payment {
×
1031

×
1032
        return h.assertPaymentStatusWithTimeout(
×
1033
                stream, lnrpc.Payment_SUCCEEDED, timeout,
1034
        )
1035
}
1036

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

×
1044
        var target *lnrpc.Payment
1045
        err := wait.NoError(func() error {
1046
                // Consume one message. This will raise an error if the message
1047
                // is not received within DefaultTimeout.
1048
                payment, err := h.receivePaymentUpdateWithTimeout(
×
1049
                        stream, timeout,
×
1050
                )
×
1051
                if err != nil {
×
1052
                        return fmt.Errorf("received error from payment "+
×
1053
                                "stream: %s", err)
×
1054
                }
1055

1056
                // Return if the desired payment state is reached.
1057
                if payment.Status == status {
1058
                        target = payment
1059

1060
                        return nil
×
1061
                }
×
UNCOV
1062

×
UNCOV
1063
                // Return the err so that it can be used for debugging when
×
UNCOV
1064
                // timeout is reached.
×
1065
                return fmt.Errorf("payment %v status, got %v, want %v",
×
1066
                        payment.PaymentHash, payment.Status, status)
×
UNCOV
1067
        }, timeout)
×
UNCOV
1068

×
1069
        require.NoError(h, err, "timeout while waiting payment")
×
1070

×
1071
        return target
×
UNCOV
1072
}
×
1073

1074
// ReceivePaymentUpdate waits until a message is received on the payment client
UNCOV
1075
// stream or the timeout is reached.
×
UNCOV
1076
func (h *HarnessTest) ReceivePaymentUpdate(
×
1077
        stream rpc.PaymentClient) (*lnrpc.Payment, error) {
×
1078

×
1079
        return h.receivePaymentUpdateWithTimeout(stream, DefaultTimeout)
×
1080
}
1081

1082
// receivePaymentUpdateWithTimeout waits until a message is received on the
UNCOV
1083
// payment client stream or the timeout is reached.
×
UNCOV
1084
func (h *HarnessTest) receivePaymentUpdateWithTimeout(stream rpc.PaymentClient,
×
1085
        timeout time.Duration) (*lnrpc.Payment, error) {
1086

1087
        chanMsg := make(chan *lnrpc.Payment, 1)
×
1088
        errChan := make(chan error, 1)
×
1089

×
1090
        go func() {
1091
                // Consume one message. This will block until the message is
1092
                // received.
1093
                resp, err := stream.Recv()
1094
                if err != nil {
1095
                        errChan <- err
×
1096

×
1097
                        return
×
1098
                }
×
1099
                chanMsg <- resp
1100
        }()
1101

1102
        select {
1103
        case <-time.After(timeout):
×
1104
                require.Fail(h, "timeout", "timeout waiting for payment update")
×
1105
                return nil, nil
×
UNCOV
1106

×
1107
        case err := <-errChan:
×
1108
                return nil, err
×
UNCOV
1109

×
1110
        case updateMsg := <-chanMsg:
×
1111
                return updateMsg, nil
×
UNCOV
1112
        }
×
UNCOV
1113
}
×
UNCOV
1114

×
UNCOV
1115
// AssertInvoiceSettled asserts a given invoice specified by its payment
×
UNCOV
1116
// address is settled.
×
1117
func (h *HarnessTest) AssertInvoiceSettled(hn *node.HarnessNode, addr []byte) {
×
1118
        msg := &invoicesrpc.LookupInvoiceMsg{
1119
                InvoiceRef: &invoicesrpc.LookupInvoiceMsg_PaymentAddr{
1120
                        PaymentAddr: addr,
×
1121
                },
×
1122
        }
×
1123

×
1124
        err := wait.NoError(func() error {
1125
                invoice := hn.RPC.LookupInvoiceV2(msg)
×
1126
                if invoice.State == lnrpc.Invoice_SETTLED {
×
1127
                        return nil
1128
                }
×
UNCOV
1129

×
1130
                return fmt.Errorf("%s: invoice with payment address %x not "+
1131
                        "settled", hn.Name(), addr)
1132
        }, DefaultTimeout)
1133
        require.NoError(h, err, "timeout waiting for invoice settled state")
1134
}
UNCOV
1135

×
UNCOV
1136
// AssertNodeNumChannels polls the provided node's list channels rpc until it
×
UNCOV
1137
// reaches the desired number of total channels.
×
UNCOV
1138
func (h *HarnessTest) AssertNodeNumChannels(hn *node.HarnessNode,
×
1139
        numChannels int) {
×
1140

×
1141
        // Get the total number of channels.
×
1142
        old := hn.State.OpenChannel.Active + hn.State.OpenChannel.Inactive
×
1143

×
1144
        err := wait.NoError(func() error {
×
1145
                // We require the RPC call to be succeeded and won't wait for
×
1146
                // it as it's an unexpected behavior.
×
1147
                chanInfo := hn.RPC.ListChannels(&lnrpc.ListChannelsRequest{})
1148

×
1149
                // Return true if the query returned the expected number of
×
1150
                // channels.
1151
                num := len(chanInfo.Channels) - old
×
1152
                if num != numChannels {
1153
                        return fmt.Errorf("expected %v channels, got %v",
1154
                                numChannels, num)
1155
                }
1156

1157
                return nil
×
UNCOV
1158
        }, DefaultTimeout)
×
UNCOV
1159

×
1160
        require.NoError(h, err, "timeout checking node's num of channels")
×
UNCOV
1161
}
×
UNCOV
1162

×
UNCOV
1163
// AssertChannelLocalBalance checks the local balance of the given channel is
×
UNCOV
1164
// expected. The channel found using the specified channel point is returned.
×
UNCOV
1165
func (h *HarnessTest) AssertChannelLocalBalance(hn *node.HarnessNode,
×
1166
        cp *lnrpc.ChannelPoint, balance int64) *lnrpc.Channel {
×
1167

×
1168
        var result *lnrpc.Channel
×
1169

×
1170
        // Get the funding point.
×
1171
        err := wait.NoError(func() error {
×
1172
                // Find the target channel first.
×
1173
                target, err := h.findChannel(hn, cp)
×
1174

1175
                // Exit early if the channel is not found.
×
1176
                if err != nil {
1177
                        return fmt.Errorf("check balance failed: %w", err)
1178
                }
×
1179

1180
                result = target
1181

1182
                // Check local balance.
1183
                if target.LocalBalance == balance {
1184
                        return nil
×
1185
                }
×
UNCOV
1186

×
1187
                return fmt.Errorf("balance is incorrect, got %v, expected %v",
×
1188
                        target.LocalBalance, balance)
×
UNCOV
1189
        }, DefaultTimeout)
×
UNCOV
1190

×
1191
        require.NoError(h, err, "timeout while checking for balance")
×
1192

×
1193
        return result
×
UNCOV
1194
}
×
UNCOV
1195

×
UNCOV
1196
// AssertChannelNumUpdates checks the num of updates is expected from the given
×
1197
// channel.
UNCOV
1198
func (h *HarnessTest) AssertChannelNumUpdates(hn *node.HarnessNode,
×
1199
        num uint64, cp *lnrpc.ChannelPoint) {
×
1200

×
1201
        old := int(hn.State.OpenChannel.NumUpdates)
×
1202

×
1203
        // Find the target channel first.
×
1204
        target, err := h.findChannel(hn, cp)
1205
        require.NoError(h, err, "unable to find channel")
×
1206

×
1207
        err = wait.NoError(func() error {
1208
                total := int(target.NumUpdates)
1209
                if total-old == int(num) {
×
1210
                        return nil
×
1211
                }
×
1212

1213
                return errNumNotMatched(hn.Name(), "channel updates",
1214
                        int(num), total-old, total, old)
1215
        }, DefaultTimeout)
1216
        require.NoError(h, err, "timeout while checking for num of updates")
UNCOV
1217
}
×
UNCOV
1218

×
UNCOV
1219
// AssertNumActiveHtlcs asserts that a given number of HTLCs are seen in the
×
UNCOV
1220
// node's channels.
×
1221
func (h *HarnessTest) AssertNumActiveHtlcs(hn *node.HarnessNode, num int) {
×
1222
        old := hn.State.HTLC
×
1223

×
1224
        err := wait.NoError(func() error {
×
1225
                // pendingHTLCs is used to print unacked HTLCs, if found.
×
1226
                var pendingHTLCs []string
×
1227

×
1228
                // We require the RPC call to be succeeded and won't wait for
×
1229
                // it as it's an unexpected behavior.
×
1230
                req := &lnrpc.ListChannelsRequest{}
1231
                nodeChans := hn.RPC.ListChannels(req)
×
1232

×
1233
                total := 0
1234
                for _, channel := range nodeChans.Channels {
×
1235
                        for _, htlc := range channel.PendingHtlcs {
1236
                                if htlc.LockedIn {
1237
                                        total++
1238
                                }
UNCOV
1239

×
1240
                                rHash := fmt.Sprintf("%x", htlc.HashLock)
×
1241
                                pendingHTLCs = append(pendingHTLCs, rHash)
×
UNCOV
1242
                        }
×
UNCOV
1243
                }
×
1244
                if total-old != num {
×
1245
                        desc := fmt.Sprintf("active HTLCs: unacked HTLCs: %v",
×
1246
                                pendingHTLCs)
×
1247

×
1248
                        return errNumNotMatched(hn.Name(), desc,
×
1249
                                num, total-old, total, old)
×
1250
                }
×
UNCOV
1251

×
1252
                return nil
×
UNCOV
1253
        }, DefaultTimeout)
×
UNCOV
1254

×
1255
        require.NoErrorf(h, err, "%s timeout checking num active htlcs",
×
1256
                hn.Name())
×
1257
}
UNCOV
1258

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

×
1264
        return h.assertHTLCActive(hn, cp, payHash, true)
×
1265
}
×
UNCOV
1266

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

1272
        return h.assertHTLCActive(hn, cp, payHash, false)
1273
}
×
UNCOV
1274

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

1280
        var result *lnrpc.HTLC
×
1281
        target := hex.EncodeToString(payHash)
×
1282

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

1288
                // Check all payment hashes active for this channel.
×
1289
                for _, htlc := range ch.PendingHtlcs {
×
1290
                        rHash := hex.EncodeToString(htlc.HashLock)
×
1291
                        if rHash != target {
×
1292
                                continue
1293
                        }
1294

1295
                        // If the payment hash is found, check the incoming
UNCOV
1296
                        // field.
×
1297
                        if htlc.Incoming == incoming {
×
1298
                                // Return the result if it's locked in.
×
1299
                                if htlc.LockedIn {
×
1300
                                        result = htlc
×
1301
                                        return nil
×
1302
                                }
×
UNCOV
1303

×
1304
                                return fmt.Errorf("htlc(%x) not locked in",
×
1305
                                        payHash)
×
UNCOV
1306
                        }
×
UNCOV
1307

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

1315
                        return fmt.Errorf("htlc(%x) has wrong direction - "+
×
1316
                                "want: %s, have: %s", payHash, want, have)
×
UNCOV
1317
                }
×
UNCOV
1318

×
1319
                return fmt.Errorf("htlc not found using payHash %x", payHash)
×
UNCOV
1320
        }, DefaultTimeout)
×
1321
        require.NoError(h, err, "%s: timeout checking pending HTLC", hn.Name())
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
UNCOV
1328
// and now settled. Returns the HTLC if found and active.
×
UNCOV
1329
//
×
UNCOV
1330
// NOTE: to check a pending HTLC becoming settled, first use AssertHLTCActive
×
UNCOV
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
UNCOV
1351
                        }
×
UNCOV
1352
                }
×
UNCOV
1353

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

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

×
1365
        return result
×
UNCOV
1366
}
×
UNCOV
1367

×
UNCOV
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")
×
UNCOV
1390

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

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

×
1399
        return nil
×
UNCOV
1400
}
×
UNCOV
1401

×
UNCOV
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.
UNCOV
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

UNCOV
1424
// assertAllTxesSpendFrom asserts that all txes in the list spend from the
×
UNCOV
1425
// given tx.
×
UNCOV
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
                }
UNCOV
1434
        }
×
UNCOV
1435
}
×
1436

UNCOV
1437
// AssertTxSpendFrom asserts that a given tx is spent from a previous tx.
×
UNCOV
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
        }
UNCOV
1445
}
×
UNCOV
1446

×
UNCOV
1447
type PendingForceClose *lnrpc.PendingChannelsResponse_ForceClosedChannel
×
UNCOV
1448

×
UNCOV
1449
// AssertChannelPendingForceClose asserts that the given channel found in the
×
UNCOV
1450
// node is pending force close. Returns the PendingForceClose if found.
×
UNCOV
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)
×
UNCOV
1472
        }, DefaultTimeout)
×
1473
        require.NoError(h, err, "assert pending force close timed out")
×
1474

×
1475
        return target
×
UNCOV
1476
}
×
UNCOV
1477

×
UNCOV
1478
// AssertNumHTLCsAndStage takes a pending force close channel's channel point
×
UNCOV
1479
// and asserts the expected number of pending HTLCs and HTLC stage are matched.
×
UNCOV
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
                }
×
UNCOV
1492

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

1497
                                break
1498
                        }
UNCOV
1499
                }
×
UNCOV
1500

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

×
1506
                if target.LimboBalance == 0 {
×
1507
                        return fmt.Errorf("zero limbo balance")
×
1508
                }
×
UNCOV
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
                }
×
UNCOV
1515

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

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

×
1526
                return nil
×
1527
        }
UNCOV
1528

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

×
1533
// findPayment queries the payment from the node's ListPayments which matches
UNCOV
1534
// the specified preimage hash.
×
UNCOV
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)
×
UNCOV
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 given
UNCOV
1554
// payment hash has the expected status. It also checks that the payment has the
×
UNCOV
1555
// expected preimage, which is empty when it's not settled and matches the given
×
UNCOV
1556
// preimage when it's succeeded.
×
UNCOV
1557
func (h *HarnessTest) AssertPaymentStatus(hn *node.HarnessNode,
×
UNCOV
1558
        payHash lntypes.Hash, status lnrpc.Payment_PaymentStatus,
×
1559
        checks ...PaymentCheck) *lnrpc.Payment {
×
1560

×
1561
        var target *lnrpc.Payment
×
1562

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

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

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

×
1579
        switch status {
×
UNCOV
1580
        // If this expected status is SUCCEEDED, we expect the final
×
UNCOV
1581
        // preimage.
×
1582
        case lnrpc.Payment_SUCCEEDED:
×
1583
                preimage, err := lntypes.MakePreimageFromStr(
×
1584
                        target.PaymentPreimage,
×
1585
                )
×
1586
                require.NoError(h, err, "fail to make preimage")
1587
                require.Equal(h, payHash, preimage.Hash(), "preimage not match")
×
UNCOV
1588

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

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

1600
        return target
×
UNCOV
1601
}
×
UNCOV
1602

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

×
1609
        var payment *lnrpc.Payment
×
1610

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

1618
                payment = p
×
1619

1620
                if reason == p.FailureReason {
1621
                        return nil
1622
                }
1623

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

×
1630
        return payment
×
UNCOV
1631
}
×
UNCOV
1632

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

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

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

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

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

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

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

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

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

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

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

×
1711
                return nil
×
UNCOV
1712
        }
×
UNCOV
1713

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

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

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

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

1736
        // Use 0 to specify the first HTLC.
1737
        h.assertHTLCError(hn, code, 0)
1738
}
1739

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

1745
        req := &lnrpc.ListPaymentsRequest{
1746
                IncludeIncomplete: true,
1747
        }
1748

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

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

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

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

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

×
1774
                htlc := htlcs[index]
×
1775

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

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

×
1790
                return fmt.Errorf("unexpected failure code")
1791
        }, DefaultTimeout)
1792

1793
        require.NoError(h, err, "timeout checking HTLC error")
×
UNCOV
1794
}
×
UNCOV
1795

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

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

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

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

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

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

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

1838
                case strings.Contains(err.Error(), "edge not found"):
×
1839
                        return nil
UNCOV
1840

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

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

×
1855
        ctxt, cancel := context.WithCancel(h.runCtx)
×
1856
        defer cancel()
1857

×
1858
        var edge *lnrpc.ChannelEdge
×
1859

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

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

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

×
1882
                edge = resp
×
1883

×
1884
                return nil
×
UNCOV
1885
        }, DefaultTimeout)
×
UNCOV
1886

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

×
1890
        return edge
×
UNCOV
1891
}
×
UNCOV
1892

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

×
1898
        var edge *lnrpc.ChannelEdge
×
1899

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

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

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

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

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

×
1923
                        edge = e
×
1924

×
1925
                        return nil
×
UNCOV
1926
                }
×
UNCOV
1927

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

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

1936
        return edge
×
UNCOV
1937
}
×
UNCOV
1938

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

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

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

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

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

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

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

×
1973
        return nil
×
1974
}
1975

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

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

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

×
1991
                if e.Node1Pub == advertisingNode {
1992
                        return e.Node1Policy, nil
1993
                }
×
UNCOV
1994

×
1995
                return e.Node2Policy, nil
×
UNCOV
1996
        }
×
1997

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

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

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

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

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

2023
        op := h.OutPointFromChannelPoint(chanPoint)
×
2024

×
2025
        var policies []*node.PolicyUpdateInfo
2026

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

×
2034
                if len(policies) == num {
×
2035
                        return nil
×
2036
                }
×
UNCOV
2037

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

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

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

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

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

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

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

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

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

×
2080
        return payments
×
UNCOV
2081
}
×
UNCOV
2082

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

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

×
2094
        return anns
×
2095
}
×
2096

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

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

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

×
2112
        randomPrivKey, err := btcec.NewPrivateKey()
×
2113
        require.NoError(h, err)
×
2114

×
2115
        randomKeyBytes := randomPrivKey.PubKey().SerializeCompressed()
×
2116
        harnessNetParams := miner.HarnessNetParams
×
2117

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

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

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

×
2140
                addr, err = btcutil.NewAddressScriptHash(
×
2141
                        h.PayToAddrScript(witnessAddr), harnessNetParams,
×
2142
                )
×
UNCOV
2143

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

×
2149
        return h.PayToAddrScript(addr), addr
×
UNCOV
2150
}
×
UNCOV
2151

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

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

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

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

2178
        case updateMsg := <-chanMsg:
×
2179
                return updateMsg
×
UNCOV
2180
        }
×
UNCOV
2181

×
2182
        return nil
×
UNCOV
2183
}
×
UNCOV
2184

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

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

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

2208
        case err := <-errChan:
2209
                require.Failf(h, "err from stream",
2210
                        "received err from stream: %v", err)
UNCOV
2211

×
2212
        case updateMsg := <-chanMsg:
×
2213
                return updateMsg
×
UNCOV
2214
        }
×
UNCOV
2215

×
2216
        return nil
×
UNCOV
2217
}
×
UNCOV
2218

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

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

×
2228
        return event
×
2229
}
×
2230

UNCOV
2231
// HtlcEvent maps the series of event types used in `*routerrpc.HtlcEvent_*`.
×
UNCOV
2232
type HtlcEvent int
×
UNCOV
2233

×
2234
const (
UNCOV
2235
        HtlcEventForward HtlcEvent = iota
×
UNCOV
2236
        HtlcEventForwardFail
×
2237
        HtlcEventSettle
2238
        HtlcEventLinkFail
UNCOV
2239
        HtlcEventFinal
×
2240
)
2241

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

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

×
2252
        var ok bool
×
2253

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

2258
        case HtlcEventForwardFail:
2259
                _, ok = event.Event.(*routerrpc.HtlcEvent_ForwardFailEvent)
2260

2261
        case HtlcEventSettle:
2262
                _, ok = event.Event.(*routerrpc.HtlcEvent_SettleEvent)
2263

2264
        case HtlcEventLinkFail:
2265
                _, ok = event.Event.(*routerrpc.HtlcEvent_LinkFailEvent)
2266

2267
        case HtlcEventFinal:
2268
                _, ok = event.Event.(*routerrpc.HtlcEvent_FinalHtlcEvent)
UNCOV
2269
        }
×
UNCOV
2270

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

×
2274
        return event
×
UNCOV
2275
}
×
UNCOV
2276

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

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

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

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

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

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

2316
        var forwards, forwardFails, settles, linkFails int
×
2317

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

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

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

2331
                require.Containsf(h, eventTypes, event.EventType,
2332
                        "wrong event type, want %v, got %v", userType,
2333
                        event.EventType)
2334

2335
                events = append(events, event)
2336

2337
                switch e := event.Event.(type) {
×
2338
                case *routerrpc.HtlcEvent_ForwardEvent:
×
2339
                        forwards++
×
UNCOV
2340

×
2341
                case *routerrpc.HtlcEvent_ForwardFailEvent:
×
2342
                        forwardFails++
×
UNCOV
2343

×
2344
                case *routerrpc.HtlcEvent_SettleEvent:
×
2345
                        settles++
×
UNCOV
2346

×
2347
                case *routerrpc.HtlcEvent_FinalHtlcEvent:
×
2348
                        if e.FinalHtlcEvent.Settled {
×
2349
                                settles++
×
2350
                        }
×
UNCOV
2351

×
2352
                case *routerrpc.HtlcEvent_LinkFailEvent:
×
2353
                        linkFails++
×
UNCOV
2354

×
2355
                default:
×
2356
                        require.Fail(h, "assert event fail",
×
2357
                                "unexpected event: %T", event.Event)
×
UNCOV
2358
                }
×
UNCOV
2359
        }
×
UNCOV
2360

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

2367
        return events
×
UNCOV
2368
}
×
2369

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

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

2384
                return fmt.Errorf("%s: expected txid=%v not found in wallet",
×
2385
                        hn.Name(), txid)
×
UNCOV
2386
        }, DefaultTimeout)
×
UNCOV
2387

×
2388
        require.NoError(h, err, "failed to find tx")
×
UNCOV
2389
}
×
UNCOV
2390

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

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

2406
                return nil
UNCOV
2407
        }, DefaultTimeout)
×
UNCOV
2408

×
2409
        require.NoErrorf(h, err, "%s: failed to assert tx not found", hn.Name())
2410
}
UNCOV
2411

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

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

×
2424
                return nil
×
UNCOV
2425
        }, DefaultTimeout)
×
UNCOV
2426

×
2427
        require.NoErrorf(h, err, "%s: timeout while waiting for height",
2428
                hn.Name())
UNCOV
2429
}
×
2430

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

2436
        err := wait.NoError(func() error {
2437
                c, err := h.findChannel(hn, cp)
2438
                if err != nil {
×
2439
                        return err
×
2440
                }
×
UNCOV
2441

×
2442
                if int(c.NumUpdates) == height {
×
2443
                        return nil
×
2444
                }
×
UNCOV
2445

×
2446
                return fmt.Errorf("expected commit height to be %v, was %v",
2447
                        height, c.NumUpdates)
×
2448
        }, DefaultTimeout)
2449

2450
        require.NoError(h, err, "timeout while waiting for commit height")
×
UNCOV
2451
}
×
2452

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

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

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

×
2468
                invoices = resp.Invoices
2469
                if len(invoices) == num {
×
2470
                        return nil
×
2471
                }
2472

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

2478
        return invoices
UNCOV
2479
}
×
UNCOV
2480

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

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

×
2495
                        return
2496
                }
×
2497
                chanMsg <- resp
×
2498
        }()
UNCOV
2499

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

2505
        case err := <-errChan:
2506
                return nil, err
UNCOV
2507

×
2508
        case updateMsg := <-chanMsg:
×
2509
                return updateMsg, nil
×
UNCOV
2510
        }
×
UNCOV
2511
}
×
UNCOV
2512

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

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

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

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

×
2573
        err := wait.NoError(func() error {
×
2574
                utxos := h.GetUTXOs(hn, account)
×
2575

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

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

×
2588
                        return nil
×
2589
                }
2590

2591
                return err
2592
        }, DefaultTimeout)
2593

2594
        require.NoErrorf(h, err, "outpoint %v not found in %s's wallet",
×
2595
                op, hn.Name())
×
UNCOV
2596
}
×
UNCOV
2597

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

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

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

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

×
UNCOV
2627
                // Skip unconfirmed balance checks for neutrino nodes.
×
2628
                if h.IsNeutrinoBackend() {
×
2629
                        return nil
×
2630
                }
×
UNCOV
2631

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

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

2650
                return nil
UNCOV
2651
        }, DefaultTimeout)
×
2652
        require.NoError(h, err, "timeout checking wallet account balance")
×
UNCOV
2653
}
×
2654

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

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

×
UNCOV
2668
        // Wait for the expected txes to be found in the mempool.
×
2669
        h.AssertNumTxsInMempool(expectedTxes)
×
2670

×
2671
        // Get the closing tx from the mempool.
×
2672
        op := h.OutPointFromChannelPoint(cp)
2673
        closeTx := h.AssertOutpointInMempool(op)
×
2674

2675
        return closeTx
×
2676
}
2677

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

×
2685
        // Get the closing tx from the mempool.
×
2686
        op := h.OutPointFromChannelPoint(cp)
×
2687
        closeTx := h.AssertOutpointInMempool(op)
×
2688

×
2689
        // Mine a block to confirm the closing transaction and potential anchor
×
2690
        // sweep.
2691
        h.MineBlocksAndAssertNumTxes(1, 1)
2692

×
2693
        return closeTx
×
2694
}
×
UNCOV
2695

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

2701
        err := wait.NoError(func() error {
2702
                balanceResp := hn.RPC.WalletBalance()
2703
                got := balanceResp.LockedBalance
2704

×
2705
                if got != balance {
×
2706
                        return fmt.Errorf("want %d, got %d", balance, got)
×
2707
                }
×
UNCOV
2708

×
2709
                return nil
×
UNCOV
2710
        }, wait.DefaultTimeout)
×
2711
        require.NoError(h, err, "%s: timeout checking locked balance",
×
2712
                hn.Name())
×
UNCOV
2713
}
×
UNCOV
2714

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

2720
        results := make([]*walletrpc.PendingSweep, 0, n)
2721

2722
        err := wait.NoError(func() error {
×
2723
                resp := hn.RPC.PendingSweeps()
×
2724
                num := len(resp.PendingSweeps)
×
2725

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

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

×
2742
                if num == n {
×
2743
                        results = resp.PendingSweeps
×
2744
                        return nil
×
2745
                }
×
UNCOV
2746

×
2747
                return fmt.Errorf("want %d , got %d, sweeps: %s", n, num,
×
2748
                        numDesc)
×
UNCOV
2749
        }, DefaultTimeout)
×
UNCOV
2750

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

×
2753
        return results
×
UNCOV
2754
}
×
UNCOV
2755

×
UNCOV
2756
// AssertAtLeastNumPendingSweeps asserts there are at least n pending sweeps for
×
UNCOV
2757
// the given node.
×
UNCOV
2758
func (h *HarnessTest) AssertAtLeastNumPendingSweeps(hn *node.HarnessNode,
×
2759
        n int) []*walletrpc.PendingSweep {
×
2760

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

×
2763
        err := wait.NoError(func() error {
2764
                resp := hn.RPC.PendingSweeps()
2765
                num := len(resp.PendingSweeps)
×
2766

×
2767
                numDesc := "\n"
×
2768
                for _, s := range resp.PendingSweeps {
×
2769
                        desc := fmt.Sprintf("op=%v:%v, amt=%v, type=%v, "+
2770
                                "deadline=%v, maturityHeight=%v\n",
×
2771
                                s.Outpoint.TxidStr, s.Outpoint.OutputIndex,
×
2772
                                s.AmountSat, s.WitnessType, s.DeadlineHeight,
2773
                                s.MaturityHeight)
2774
                        numDesc += desc
×
2775

×
2776
                        // The deadline height must be set, otherwise the
×
2777
                        // pending input response is not update-to-date.
2778
                        if s.DeadlineHeight == 0 {
2779
                                return fmt.Errorf("input not updated: %s", desc)
2780
                        }
2781
                }
UNCOV
2782

×
2783
                if num >= n {
×
2784
                        results = resp.PendingSweeps
×
2785
                        return nil
×
2786
                }
×
UNCOV
2787

×
2788
                return fmt.Errorf("want %d , got %d, sweeps: %s", n, num,
×
2789
                        numDesc)
×
UNCOV
2790
        }, DefaultTimeout)
×
UNCOV
2791

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

×
2794
        return results
×
UNCOV
2795
}
×
UNCOV
2796

×
UNCOV
2797
// FindSweepingTxns asserts the expected number of sweeping txns are found in
×
UNCOV
2798
// the txns specified and return them.
×
UNCOV
2799
func (h *HarnessTest) FindSweepingTxns(txns []*wire.MsgTx,
×
2800
        expectedNumSweeps int, closeTxid chainhash.Hash) []*wire.MsgTx {
×
2801

×
2802
        var sweepTxns []*wire.MsgTx
×
2803

×
2804
        for _, tx := range txns {
2805
                if tx.TxIn[0].PreviousOutPoint.Hash == closeTxid {
2806
                        sweepTxns = append(sweepTxns, tx)
×
2807
                }
×
UNCOV
2808
        }
×
2809
        require.Len(h, sweepTxns, expectedNumSweeps, "unexpected num of sweeps")
×
2810

2811
        return sweepTxns
×
UNCOV
2812
}
×
2813

2814
// AssertForceCloseAndAnchorTxnsInMempool asserts that the force close and
UNCOV
2815
// anchor sweep txns are found in the mempool and returns the force close tx
×
UNCOV
2816
// and the anchor sweep tx.
×
UNCOV
2817
func (h *HarnessTest) AssertForceCloseAndAnchorTxnsInMempool() (*wire.MsgTx,
×
2818
        *wire.MsgTx) {
2819

2820
        // Assert there are two txns in the mempool.
2821
        txns := h.GetNumTxsFromMempool(2)
2822

2823
        // isParentAndChild checks whether there is an input used in the
×
2824
        // assumed child tx by checking every input's previous outpoint against
×
2825
        // the assumed parentTxid.
×
2826
        isParentAndChild := func(parent, child *wire.MsgTx) bool {
×
2827
                parentTxid := parent.TxHash()
×
2828

×
2829
                for _, inp := range child.TxIn {
×
2830
                        if inp.PreviousOutPoint.Hash == parentTxid {
×
2831
                                // Found a match, this is indeed the anchor
2832
                                // sweeping tx so we return it here.
×
2833
                                return true
×
2834
                        }
×
2835
                }
2836

2837
                return false
2838
        }
2839

2840
        switch {
UNCOV
2841
        // Assume the first one is the closing tx and the second one is the
×
UNCOV
2842
        // anchor sweeping tx.
×
2843
        case isParentAndChild(txns[0], txns[1]):
×
2844
                return txns[0], txns[1]
×
UNCOV
2845

×
UNCOV
2846
        // Assume the first one is the anchor sweeping tx and the second one is
×
UNCOV
2847
        // the closing tx.
×
2848
        case isParentAndChild(txns[1], txns[0]):
×
2849
                return txns[1], txns[0]
×
UNCOV
2850

×
UNCOV
2851
        // Unrelated txns found, fail the test.
×
2852
        default:
×
2853
                h.Fatalf("the two txns not related: %v", txns)
×
2854

×
2855
                return nil, nil
×
UNCOV
2856
        }
×
UNCOV
2857
}
×
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