Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RawClientWithMacAuth to each client #190

Merged
merged 2 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -41,6 +41,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 @@ -75,6 +77,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 @@ -94,6 +100,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
16 changes: 15 additions & 1 deletion lightning_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ func WithRemoteReserve(reserve uint64) OpenChannelOption {
return func(r *lnrpc.OpenChannelRequest) {
r.RemoteChanReserveSat = reserve
}

}

// 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 @@ -1321,6 +1322,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 @@ -1344,6 +1349,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
10 changes: 9 additions & 1 deletion 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 Expand Up @@ -307,7 +315,7 @@ func NewLndServices(cfg *LndServicesConfig) (*GrpcLndServices, error) {
}

basicClient := lnrpc.NewLightningClient(conn)
stateClient := newStateClient(conn, readonlyMac)
stateClient := newStateClient(conn, readonlyMac, timeout)
versionerClient := newVersionerClient(conn, readonlyMac, timeout)

cleanupConn := func() {
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 @@ -401,6 +403,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 @@ -422,6 +428,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
20 changes: 19 additions & 1 deletion state_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import (
"context"
"fmt"
"sync"
"time"

"github.com/lightningnetwork/lnd/lnrpc"
"google.golang.org/grpc"
)

// 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 @@ -90,17 +93,23 @@ func (s WalletState) ReadyForGetInfo() bool {
type stateClient struct {
client lnrpc.StateClient
readonlyMac serializedMacaroon
timeout time.Duration

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) *stateClient {
readonlyMac serializedMacaroon, timeout time.Duration) *stateClient {

return &stateClient{
client: lnrpc.NewStateClient(conn),
readonlyMac: readonlyMac,
timeout: timeout,
}
}

Expand All @@ -109,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
Loading
Loading