lnwallet/btcwallet: update implementation to account for recent API changes
The new version of the internal core of btcwallet now uses KeyScopes rather than address types to derive particular addresses. As a result, in this commit, we update our API usage to ensure that proper addresses are still derived.
This commit is contained in:
parent
6290a520fd
commit
93280ad60a
@ -9,6 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/roasbeef/btcd/btcec"
|
"github.com/roasbeef/btcd/btcec"
|
||||||
"github.com/roasbeef/btcd/chaincfg"
|
"github.com/roasbeef/btcd/chaincfg"
|
||||||
@ -27,9 +28,25 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
lnNamespace = []byte("ln")
|
// waddrmgrNamespaceKey is the namespace key that the waddrmgr state is
|
||||||
rootKey = []byte("ln-root")
|
// stored within the top-level waleltdb buckets of btcwallet.
|
||||||
waddrmgrNamespaceKey = []byte("waddrmgr")
|
waddrmgrNamespaceKey = []byte("waddrmgr")
|
||||||
|
|
||||||
|
// lightningKeyScope is the key scope that will be used within the
|
||||||
|
// waddrmgr to create an HD chain for deriving all of our required
|
||||||
|
// keys. We'll ensure this this scope is created upon start.
|
||||||
|
lightningKeyScope = waddrmgr.KeyScope{
|
||||||
|
Purpose: keychain.BIP0043Purpose,
|
||||||
|
Coin: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
// lightningAddrSchema is the scope addr schema for all keys that we
|
||||||
|
// derive. We'll treat them all as p2wkh addresses, as atm we must
|
||||||
|
// specify a particular type.
|
||||||
|
lightningAddrSchema = waddrmgr.ScopeAddrSchema{
|
||||||
|
ExternalAddrType: waddrmgr.WitnessPubKey,
|
||||||
|
InternalAddrType: waddrmgr.WitnessPubKey,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// BtcWallet is an implementation of the lnwallet.WalletController interface
|
// BtcWallet is an implementation of the lnwallet.WalletController interface
|
||||||
@ -83,49 +100,23 @@ func New(cfg Config) (*BtcWallet, error) {
|
|||||||
wallet, err = loader.CreateNewWallet(
|
wallet, err = loader.CreateNewWallet(
|
||||||
pubPass, cfg.PrivatePass, cfg.HdSeed,
|
pubPass, cfg.PrivatePass, cfg.HdSeed,
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
switch {
|
|
||||||
// If the wallet already exists, then we'll ignore this error
|
|
||||||
// and proceed directly to opening the wallet.
|
|
||||||
case err == base.ErrExists:
|
|
||||||
|
|
||||||
// Otherwise, there's a greater error here, and we'll return
|
|
||||||
// early.
|
|
||||||
case err != nil:
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if err := loader.UnloadWallet(); err != nil {
|
// Wallet has been created and been initialized at this point,
|
||||||
|
// open it along with all the required DB namespaces, and the
|
||||||
|
// DB itself.
|
||||||
|
wallet, err = loader.OpenExistingWallet(pubPass, false)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wallet has been created and been initialized at this point, open it
|
|
||||||
// along with all the required DB namepsaces, and the DB itself.
|
|
||||||
wallet, err = loader.OpenExistingWallet(pubPass, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a bucket within the wallet's database dedicated to storing
|
|
||||||
// our LN specific data.
|
|
||||||
db := wallet.Database()
|
|
||||||
err = walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
|
|
||||||
_, err := tx.CreateTopLevelBucket(lnNamespace)
|
|
||||||
if err != nil && err != walletdb.ErrBucketExists {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &BtcWallet{
|
return &BtcWallet{
|
||||||
cfg: &cfg,
|
cfg: &cfg,
|
||||||
wallet: wallet,
|
wallet: wallet,
|
||||||
db: db,
|
db: wallet.Database(),
|
||||||
chain: cfg.ChainSource,
|
chain: cfg.ChainSource,
|
||||||
netParams: cfg.NetParams,
|
netParams: cfg.NetParams,
|
||||||
utxoCache: make(map[wire.OutPoint]*wire.TxOut),
|
utxoCache: make(map[wire.OutPoint]*wire.TxOut),
|
||||||
@ -143,6 +134,12 @@ func (b *BtcWallet) BackEnd() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InternalWallet returns a pointer to the internal base wallet which is the
|
||||||
|
// core of btcwallet.
|
||||||
|
func (b *BtcWallet) InternalWallet() *base.Wallet {
|
||||||
|
return b.wallet
|
||||||
|
}
|
||||||
|
|
||||||
// Start initializes the underlying rpc connection, the wallet itself, and
|
// Start initializes the underlying rpc connection, the wallet itself, and
|
||||||
// begins syncing to the current available blockchain state.
|
// begins syncing to the current available blockchain state.
|
||||||
//
|
//
|
||||||
@ -165,6 +162,27 @@ func (b *BtcWallet) Start() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll now ensure that the KeyScope: (1017, 1) exists within the
|
||||||
|
// internal waddrmgr. We'll need this in order to properly generate the
|
||||||
|
// keys required for signing various contracts.
|
||||||
|
_, err := b.wallet.Manager.FetchScopedKeyManager(lightningKeyScope)
|
||||||
|
if err != nil {
|
||||||
|
// If the scope hasn't yet been created (it wouldn't been
|
||||||
|
// loaded by default if it was), then we'll manually create the
|
||||||
|
// scope for the first time ourselves.
|
||||||
|
err := walletdb.Update(b.db, func(tx walletdb.ReadWriteTx) error {
|
||||||
|
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||||
|
|
||||||
|
_, err := b.wallet.Manager.NewScopedKeyManager(
|
||||||
|
addrmgrNs, lightningKeyScope, lightningAddrSchema,
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +227,8 @@ func (b *BtcWallet) ConfirmedBalance(confs int32, witness bool) (btcutil.Amount,
|
|||||||
balance = outputSum
|
balance = outputSum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(roasbeef): remove witness only distinction?
|
||||||
|
|
||||||
return balance, nil
|
return balance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,24 +239,22 @@ func (b *BtcWallet) ConfirmedBalance(confs int32, witness bool) (btcutil.Amount,
|
|||||||
//
|
//
|
||||||
// This is a part of the WalletController interface.
|
// This is a part of the WalletController interface.
|
||||||
func (b *BtcWallet) NewAddress(t lnwallet.AddressType, change bool) (btcutil.Address, error) {
|
func (b *BtcWallet) NewAddress(t lnwallet.AddressType, change bool) (btcutil.Address, error) {
|
||||||
var addrType waddrmgr.AddressType
|
var keyScope waddrmgr.KeyScope
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
case lnwallet.WitnessPubKey:
|
case lnwallet.WitnessPubKey:
|
||||||
addrType = waddrmgr.WitnessPubKey
|
keyScope = waddrmgr.KeyScopeBIP0084
|
||||||
case lnwallet.NestedWitnessPubKey:
|
case lnwallet.NestedWitnessPubKey:
|
||||||
addrType = waddrmgr.NestedWitnessPubKey
|
keyScope = waddrmgr.KeyScopeBIP0049Plus
|
||||||
case lnwallet.PubKeyHash:
|
|
||||||
addrType = waddrmgr.PubKeyHash
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown address type")
|
return nil, fmt.Errorf("unknown address type")
|
||||||
}
|
}
|
||||||
|
|
||||||
if change {
|
if change {
|
||||||
return b.wallet.NewChangeAddress(defaultAccount, addrType)
|
return b.wallet.NewChangeAddress(defaultAccount, keyScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.wallet.NewAddress(defaultAccount, addrType)
|
return b.wallet.NewAddress(defaultAccount, keyScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPrivKey retrieves the underlying private key associated with the passed
|
// GetPrivKey retrieves the underlying private key associated with the passed
|
||||||
|
Loading…
Reference in New Issue
Block a user