mirror of
https://github.com/lightninglabs/loop.git
synced 2026-08-13 12:33:03 +02:00
assets: make tapd macaroon path network-aware
Build the default tapd admin macaroon path from the configured Bitcoin network while preserving explicit path overrides. Add regression tests for tapd credential loading and network-specific path selection.
This commit is contained in:
parent
74cbb651bc
commit
378825414b
4 changed files with 128 additions and 4 deletions
|
|
@ -49,13 +49,21 @@ type TapdConfig struct {
|
|||
// DefaultTapdConfig returns a default configuration to connect to a taproot
|
||||
// assets daemon.
|
||||
func DefaultTapdConfig() *TapdConfig {
|
||||
defaultTapdDir := btcutil.AppDataDir("tapd", false)
|
||||
return DefaultTapdConfigForNetwork(
|
||||
btcutil.AppDataDir("tapd", false), "mainnet",
|
||||
)
|
||||
}
|
||||
|
||||
// DefaultTapdConfigForNetwork returns the default tapd configuration rooted in
|
||||
// defaultTapdDir for the given Bitcoin network. Passing the directory
|
||||
// explicitly keeps path construction testable without accessing the user's
|
||||
// real tapd data.
|
||||
func DefaultTapdConfigForNetwork(defaultTapdDir, network string) *TapdConfig {
|
||||
return &TapdConfig{
|
||||
Activate: false,
|
||||
Host: "localhost:10029",
|
||||
MacaroonPath: filepath.Join(
|
||||
defaultTapdDir, "mainnet", "admin.macaroon",
|
||||
defaultTapdDir, "data", network, "admin.macaroon",
|
||||
),
|
||||
TLSPath: filepath.Join(defaultTapdDir, "tls.cert"),
|
||||
RFQtimeout: defaultRfqTimeout,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
package assets
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
|
|
@ -8,6 +12,7 @@ import (
|
|||
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/macaroon.v2"
|
||||
)
|
||||
|
||||
// TestDefaultTapdConfig tests that the default tapd connection paths match
|
||||
|
|
@ -16,10 +21,62 @@ func TestDefaultTapdConfig(t *testing.T) {
|
|||
defaultTapdDir := btcutil.AppDataDir("tapd", false)
|
||||
config := DefaultTapdConfig()
|
||||
|
||||
require.Equal(t, filepath.Join(
|
||||
defaultTapdDir, "data", "mainnet", "admin.macaroon",
|
||||
), config.MacaroonPath)
|
||||
require.Equal(
|
||||
t, filepath.Join(defaultTapdDir, "mainnet", "admin.macaroon"),
|
||||
config.MacaroonPath,
|
||||
t, filepath.Join(defaultTapdDir, "tls.cert"), config.TLSPath,
|
||||
)
|
||||
}
|
||||
|
||||
// TestTapdConfigClientConn tests that the default tapd file layout can be used
|
||||
// to construct a client connection.
|
||||
func TestTapdConfigClientConn(t *testing.T) {
|
||||
// Use an isolated tapd root so the test never reads from or writes to a
|
||||
// user's real tapd data directory.
|
||||
defaultTapdDir := t.TempDir()
|
||||
network := "regtest"
|
||||
macaroonPath := filepath.Join(
|
||||
defaultTapdDir, "data", network, "admin.macaroon",
|
||||
)
|
||||
require.NoError(t, os.MkdirAll(filepath.Dir(macaroonPath), 0o700))
|
||||
|
||||
// NewTapdClient parses the configured TLS certificate before creating
|
||||
// its gRPC client. An httptest server provides a valid certificate
|
||||
// without requiring a running tapd instance.
|
||||
tlsServer := httptest.NewTLSServer(http.NotFoundHandler())
|
||||
t.Cleanup(tlsServer.Close)
|
||||
cert := tlsServer.Certificate()
|
||||
certBytes := pem.EncodeToMemory(&pem.Block{
|
||||
Type: "CERTIFICATE", Bytes: cert.Raw,
|
||||
})
|
||||
require.NoError(t, os.WriteFile(
|
||||
filepath.Join(defaultTapdDir, "tls.cert"), certBytes, 0o600,
|
||||
))
|
||||
|
||||
// Store a valid serialized macaroon at tapd's production path. This
|
||||
// ensures connection setup tests the path itself rather than failing on
|
||||
// malformed credentials.
|
||||
mac, err := macaroon.New(
|
||||
[]byte("root-key"), []byte("id"), "tapd",
|
||||
macaroon.LatestVersion,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
macBytes, err := mac.MarshalBinary()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, os.WriteFile(macaroonPath, macBytes, 0o600))
|
||||
|
||||
// grpc.NewClient connects lazily, so constructing the tapd client verifies
|
||||
// that both credentials can be loaded and parsed without needing a live
|
||||
// tapd server.
|
||||
config := DefaultTapdConfigForNetwork(defaultTapdDir, network)
|
||||
client, err := NewTapdClient(config)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, client.cc.Close())
|
||||
})
|
||||
|
||||
require.Equal(t, macaroonPath, config.MacaroonPath)
|
||||
require.Equal(
|
||||
t, filepath.Join(defaultTapdDir, "tls.cert"), config.TLSPath,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -335,6 +335,14 @@ func Validate(cfg *Config) error {
|
|||
)
|
||||
}
|
||||
|
||||
// If the user doesn't specify Tapd.MacaroonPath, reassemble it with
|
||||
// the configured Bitcoin network.
|
||||
if cfg.Tapd.MacaroonPath == assets.DefaultTapdConfig().MacaroonPath {
|
||||
cfg.Tapd.MacaroonPath = assets.DefaultTapdConfigForNetwork(
|
||||
btcutil.AppDataDir("tapd", false), cfg.Network,
|
||||
).MacaroonPath
|
||||
}
|
||||
|
||||
// We'll also update the database file location as well, if it wasn't
|
||||
// set.
|
||||
if cfg.Sqlite.DatabaseFileName == defaultSqliteDatabasePath {
|
||||
|
|
|
|||
51
loopd/config_test.go
Normal file
51
loopd/config_test.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package loopd
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/lightninglabs/loop/assets"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestValidateTapdMacaroonPath tests that validation updates the default tapd
|
||||
// macaroon path for the configured network without changing an explicit path.
|
||||
func TestValidateTapdMacaroonPath(t *testing.T) {
|
||||
customPath := filepath.Join(t.TempDir(), "custom.macaroon")
|
||||
defaultConfig := assets.DefaultTapdConfig()
|
||||
regtestConfig := assets.DefaultTapdConfigForNetwork(
|
||||
btcutil.AppDataDir("tapd", false), "regtest",
|
||||
)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
macaroonPath string
|
||||
expectedPath string
|
||||
}{
|
||||
{
|
||||
name: "default path",
|
||||
macaroonPath: defaultConfig.MacaroonPath,
|
||||
expectedPath: regtestConfig.MacaroonPath,
|
||||
},
|
||||
{
|
||||
name: "explicit path",
|
||||
macaroonPath: customPath,
|
||||
expectedPath: customPath,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
cfg.Network = "regtest"
|
||||
cfg.LoopDir = t.TempDir()
|
||||
cfg.Tapd.MacaroonPath = test.macaroonPath
|
||||
|
||||
require.NoError(t, Validate(&cfg))
|
||||
require.Equal(
|
||||
t, test.expectedPath, cfg.Tapd.MacaroonPath,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue