From ee6191f8448f41880ff4bec351bdfa8ba5f6e8b2 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 16 Apr 2019 19:11:34 -0700 Subject: [PATCH 1/6] lndclient: add new macaroonPouch struct In this commit, we add a new struct, the `macaroonPouch`. This struct bundles all the macaroons we need for each sub-server. Along the way, we also export the set of default* paths for lnd, and add a new set of variables that store the default file names of each of the macaroons for each sub-server. The `WithMacaroonAuth` method on the `serializedMacaroon` type will allow us to attach a macaroon for each call rather than attaching it at the connection level. This slight change will allow us to use multiple macaroons over a single RPC connection, rather than a single global macaroon. --- lndclient/lnd_services.go | 18 ++++--- lndclient/macaroon_pouch.go | 98 +++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 lndclient/macaroon_pouch.go diff --git a/lndclient/lnd_services.go b/lndclient/lnd_services.go index 3d3bb54..75e5388 100644 --- a/lndclient/lnd_services.go +++ b/lndclient/lnd_services.go @@ -122,11 +122,17 @@ var ( defaultRPCPort = "10009" defaultLndDir = btcutil.AppDataDir("lnd", false) defaultTLSCertFilename = "tls.cert" - defaultTLSCertPath = filepath.Join(defaultLndDir, - defaultTLSCertFilename) - defaultDataDir = "data" - defaultChainSubDir = "chain" - defaultMacaroonFilename = "admin.macaroon" + defaultTLSCertPath = filepath.Join( + defaultLndDir, defaultTLSCertFilename, + ) + defaultDataDir = "data" + defaultChainSubDir = "chain" + + defaultAdminMacaroonFilename = "admin.macaroon" + defaultInvoiceMacaroonFilename = "invoices.macaroon" + defaultChainMacaroonFilename = "chainnotifier.macaroon" + defaultWalletKitMacaroonFilename = "walletkit.macaroon" + defaultSignerFilename = "signer.macaroon" ) func getClientConn(address string, network string, macPath, tlsPath string) ( @@ -151,7 +157,7 @@ func getClientConn(address string, network string, macPath, tlsPath string) ( if macPath == "" { macPath = filepath.Join( defaultLndDir, defaultDataDir, defaultChainSubDir, - "bitcoin", network, defaultMacaroonFilename, + "bitcoin", network, defaultAdminMacaroonFilename, ) } diff --git a/lndclient/macaroon_pouch.go b/lndclient/macaroon_pouch.go new file mode 100644 index 0000000..350224b --- /dev/null +++ b/lndclient/macaroon_pouch.go @@ -0,0 +1,98 @@ +package lndclient + +import ( + "context" + "encoding/hex" + "io/ioutil" + "path/filepath" + + "google.golang.org/grpc/metadata" +) + +// serializedMacaroon is a type that represents a hex-encoded macaroon. We'll +// use this primarily vs the raw binary format as the gRPC metadata feature +// requires that all keys and values be strings. +type serializedMacaroon string + +// newSerializedMacaroon reads a new serializedMacaroon from that target +// macaroon path. If the file can't be found, then an error is returned. +func newSerializedMacaroon(macaroonPath string) (serializedMacaroon, error) { + macBytes, err := ioutil.ReadFile(macaroonPath) + if err != nil { + return "", err + } + + return serializedMacaroon(hex.EncodeToString(macBytes)), nil +} + +// WithMacaroonAuth modifies the passed context to include the macaroon KV +// metadata of the target macaroon. This method can be used to add the macaroon +// at call time, rather than when the connection to the gRPC server is created. +func (s serializedMacaroon) WithMacaroonAuth(ctx context.Context) context.Context { + return metadata.AppendToOutgoingContext(ctx, "macaroon", string(s)) +} + +// macaroonPouch holds the set of macaroons we need to interact with lnd for +// Loop. Each sub-server has its own macaroon, and for the remaining temporary +// calls that directly hit lnd, we'll use the admin macaroon. +type macaroonPouch struct { + // invoiceMac is the macaroon for the invoices sub-server. + invoiceMac serializedMacaroon + + // chainMac is the macaroon for the ChainNotifier sub-server. + chainMac serializedMacaroon + + // signerMac is the macaroon for the Signer sub-server. + signerMac serializedMacaroon + + // walletKitMac is the macaroon for the WalletKit sub-server. + walletKitMac serializedMacaroon + + // adminMac is the primary admin macaroon for lnd. + adminMac serializedMacaroon +} + +// newMacaroonPouch returns a new instance of a fully populated macaroonPouch +// given the directory where all the macaroons are stored. +func newMacaroonPouch(macaroonDir string) (*macaroonPouch, error) { + m := &macaroonPouch{} + + var err error + + m.invoiceMac, err = newSerializedMacaroon( + filepath.Join(macaroonDir, defaultInvoiceMacaroonFilename), + ) + if err != nil { + return nil, err + } + + m.chainMac, err = newSerializedMacaroon( + filepath.Join(macaroonDir, defaultChainMacaroonFilename), + ) + if err != nil { + return nil, err + } + + m.signerMac, err = newSerializedMacaroon( + filepath.Join(macaroonDir, defaultSignerFilename), + ) + if err != nil { + return nil, err + } + + m.walletKitMac, err = newSerializedMacaroon( + filepath.Join(macaroonDir, defaultWalletKitMacaroonFilename), + ) + if err != nil { + return nil, err + } + + m.adminMac, err = newSerializedMacaroon( + filepath.Join(macaroonDir, defaultAdminMacaroonFilename), + ) + if err != nil { + return nil, err + } + + return m, nil +} From 2c97258ce71f08b6ccec10e4a02522d367a91fd7 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 16 Apr 2019 19:15:10 -0700 Subject: [PATCH 2/6] lndclient: NewLndServices now accepts a macaroon directory, not admin mac path In this commit, we modify the `NewLndServices` method to accept the directory where macaroons are stored, rather than the path for the admin macaroon. This is a prep to moving towards a multi-macaroon system, as the `macaroonPouch` will handle storing the various macaroons. --- lndclient/lnd_services.go | 51 +++++++++++++++------------------------ 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/lndclient/lnd_services.go b/lndclient/lnd_services.go index 75e5388..2249d67 100644 --- a/lndclient/lnd_services.go +++ b/lndclient/lnd_services.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "path/filepath" "time" @@ -12,11 +11,8 @@ import ( "github.com/btcsuite/btcutil" "github.com/lightninglabs/loop/swap" "github.com/lightningnetwork/lnd/lncfg" - "github.com/lightningnetwork/lnd/macaroons" "google.golang.org/grpc" "google.golang.org/grpc/credentials" - - macaroon "gopkg.in/macaroon.v2" ) var rpcTimeout = 30 * time.Second @@ -30,6 +26,8 @@ type LndServices struct { Invoices InvoicesClient ChainParams *chaincfg.Params + + macaroons *macaroonPouch } // GrpcLndServices constitutes a set of required RPC services. @@ -40,13 +38,25 @@ type GrpcLndServices struct { } // NewLndServices creates a set of required RPC services. -func NewLndServices(lndAddress string, application string, - network string, macPath, tlsPath string) ( - *GrpcLndServices, error) { +func NewLndServices(lndAddress, application, network, macaroonDir, + tlsPath string) (*GrpcLndServices, error) { + + // If the macaroon directory isn't set, then we can't proceed as we + // need then to obtain the macaroons for all sub-servers. + if macaroonDir == "" { + return nil, fmt.Errorf("macarooon dir must be set") + } + + // Now that we've ensured our macaroon directory is set properly, we + // can retrieve our full macaroon pouch from the directory. + macaroons, err := newMacaroonPouch(macaroonDir) + if err != nil { + return nil, fmt.Errorf("unable to obtain macaroons: %v", err) + } // Setup connection with lnd logger.Infof("Creating lnd connection to %v", lndAddress) - conn, err := getClientConn(lndAddress, network, macPath, tlsPath) + conn, err := getClientConn(lndAddress, network, tlsPath) if err != nil { return nil, err } @@ -101,6 +111,7 @@ func NewLndServices(lndAddress string, application string, Signer: signerClient, Invoices: invoicesClient, ChainParams: chainParams, + macaroons: macaroons, }, cleanup: cleanup, } @@ -135,7 +146,7 @@ var ( defaultSignerFilename = "signer.macaroon" ) -func getClientConn(address string, network string, macPath, tlsPath string) ( +func getClientConn(address string, network string, tlsPath string) ( *grpc.ClientConn, error) { // Load the specified TLS certificate and build transport credentials @@ -154,28 +165,6 @@ func getClientConn(address string, network string, macPath, tlsPath string) ( grpc.WithTransportCredentials(creds), } - if macPath == "" { - macPath = filepath.Join( - defaultLndDir, defaultDataDir, defaultChainSubDir, - "bitcoin", network, defaultAdminMacaroonFilename, - ) - } - - // Load the specified macaroon file. - macBytes, err := ioutil.ReadFile(macPath) - if err == nil { - // Only if file is found - mac := &macaroon.Macaroon{} - if err = mac.UnmarshalBinary(macBytes); err != nil { - return nil, fmt.Errorf("unable to decode macaroon: %v", - err) - } - - // Now we append the macaroon credentials to the dial options. - cred := macaroons.NewMacaroonCredential(mac) - opts = append(opts, grpc.WithPerRPCCredentials(cred)) - } - // We need to use a custom dialer so we can also connect to unix sockets // and not just TCP addresses. opts = append( From 5f6ad1161b7efeb1f1e5407b03dec35a9688212e Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 16 Apr 2019 19:17:19 -0700 Subject: [PATCH 3/6] 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. --- lndclient/chainnotifier_client.go | 38 +++++++++++++++++-------------- lndclient/invoices_client.go | 24 +++++++++++-------- lndclient/lightning_client.go | 19 +++++++++++----- lndclient/lnd_services.go | 19 +++++++++++----- lndclient/signer_client.go | 11 ++++++--- lndclient/walletkit_client.go | 16 ++++++++++--- 6 files changed, 83 insertions(+), 44 deletions(-) diff --git a/lndclient/chainnotifier_client.go b/lndclient/chainnotifier_client.go index 319788e..c48a2ed 100644 --- a/lndclient/chainnotifier_client.go +++ b/lndclient/chainnotifier_client.go @@ -28,13 +28,16 @@ type ChainNotifierClient interface { } type chainNotifierClient struct { - client chainrpc.ChainNotifierClient - wg sync.WaitGroup + client chainrpc.ChainNotifierClient + chainMac serializedMacaroon + + wg sync.WaitGroup } -func newChainNotifierClient(conn *grpc.ClientConn) *chainNotifierClient { +func newChainNotifierClient(conn *grpc.ClientConn, chainMac serializedMacaroon) *chainNotifierClient { return &chainNotifierClient{ - client: chainrpc.NewChainNotifierClient(conn), + client: chainrpc.NewChainNotifierClient(conn), + chainMac: chainMac, } } @@ -54,7 +57,8 @@ func (s *chainNotifierClient) RegisterSpendNtfn(ctx context.Context, } } - resp, err := s.client.RegisterSpendNtfn(ctx, &chainrpc.SpendRequest{ + macaroonAuth := s.chainMac.WithMacaroonAuth(ctx) + resp, err := s.client.RegisterSpendNtfn(macaroonAuth, &chainrpc.SpendRequest{ HeightHint: uint32(heightHint), Outpoint: rpcOutpoint, Script: pkScript, @@ -125,16 +129,15 @@ func (s *chainNotifierClient) RegisterConfirmationsNtfn(ctx context.Context, if txid != nil { txidSlice = txid[:] } - confStream, err := s.client. - RegisterConfirmationsNtfn( - ctx, - &chainrpc.ConfRequest{ - Script: pkScript, - NumConfs: uint32(numConfs), - HeightHint: uint32(heightHint), - Txid: txidSlice, - }, - ) + confStream, err := s.client.RegisterConfirmationsNtfn( + s.chainMac.WithMacaroonAuth(ctx), + &chainrpc.ConfRequest{ + Script: pkScript, + NumConfs: uint32(numConfs), + HeightHint: uint32(heightHint), + Txid: txidSlice, + }, + ) if err != nil { return nil, nil, err } @@ -203,8 +206,9 @@ func (s *chainNotifierClient) RegisterConfirmationsNtfn(ctx context.Context, func (s *chainNotifierClient) RegisterBlockEpochNtfn(ctx context.Context) ( chan int32, chan error, error) { - blockEpochClient, err := s.client. - RegisterBlockEpochNtfn(ctx, &chainrpc.BlockEpoch{}) + blockEpochClient, err := s.client.RegisterBlockEpochNtfn( + s.chainMac.WithMacaroonAuth(ctx), &chainrpc.BlockEpoch{}, + ) if err != nil { return nil, nil, err } diff --git a/lndclient/invoices_client.go b/lndclient/invoices_client.go index 5e92138..60663ba 100644 --- a/lndclient/invoices_client.go +++ b/lndclient/invoices_client.go @@ -33,13 +33,15 @@ type InvoiceUpdate struct { } type invoicesClient struct { - client invoicesrpc.InvoicesClient - wg sync.WaitGroup + client invoicesrpc.InvoicesClient + invoiceMac serializedMacaroon + wg sync.WaitGroup } -func newInvoicesClient(conn *grpc.ClientConn) *invoicesClient { +func newInvoicesClient(conn *grpc.ClientConn, invoiceMac serializedMacaroon) *invoicesClient { return &invoicesClient{ - client: invoicesrpc.NewInvoicesClient(conn), + client: invoicesrpc.NewInvoicesClient(conn), + invoiceMac: invoiceMac, } } @@ -53,6 +55,7 @@ func (s *invoicesClient) SettleInvoice(ctx context.Context, rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = s.invoiceMac.WithMacaroonAuth(ctx) _, err := s.client.SettleInvoice(rpcCtx, &invoicesrpc.SettleInvoiceMsg{ Preimage: preimage[:], }) @@ -66,6 +69,7 @@ func (s *invoicesClient) CancelInvoice(ctx context.Context, rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = s.invoiceMac.WithMacaroonAuth(rpcCtx) _, err := s.client.CancelInvoice(rpcCtx, &invoicesrpc.CancelInvoiceMsg{ PaymentHash: hash[:], }) @@ -77,11 +81,12 @@ func (s *invoicesClient) SubscribeSingleInvoice(ctx context.Context, hash lntypes.Hash) (<-chan InvoiceUpdate, <-chan error, error) { - invoiceStream, err := s.client. - SubscribeSingleInvoice(ctx, - &lnrpc.PaymentHash{ - RHash: hash[:], - }) + invoiceStream, err := s.client.SubscribeSingleInvoice( + s.invoiceMac.WithMacaroonAuth(ctx), + &lnrpc.PaymentHash{ + RHash: hash[:], + }, + ) if err != nil { return nil, nil, err } @@ -135,6 +140,7 @@ func (s *invoicesClient) AddHoldInvoice(ctx context.Context, Private: true, } + rpcCtx = s.invoiceMac.WithMacaroonAuth(rpcCtx) resp, err := s.client.AddHoldInvoice(rpcCtx, rpcIn) if err != nil { return "", err diff --git a/lndclient/lightning_client.go b/lndclient/lightning_client.go index d74c538..23d7456 100644 --- a/lndclient/lightning_client.go +++ b/lndclient/lightning_client.go @@ -78,17 +78,19 @@ var ( ) type lightningClient struct { - client lnrpc.LightningClient - wg sync.WaitGroup - params *chaincfg.Params + client lnrpc.LightningClient + wg sync.WaitGroup + params *chaincfg.Params + adminMac serializedMacaroon } func newLightningClient(conn *grpc.ClientConn, - params *chaincfg.Params) *lightningClient { + params *chaincfg.Params, adminMac serializedMacaroon) *lightningClient { return &lightningClient{ - client: lnrpc.NewLightningClient(conn), - params: params, + client: lnrpc.NewLightningClient(conn), + params: params, + adminMac: adminMac, } } @@ -110,6 +112,7 @@ func (s *lightningClient) ConfirmedWalletBalance(ctx context.Context) ( rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx) resp, err := s.client.WalletBalance(rpcCtx, &lnrpc.WalletBalanceRequest{}) if err != nil { return 0, err @@ -122,6 +125,7 @@ func (s *lightningClient) GetInfo(ctx context.Context) (*Info, error) { rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx) resp, err := s.client.GetInfo(rpcCtx, &lnrpc.GetInfoRequest{}) if err != nil { return nil, err @@ -159,6 +163,7 @@ func (s *lightningClient) EstimateFeeToP2WSH(ctx context.Context, return 0, err } + rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx) resp, err := s.client.EstimateFee( rpcCtx, &lnrpc.EstimateFeeRequest{ @@ -216,6 +221,7 @@ func (s *lightningClient) payInvoice(ctx context.Context, invoice string, hash := lntypes.Hash(*payReq.PaymentHash) + ctx = s.adminMac.WithMacaroonAuth(ctx) for { // Create no timeout context as this call can block for a long // time. @@ -329,6 +335,7 @@ func (s *lightningClient) AddInvoice(ctx context.Context, rpcIn.RHash = in.Hash[:] } + rpcCtx = s.adminMac.WithMacaroonAuth(rpcCtx) resp, err := s.client.AddInvoice(rpcCtx, rpcIn) if err != nil { return lntypes.Hash{}, "", err diff --git a/lndclient/lnd_services.go b/lndclient/lnd_services.go index 2249d67..8350d6f 100644 --- a/lndclient/lnd_services.go +++ b/lndclient/lnd_services.go @@ -68,12 +68,17 @@ func NewLndServices(lndAddress, application, network, macaroonDir, return nil, err } - lightningClient := newLightningClient(conn, chainParams) + lightningClient := newLightningClient( + conn, chainParams, macaroons.adminMac, + ) + // With our macaroons obtained, we'll ensure that the network for lnd + // matches our expected network. info, err := lightningClient.GetInfo(context.Background()) if err != nil { conn.Close() - return nil, err + return nil, fmt.Errorf("unable to get info for lnd "+ + "node: %v", err) } if network != info.Network { conn.Close() @@ -82,10 +87,12 @@ func NewLndServices(lndAddress, application, network, macaroonDir, ) } - notifierClient := newChainNotifierClient(conn) - signerClient := newSignerClient(conn) - walletKitClient := newWalletKitClient(conn) - invoicesClient := newInvoicesClient(conn) + // With the network check passed, we'll now initialize the rest of the + // sub-sever connections, giving each of them their specific macaroon. + notifierClient := newChainNotifierClient(conn, macaroons.chainMac) + signerClient := newSignerClient(conn, macaroons.signerMac) + walletKitClient := newWalletKitClient(conn, macaroons.walletKitMac) + invoicesClient := newInvoicesClient(conn, macaroons.invoiceMac) cleanup := func() { logger.Debugf("Closing lnd connection") diff --git a/lndclient/signer_client.go b/lndclient/signer_client.go index e9397ba..a5cad28 100644 --- a/lndclient/signer_client.go +++ b/lndclient/signer_client.go @@ -17,12 +17,16 @@ type SignerClient interface { } type signerClient struct { - client signrpc.SignerClient + client signrpc.SignerClient + signerMac serializedMacaroon } -func newSignerClient(conn *grpc.ClientConn) *signerClient { +func newSignerClient(conn *grpc.ClientConn, + signerMac serializedMacaroon) *signerClient { + return &signerClient{ - client: signrpc.NewSignerClient(conn), + client: signrpc.NewSignerClient(conn), + signerMac: signerMac, } } @@ -76,6 +80,7 @@ func (s *signerClient) SignOutputRaw(ctx context.Context, tx *wire.MsgTx, rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = s.signerMac.WithMacaroonAuth(rpcCtx) resp, err := s.client.SignOutputRaw(rpcCtx, &signrpc.SignReq{ RawTxBytes: txRaw, diff --git a/lndclient/walletkit_client.go b/lndclient/walletkit_client.go index a477978..7b7156b 100644 --- a/lndclient/walletkit_client.go +++ b/lndclient/walletkit_client.go @@ -34,12 +34,16 @@ type WalletKitClient interface { } type walletKitClient struct { - client walletrpc.WalletKitClient + client walletrpc.WalletKitClient + walletKitMac serializedMacaroon } -func newWalletKitClient(conn *grpc.ClientConn) *walletKitClient { +func newWalletKitClient(conn *grpc.ClientConn, + walletKitMac serializedMacaroon) *walletKitClient { + return &walletKitClient{ - client: walletrpc.NewWalletKitClient(conn), + client: walletrpc.NewWalletKitClient(conn), + walletKitMac: walletKitMac, } } @@ -49,6 +53,7 @@ func (m *walletKitClient) DeriveNextKey(ctx context.Context, family int32) ( rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx) resp, err := m.client.DeriveNextKey(rpcCtx, &walletrpc.KeyReq{ KeyFamily: family, }) @@ -76,6 +81,7 @@ func (m *walletKitClient) DeriveKey(ctx context.Context, in *keychain.KeyLocator rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx) resp, err := m.client.DeriveKey(rpcCtx, &signrpc.KeyLocator{ KeyFamily: int32(in.Family), KeyIndex: int32(in.Index), @@ -101,6 +107,7 @@ func (m *walletKitClient) NextAddr(ctx context.Context) ( rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx) resp, err := m.client.NextAddr(rpcCtx, &walletrpc.AddrRequest{}) if err != nil { return nil, err @@ -125,6 +132,7 @@ func (m *walletKitClient) PublishTransaction(ctx context.Context, rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx) _, err = m.client.PublishTransaction(rpcCtx, &walletrpc.Transaction{ TxHex: txHex, }) @@ -147,6 +155,7 @@ func (m *walletKitClient) SendOutputs(ctx context.Context, rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx) resp, err := m.client.SendOutputs(rpcCtx, &walletrpc.SendOutputsRequest{ Outputs: rpcOutputs, SatPerKw: int64(feeRate), @@ -169,6 +178,7 @@ func (m *walletKitClient) EstimateFee(ctx context.Context, confTarget int32) ( rpcCtx, cancel := context.WithTimeout(ctx, rpcTimeout) defer cancel() + rpcCtx = m.walletKitMac.WithMacaroonAuth(rpcCtx) resp, err := m.client.EstimateFee(rpcCtx, &walletrpc.EstimateFeeRequest{ ConfTarget: int32(confTarget), }) From 6d008095750dd9fb700f5ad2c2e709fcf7d4bc96 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 16 Apr 2019 19:18:28 -0700 Subject: [PATCH 4/6] cmd/loopd+lndclient: based on the network, update the macaron path if unset --- cmd/loopd/daemon.go | 3 ++- lndclient/lnd_services.go | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/cmd/loopd/daemon.go b/cmd/loopd/daemon.go index e9008a9..5d8060a 100644 --- a/cmd/loopd/daemon.go +++ b/cmd/loopd/daemon.go @@ -34,7 +34,8 @@ func daemon(config *config) error { // Create an instance of the loop client library. swapClient, cleanup, err := getClient( - config.Network, config.SwapServer, config.Insecure, &lnd.LndServices, + config.Network, config.SwapServer, config.Insecure, + &lnd.LndServices, ) if err != nil { return err diff --git a/lndclient/lnd_services.go b/lndclient/lnd_services.go index 8350d6f..244c26d 100644 --- a/lndclient/lnd_services.go +++ b/lndclient/lnd_services.go @@ -41,10 +41,38 @@ type GrpcLndServices struct { func NewLndServices(lndAddress, application, network, macaroonDir, tlsPath string) (*GrpcLndServices, error) { - // If the macaroon directory isn't set, then we can't proceed as we - // need then to obtain the macaroons for all sub-servers. + // Based on the network, if the macaroon directory isn't set, then + // we'll use the expected default locations. if macaroonDir == "" { - return nil, fmt.Errorf("macarooon dir must be set") + switch network { + case "testnet": + macaroonDir = filepath.Join( + defaultLndDir, defaultDataDir, + defaultChainSubDir, "bitcoin", "testnet", + ) + + case "mainnet": + macaroonDir = filepath.Join( + defaultLndDir, defaultDataDir, + defaultChainSubDir, "bitcoin", "mainnet", + ) + + case "simnet": + macaroonDir = filepath.Join( + defaultLndDir, defaultDataDir, + defaultChainSubDir, "bitcoin", "simnet", + ) + + case "regtest": + macaroonDir = filepath.Join( + defaultLndDir, defaultDataDir, + defaultChainSubDir, "bitcoin", "regtest", + ) + + default: + return nil, fmt.Errorf("unsupported network: %v", + network) + } } // Now that we've ensured our macaroon directory is set properly, we @@ -88,7 +116,7 @@ func NewLndServices(lndAddress, application, network, macaroonDir, } // With the network check passed, we'll now initialize the rest of the - // sub-sever connections, giving each of them their specific macaroon. + // sub-server connections, giving each of them their specific macaroon. notifierClient := newChainNotifierClient(conn, macaroons.chainMac) signerClient := newSignerClient(conn, macaroons.signerMac) walletKitClient := newWalletKitClient(conn, macaroons.walletKitMac) From 74d381fa6301aa806cdc0769a154f4762aff7b91 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 16 Apr 2019 19:18:44 -0700 Subject: [PATCH 5/6] build: go mod tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6e7679f..64a6d8e 100644 --- a/go.mod +++ b/go.mod @@ -15,5 +15,5 @@ require ( golang.org/x/net v0.0.0-20190313220215-9f648a60d977 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 google.golang.org/grpc v1.19.0 - gopkg.in/macaroon.v2 v2.1.0 + gopkg.in/macaroon.v2 v2.1.0 // indirect ) From 6037d0105fb801439e5e3a52ab957dbee690ff3c Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 17 Apr 2019 15:49:23 -0700 Subject: [PATCH 6/6] cmd/loopd: rename MacaroonPath to MacaroonDir --- cmd/loopd/config.go | 6 +++--- cmd/loopd/utils.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/loopd/config.go b/cmd/loopd/config.go index cc9ba91..2d8855b 100644 --- a/cmd/loopd/config.go +++ b/cmd/loopd/config.go @@ -1,9 +1,9 @@ package main type lndConfig struct { - Host string `long:"host" description:"lnd instance rpc address"` - MacaroonPath string `long:"macaroonpath" description:"Path to lnd macaroon"` - TLSPath string `long:"tlspath" description:"Path to lnd tls certificate"` + Host string `long:"host" description:"lnd instance rpc address"` + MacaroonDir string `long:"macaroondir" description:"Path to the directory containing all the required lnd macaroons"` + TLSPath string `long:"tlspath" description:"Path to lnd tls certificate"` } type viewParameters struct{} diff --git a/cmd/loopd/utils.go b/cmd/loopd/utils.go index 787cf23..0e10b44 100644 --- a/cmd/loopd/utils.go +++ b/cmd/loopd/utils.go @@ -11,7 +11,7 @@ import ( // getLnd returns an instance of the lnd services proxy. func getLnd(network string, cfg *lndConfig) (*lndclient.GrpcLndServices, error) { return lndclient.NewLndServices( - cfg.Host, "client", network, cfg.MacaroonPath, cfg.TLSPath, + cfg.Host, "client", network, cfg.MacaroonDir, cfg.TLSPath, ) }