From 798113a024ab2e3210976232a565c8e5555c77eb Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 25 May 2021 15:59:59 -0700 Subject: [PATCH 1/3] lnwallet: refactor common logic between NewAddress and LastUnusedAddress --- lnwallet/btcwallet/btcwallet.go | 94 +++++++++++++++++---------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/lnwallet/btcwallet/btcwallet.go b/lnwallet/btcwallet/btcwallet.go index 8cf9a845..141b2878 100644 --- a/lnwallet/btcwallet/btcwallet.go +++ b/lnwallet/btcwallet/btcwallet.go @@ -70,6 +70,10 @@ var ( // requested for the default imported account within the wallet. errNoImportedAddrGen = errors.New("addresses cannot be generated for " + "the default imported account") + + // errIncompatibleAccountAddr + errIncompatibleAccountAddr = errors.New("incompatible address type " + + "for account") ) // BtcWallet is an implementation of the lnwallet.WalletController interface @@ -365,6 +369,38 @@ func (b *BtcWallet) ConfirmedBalance(confs int32, 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. + keyScope, account, err := b.wallet.LookupAccount(accountName) + if err != nil { + return waddrmgr.KeyScope{}, 0, err + } + + return keyScope, account, nil +} + // 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 // internal address will be returned, otherwise an external address should be @@ -375,31 +411,14 @@ func (b *BtcWallet) ConfirmedBalance(confs int32, func (b *BtcWallet) NewAddress(t lnwallet.AddressType, change bool, accountName string) (btcutil.Address, error) { - var ( - keyScope waddrmgr.KeyScope - account uint32 - ) - switch accountName { - case waddrmgr.ImportedAddrAccountName: + // Addresses cannot be derived from the catch-all imported accounts. + if accountName == waddrmgr.ImportedAddrAccountName { 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: - var err error - keyScope, account, err = b.wallet.LookupAccount(accountName) - if err != nil { - return nil, err - } + keyScope, account, err := b.keyScopeForAccountAddr(accountName, t) + if err != nil { + return nil, err } if change { @@ -418,31 +437,14 @@ func (b *BtcWallet) NewAddress(t lnwallet.AddressType, change bool, func (b *BtcWallet) LastUnusedAddress(addrType lnwallet.AddressType, accountName string) (btcutil.Address, error) { - var ( - keyScope waddrmgr.KeyScope - account uint32 - ) - switch accountName { - case waddrmgr.ImportedAddrAccountName: + // Addresses cannot be derived from the catch-all imported accounts. + if accountName == waddrmgr.ImportedAddrAccountName { 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: - var err error - keyScope, account, err = b.wallet.LookupAccount(accountName) - if err != nil { - return nil, err - } + keyScope, account, err := b.keyScopeForAccountAddr(accountName, addrType) + if err != nil { + return nil, err } return b.wallet.CurrentAddress(account, keyScope) From 8745cf03c1502a687e240e51cd705d20e9137601 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 25 May 2021 16:08:23 -0700 Subject: [PATCH 2/3] lnwallet: check if requested address type is compatible with account --- lnwallet/btcwallet/btcwallet.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lnwallet/btcwallet/btcwallet.go b/lnwallet/btcwallet/btcwallet.go index 141b2878..09ffb77b 100644 --- a/lnwallet/btcwallet/btcwallet.go +++ b/lnwallet/btcwallet/btcwallet.go @@ -71,7 +71,8 @@ var ( errNoImportedAddrGen = errors.New("addresses cannot be generated for " + "the default imported account") - // errIncompatibleAccountAddr + // 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") ) @@ -392,12 +393,17 @@ func (b *BtcWallet) keyScopeForAccountAddr(accountName string, return addrKeyScope, defaultAccount, nil } - // Otherwise, look up the account's key scope. + // 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 } From f195f21c8c33a8649de52ede51784c41b64f1af7 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 25 May 2021 16:09:48 -0700 Subject: [PATCH 3/3] lncli: remove RPC name from list wallet accounts command description --- cmd/lncli/walletrpc_active.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/lncli/walletrpc_active.go b/cmd/lncli/walletrpc_active.go index ad2561e2..21870d46 100644 --- a/cmd/lncli/walletrpc_active.go +++ b/cmd/lncli/walletrpc_active.go @@ -873,9 +873,9 @@ var listAccountsCommand = cli.Command{ Name: "list", Usage: "Retrieve information of existing on-chain wallet accounts.", Description: ` - ListAccounts retrieves all accounts belonging to the wallet by default. - A name and key scope filter can be provided to filter through all of the - wallet accounts and return only those matching. + Retrieves all accounts belonging to the wallet by default. A name and + key scope filter can be provided to filter through all of the wallet + accounts and return only those matching. `, Flags: []cli.Flag{ cli.StringFlag{