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

lightningnetwork / lnd / 17301176272

28 Aug 2025 03:54PM UTC coverage: 66.765% (+9.4%) from 57.321%
17301176272

Pull #9868

github

web-flow
Merge 9549248bd into 0c2f045f5
Pull Request #9868: PoC Onion messaging using `msgmux`

150 of 225 new or added lines in 10 files covered. (66.67%)

9 existing lines in 4 files now uncovered.

136145 of 203917 relevant lines covered (66.76%)

21438.06 hits per line

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

0.0
/lntest/rpc/lnd.go
1
package rpc
2

3
import (
4
        "context"
5
        "strings"
6

7
        "github.com/lightningnetwork/lnd/lnrpc"
8
        "github.com/lightningnetwork/lnd/lnrpc/devrpc"
9
        "github.com/stretchr/testify/require"
10
)
11

12
// =====================
13
// LightningClient related RPCs.
14
// =====================
15

16
// NewAddress makes a RPC call to NewAddress and asserts.
17
func (h *HarnessRPC) NewAddress(
18
        req *lnrpc.NewAddressRequest) *lnrpc.NewAddressResponse {
×
19

×
20
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
21
        defer cancel()
×
22

×
23
        resp, err := h.LN.NewAddress(ctxt, req)
×
24
        h.NoError(err, "NewAddress")
×
25

×
26
        return resp
×
27
}
×
28

29
// WalletBalance makes a RPC call to WalletBalance and asserts.
30
func (h *HarnessRPC) WalletBalance() *lnrpc.WalletBalanceResponse {
×
31
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
32
        defer cancel()
×
33

×
34
        req := &lnrpc.WalletBalanceRequest{}
×
35
        resp, err := h.LN.WalletBalance(ctxt, req)
×
36
        h.NoError(err, "WalletBalance")
×
37

×
38
        return resp
×
39
}
×
40

41
// ListPeers makes a RPC call to the node's ListPeers and asserts.
42
func (h *HarnessRPC) ListPeers() *lnrpc.ListPeersResponse {
×
43
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
44
        defer cancel()
×
45

×
46
        resp, err := h.LN.ListPeers(ctxt, &lnrpc.ListPeersRequest{})
×
47
        h.NoError(err, "ListPeers")
×
48

×
49
        return resp
×
50
}
×
51

52
// DisconnectPeer calls the DisconnectPeer RPC on a given node with a specified
53
// public key string and asserts there's no error.
54
func (h *HarnessRPC) DisconnectPeer(
55
        pubkey string) *lnrpc.DisconnectPeerResponse {
×
56

×
57
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
58
        defer cancel()
×
59

×
60
        req := &lnrpc.DisconnectPeerRequest{PubKey: pubkey}
×
61

×
62
        resp, err := h.LN.DisconnectPeer(ctxt, req)
×
63
        h.NoError(err, "DisconnectPeer")
×
64

×
65
        return resp
×
66
}
×
67

68
// DeleteAllPayments makes a RPC call to the node's DeleteAllPayments and
69
// asserts.
70
func (h *HarnessRPC) DeleteAllPayments() {
×
71
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
72
        defer cancel()
×
73

×
74
        req := &lnrpc.DeleteAllPaymentsRequest{AllPayments: true}
×
75
        _, err := h.LN.DeleteAllPayments(ctxt, req)
×
76
        h.NoError(err, "DeleteAllPayments")
×
77
}
×
78

79
// GetInfo calls the GetInfo RPC on a given node and asserts there's no error.
80
func (h *HarnessRPC) GetInfo() *lnrpc.GetInfoResponse {
×
81
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
82
        defer cancel()
×
83

×
84
        info, err := h.LN.GetInfo(ctxt, &lnrpc.GetInfoRequest{})
×
85
        h.NoError(err, "GetInfo")
×
86

×
87
        return info
×
88
}
×
89

90
// ConnectPeer makes a RPC call to ConnectPeer and asserts there's no error.
91
func (h *HarnessRPC) ConnectPeer(
92
        req *lnrpc.ConnectPeerRequest) *lnrpc.ConnectPeerResponse {
×
93

×
94
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
95
        defer cancel()
×
96

×
97
        resp, err := h.LN.ConnectPeer(ctxt, req)
×
98
        h.NoError(err, "ConnectPeer")
×
99

×
100
        return resp
×
101
}
×
102

103
// ConnectPeerAssertErr makes a RPC call to ConnectPeer and asserts an error
104
// returned.
105
func (h *HarnessRPC) ConnectPeerAssertErr(req *lnrpc.ConnectPeerRequest) error {
×
106
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
107
        defer cancel()
×
108

×
109
        _, err := h.LN.ConnectPeer(ctxt, req)
×
110
        require.Error(h, err, "expected an error from ConnectPeer")
×
111

×
112
        return err
×
113
}
×
114

115
// ListChannels list the channels for the given node and asserts it's
116
// successful.
117
func (h *HarnessRPC) ListChannels(
118
        req *lnrpc.ListChannelsRequest) *lnrpc.ListChannelsResponse {
×
119

×
120
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
121
        defer cancel()
×
122

×
123
        resp, err := h.LN.ListChannels(ctxt, req)
×
124
        h.NoError(err, "ListChannels")
×
125

×
126
        return resp
×
127
}
×
128

129
// PendingChannels makes a RPC request to PendingChannels and asserts there's
130
// no error.
131
func (h *HarnessRPC) PendingChannels() *lnrpc.PendingChannelsResponse {
×
132
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
133
        defer cancel()
×
134

×
135
        pendingChansRequest := &lnrpc.PendingChannelsRequest{
×
136
                IncludeRawTx: true,
×
137
        }
×
138
        resp, err := h.LN.PendingChannels(ctxt, pendingChansRequest)
×
139

×
140
        // TODO(yy): We may get a `unable to find arbitrator` error from the
×
141
        // rpc point, due to a timing issue in rpcserver,
×
142
        // 1. `r.server.chanStateDB.FetchClosedChannels` fetches
×
143
        //    the pending force close channel.
×
144
        // 2. `r.arbitratorPopulateForceCloseResp` relies on the
×
145
        //    channel arbitrator to get the report, and,
×
146
        // 3. the arbitrator may be deleted due to the force close
×
147
        //    channel being resolved.
×
148
        // Somewhere along the line is missing a lock to keep the data
×
149
        // consistent.
×
150
        //
×
151
        // Return if there's no error.
×
152
        if err == nil {
×
153
                return resp
×
154
        }
×
155

156
        // Otherwise, give it a second shot if it's the arbitrator error.
157
        if strings.Contains(err.Error(), "unable to find arbitrator") {
×
158
                resp, err = h.LN.PendingChannels(ctxt, pendingChansRequest)
×
159
        }
×
160

161
        // It's very unlikely we'd get the arbitrator not found error again.
162
        h.NoError(err, "PendingChannels")
×
163

×
164
        return resp
×
165
}
166

167
// ClosedChannels makes a RPC call to node's ClosedChannels and asserts.
168
func (h *HarnessRPC) ClosedChannels(
169
        req *lnrpc.ClosedChannelsRequest) *lnrpc.ClosedChannelsResponse {
×
170

×
171
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
172
        defer cancel()
×
173

×
174
        resp, err := h.LN.ClosedChannels(ctxt, req)
×
175
        h.NoError(err, "ClosedChannels")
×
176

×
177
        return resp
×
178
}
×
179

180
// ListPayments lists the node's payments and asserts.
181
func (h *HarnessRPC) ListPayments(
182
        req *lnrpc.ListPaymentsRequest) *lnrpc.ListPaymentsResponse {
×
183

×
184
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
185
        defer cancel()
×
186

×
187
        resp, err := h.LN.ListPayments(ctxt, req)
×
188
        h.NoError(err, "ListPayments")
×
189

×
190
        return resp
×
191
}
×
192

193
// ListInvoices list the node's invoice using the request and asserts.
194
func (h *HarnessRPC) ListInvoices(
195
        req *lnrpc.ListInvoiceRequest) *lnrpc.ListInvoiceResponse {
×
196

×
197
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
198
        defer cancel()
×
199

×
200
        if req == nil {
×
201
                req = &lnrpc.ListInvoiceRequest{}
×
202
        }
×
203

204
        resp, err := h.LN.ListInvoices(ctxt, req)
×
205
        h.NoError(err, "ListInvoice")
×
206

×
207
        return resp
×
208
}
209

210
// DescribeGraph makes a RPC call to the node's DescribeGraph and asserts. It
211
// takes a bool to indicate whether we want to include private edges or not.
212
func (h *HarnessRPC) DescribeGraph(
213
        req *lnrpc.ChannelGraphRequest) *lnrpc.ChannelGraph {
×
214

×
215
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
216
        defer cancel()
×
217

×
218
        resp, err := h.LN.DescribeGraph(ctxt, req)
×
219
        h.NoError(err, "DescribeGraph")
×
220

×
221
        return resp
×
222
}
×
223

224
// ChannelBalance gets the channel balance and asserts.
225
func (h *HarnessRPC) ChannelBalance() *lnrpc.ChannelBalanceResponse {
×
226
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
227
        defer cancel()
×
228

×
229
        req := &lnrpc.ChannelBalanceRequest{}
×
230
        resp, err := h.LN.ChannelBalance(ctxt, req)
×
231
        h.NoError(err, "ChannelBalance")
×
232

×
233
        return resp
×
234
}
×
235

236
type OpenChanClient lnrpc.Lightning_OpenChannelClient
237

238
// OpenChannel makes a rpc call to LightningClient and returns the open channel
239
// client.
240
func (h *HarnessRPC) OpenChannel(req *lnrpc.OpenChannelRequest) OpenChanClient {
×
241
        stream, err := h.LN.OpenChannel(h.runCtx, req)
×
242
        h.NoError(err, "OpenChannel")
×
243

×
244
        return stream
×
245
}
×
246

247
type CloseChanClient lnrpc.Lightning_CloseChannelClient
248

249
// CloseChannel makes a rpc call to LightningClient and returns the close
250
// channel client.
251
func (h *HarnessRPC) CloseChannel(
252
        req *lnrpc.CloseChannelRequest) CloseChanClient {
×
253

×
254
        // Use runCtx here instead of a timeout context to keep the client
×
255
        // alive for the entire test case.
×
256
        stream, err := h.LN.CloseChannel(h.runCtx, req)
×
257
        h.NoError(err, "CloseChannel")
×
258

×
259
        return stream
×
260
}
×
261

262
// FundingStateStep makes a RPC call to FundingStateStep and asserts.
263
func (h *HarnessRPC) FundingStateStep(
264
        msg *lnrpc.FundingTransitionMsg) *lnrpc.FundingStateStepResp {
×
265

×
266
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
267
        defer cancel()
×
268

×
269
        resp, err := h.LN.FundingStateStep(ctxt, msg)
×
270
        h.NoError(err, "FundingStateStep")
×
271

×
272
        return resp
×
273
}
×
274

275
// FundingStateStepAssertErr makes a RPC call to FundingStateStep and asserts
276
// there's an error.
277
func (h *HarnessRPC) FundingStateStepAssertErr(m *lnrpc.FundingTransitionMsg) {
×
278
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
279
        defer cancel()
×
280

×
281
        _, err := h.LN.FundingStateStep(ctxt, m)
×
282
        require.Error(h, err, "expected an error from FundingStateStep")
×
283
}
×
284

285
// AddInvoice adds a invoice for the given node and asserts.
286
func (h *HarnessRPC) AddInvoice(req *lnrpc.Invoice) *lnrpc.AddInvoiceResponse {
×
287
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
288
        defer cancel()
×
289

×
290
        invoice, err := h.LN.AddInvoice(ctxt, req)
×
291
        h.NoError(err, "AddInvoice")
×
292

×
293
        return invoice
×
294
}
×
295

296
// AddInvoiceAssertErr makes a RPC call to AddInvoice and asserts an error
297
// has returned with a specific error message.
298
func (h *HarnessRPC) AddInvoiceAssertErr(req *lnrpc.Invoice, errStr string) {
×
299
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
300
        defer cancel()
×
301

×
302
        _, err := h.LN.AddInvoice(ctxt, req)
×
303
        require.ErrorContains(h, err, errStr)
×
304
}
×
305

306
// GetChanInfoAssertErr makes an RPC call to GetChanInfo and asserts an error
307
// has returned with a specific error message.
308
func (h *HarnessRPC) GetChanInfoAssertErr(req *lnrpc.ChanInfoRequest,
309
        errStr string) {
×
310

×
311
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
312
        defer cancel()
×
313

×
314
        _, err := h.LN.GetChanInfo(ctxt, req)
×
315
        require.ErrorContains(h, err, errStr)
×
316
}
×
317

318
// GetNodeInfoAssertErr makes an RPC call to GetNodeInfo and asserts an error
319
// has returned with a specific error message.
320
func (h *HarnessRPC) GetNodeInfoAssertErr(req *lnrpc.NodeInfoRequest,
321
        errStr string) {
×
322

×
323
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
324
        defer cancel()
×
325

×
326
        _, err := h.LN.GetNodeInfo(ctxt, req)
×
327
        require.ErrorContains(h, err, errStr)
×
328
}
×
329

330
// SendCustomMessageAssertErr makes an RPC call to SendCustomMessage and asserts
331
// an error has returned with a specific error message.
332
func (h *HarnessRPC) SendCustomMessageAssertErr(
333
        req *lnrpc.SendCustomMessageRequest, errStr string) {
×
334

×
335
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
336
        defer cancel()
×
337

×
338
        _, err := h.LN.SendCustomMessage(ctxt, req)
×
339
        require.ErrorContains(h, err, errStr)
×
340
}
×
341

342
// LookupInvoiceAssertErr makes an RPC call to LookupInvoice and asserts an
343
// error has returned with a specific error message.
344
func (h *HarnessRPC) LookupInvoiceAssertErr(req *lnrpc.PaymentHash,
345
        errStr string) {
×
346

×
347
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
348
        defer cancel()
×
349

×
350
        _, err := h.LN.LookupInvoice(ctxt, req)
×
351
        require.ErrorContains(h, err, errStr)
×
352
}
×
353

354
// LookupHTLCResolutionAssertErr makes an RPC call to LookupHTLCResolution and
355
// asserts an error has returned with a specific error message.
356
func (h *HarnessRPC) LookupHTLCResolutionAssertErr(
357
        req *lnrpc.LookupHtlcResolutionRequest, errStr string) {
×
358

×
359
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
360
        defer cancel()
×
361

×
362
        _, err := h.LN.LookupHtlcResolution(ctxt, req)
×
363
        require.ErrorContains(h, err, errStr)
×
364
}
×
365

366
// AbandonChannel makes a RPC call to AbandonChannel and asserts.
367
func (h *HarnessRPC) AbandonChannel(
368
        req *lnrpc.AbandonChannelRequest) *lnrpc.AbandonChannelResponse {
×
369

×
370
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
371
        defer cancel()
×
372

×
373
        resp, err := h.LN.AbandonChannel(ctxt, req)
×
374
        h.NoError(err, "AbandonChannel")
×
375

×
376
        return resp
×
377
}
×
378

379
// ExportAllChanBackups makes a RPC call to the node's ExportAllChannelBackups
380
// and asserts.
381
func (h *HarnessRPC) ExportAllChanBackups() *lnrpc.ChanBackupSnapshot {
×
382
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
383
        defer cancel()
×
384

×
385
        req := &lnrpc.ChanBackupExportRequest{}
×
386
        chanBackup, err := h.LN.ExportAllChannelBackups(ctxt, req)
×
387
        h.NoError(err, "ExportAllChannelBackups")
×
388

×
389
        return chanBackup
×
390
}
×
391

392
// ExportChanBackup makes a RPC call to the node's ExportChannelBackup
393
// and asserts.
394
func (h *HarnessRPC) ExportChanBackup(
395
        chanPoint *lnrpc.ChannelPoint) *lnrpc.ChannelBackup {
×
396

×
397
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
398
        defer cancel()
×
399

×
400
        req := &lnrpc.ExportChannelBackupRequest{
×
401
                ChanPoint: chanPoint,
×
402
        }
×
403
        chanBackup, err := h.LN.ExportChannelBackup(ctxt, req)
×
404
        h.NoError(err, "ExportChannelBackup")
×
405

×
406
        return chanBackup
×
407
}
×
408

409
// RestoreChanBackups makes a RPC call to the node's RestoreChannelBackups and
410
// asserts.
411
func (h *HarnessRPC) RestoreChanBackups(
412
        req *lnrpc.RestoreChanBackupRequest) *lnrpc.RestoreBackupResponse {
×
413

×
414
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
415
        defer cancel()
×
416

×
417
        resp, err := h.LN.RestoreChannelBackups(ctxt, req)
×
418
        h.NoError(err, "RestoreChannelBackups")
×
419

×
420
        return resp
×
421
}
×
422

423
type AcceptorClient lnrpc.Lightning_ChannelAcceptorClient
424

425
// ChannelAcceptor makes a RPC call to the node's ChannelAcceptor and asserts.
426
func (h *HarnessRPC) ChannelAcceptor() (AcceptorClient, context.CancelFunc) {
×
427
        // Use runCtx here instead of a timeout context to keep the client
×
428
        // alive for the entire test case.
×
429
        ctxt, cancel := context.WithCancel(h.runCtx)
×
430
        resp, err := h.LN.ChannelAcceptor(ctxt)
×
431
        h.NoError(err, "ChannelAcceptor")
×
432

×
433
        return resp, cancel
×
434
}
×
435

436
// SendCoins sends a given amount of money to the specified address from the
437
// passed node.
438
func (h *HarnessRPC) SendCoins(
439
        req *lnrpc.SendCoinsRequest) *lnrpc.SendCoinsResponse {
×
440

×
441
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
442
        defer cancel()
×
443

×
444
        resp, err := h.LN.SendCoins(ctxt, req)
×
445
        h.NoError(err, "SendCoins")
×
446

×
447
        return resp
×
448
}
×
449

450
// SendCoinsAssertErr sends a given amount of money to the specified address
451
// from the passed node and asserts an error has returned.
452
func (h *HarnessRPC) SendCoinsAssertErr(req *lnrpc.SendCoinsRequest) error {
×
453
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
454
        defer cancel()
×
455

×
456
        _, err := h.LN.SendCoins(ctxt, req)
×
457
        require.Error(h, err, "node %s didn't not return an error", h.Name)
×
458

×
459
        return err
×
460
}
×
461

462
// GetTransactions makes a RPC call to GetTransactions and asserts.
463
func (h *HarnessRPC) GetTransactions(
464
        req *lnrpc.GetTransactionsRequest) *lnrpc.TransactionDetails {
×
465

×
466
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
467
        defer cancel()
×
468

×
469
        if req == nil {
×
470
                req = &lnrpc.GetTransactionsRequest{}
×
471
        }
×
472

473
        resp, err := h.LN.GetTransactions(ctxt, req)
×
474
        h.NoError(err, "GetTransactions")
×
475

×
476
        return resp
×
477
}
478

479
// SignMessage makes a RPC call to node's SignMessage and asserts.
480
func (h *HarnessRPC) SignMessage(msg []byte) *lnrpc.SignMessageResponse {
×
481
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
482
        defer cancel()
×
483

×
484
        req := &lnrpc.SignMessageRequest{Msg: msg}
×
485
        resp, err := h.LN.SignMessage(ctxt, req)
×
486
        h.NoError(err, "SignMessage")
×
487

×
488
        return resp
×
489
}
×
490

491
// VerifyMessage makes a RPC call to node's VerifyMessage and asserts.
492
func (h *HarnessRPC) VerifyMessage(msg []byte,
493
        sig string) *lnrpc.VerifyMessageResponse {
×
494

×
495
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
496
        defer cancel()
×
497

×
498
        req := &lnrpc.VerifyMessageRequest{Msg: msg, Signature: sig}
×
499
        resp, err := h.LN.VerifyMessage(ctxt, req)
×
500
        h.NoError(err, "VerifyMessage")
×
501

×
502
        return resp
×
503
}
×
504

505
// GetRecoveryInfo uses the specified node to make a RPC call to
506
// GetRecoveryInfo and asserts.
507
func (h *HarnessRPC) GetRecoveryInfo(
508
        req *lnrpc.GetRecoveryInfoRequest) *lnrpc.GetRecoveryInfoResponse {
×
509

×
510
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
511
        defer cancel()
×
512

×
513
        if req == nil {
×
514
                req = &lnrpc.GetRecoveryInfoRequest{}
×
515
        }
×
516

517
        resp, err := h.LN.GetRecoveryInfo(ctxt, req)
×
518
        h.NoError(err, "GetRecoveryInfo")
×
519

×
520
        return resp
×
521
}
522

523
// BatchOpenChannel makes a RPC call to BatchOpenChannel and asserts.
524
func (h *HarnessRPC) BatchOpenChannel(
525
        req *lnrpc.BatchOpenChannelRequest) *lnrpc.BatchOpenChannelResponse {
×
526

×
527
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
528
        defer cancel()
×
529

×
530
        resp, err := h.LN.BatchOpenChannel(ctxt, req)
×
531
        h.NoError(err, "BatchOpenChannel")
×
532

×
533
        return resp
×
534
}
×
535

536
// BatchOpenChannelAssertErr makes a RPC call to BatchOpenChannel and asserts
537
// there's an error returned.
538
func (h *HarnessRPC) BatchOpenChannelAssertErr(
539
        req *lnrpc.BatchOpenChannelRequest) error {
×
540

×
541
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
542
        defer cancel()
×
543

×
544
        _, err := h.LN.BatchOpenChannel(ctxt, req)
×
545
        require.Error(h, err, "expecte batch open channel fail")
×
546

×
547
        return err
×
548
}
×
549

550
// QueryRoutes makes a RPC call to QueryRoutes and asserts.
551
func (h *HarnessRPC) QueryRoutes(
552
        req *lnrpc.QueryRoutesRequest) *lnrpc.QueryRoutesResponse {
×
553

×
554
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
555
        defer cancel()
×
556

×
557
        routes, err := h.LN.QueryRoutes(ctxt, req)
×
558
        h.NoError(err, "QueryRoutes")
×
559

×
560
        return routes
×
561
}
×
562

563
type SendToRouteClient lnrpc.Lightning_SendToRouteClient
564

565
// SendToRoute makes a RPC call to SendToRoute and asserts.
566
func (h *HarnessRPC) SendToRoute() SendToRouteClient {
×
567
        // SendToRoute needs to have the context alive for the entire test case
×
568
        // as the returned client will be used for send and receive payment
×
569
        // stream. Thus we use runCtx here instead of a timeout context.
×
570
        client, err := h.LN.SendToRoute(h.runCtx)
×
571
        h.NoError(err, "SendToRoute")
×
572

×
573
        return client
×
574
}
×
575

576
// SendToRouteSync makes a RPC call to SendToRouteSync and asserts.
577
func (h *HarnessRPC) SendToRouteSync(
578
        req *lnrpc.SendToRouteRequest) *lnrpc.SendResponse {
×
579

×
580
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
581
        defer cancel()
×
582

×
583
        resp, err := h.LN.SendToRouteSync(ctxt, req)
×
584
        h.NoError(err, "SendToRouteSync")
×
585

×
586
        return resp
×
587
}
×
588

589
// UpdateChannelPolicy makes a RPC call to UpdateChannelPolicy and asserts.
590
func (h *HarnessRPC) UpdateChannelPolicy(
591
        req *lnrpc.PolicyUpdateRequest) *lnrpc.PolicyUpdateResponse {
×
592

×
593
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
594
        defer cancel()
×
595

×
596
        resp, err := h.LN.UpdateChannelPolicy(ctxt, req)
×
597
        h.NoError(err, "UpdateChannelPolicy")
×
598

×
599
        return resp
×
600
}
×
601

602
type InvoiceUpdateClient lnrpc.Lightning_SubscribeInvoicesClient
603

604
// SubscribeInvoices creates a subscription client for invoice events and
605
// asserts its creation.
606
//
607
// NOTE: make sure to subscribe an invoice as early as possible as it takes
608
// some time for the lnd to create the subscription client. If an invoice is
609
// added right after the subscription, it may be missed. However, if AddIndex
610
// or SettleIndex is used in the request, it will be fine as a backlog will
611
// always be sent.
612
func (h *HarnessRPC) SubscribeInvoices(
613
        req *lnrpc.InvoiceSubscription) InvoiceUpdateClient {
×
614

×
615
        // SubscribeInvoices needs to have the context alive for the
×
616
        // entire test case as the returned client will be used for send and
×
617
        // receive events stream. Thus we use runCtx here instead of a timeout
×
618
        // context.
×
619
        client, err := h.LN.SubscribeInvoices(h.runCtx, req)
×
620
        h.NoError(err, "SubscribeInvoices")
×
621

×
622
        return client
×
623
}
×
624

625
type BackupSubscriber lnrpc.Lightning_SubscribeChannelBackupsClient
626

627
// SubscribeChannelBackups creates a client to listen to channel backup stream.
628
func (h *HarnessRPC) SubscribeChannelBackups() BackupSubscriber {
×
629
        // Use runCtx here instead of timeout context to keep the stream client
×
630
        // alive.
×
631
        backupStream, err := h.LN.SubscribeChannelBackups(
×
632
                h.runCtx, &lnrpc.ChannelBackupSubscription{},
×
633
        )
×
634
        h.NoError(err, "SubscribeChannelBackups")
×
635

×
636
        return backupStream
×
637
}
×
638

639
// VerifyChanBackup makes a RPC call to node's VerifyChanBackup and asserts.
640
func (h *HarnessRPC) VerifyChanBackup(
641
        ss *lnrpc.ChanBackupSnapshot) *lnrpc.VerifyChanBackupResponse {
×
642

×
643
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
644
        defer cancel()
×
645

×
646
        resp, err := h.LN.VerifyChanBackup(ctxt, ss)
×
647
        h.NoError(err, "VerifyChanBackup")
×
648

×
649
        return resp
×
650
}
×
651

652
// LookupInvoice queries the node's invoices using the specified rHash.
653
func (h *HarnessRPC) LookupInvoice(rHash []byte) *lnrpc.Invoice {
×
654
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
655
        defer cancel()
×
656

×
657
        payHash := &lnrpc.PaymentHash{RHash: rHash}
×
658
        resp, err := h.LN.LookupInvoice(ctxt, payHash)
×
659
        h.NoError(err, "LookupInvoice")
×
660

×
661
        return resp
×
662
}
×
663

664
// DecodePayReq makes a RPC call to node's DecodePayReq and asserts.
665
func (h *HarnessRPC) DecodePayReq(req string) *lnrpc.PayReq {
×
666
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
667
        defer cancel()
×
668

×
669
        payReq := &lnrpc.PayReqString{PayReq: req}
×
670
        resp, err := h.LN.DecodePayReq(ctxt, payReq)
×
671
        h.NoError(err, "DecodePayReq")
×
672

×
673
        return resp
×
674
}
×
675

676
// ForwardingHistory makes a RPC call to the node's ForwardingHistory and
677
// asserts.
678
func (h *HarnessRPC) ForwardingHistory(
679
        req *lnrpc.ForwardingHistoryRequest) *lnrpc.ForwardingHistoryResponse {
×
680

×
681
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
682
        defer cancel()
×
683

×
684
        if req == nil {
×
685
                req = &lnrpc.ForwardingHistoryRequest{}
×
686
        }
×
687

688
        resp, err := h.LN.ForwardingHistory(ctxt, req)
×
689
        h.NoError(err, "ForwardingHistory")
×
690

×
691
        return resp
×
692
}
693

694
type MiddlewareClient lnrpc.Lightning_RegisterRPCMiddlewareClient
695

696
// RegisterRPCMiddleware makes a RPC call to the node's RegisterRPCMiddleware
697
// and asserts. It also returns a cancel context which can cancel the context
698
// used by the client.
699
func (h *HarnessRPC) RegisterRPCMiddleware() (MiddlewareClient,
700
        context.CancelFunc) {
×
701

×
702
        ctxt, cancel := context.WithCancel(h.runCtx)
×
703

×
704
        stream, err := h.LN.RegisterRPCMiddleware(ctxt)
×
705
        h.NoError(err, "RegisterRPCMiddleware")
×
706

×
707
        return stream, cancel
×
708
}
×
709

710
type ChannelEventsClient lnrpc.Lightning_SubscribeChannelEventsClient
711

712
// SubscribeChannelEvents creates a subscription client for channel events and
713
// asserts its creation.
714
func (h *HarnessRPC) SubscribeChannelEvents() ChannelEventsClient {
×
715
        req := &lnrpc.ChannelEventSubscription{}
×
716

×
717
        // SubscribeChannelEvents needs to have the context alive for the
×
718
        // entire test case as the returned client will be used for send and
×
719
        // receive events stream. Thus we use runCtx here instead of a timeout
×
720
        // context.
×
721
        client, err := h.LN.SubscribeChannelEvents(h.runCtx, req)
×
722
        h.NoError(err, "SubscribeChannelEvents")
×
723

×
724
        return client
×
725
}
×
726

727
type CustomMessageClient lnrpc.Lightning_SubscribeCustomMessagesClient
728

729
type OnionMessageClient lnrpc.Lightning_SubscribeOnionMessagesClient
730

731
// SubscribeCustomMessages creates a subscription client for custom messages.
732
func (h *HarnessRPC) SubscribeCustomMessages() (CustomMessageClient,
733
        context.CancelFunc) {
×
734

×
735
        ctxt, cancel := context.WithCancel(h.runCtx)
×
736

×
737
        req := &lnrpc.SubscribeCustomMessagesRequest{}
×
738

×
739
        // SubscribeCustomMessages needs to have the context alive for the
×
740
        // entire test case as the returned client will be used for send and
×
741
        // receive events stream. Thus we use runCtx here instead of a timeout
×
742
        // context.
×
743
        stream, err := h.LN.SubscribeCustomMessages(ctxt, req)
×
744
        h.NoError(err, "SubscribeCustomMessages")
×
745

×
746
        return stream, cancel
×
747
}
×
748

749
// SendCustomMessage makes a RPC call to the node's SendCustomMessage and
750
// returns the response.
751
func (h *HarnessRPC) SendCustomMessage(
752
        req *lnrpc.SendCustomMessageRequest) *lnrpc.SendCustomMessageResponse {
×
753

×
754
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
755
        defer cancel()
×
756

×
757
        resp, err := h.LN.SendCustomMessage(ctxt, req)
×
758
        h.NoError(err, "SendCustomMessage")
×
759

×
760
        return resp
×
761
}
×
762

763
// SendOnionMessage makes a RPC call to the node's SendOnionMessage and
764
// returns the response.
765
func (h *HarnessRPC) SendOnionMessage(
NEW
766
        req *lnrpc.SendOnionMessageRequest) *lnrpc.SendOnionMessageResponse {
×
NEW
767

×
NEW
768
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
NEW
769
        defer cancel()
×
NEW
770

×
NEW
771
        resp, err := h.LN.SendOnionMessage(ctxt, req)
×
NEW
772
        h.NoError(err, "SendOnionMessage")
×
NEW
773

×
NEW
774
        return resp
×
NEW
775
}
×
776

777
// SubscribeOnionMessages creates a subscription client for onion messages.
778
func (h *HarnessRPC) SubscribeOnionMessages() (OnionMessageClient,
NEW
779
        context.CancelFunc) {
×
NEW
780

×
NEW
781
        ctxt, cancel := context.WithCancel(h.runCtx)
×
NEW
782

×
NEW
783
        req := &lnrpc.SubscribeOnionMessagesRequest{}
×
NEW
784

×
NEW
785
        // SubscribeCustomMessages needs to have the context alive for the
×
NEW
786
        // entire test case as the returned client will be used for send and
×
NEW
787
        // receive events stream. Thus we use runCtx here instead of a timeout
×
NEW
788
        // context.
×
NEW
789
        stream, err := h.LN.SubscribeOnionMessages(ctxt, req)
×
NEW
790
        h.NoError(err, "SubscribeOnionMessages")
×
NEW
791

×
NEW
792
        return stream, cancel
×
NEW
793
}
×
794

795
// GetChanInfo makes a RPC call to the node's GetChanInfo and returns the
796
// response.
797
func (h *HarnessRPC) GetChanInfo(
798
        req *lnrpc.ChanInfoRequest) *lnrpc.ChannelEdge {
×
799

×
800
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
801
        defer cancel()
×
802

×
803
        resp, err := h.LN.GetChanInfo(ctxt, req)
×
804
        h.NoError(err, "GetChanInfo")
×
805

×
806
        return resp
×
807
}
×
808

809
// LookupHtlcResolution makes a RPC call to the node's LookupHtlcResolution and
810
// returns the response.
811
//
812
//nolint:ll
813
func (h *HarnessRPC) LookupHtlcResolution(
814
        req *lnrpc.LookupHtlcResolutionRequest) *lnrpc.LookupHtlcResolutionResponse {
×
815

×
816
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
817
        defer cancel()
×
818

×
819
        resp, err := h.LN.LookupHtlcResolution(ctxt, req)
×
820
        h.NoError(err, "LookupHtlcResolution")
×
821

×
822
        return resp
×
823
}
×
824

825
// LookupHtlcResolutionAssertErr makes a RPC call to the node's
826
// LookupHtlcResolution and asserts an RPC error is returned.
827
func (h *HarnessRPC) LookupHtlcResolutionAssertErr(
828
        req *lnrpc.LookupHtlcResolutionRequest) error {
×
829

×
830
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
831
        defer cancel()
×
832

×
833
        _, err := h.LN.LookupHtlcResolution(ctxt, req)
×
834
        require.Error(h, err, "expected an error")
×
835

×
836
        return err
×
837
}
×
838

839
// Quiesce makes an RPC call to the node's Quiesce method and returns the
840
// response.
841
func (h *HarnessRPC) Quiesce(
842
        req *devrpc.QuiescenceRequest) *devrpc.QuiescenceResponse {
×
843

×
844
        ctx, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
845
        defer cancel()
×
846

×
847
        res, err := h.Dev.Quiesce(ctx, req)
×
848
        h.NoError(err, "Quiesce returned an error")
×
849

×
850
        return res
×
851
}
×
852

853
type PeerEventsClient lnrpc.Lightning_SubscribePeerEventsClient
854

855
// SubscribePeerEvents makes a RPC call to the node's SubscribePeerEvents and
856
// returns the stream client.
857
func (h *HarnessRPC) SubscribePeerEvents(
858
        req *lnrpc.PeerEventSubscription) PeerEventsClient {
×
859

×
860
        // SubscribePeerEvents needs to have the context alive for the entire
×
861
        // test case as the returned client will be used for send and receive
×
862
        // events stream. Thus we use runCtx here instead of a timeout context.
×
863
        resp, err := h.LN.SubscribePeerEvents(h.runCtx, req)
×
864
        h.NoError(err, "SubscribePeerEvents")
×
865

×
866
        return resp
×
867
}
×
868

869
// DeleteCanceledInvoice makes a RPC call to the node's DeleteCanceledInvoice
870
// and asserts.
871
func (h *HarnessRPC) DeleteCanceledInvoice(
872
        req *lnrpc.DelCanceledInvoiceReq) *lnrpc.DelCanceledInvoiceResp {
×
873

×
874
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
875
        defer cancel()
×
876

×
877
        resp, err := h.LN.DeleteCanceledInvoice(ctxt, req)
×
878
        h.NoError(err, "DeleteCanceledInvoice")
×
879

×
880
        return resp
×
881
}
×
882

883
// DeleteCanceledInvoiceAssertErr makes a RPC call to the node's
884
// DeleteCanceledInvoice and asserts if an RPC error is returned.
885
func (h *HarnessRPC) DeleteCanceledInvoiceAssertErr(
886
        req *lnrpc.DelCanceledInvoiceReq, errStr string) {
×
887

×
888
        ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
×
889
        defer cancel()
×
890

×
891
        _, err := h.LN.DeleteCanceledInvoice(ctxt, req)
×
892
        require.ErrorContains(h, err, errStr)
×
893
}
×
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