Skip to content

Commit 5f6ad11

Browse files
committed
lndclient: switch to using per-call macaroons instead of a conn level macaroon
In this commit, we modify all sub-servers as well as the main lnd gRPC service to use a macaroon per call rather than a connection level macaroon. The old approach would result in us using the same macaroon for the entire connection, while this new approach allows us to use multiple macaroons with a single connection. We move to this new approach as it doesn't require users to delete their admin macaroon before being able to use Loop. It also preps us for a future where there is no admin macaroon, and we instead need to use a set of macaroons to accomplish our tasks.
1 parent 2c97258 commit 5f6ad11

File tree

6 files changed

+83
-44
lines changed

6 files changed

+83
-44
lines changed

lndclient/chainnotifier_client.go

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,16 @@ type ChainNotifierClient interface {
2828
}
2929

3030
type chainNotifierClient struct {
31-
client chainrpc.ChainNotifierClient
32-
wg sync.WaitGroup
31+
client chainrpc.ChainNotifierClient
32+
chainMac serializedMacaroon
33+
34+
wg sync.WaitGroup
3335
}
3436

35-
func newChainNotifierClient(conn *grpc.ClientConn) *chainNotifierClient {
37+
func newChainNotifierClient(conn *grpc.ClientConn, chainMac serializedMacaroon) *chainNotifierClient {
3638
return &chainNotifierClient{
37-
client: chainrpc.NewChainNotifierClient(conn),
39+
client: chainrpc.NewChainNotifierClient(conn),
40+
chainMac: chainMac,
3841
}
3942
}
4043

@@ -54,7 +57,8 @@ func (s *chainNotifierClient) RegisterSpendNtfn(ctx context.Context,
5457
}
5558
}
5659

57-
resp, err := s.client.RegisterSpendNtfn(ctx, &chainrpc.SpendRequest{
60+
macaroonAuth := s.chainMac.WithMacaroonAuth(ctx)
61+
resp, err := s.client.RegisterSpendNtfn(macaroonAuth, &chainrpc.SpendRequest{
5862
HeightHint: uint32(heightHint),
5963
Outpoint: rpcOutpoint,
6064
Script: pkScript,
@@ -125,16 +129,15 @@ func (s *chainNotifierClient) RegisterConfirmationsNtfn(ctx context.Context,
125129
if txid != nil {
126130
txidSlice = txid[:]
127131
}
128-
confStream, err := s.client.
129-
RegisterConfirmationsNtfn(
130-
ctx,
131-
&chainrpc.ConfRequest{
132-
Script: pkScript,
133-
NumConfs: uint32(numConfs),
134-
HeightHint: uint32(heightHint),
135-
Txid: txidSlice,
136-
},
137-
)
132+
confStream, err := s.client.RegisterConfirmationsNtfn(
133+
s.chainMac.WithMacaroonAuth(ctx),
134+
&chainrpc.ConfRequest{
135+
Script: pkScript,
136+
NumConfs: uint32(numConfs),
137+
HeightHint: uint32(heightHint),
138+
Txid: txidSlice,
139+
},
140+
)
138141
if err != nil {
139142
return nil, nil, err
140143
}
@@ -203,8 +206,9 @@ func (s *chainNotifierClient) RegisterConfirmationsNtfn(ctx context.Context,
203206
func (s *chainNotifierClient) RegisterBlockEpochNtfn(ctx context.Context) (
204207
chan int32, chan error, error) {
205208

206-
blockEpochClient, err := s.client.
207-
RegisterBlockEpochNtfn(ctx, &chainrpc.BlockEpoch{})
209+
blockEpochClient, err := s.client.RegisterBlockEpochNtfn(
210+
s.chainMac.WithMacaroonAuth(ctx), &chainrpc.BlockEpoch{},
211+
)
208212
if err != nil {
209213
return nil, nil, err
210214
}

lndclient/invoices_client.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,15 @@ type InvoiceUpdate struct {
3333
}
3434

3535
type invoicesClient struct {
36-
client invoicesrpc.InvoicesClient
37-
wg sync.WaitGroup
36+
client invoicesrpc.InvoicesClient
37+
invoiceMac serializedMacaroon
38+
wg sync.WaitGroup
3839
}
3940

40-
func newInvoicesClient(conn *grpc.ClientConn) *invoicesClient {
41+
func newInvoicesClient(conn *grpc.ClientConn, invoiceMac serializedMacaroon) *invoicesClient {
4142
return &invoicesClient{
42-
client: invoicesrpc.NewInvoicesClient(conn),
43+
client: invoicesrpc.NewInvoicesClient(conn),
44+
invoiceMac: invoiceMac,
4345
}
4446
}
4547

@@ -53,6 +55,7 @@ func (s *invoicesClient) SettleInvoice(ctx context.Context,
5355
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
5456
defer cancel()
5557

58+
rpcCtx = s.invoiceMac.WithMacaroonAuth(ctx)
5659
_, err := s.client.SettleInvoice(rpcCtx, &invoicesrpc.SettleInvoiceMsg{
5760
Preimage: preimage[:],
5861
})
@@ -66,6 +69,7 @@ func (s *invoicesClient) CancelInvoice(ctx context.Context,
6669
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
6770
defer cancel()
6871

72+
rpcCtx = s.invoiceMac.WithMacaroonAuth(rpcCtx)
6973
_, err := s.client.CancelInvoice(rpcCtx, &invoicesrpc.CancelInvoiceMsg{
7074
PaymentHash: hash[:],
7175
})
@@ -77,11 +81,12 @@ func (s *invoicesClient) SubscribeSingleInvoice(ctx context.Context,
7781
hash lntypes.Hash) (<-chan InvoiceUpdate,
7882
<-chan error, error) {
7983

80-
invoiceStream, err := s.client.
81-
SubscribeSingleInvoice(ctx,
82-
&lnrpc.PaymentHash{
83-
RHash: hash[:],
84-
})
84+
invoiceStream, err := s.client.SubscribeSingleInvoice(
85+
s.invoiceMac.WithMacaroonAuth(ctx),
86+
&lnrpc.PaymentHash{
87+
RHash: hash[:],
88+
},
89+
)
8590
if err != nil {
8691
return nil, nil, err
8792
}
@@ -135,6 +140,7 @@ func (s *invoicesClient) AddHoldInvoice(ctx context.Context,
135140
Private: true,
136141
}
137142

143+
rpcCtx = s.invoiceMac.WithMacaroonAuth(rpcCtx)
138144
resp, err := s.client.AddHoldInvoice(rpcCtx, rpcIn)
139145
if err != nil {
140146
return "", err

lndclient/lightning_client.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,19 @@ var (
7878
)
7979

8080
type lightningClient struct {
81-
client lnrpc.LightningClient
82-
wg sync.WaitGroup
83-
params *chaincfg.Params
81+
client lnrpc.LightningClient
82+
wg sync.WaitGroup
83+
params *chaincfg.Params
84+
adminMac serializedMacaroon
8485
}
8586

8687
func newLightningClient(conn *grpc.ClientConn,
87-
params *chaincfg.Params) *lightningClient {
88+
params *chaincfg.Params, adminMac serializedMacaroon) *lightningClient {
8889

8990
return &lightningClient{
90-
client: lnrpc.NewLightningClient(conn),
91-
params: params,
91+
client: lnrpc.NewLightningClient(conn),
92+
params: params,
93+
adminMac: adminMac,
9294
}
9395
}
9496

@@ -110,6 +112,7 @@ func (s *lightningClient) ConfirmedWalletBalance(ctx context.Context) (
110112
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
111113
defer cancel()
112114

115+
rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx)
113116
resp, err := s.client.WalletBalance(rpcCtx, &lnrpc.WalletBalanceRequest{})
114117
if err != nil {
115118
return 0, err
@@ -122,6 +125,7 @@ func (s *lightningClient) GetInfo(ctx context.Context) (*Info, error) {
122125
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
123126
defer cancel()
124127

128+
rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx)
125129
resp, err := s.client.GetInfo(rpcCtx, &lnrpc.GetInfoRequest{})
126130
if err != nil {
127131
return nil, err
@@ -159,6 +163,7 @@ func (s *lightningClient) EstimateFeeToP2WSH(ctx context.Context,
159163
return 0, err
160164
}
161165

166+
rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx)
162167
resp, err := s.client.EstimateFee(
163168
rpcCtx,
164169
&lnrpc.EstimateFeeRequest{
@@ -216,6 +221,7 @@ func (s *lightningClient) payInvoice(ctx context.Context, invoice string,
216221

217222
hash := lntypes.Hash(*payReq.PaymentHash)
218223

224+
ctx = s.adminMac.WithMacaroonAuth(ctx)
219225
for {
220226
// Create no timeout context as this call can block for a long
221227
// time.
@@ -329,6 +335,7 @@ func (s *lightningClient) AddInvoice(ctx context.Context,
329335
rpcIn.RHash = in.Hash[:]
330336
}
331337

338+
rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx)
332339
resp, err := s.client.AddInvoice(rpcCtx, rpcIn)
333340
if err != nil {
334341
return lntypes.Hash{}, "", err

lndclient/lnd_services.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,17 @@ func NewLndServices(lndAddress, application, network, macaroonDir,
6868
return nil, err
6969
}
7070

71-
lightningClient := newLightningClient(conn, chainParams)
71+
lightningClient := newLightningClient(
72+
conn, chainParams, macaroons.adminMac,
73+
)
7274

75+
// With our macaroons obtained, we'll ensure that the network for lnd
76+
// matches our expected network.
7377
info, err := lightningClient.GetInfo(context.Background())
7478
if err != nil {
7579
conn.Close()
76-
return nil, err
80+
return nil, fmt.Errorf("unable to get info for lnd "+
81+
"node: %v", err)
7782
}
7883
if network != info.Network {
7984
conn.Close()
@@ -82,10 +87,12 @@ func NewLndServices(lndAddress, application, network, macaroonDir,
8287
)
8388
}
8489

85-
notifierClient := newChainNotifierClient(conn)
86-
signerClient := newSignerClient(conn)
87-
walletKitClient := newWalletKitClient(conn)
88-
invoicesClient := newInvoicesClient(conn)
90+
// With the network check passed, we'll now initialize the rest of the
91+
// sub-sever connections, giving each of them their specific macaroon.
92+
notifierClient := newChainNotifierClient(conn, macaroons.chainMac)
93+
signerClient := newSignerClient(conn, macaroons.signerMac)
94+
walletKitClient := newWalletKitClient(conn, macaroons.walletKitMac)
95+
invoicesClient := newInvoicesClient(conn, macaroons.invoiceMac)
8996

9097
cleanup := func() {
9198
logger.Debugf("Closing lnd connection")

lndclient/signer_client.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ type SignerClient interface {
1717
}
1818

1919
type signerClient struct {
20-
client signrpc.SignerClient
20+
client signrpc.SignerClient
21+
signerMac serializedMacaroon
2122
}
2223

23-
func newSignerClient(conn *grpc.ClientConn) *signerClient {
24+
func newSignerClient(conn *grpc.ClientConn,
25+
signerMac serializedMacaroon) *signerClient {
26+
2427
return &signerClient{
25-
client: signrpc.NewSignerClient(conn),
28+
client: signrpc.NewSignerClient(conn),
29+
signerMac: signerMac,
2630
}
2731
}
2832

@@ -76,6 +80,7 @@ func (s *signerClient) SignOutputRaw(ctx context.Context, tx *wire.MsgTx,
7680
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
7781
defer cancel()
7882

83+
rpcCtx = s.signerMac.WithMacaroonAuth(rpcCtx)
7984
resp, err := s.client.SignOutputRaw(rpcCtx,
8085
&signrpc.SignReq{
8186
RawTxBytes: txRaw,

lndclient/walletkit_client.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,16 @@ type WalletKitClient interface {
3434
}
3535

3636
type walletKitClient struct {
37-
client walletrpc.WalletKitClient
37+
client walletrpc.WalletKitClient
38+
walletKitMac serializedMacaroon
3839
}
3940

40-
func newWalletKitClient(conn *grpc.ClientConn) *walletKitClient {
41+
func newWalletKitClient(conn *grpc.ClientConn,
42+
walletKitMac serializedMacaroon) *walletKitClient {
43+
4144
return &walletKitClient{
42-
client: walletrpc.NewWalletKitClient(conn),
45+
client: walletrpc.NewWalletKitClient(conn),
46+
walletKitMac: walletKitMac,
4347
}
4448
}
4549

@@ -49,6 +53,7 @@ func (m *walletKitClient) DeriveNextKey(ctx context.Context, family int32) (
4953
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
5054
defer cancel()
5155

56+
rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx)
5257
resp, err := m.client.DeriveNextKey(rpcCtx, &walletrpc.KeyReq{
5358
KeyFamily: family,
5459
})
@@ -76,6 +81,7 @@ func (m *walletKitClient) DeriveKey(ctx context.Context, in *keychain.KeyLocator
7681
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
7782
defer cancel()
7883

84+
rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx)
7985
resp, err := m.client.DeriveKey(rpcCtx, &signrpc.KeyLocator{
8086
KeyFamily: int32(in.Family),
8187
KeyIndex: int32(in.Index),
@@ -101,6 +107,7 @@ func (m *walletKitClient) NextAddr(ctx context.Context) (
101107
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
102108
defer cancel()
103109

110+
rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx)
104111
resp, err := m.client.NextAddr(rpcCtx, &walletrpc.AddrRequest{})
105112
if err != nil {
106113
return nil, err
@@ -125,6 +132,7 @@ func (m *walletKitClient) PublishTransaction(ctx context.Context,
125132
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
126133
defer cancel()
127134

135+
rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx)
128136
_, err = m.client.PublishTransaction(rpcCtx, &walletrpc.Transaction{
129137
TxHex: txHex,
130138
})
@@ -147,6 +155,7 @@ func (m *walletKitClient) SendOutputs(ctx context.Context,
147155
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
148156
defer cancel()
149157

158+
rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx)
150159
resp, err := m.client.SendOutputs(rpcCtx, &walletrpc.SendOutputsRequest{
151160
Outputs: rpcOutputs,
152161
SatPerKw: int64(feeRate),
@@ -169,6 +178,7 @@ func (m *walletKitClient) EstimateFee(ctx context.Context, confTarget int32) (
169178
rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout)
170179
defer cancel()
171180

181+
rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx)
172182
resp, err := m.client.EstimateFee(rpcCtx, &walletrpc.EstimateFeeRequest{
173183
ConfTarget: int32(confTarget),
174184
})

0 commit comments

Comments
 (0)