mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-10 06:07:16 +01:00
multi: make macaroon DB remote compatible
The macaroon root keys should also be stored to the remote database if a replicated backend such as etcd is used. This commit refactors the macaroons service and wallet unlocker to accept a kvdb backend directly instead of creating the bolt instance automatically.
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/aezeed"
|
||||
"github.com/lightningnetwork/lnd/chanbackup"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
|
||||
@@ -124,30 +125,28 @@ type UnlockerService struct {
|
||||
// the WalletUnlocker service.
|
||||
MacResponseChan chan []byte
|
||||
|
||||
chainDir string
|
||||
noFreelistSync bool
|
||||
netParams *chaincfg.Params
|
||||
netParams *chaincfg.Params
|
||||
|
||||
// macaroonFiles is the path to the three generated macaroons with
|
||||
// different access permissions. These might not exist in a stateless
|
||||
// initialization of lnd.
|
||||
macaroonFiles []string
|
||||
|
||||
// dbTimeout specifies the timeout value to use when opening the wallet
|
||||
// database.
|
||||
dbTimeout time.Duration
|
||||
|
||||
// resetWalletTransactions indicates that the wallet state should be
|
||||
// reset on unlock to force a full chain rescan.
|
||||
resetWalletTransactions bool
|
||||
|
||||
// LoaderOpts holds the functional options for the wallet loader.
|
||||
loaderOpts []btcwallet.LoaderOption
|
||||
|
||||
// macaroonDB is an instance of a database backend that stores all
|
||||
// macaroon root keys. This will be nil on initialization and must be
|
||||
// set using the SetMacaroonDB method as soon as it's available.
|
||||
macaroonDB kvdb.Backend
|
||||
}
|
||||
|
||||
// New creates and returns a new UnlockerService.
|
||||
func New(chainDir string, params *chaincfg.Params, noFreelistSync bool,
|
||||
macaroonFiles []string, dbTimeout time.Duration,
|
||||
func New(params *chaincfg.Params, macaroonFiles []string,
|
||||
resetWalletTransactions bool,
|
||||
loaderOpts []btcwallet.LoaderOption) *UnlockerService {
|
||||
|
||||
@@ -158,11 +157,8 @@ func New(chainDir string, params *chaincfg.Params, noFreelistSync bool,
|
||||
// Make sure we buffer the channel is buffered so the main lnd
|
||||
// goroutine isn't blocking on writing to it.
|
||||
MacResponseChan: make(chan []byte, 1),
|
||||
chainDir: chainDir,
|
||||
netParams: params,
|
||||
macaroonFiles: macaroonFiles,
|
||||
dbTimeout: dbTimeout,
|
||||
noFreelistSync: noFreelistSync,
|
||||
resetWalletTransactions: resetWalletTransactions,
|
||||
loaderOpts: loaderOpts,
|
||||
}
|
||||
@@ -174,6 +170,12 @@ func (u *UnlockerService) SetLoaderOpts(loaderOpts []btcwallet.LoaderOption) {
|
||||
u.loaderOpts = loaderOpts
|
||||
}
|
||||
|
||||
// SetMacaroonDB can be used to inject the macaroon database after the unlocker
|
||||
// service has been hooked to the main RPC server.
|
||||
func (u *UnlockerService) SetMacaroonDB(macaroonDB kvdb.Backend) {
|
||||
u.macaroonDB = macaroonDB
|
||||
}
|
||||
|
||||
func (u *UnlockerService) newLoader(recoveryWindow uint32) (*wallet.Loader,
|
||||
error) {
|
||||
|
||||
@@ -607,9 +609,8 @@ func (u *UnlockerService) ChangePassword(ctx context.Context,
|
||||
// then close it again.
|
||||
// Attempt to open the macaroon DB, unlock it and then change
|
||||
// the passphrase.
|
||||
netDir := btcwallet.NetworkDir(u.chainDir, u.netParams)
|
||||
macaroonService, err := macaroons.NewService(
|
||||
netDir, "lnd", in.StatelessInit, u.dbTimeout,
|
||||
u.macaroonDB, "lnd", in.StatelessInit,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -113,7 +113,7 @@ func openOrCreateTestMacStore(tempDir string, pw *[]byte,
|
||||
return nil, err
|
||||
}
|
||||
db, err := kvdb.Create(
|
||||
kvdb.BoltBackendName, path.Join(netDir, macaroons.DBFilename),
|
||||
kvdb.BoltBackendName, path.Join(netDir, "macaroons.db"),
|
||||
true, kvdb.DefaultDBTimeout,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -154,8 +154,7 @@ func TestGenSeed(t *testing.T) {
|
||||
}()
|
||||
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, nil, kvdb.DefaultDBTimeout,
|
||||
false, testLoaderOpts(testDir),
|
||||
testNetParams, nil, false, testLoaderOpts(testDir),
|
||||
)
|
||||
|
||||
// Now that the service has been created, we'll ask it to generate a
|
||||
@@ -192,8 +191,7 @@ func TestGenSeedGenerateEntropy(t *testing.T) {
|
||||
_ = os.RemoveAll(testDir)
|
||||
}()
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, nil, kvdb.DefaultDBTimeout,
|
||||
false, testLoaderOpts(testDir),
|
||||
testNetParams, nil, false, testLoaderOpts(testDir),
|
||||
)
|
||||
|
||||
// Now that the service has been created, we'll ask it to generate a
|
||||
@@ -229,8 +227,7 @@ func TestGenSeedInvalidEntropy(t *testing.T) {
|
||||
_ = os.RemoveAll(testDir)
|
||||
}()
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, nil, kvdb.DefaultDBTimeout,
|
||||
false, testLoaderOpts(testDir),
|
||||
testNetParams, nil, false, testLoaderOpts(testDir),
|
||||
)
|
||||
|
||||
// Now that the service has been created, we'll ask it to generate a
|
||||
@@ -263,8 +260,7 @@ func TestInitWallet(t *testing.T) {
|
||||
|
||||
// Create new UnlockerService.
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, nil, kvdb.DefaultDBTimeout,
|
||||
false, testLoaderOpts(testDir),
|
||||
testNetParams, nil, false, testLoaderOpts(testDir),
|
||||
)
|
||||
|
||||
// Once we have the unlocker service created, we'll now instantiate a
|
||||
@@ -352,8 +348,7 @@ func TestCreateWalletInvalidEntropy(t *testing.T) {
|
||||
|
||||
// Create new UnlockerService.
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, nil, kvdb.DefaultDBTimeout,
|
||||
false, testLoaderOpts(testDir),
|
||||
testNetParams, nil, false, testLoaderOpts(testDir),
|
||||
)
|
||||
|
||||
// We'll attempt to init the wallet with an invalid cipher seed and
|
||||
@@ -385,8 +380,7 @@ func TestUnlockWallet(t *testing.T) {
|
||||
// Create new UnlockerService that'll also drop the wallet's history on
|
||||
// unlock.
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, nil, kvdb.DefaultDBTimeout,
|
||||
true, testLoaderOpts(testDir),
|
||||
testNetParams, nil, true, testLoaderOpts(testDir),
|
||||
)
|
||||
|
||||
ctx := context.Background()
|
||||
@@ -477,9 +471,9 @@ func TestChangeWalletPasswordNewRootkey(t *testing.T) {
|
||||
|
||||
// Create a new UnlockerService with our temp files.
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, tempFiles, kvdb.DefaultDBTimeout,
|
||||
false, testLoaderOpts(testDir),
|
||||
testNetParams, tempFiles, false, testLoaderOpts(testDir),
|
||||
)
|
||||
service.SetMacaroonDB(store.Backend)
|
||||
|
||||
ctx := context.Background()
|
||||
newPassword := []byte("hunter2???")
|
||||
@@ -588,10 +582,11 @@ func TestChangeWalletPasswordStateless(t *testing.T) {
|
||||
|
||||
// Create a new UnlockerService with our temp files.
|
||||
service := walletunlocker.New(
|
||||
testDir, testNetParams, true, []string{
|
||||
testNetParams, []string{
|
||||
tempMacFile, nonExistingFile,
|
||||
}, kvdb.DefaultDBTimeout, false, testLoaderOpts(testDir),
|
||||
}, false, testLoaderOpts(testDir),
|
||||
)
|
||||
service.SetMacaroonDB(store.Backend)
|
||||
|
||||
// Create a wallet we can try to unlock. We use the default password
|
||||
// so we can check that the unlocker service defaults to this when
|
||||
|
||||
Reference in New Issue
Block a user