Skip to content

Commit a8d8b5a

Browse files
authored
Merge pull request #1048 from lightninglabs/tap-channel-rpcs
[custom channels]: add new RPC methods for asset channel specific calls
2 parents 1b5a4ef + 23c09ff commit a8d8b5a

18 files changed

+2767
-96
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ require (
2828
github.com/lib/pq v1.10.9
2929
github.com/lightninglabs/aperture v0.1.21-beta.0.20230705004936-87bb996a4030
3030
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2
31-
github.com/lightninglabs/lndclient v1.0.1-0.20240723001046-925d3c8297bf
31+
github.com/lightninglabs/lndclient v1.0.1-0.20240725080034-64a756aa4c36
3232
github.com/lightninglabs/neutrino/cache v1.1.2
3333
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240723043204-f09d4042aee4
3434
github.com/lightningnetwork/lnd/cert v1.2.2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,8 @@ github.com/lightninglabs/lightning-node-connect v0.2.5-alpha h1:ZRVChwczFXK0CEbx
480480
github.com/lightninglabs/lightning-node-connect v0.2.5-alpha/go.mod h1:A9Pof9fETkH+F67BnOmrBDThPKstqp73wlImWOZvTXQ=
481481
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 h1:Er1miPZD2XZwcfE4xoS5AILqP1mj7kqnhbBSxW9BDxY=
482482
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2/go.mod h1:antQGRDRJiuyQF6l+k6NECCSImgCpwaZapATth2Chv4=
483-
github.com/lightninglabs/lndclient v1.0.1-0.20240723001046-925d3c8297bf h1:VcTK/juPtAqwEBckCcSHCsVRSbHGbWtDZgnXL5JOLkg=
484-
github.com/lightninglabs/lndclient v1.0.1-0.20240723001046-925d3c8297bf/go.mod h1:bxd2a15cIaW8KKcmOf9nNDI/GTxxj0upEYs1EIkttqw=
483+
github.com/lightninglabs/lndclient v1.0.1-0.20240725080034-64a756aa4c36 h1:gfJ3TOuqSnuXEo1Boj1H9P6tpxPSH9cvi+rB10L0svI=
484+
github.com/lightninglabs/lndclient v1.0.1-0.20240725080034-64a756aa4c36/go.mod h1:bxd2a15cIaW8KKcmOf9nNDI/GTxxj0upEYs1EIkttqw=
485485
github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd h1:D8aRocHpoCv43hL8egXEMYyPmyOiefFHZ66338KQB2s=
486486
github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd/go.mod h1:x3OmY2wsA18+Kc3TSV2QpSUewOCiscw2mKpXgZv2kZk=
487487
github.com/lightninglabs/neutrino/cache v1.1.2 h1:C9DY/DAPaPxbFC+xNNEI/z1SJY9GS3shmlu5hIQ798g=

itest/channels_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package itest
2+
3+
import (
4+
"context"
5+
6+
"github.com/lightninglabs/taproot-assets/rfqmsg"
7+
tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
8+
"github.com/lightningnetwork/lnd/lnrpc"
9+
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
10+
"github.com/lightningnetwork/lnd/record"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
var (
15+
dummyByteArr = [32]byte{0x01, 0x02, 0x03, 0x04}
16+
)
17+
18+
// testChannelRPCs tests that we can call all Taproot Asset Channel related
19+
// RPCs and get the correct error message back (as we can't really test the
20+
// actual functionality without running within litd). This at least makes sure
21+
// we've set up everything correctly in terms of macaroons and permissions.
22+
func testChannelRPCs(t *harnessTest) {
23+
ctx := context.Background()
24+
25+
// The EncodeCustomRecords RPC is available, as it only does static
26+
// encoding.
27+
encodeReq := &tchrpc.EncodeCustomRecordsRequest_RouterSendPayment{
28+
RouterSendPayment: &tchrpc.RouterSendPaymentData{
29+
RfqId: dummyByteArr[:],
30+
},
31+
}
32+
encodeResp, err := t.tapd.EncodeCustomRecords(
33+
ctx, &tchrpc.EncodeCustomRecordsRequest{
34+
Input: encodeReq,
35+
},
36+
)
37+
require.NoError(t.t, err)
38+
require.Len(t.t, encodeResp.CustomRecords, 2)
39+
40+
var rfqIdType rfqmsg.HtlcRfqIDType
41+
rfqIdTlvTypeNumber := uint64(rfqIdType.TypeVal())
42+
require.Len(t.t, encodeResp.CustomRecords[rfqIdTlvTypeNumber], 32)
43+
44+
// All the following calls can't go fully through, and we'll encounter
45+
// an error at some point.
46+
_, err = t.tapd.FundChannel(ctx, &tchrpc.FundChannelRequest{})
47+
require.ErrorContains(t.t, err, "only available when running inside")
48+
49+
// Try the keysend path first, which should go all the way through to
50+
// lnd, where it should fail because we didn't set a timeout.
51+
stream, err := t.tapd.SendPayment(ctx, &tchrpc.SendPaymentRequest{
52+
AssetAmount: 123,
53+
AssetId: dummyByteArr[:],
54+
PaymentRequest: &routerrpc.SendPaymentRequest{
55+
DestCustomRecords: map[uint64][]byte{
56+
record.KeySendType: dummyByteArr[:],
57+
},
58+
},
59+
})
60+
require.NoError(t.t, err)
61+
62+
_, err = stream.Recv()
63+
require.ErrorContains(t.t, err, "timeout_seconds")
64+
65+
// Now let's also try the invoice path, which should fail because we
66+
// don't have any asset channels with peers that we could ask for a
67+
// quote.
68+
invoiceResp := t.lndHarness.Alice.RPC.AddInvoice(&lnrpc.Invoice{
69+
AmtPaidSat: 1234,
70+
})
71+
stream, err = t.tapd.SendPayment(ctx, &tchrpc.SendPaymentRequest{
72+
AssetId: dummyByteArr[:],
73+
PaymentRequest: &routerrpc.SendPaymentRequest{
74+
PaymentRequest: invoiceResp.PaymentRequest,
75+
},
76+
})
77+
require.NoError(t.t, err)
78+
79+
_, err = stream.Recv()
80+
require.ErrorContains(t.t, err, "no asset channel balance found")
81+
82+
// We can't add an invoice either, because we have no peers to do RFQ
83+
// negotiation with.
84+
_, err = t.tapd.AddInvoice(ctx, &tchrpc.AddInvoiceRequest{
85+
AssetAmount: 123,
86+
AssetId: dummyByteArr[:],
87+
InvoiceRequest: &lnrpc.Invoice{
88+
Private: false,
89+
},
90+
})
91+
require.ErrorContains(t.t, err, "no asset channel balance found")
92+
}

itest/tapd_harness.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/lightninglabs/taproot-assets/taprpc/assetwalletrpc"
2424
"github.com/lightninglabs/taproot-assets/taprpc/mintrpc"
2525
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
26+
tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
2627
"github.com/lightninglabs/taproot-assets/taprpc/tapdevrpc"
2728
"github.com/lightninglabs/taproot-assets/taprpc/universerpc"
2829
"github.com/lightningnetwork/lnd/lnrpc"
@@ -96,6 +97,7 @@ type tapdHarness struct {
9697
assetwalletrpc.AssetWalletClient
9798
mintrpc.MintClient
9899
rfqrpc.RfqClient
100+
tchrpc.TaprootAssetChannelsClient
99101
universerpc.UniverseClient
100102
tapdevrpc.TapDevClient
101103
}
@@ -348,6 +350,9 @@ func (hs *tapdHarness) start(expectErrExit bool) error {
348350
hs.AssetWalletClient = assetwalletrpc.NewAssetWalletClient(rpcConn)
349351
hs.MintClient = mintrpc.NewMintClient(rpcConn)
350352
hs.RfqClient = rfqrpc.NewRfqClient(rpcConn)
353+
hs.TaprootAssetChannelsClient = tchrpc.NewTaprootAssetChannelsClient(
354+
rpcConn,
355+
)
351356
hs.UniverseClient = universerpc.NewUniverseClient(rpcConn)
352357
hs.TapDevClient = tapdevrpc.NewTapDevClient(rpcConn)
353358

itest/test_list_on_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,10 @@ var testCases = []*testCase{
304304
name: "anchor multiple virtual transactions",
305305
test: testAnchorMultipleVirtualTransactions,
306306
},
307+
{
308+
name: "channel RPCs",
309+
test: testChannelRPCs,
310+
},
307311
}
308312

309313
var optionalTestCases = []*testCase{

perms/perms.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@ var (
268268
Entity: "channels",
269269
Action: "write",
270270
}},
271+
"/tapchannelrpc.TaprootAssetChannels/SendPayment": {{
272+
Entity: "channels",
273+
Action: "write",
274+
}},
275+
"/tapchannelrpc.TaprootAssetChannels/AddInvoice": {{
276+
Entity: "channels",
277+
Action: "write",
278+
}},
271279
"/tapchannelrpc.TaprootAssetChannels/EncodeCustomRecords": {
272280
// This RPC is completely stateless and doesn't require
273281
// any permissions to use.

rfq/manager.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ const (
2121
// DefaultTimeout is the default timeout used for context operations.
2222
DefaultTimeout = 30 * time.Second
2323

24+
// DefaultInvoiceExpiry is the default expiry time for asset invoices.
25+
// The current value corresponds to 5 minutes.
26+
DefaultInvoiceExpiry = time.Second * 300
27+
2428
// CacheCleanupInterval is the interval at which local runtime caches
2529
// are cleaned up.
2630
CacheCleanupInterval = 30 * time.Second

0 commit comments

Comments
 (0)