Skip to content

Commit

Permalink
multi: move challenger and secrets files to new packages so they can …
Browse files Browse the repository at this point in the history
…be imported elsewhere.

This commit:
- Moves challenger and secrets files to new packages so they can be imported elsewhere.
- Alters NewLndChallenger so that it takes the lnd client in as a parameter. (This is useful in the case of using NewLndChallenger in the lnd watchtower project, to avoid having to import lndclient, which leads to` an import cycle.)
  • Loading branch information
orbitalturtle committed Mar 6, 2023
1 parent b952e4e commit c43f4a8
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 38 deletions.
30 changes: 17 additions & 13 deletions aperture.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ import (
gateway "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
flags "github.com/jessevdk/go-flags"
"github.com/lightninglabs/aperture/auth"
"github.com/lightninglabs/aperture/challenger"
"github.com/lightninglabs/aperture/mint"
"github.com/lightninglabs/aperture/proxy"
"github.com/lightninglabs/aperture/secrets"
"github.com/lightninglabs/lightning-node-connect/hashmailrpc"
"github.com/lightninglabs/lndclient"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/cert"
Expand All @@ -42,14 +45,6 @@ import (
)

const (
// topLevelKey is the top level key for an etcd cluster where we'll
// store all LSAT proxy related data.
topLevelKey = "lsat/proxy"

// etcdKeyDelimeter is the delimeter we'll use for all etcd keys to
// represent a path-like structure.
etcdKeyDelimeter = "/"

// selfSignedCertOrganization is the static string that we encode in the
// organization field of a certificate if we create it ourselves.
selfSignedCertOrganization = "aperture autogenerated cert"
Expand Down Expand Up @@ -160,7 +155,7 @@ type Aperture struct {
cfg *Config

etcdClient *clientv3.Client
challenger *LndChallenger
challenger *challenger.LndChallenger
httpsServer *http.Server
torHTTPServer *http.Server
proxy *proxy.Proxy
Expand Down Expand Up @@ -229,8 +224,17 @@ func (a *Aperture) Start(errChan chan error) error {
}

if !a.cfg.Authenticator.Disable {
a.challenger, err = NewLndChallenger(
a.cfg.Authenticator, genInvoiceReq, errChan,
client, err := lndclient.NewBasicClient(
a.cfg.Authenticator.LndHost, a.cfg.Authenticator.TLSPath,
a.cfg.Authenticator.MacDir, a.cfg.Authenticator.Network,
lndclient.MacFilename(challenger.InvoiceMacaroonName),
)
if err != nil {
return err
}

a.challenger, err = challenger.NewLndChallenger(
genInvoiceReq, errChan, client,
)
if err != nil {
return err
Expand Down Expand Up @@ -655,12 +659,12 @@ func initTorListener(cfg *Config, etcd *clientv3.Client) (*tor.Controller, error
}

// createProxy creates the proxy with all the services it needs.
func createProxy(cfg *Config, challenger *LndChallenger,
func createProxy(cfg *Config, challenger *challenger.LndChallenger,
etcdClient *clientv3.Client) (*proxy.Proxy, func(), error) {

minter := mint.New(&mint.Config{
Challenger: challenger,
Secrets: newSecretStore(etcdClient),
Secrets: secrets.NewSecretStore(etcdClient),
ServiceLimiter: newStaticServiceLimiter(cfg.Services),
})
authenticator := auth.NewLsatAuthenticator(minter, challenger)
Expand Down
17 changes: 4 additions & 13 deletions challenger.go → challenger/challenger.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aperture
package challenger

import (
"context"
Expand All @@ -11,7 +11,6 @@ import (

"github.com/lightninglabs/aperture/auth"
"github.com/lightninglabs/aperture/mint"
"github.com/lightninglabs/lndclient"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntypes"
"google.golang.org/grpc"
Expand Down Expand Up @@ -63,26 +62,18 @@ var _ auth.InvoiceChecker = (*LndChallenger)(nil)
const (
// invoiceMacaroonName is the name of the invoice macaroon belonging
// to the target lnd node.
invoiceMacaroonName = "invoice.macaroon"
InvoiceMacaroonName = "invoice.macaroon"
)

// NewLndChallenger creates a new challenger that uses the given connection
// details to connect to an lnd backend to create payment challenges.
func NewLndChallenger(cfg *AuthConfig, genInvoiceReq InvoiceRequestGenerator,
errChan chan<- error) (*LndChallenger, error) {
func NewLndChallenger(genInvoiceReq InvoiceRequestGenerator,
errChan chan<- error, client InvoiceClient) (*LndChallenger, error) {

if genInvoiceReq == nil {
return nil, fmt.Errorf("genInvoiceReq cannot be nil")
}

client, err := lndclient.NewBasicClient(
cfg.LndHost, cfg.TLSPath, cfg.MacDir, cfg.Network,
lndclient.MacFilename(invoiceMacaroonName),
)
if err != nil {
return nil, err
}

invoicesMtx := &sync.Mutex{}
return &LndChallenger{
client: client,
Expand Down
4 changes: 2 additions & 2 deletions challenger_test.go → challenger/challenger_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aperture
package challenger

import (
"context"
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestLndChallenger(t *testing.T) {
// First of all, test that the NewLndChallenger doesn't allow a nil
// invoice generator function.
errChan := make(chan error)
_, err := NewLndChallenger(nil, nil, errChan)
_, err := NewLndChallenger(nil, errChan, nil)
require.Error(t, err)

// Now mock the lnd backend and create a challenger instance that we can
Expand Down
31 changes: 31 additions & 0 deletions challenger/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package challenger

import (
"github.com/btcsuite/btclog"
"github.com/lightningnetwork/lnd/build"
)

const Subsystem = "CHAL"

// log is a logger that is initialized with no output filters. This
// means the package will not perform any logging by default until the caller
// requests it.
var log btclog.Logger

// The default amount of logging is none.
func init() {
UseLogger(build.NewSubLogger(Subsystem, nil))
}

// DisableLog disables all library log output. Logging output is disabled
// by default until UseLogger is called.
func DisableLog() {
UseLogger(btclog.Disabled)
}

// UseLogger uses a specified Logger to output package logging info.
// This should be used in preference to SetLogWriter if the caller is also
// using btclog.
func UseLogger(logger btclog.Logger) {
log = logger
}
2 changes: 2 additions & 0 deletions log.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package aperture
import (
"github.com/btcsuite/btclog"
"github.com/lightninglabs/aperture/auth"
"github.com/lightninglabs/aperture/challenger"
"github.com/lightninglabs/aperture/lsat"
"github.com/lightninglabs/aperture/proxy"
"github.com/lightninglabs/lndclient"
Expand All @@ -27,6 +28,7 @@ func SetupLoggers(root *build.RotatingLogWriter, intercept signal.Interceptor) {

lnd.SetSubLogger(root, Subsystem, log)
lnd.AddSubLogger(root, auth.Subsystem, intercept, auth.UseLogger)
lnd.AddSubLogger(root, challenger.Subsystem, intercept, challenger.UseLogger)
lnd.AddSubLogger(root, lsat.Subsystem, intercept, lsat.UseLogger)
lnd.AddSubLogger(root, proxy.Subsystem, intercept, proxy.UseLogger)
lnd.AddSubLogger(root, "LNDC", intercept, lndclient.UseLogger)
Expand Down
3 changes: 2 additions & 1 deletion onion_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"strings"

"github.com/lightninglabs/aperture/secrets"
"github.com/lightningnetwork/lnd/tor"
clientv3 "go.etcd.io/etcd/client/v3"
)
Expand All @@ -20,7 +21,7 @@ const (

// onionPath is the full path to an onion service's private key.
var onionPath = strings.Join(
[]string{topLevelKey, onionDir, onionV3Dir}, etcdKeyDelimeter,
[]string{secrets.TopLevelKey, onionDir, onionV3Dir}, secrets.EtcdKeyDelimeter,
)

// onionStore is an etcd-based implementation of tor.OnionStore.
Expand Down
3 changes: 2 additions & 1 deletion onion_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"testing"

"github.com/lightninglabs/aperture/secrets"
"github.com/lightningnetwork/lnd/tor"
)

Expand Down Expand Up @@ -35,7 +36,7 @@ func assertPrivateKeyExists(t *testing.T, store *onionStore,
// TestOnionStore ensures the different operations of the onionStore behave
// as expected.
func TestOnionStore(t *testing.T) {
etcdClient, serverCleanup := etcdSetup(t)
etcdClient, serverCleanup := secrets.EtcdSetup(t)
defer etcdClient.Close()
defer serverCleanup()

Expand Down
20 changes: 15 additions & 5 deletions secrets.go → secrets/secrets.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aperture
package secrets

import (
"context"
Expand All @@ -13,6 +13,16 @@ import (
clientv3 "go.etcd.io/etcd/client/v3"
)

const (
// TopLevelKey is the top level key for an etcd cluster where we'll
// store all LSAT proxy related data.
TopLevelKey = "lsat/proxy"

// EtcdKeyDelimeter is the delimeter we'll use for all etcd keys to
// represent a path-like structure.
EtcdKeyDelimeter = "/"
)

var (
// secretsPrefix is the key we'll use to prefix all LSAT identifiers
// with when storing secrets in an etcd cluster.
Expand All @@ -27,8 +37,8 @@ var (
// lsat/proxy/secrets/bff4ee83
func idKey(id [sha256.Size]byte) string {
return strings.Join(
[]string{topLevelKey, secretsPrefix, hex.EncodeToString(id[:])},
etcdKeyDelimeter,
[]string{TopLevelKey, secretsPrefix, hex.EncodeToString(id[:])},
EtcdKeyDelimeter,
)
}

Expand All @@ -40,9 +50,9 @@ type secretStore struct {
// A compile-time constraint to ensure secretStore implements mint.SecretStore.
var _ mint.SecretStore = (*secretStore)(nil)

// newSecretStore instantiates a new LSAT secrets store backed by an etcd
// NewSecretStore instantiates a new LSAT secrets store backed by an etcd
// cluster.
func newSecretStore(client *clientv3.Client) *secretStore {
func NewSecretStore(client *clientv3.Client) *secretStore {
return &secretStore{Client: client}
}

Expand Down
6 changes: 3 additions & 3 deletions secrets_test.go → secrets/secrets_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package aperture
package secrets

import (
"bytes"
Expand Down Expand Up @@ -87,12 +87,12 @@ func assertSecretExists(t *testing.T, store *secretStore, id [sha256.Size]byte,
// TestSecretStore ensures the different operations of the secretStore behave as
// expected.
func TestSecretStore(t *testing.T) {
etcdClient, serverCleanup := etcdSetup(t)
etcdClient, serverCleanup := EtcdSetup(t)
defer etcdClient.Close()
defer serverCleanup()

ctx := context.Background()
store := newSecretStore(etcdClient)
store := NewSecretStore(etcdClient)

// Create a test ID and ensure a secret doesn't exist for it yet as we
// haven't created one.
Expand Down
57 changes: 57 additions & 0 deletions secrets/test_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package secrets

import (
"io/ioutil"
"net/url"
"os"
"testing"
"time"

clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/server/v3/embed"
)

// EtcdSetup is a helper that instantiates a new etcd cluster along with a
// client connection to it. A cleanup closure is also returned to free any
// allocated resources required by etcd.
func EtcdSetup(t *testing.T) (*clientv3.Client, func()) {
t.Helper()

tempDir, err := ioutil.TempDir("", "etcd")
if err != nil {
t.Fatalf("unable to create temp dir: %v", err)
}

cfg := embed.NewConfig()
cfg.Dir = tempDir
cfg.Logger = "zap"
cfg.LCUrls = []url.URL{{Host: "127.0.0.1:9125"}}
cfg.LPUrls = []url.URL{{Host: "127.0.0.1:9126"}}

etcd, err := embed.StartEtcd(cfg)
if err != nil {
os.RemoveAll(tempDir)
t.Fatalf("unable to start etcd: %v", err)
}

select {
case <-etcd.Server.ReadyNotify():
case <-time.After(5 * time.Second):
os.RemoveAll(tempDir)
etcd.Server.Stop() // trigger a shutdown
t.Fatal("server took too long to start")
}

client, err := clientv3.New(clientv3.Config{
Endpoints: []string{cfg.LCUrls[0].Host},
DialTimeout: 5 * time.Second,
})
if err != nil {
t.Fatalf("unable to connect to etcd: %v", err)
}

return client, func() {
etcd.Close()
os.RemoveAll(tempDir)
}
}

0 comments on commit c43f4a8

Please sign in to comment.