Skip to content

Commit

Permalink
multi: add RawClientWithMacAuth to every client
Browse files Browse the repository at this point in the history
  • Loading branch information
guggero committed Sep 19, 2024
1 parent 8014a45 commit 88faa4e
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 3 deletions.
15 changes: 15 additions & 0 deletions chainkit_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (

// ChainKitClient exposes chain functionality.
type ChainKitClient interface {
ServiceClient[chainrpc.ChainKitClient]

// GetBlock returns a block given the corresponding block hash.
GetBlock(ctx context.Context, hash chainhash.Hash) (*wire.MsgBlock,
error)
Expand Down Expand Up @@ -41,6 +43,10 @@ type chainKitClient struct {
wg sync.WaitGroup
}

// A compile time check to ensure that chainKitClient implements the
// ChainKitClient interface.
var _ ChainKitClient = (*chainKitClient)(nil)

func newChainKitClient(conn grpc.ClientConnInterface,
chainMac serializedMacaroon, timeout time.Duration) *chainKitClient {

Expand All @@ -55,6 +61,15 @@ func (s *chainKitClient) WaitForFinished() {
s.wg.Wait()
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (s *chainKitClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
chainrpc.ChainKitClient) {

return s.chainMac.WithMacaroonAuth(parentCtx), s.timeout, s.client
}

// GetBlock returns a block given the corresponding block hash.
func (s *chainKitClient) GetBlock(ctxParent context.Context,
hash chainhash.Hash) (*wire.MsgBlock, error) {
Expand Down
15 changes: 15 additions & 0 deletions chainnotifier_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ func WithReOrgChan(reOrgChan chan struct{}) NotifierOption {

// ChainNotifierClient exposes base lightning functionality.
type ChainNotifierClient interface {
ServiceClient[chainrpc.ChainNotifierClient]

RegisterBlockEpochNtfn(ctx context.Context) (
chan int32, chan error, error)

Expand All @@ -81,6 +83,10 @@ type chainNotifierClient struct {
wg sync.WaitGroup
}

// A compile time check to ensure that chainNotifierClient implements the
// ChainNotifierClient interface.
var _ ChainNotifierClient = (*chainNotifierClient)(nil)

func newChainNotifierClient(conn grpc.ClientConnInterface,
chainMac serializedMacaroon, timeout time.Duration) *chainNotifierClient {

Expand All @@ -95,6 +101,15 @@ func (s *chainNotifierClient) WaitForFinished() {
s.wg.Wait()
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (s *chainNotifierClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
chainrpc.ChainNotifierClient) {

return s.chainMac.WithMacaroonAuth(parentCtx), s.timeout, s.client
}

func (s *chainNotifierClient) RegisterSpendNtfn(ctx context.Context,
outpoint *wire.OutPoint, pkScript []byte, heightHint int32) (
chan *chainntnfs.SpendDetail, chan error, error) {
Expand Down
15 changes: 15 additions & 0 deletions invoices_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type InvoiceHtlcModifyHandler func(context.Context,

// InvoicesClient exposes invoice functionality.
type InvoicesClient interface {
ServiceClient[invoicesrpc.InvoicesClient]

SubscribeSingleInvoice(ctx context.Context, hash lntypes.Hash) (
<-chan InvoiceUpdate, <-chan error, error)

Expand Down Expand Up @@ -97,6 +99,10 @@ type invoicesClient struct {
wg sync.WaitGroup
}

// A compile time check to ensure that invoicesClient implements the
// InvoicesClient interface.
var _ InvoicesClient = (*invoicesClient)(nil)

func newInvoicesClient(conn grpc.ClientConnInterface,
invoiceMac serializedMacaroon, timeout time.Duration) *invoicesClient {

Expand All @@ -116,6 +122,15 @@ func (s *invoicesClient) WaitForFinished() {
s.wg.Wait()
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (s *invoicesClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
invoicesrpc.InvoicesClient) {

return s.invoiceMac.WithMacaroonAuth(parentCtx), s.timeout, s.client
}

func (s *invoicesClient) SettleInvoice(ctx context.Context,
preimage lntypes.Preimage) error {

Expand Down
15 changes: 15 additions & 0 deletions lightning_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ func WithRemoteReserve(reserve uint64) OpenChannelOption {

// LightningClient exposes base lightning functionality.
type LightningClient interface {
ServiceClient[lnrpc.LightningClient]

PayInvoice(ctx context.Context, invoice string,
maxFee btcutil.Amount,
outgoingChannel *uint64) chan PaymentResult
Expand Down Expand Up @@ -1323,6 +1325,10 @@ type lightningClient struct {
adminMac serializedMacaroon
}

// A compile time check to ensure that lightningClient implements the
// LightningClient interface.
var _ LightningClient = (*lightningClient)(nil)

func newLightningClient(conn grpc.ClientConnInterface, timeout time.Duration,
params *chaincfg.Params, adminMac serializedMacaroon) *lightningClient {

Expand All @@ -1346,6 +1352,15 @@ func (s *lightningClient) WaitForFinished() {
s.wg.Wait()
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (s *lightningClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
lnrpc.LightningClient) {

return s.adminMac.WithMacaroonAuth(parentCtx), s.timeout, s.client
}

// WalletBalance returns a summary of the node's wallet balance.
func (s *lightningClient) WalletBalance(ctx context.Context) (
*WalletBalance, error) {
Expand Down
8 changes: 8 additions & 0 deletions lnd_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ var (
}
)

// ServiceClient is an interface that all lnd service clients need to implement.
type ServiceClient[T any] interface {
// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
RawClientWithMacAuth(parentCtx context.Context) (context.Context,
time.Duration, T)
}

// LndServicesConfig holds all configuration settings that are needed to connect
// to an lnd node.
type LndServicesConfig struct {
Expand Down
10 changes: 10 additions & 0 deletions lnd_services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"testing"
"time"

"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/verrpc"
Expand All @@ -18,6 +19,15 @@ type mockVersioner struct {
err error
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (m *mockVersioner) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
verrpc.VersionerClient) {

return parentCtx, 0, nil
}

func (m *mockVersioner) GetVersion(_ context.Context) (*verrpc.Version, error) {
return m.version, m.err
}
Expand Down
11 changes: 11 additions & 0 deletions macaroon_recipes.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"reflect"
"slices"
"strings"
)

Expand Down Expand Up @@ -43,6 +44,12 @@ var (
"OpenChannelStream": "OpenChannel",
"ListSweepsVerbose": "ListSweeps",
}

// ignores is a list of method names on the client implementations that
// we don't need to check macaroon permissions for.
ignores = []string{
"RawClientWithMacAuth",
}
)

// MacaroonRecipe returns a list of macaroon permissions that is required to use
Expand Down Expand Up @@ -79,6 +86,10 @@ func MacaroonRecipe(c LightningClient, packages []string) ([]MacaroonPermission,
methodName = rename
}

if slices.Contains(ignores, methodName) {
continue
}

// The full RPC URI is /package.Service/MethodName.
rpcURI := fmt.Sprintf(
"/%s.%s/%s", pkg, serverName, methodName,
Expand Down
15 changes: 15 additions & 0 deletions router_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ var ErrRouterShuttingDown = errors.New("router shutting down")

// RouterClient exposes payment functionality.
type RouterClient interface {
ServiceClient[routerrpc.RouterClient]

// SendPayment attempts to route a payment to the final destination. The
// call returns a payment update stream and an error stream.
SendPayment(ctx context.Context, request SendPaymentRequest) (
Expand Down Expand Up @@ -405,6 +407,10 @@ type routerClient struct {
wg sync.WaitGroup
}

// A compile time check to ensure that routerClient implements the RouterClient
// interface.
var _ RouterClient = (*routerClient)(nil)

func newRouterClient(conn grpc.ClientConnInterface,
routerKitMac serializedMacaroon, timeout time.Duration) *routerClient {

Expand All @@ -426,6 +432,15 @@ func (r *routerClient) WaitForFinished() {
r.wg.Wait()
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (r *routerClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
routerrpc.RouterClient) {

return r.routerKitMac.WithMacaroonAuth(parentCtx), r.timeout, r.client
}

// SendPayment attempts to route a payment to the final destination. The call
// returns a payment update stream and an error stream.
func (r *routerClient) SendPayment(ctx context.Context,
Expand Down
15 changes: 15 additions & 0 deletions signer_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (

// SignerClient exposes sign functionality.
type SignerClient interface {
ServiceClient[signrpc.SignerClient]

// SignOutputRaw is a method that can be used to generate a signature
// for a set of inputs/outputs to a transaction. Each request specifies
// details concerning how the outputs should be signed, which keys they
Expand Down Expand Up @@ -190,6 +192,10 @@ type signerClient struct {
timeout time.Duration
}

// A compile time check to ensure that signerClient implements the SignerClient
// interface.
var _ SignerClient = (*signerClient)(nil)

func newSignerClient(conn grpc.ClientConnInterface,
signerMac serializedMacaroon, timeout time.Duration) *signerClient {

Expand All @@ -200,6 +206,15 @@ func newSignerClient(conn grpc.ClientConnInterface,
}
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (s *signerClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
signrpc.SignerClient) {

return s.signerMac.WithMacaroonAuth(parentCtx), s.timeout, s.client
}

func marshallSignDescriptors(
signDescriptors []*SignDescriptor) []*signrpc.SignDescriptor {

Expand Down
15 changes: 15 additions & 0 deletions state_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (

// StateClient exposes base lightning functionality.
type StateClient interface {
ServiceClient[lnrpc.StateClient]

// SubscribeState subscribes to the current state of the wallet.
SubscribeState(ctx context.Context) (chan WalletState, chan error,
error)
Expand Down Expand Up @@ -96,6 +98,10 @@ type stateClient struct {
wg sync.WaitGroup
}

// A compile time check to ensure that stateClient implements the StateClient
// interface.
var _ StateClient = (*stateClient)(nil)

// newStateClient returns a new stateClient.
func newStateClient(conn grpc.ClientConnInterface,
readonlyMac serializedMacaroon, timeout time.Duration) *stateClient {
Expand All @@ -112,6 +118,15 @@ func (s *stateClient) WaitForFinished() {
s.wg.Wait()
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (s *stateClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
lnrpc.StateClient) {

return s.readonlyMac.WithMacaroonAuth(parentCtx), s.timeout, s.client
}

// SubscribeState subscribes to the current state of the wallet.
func (s *stateClient) SubscribeState(ctx context.Context) (chan WalletState,
chan error, error) {
Expand Down
19 changes: 17 additions & 2 deletions versioner_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (

// VersionerClient exposes the version of lnd.
type VersionerClient interface {
ServiceClient[verrpc.VersionerClient]

// GetVersion returns the version and build information of the lnd
// daemon.
GetVersion(ctx context.Context) (*verrpc.Version, error)
Expand All @@ -23,6 +25,10 @@ type versionerClient struct {
timeout time.Duration
}

// A compile time check to ensure that versionerClient implements the
// VersionerClient interface.
var _ VersionerClient = (*versionerClient)(nil)

func newVersionerClient(conn grpc.ClientConnInterface,
readonlyMac serializedMacaroon, timeout time.Duration) *versionerClient {

Expand All @@ -33,6 +39,15 @@ func newVersionerClient(conn grpc.ClientConnInterface,
}
}

// RawClientWithMacAuth returns a context with the proper macaroon
// authentication, the default RPC timeout, and the raw client.
func (v *versionerClient) RawClientWithMacAuth(
parentCtx context.Context) (context.Context, time.Duration,
verrpc.VersionerClient) {

return v.readonlyMac.WithMacaroonAuth(parentCtx), v.timeout, v.client
}

// GetVersion returns the version and build information of the lnd
// daemon.
//
Expand All @@ -47,15 +62,15 @@ func (v *versionerClient) GetVersion(ctx context.Context) (*verrpc.Version,
return v.client.GetVersion(rpcCtx, &verrpc.VersionRequest{})
}

// VersionString returns a nice, human readable string of a version returned by
// VersionString returns a nice, human-readable string of a version returned by
// the VersionerClient, including all build tags.
func VersionString(version *verrpc.Version) string {
short := VersionStringShort(version)
enabledTags := strings.Join(version.BuildTags, ",")
return fmt.Sprintf("%s, build tags '%s'", short, enabledTags)
}

// VersionStringShort returns a nice, human readable string of a version
// VersionStringShort returns a nice, human-readable string of a version
// returned by the VersionerClient.
func VersionStringShort(version *verrpc.Version) string {
versionStr := fmt.Sprintf(
Expand Down
Loading

0 comments on commit 88faa4e

Please sign in to comment.