Merge pull request #5333 from wpaulino/incompatible-account-addr-type

lnwallet: check if requested address type is compatible with account
This commit is contained in:
Olaoluwa Osuntokun 2021-05-27 19:06:13 -07:00 committed by GitHub
commit ad0ecc4d58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 49 deletions

@ -873,9 +873,9 @@ var listAccountsCommand = cli.Command{
Name: "list", Name: "list",
Usage: "Retrieve information of existing on-chain wallet accounts.", Usage: "Retrieve information of existing on-chain wallet accounts.",
Description: ` Description: `
ListAccounts retrieves all accounts belonging to the wallet by default. Retrieves all accounts belonging to the wallet by default. A name and
A name and key scope filter can be provided to filter through all of the key scope filter can be provided to filter through all of the wallet
wallet accounts and return only those matching. accounts and return only those matching.
`, `,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{

@ -70,6 +70,11 @@ var (
// requested for the default imported account within the wallet. // requested for the default imported account within the wallet.
errNoImportedAddrGen = errors.New("addresses cannot be generated for " + errNoImportedAddrGen = errors.New("addresses cannot be generated for " +
"the default imported account") "the default imported account")
// errIncompatibleAccountAddr is an error returned when the type of a
// new address being requested is incompatible with the account.
errIncompatibleAccountAddr = errors.New("incompatible address type " +
"for account")
) )
// BtcWallet is an implementation of the lnwallet.WalletController interface // BtcWallet is an implementation of the lnwallet.WalletController interface
@ -365,6 +370,43 @@ func (b *BtcWallet) ConfirmedBalance(confs int32,
return balance, nil return balance, nil
} }
// keyScopeForAccountAddr determines the appropriate key scope of an account
// based on its name/address type.
func (b *BtcWallet) keyScopeForAccountAddr(accountName string,
addrType lnwallet.AddressType) (waddrmgr.KeyScope, uint32, error) {
// Map the requested address type to its key scope.
var addrKeyScope waddrmgr.KeyScope
switch addrType {
case lnwallet.WitnessPubKey:
addrKeyScope = waddrmgr.KeyScopeBIP0084
case lnwallet.NestedWitnessPubKey:
addrKeyScope = waddrmgr.KeyScopeBIP0049Plus
default:
return waddrmgr.KeyScope{}, 0,
fmt.Errorf("unknown address type")
}
// The default account spans across multiple key scopes, so the
// requested address type should already be valid for this account.
if accountName == lnwallet.DefaultAccountName {
return addrKeyScope, defaultAccount, nil
}
// Otherwise, look up the account's key scope and check that it supports
// the requested address type.
keyScope, account, err := b.wallet.LookupAccount(accountName)
if err != nil {
return waddrmgr.KeyScope{}, 0, err
}
if keyScope != addrKeyScope {
return waddrmgr.KeyScope{}, 0, errIncompatibleAccountAddr
}
return keyScope, account, nil
}
// NewAddress returns the next external or internal address for the wallet // NewAddress returns the next external or internal address for the wallet
// dictated by the value of the `change` parameter. If change is true, then an // dictated by the value of the `change` parameter. If change is true, then an
// internal address will be returned, otherwise an external address should be // internal address will be returned, otherwise an external address should be
@ -375,32 +417,15 @@ func (b *BtcWallet) ConfirmedBalance(confs int32,
func (b *BtcWallet) NewAddress(t lnwallet.AddressType, change bool, func (b *BtcWallet) NewAddress(t lnwallet.AddressType, change bool,
accountName string) (btcutil.Address, error) { accountName string) (btcutil.Address, error) {
var ( // Addresses cannot be derived from the catch-all imported accounts.
keyScope waddrmgr.KeyScope if accountName == waddrmgr.ImportedAddrAccountName {
account uint32
)
switch accountName {
case waddrmgr.ImportedAddrAccountName:
return nil, errNoImportedAddrGen return nil, errNoImportedAddrGen
case lnwallet.DefaultAccountName:
switch t {
case lnwallet.WitnessPubKey:
keyScope = waddrmgr.KeyScopeBIP0084
case lnwallet.NestedWitnessPubKey:
keyScope = waddrmgr.KeyScopeBIP0049Plus
default:
return nil, fmt.Errorf("unknown address type")
} }
account = defaultAccount
default: keyScope, account, err := b.keyScopeForAccountAddr(accountName, t)
var err error
keyScope, account, err = b.wallet.LookupAccount(accountName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
if change { if change {
return b.wallet.NewChangeAddress(account, keyScope) return b.wallet.NewChangeAddress(account, keyScope)
@ -418,32 +443,15 @@ func (b *BtcWallet) NewAddress(t lnwallet.AddressType, change bool,
func (b *BtcWallet) LastUnusedAddress(addrType lnwallet.AddressType, func (b *BtcWallet) LastUnusedAddress(addrType lnwallet.AddressType,
accountName string) (btcutil.Address, error) { accountName string) (btcutil.Address, error) {
var ( // Addresses cannot be derived from the catch-all imported accounts.
keyScope waddrmgr.KeyScope if accountName == waddrmgr.ImportedAddrAccountName {
account uint32
)
switch accountName {
case waddrmgr.ImportedAddrAccountName:
return nil, errNoImportedAddrGen return nil, errNoImportedAddrGen
case lnwallet.DefaultAccountName:
switch addrType {
case lnwallet.WitnessPubKey:
keyScope = waddrmgr.KeyScopeBIP0084
case lnwallet.NestedWitnessPubKey:
keyScope = waddrmgr.KeyScopeBIP0049Plus
default:
return nil, fmt.Errorf("unknown address type")
} }
account = defaultAccount
default: keyScope, account, err := b.keyScopeForAccountAddr(accountName, addrType)
var err error
keyScope, account, err = b.wallet.LookupAccount(accountName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
return b.wallet.CurrentAddress(account, keyScope) return b.wallet.CurrentAddress(account, keyScope)
} }