walletrpc+btcwallet: no custom account with various key scopes

Currently, a user can create a custom account with various key scopes.
This is not a desired behaviour.
This commit is contained in:
Torakushi 2023-02-17 18:06:19 +01:00
parent dd5ed71669
commit 77d3f00c3b
No known key found for this signature in database
GPG Key ID: 19C7D027EAB8B169
4 changed files with 70 additions and 0 deletions

View File

@ -1447,6 +1447,9 @@ var importAccountCommand = cli.Command{
The address type can usually be inferred from the key's version, but may The address type can usually be inferred from the key's version, but may
be required for certain keys to map them into the proper scope. be required for certain keys to map them into the proper scope.
If an account with the same name already exists (even with a different
key scope), an error will be returned.
For BIP-0044 keys, an address type must be specified as we intend to not For BIP-0044 keys, an address type must be specified as we intend to not
support importing BIP-0044 keys into the wallet using the legacy support importing BIP-0044 keys into the wallet using the legacy
pay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will pay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will

View File

@ -2,6 +2,7 @@ package itest
import ( import (
"bytes" "bytes"
"fmt"
"testing" "testing"
"time" "time"
@ -468,6 +469,10 @@ func testWalletImportAccount(ht *lntest.HarnessTest) {
name string name string
addrType walletrpc.AddressType addrType walletrpc.AddressType
}{ }{
{
name: "standard BIP-0044",
addrType: walletrpc.AddressType_WITNESS_PUBKEY_HASH,
},
{ {
name: "standard BIP-0049", name: "standard BIP-0049",
addrType: walletrpc. addrType: walletrpc.
@ -550,6 +555,34 @@ func runWalletImportAccountScenario(ht *lntest.HarnessTest,
} }
dave.RPC.ImportAccount(importReq) dave.RPC.ImportAccount(importReq)
// Try to import an account with the same name but with a different
// key scope. It should return an error.
otherAddrType := walletrpc.AddressType_TAPROOT_PUBKEY
if addrType == walletrpc.AddressType_TAPROOT_PUBKEY {
otherAddrType--
}
listReq = &walletrpc.ListAccountsRequest{
Name: "default",
AddressType: otherAddrType,
}
listResp = carol.RPC.ListAccounts(listReq)
require.Len(ht, listResp.Accounts, 1)
carolAccountOtherAddrType := listResp.Accounts[0]
errAccountExists := fmt.Sprintf(
"account '%s' already exists", importedAccount,
)
importReq = &walletrpc.ImportAccountRequest{
Name: importedAccount,
ExtendedPublicKey: carolAccountOtherAddrType.ExtendedPublicKey,
AddressType: otherAddrType,
}
err := dave.RPC.ImportAccountAssertErr(importReq)
require.ErrorContains(ht, err, errAccountExists)
// We'll generate an address for Carol from Dave's node to receive some // We'll generate an address for Carol from Dave's node to receive some
// funds. // funds.
externalAddr := newExternalAddr( externalAddr := newExternalAddr(

View File

@ -235,6 +235,20 @@ func (h *HarnessRPC) ImportAccount(
return resp return resp
} }
// ImportAccountAssertErr makes the ImportAccount RPC call and asserts an error
// is returned. It then returns the error.
func (h *HarnessRPC) ImportAccountAssertErr(
req *walletrpc.ImportAccountRequest) error {
ctxt, cancel := context.WithTimeout(h.runCtx, DefaultTimeout)
defer cancel()
_, err := h.WalletKit.ImportAccount(ctxt, req)
require.Error(h, err)
return err
}
// ImportPublicKey makes a RPC call to the node's WalletKitClient and asserts. // ImportPublicKey makes a RPC call to the node's WalletKitClient and asserts.
// //
//nolint:lll //nolint:lll

View File

@ -843,6 +843,10 @@ func (b *BtcWallet) ListAddresses(name string,
// The address type can usually be inferred from the key's version, but may be // The address type can usually be inferred from the key's version, but may be
// required for certain keys to map them into the proper scope. // required for certain keys to map them into the proper scope.
// //
// For custom accounts, we will first check if there is no account with the same
// name (even with a different key scope). No custom account should have various
// key scopes as it will result in non-deterministic behaviour.
//
// For BIP-0044 keys, an address type must be specified as we intend to not // For BIP-0044 keys, an address type must be specified as we intend to not
// support importing BIP-0044 keys into the wallet using the legacy // support importing BIP-0044 keys into the wallet using the legacy
// pay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will force // pay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will force
@ -860,6 +864,22 @@ func (b *BtcWallet) ImportAccount(name string, accountPubKey *hdkeychain.Extende
dryRun bool) (*waddrmgr.AccountProperties, []btcutil.Address, dryRun bool) (*waddrmgr.AccountProperties, []btcutil.Address,
[]btcutil.Address, error) { []btcutil.Address, error) {
// For custom accounts, we first check if there is no existing account
// with the same name.
if name != lnwallet.DefaultAccountName &&
name != waddrmgr.ImportedAddrAccountName {
_, err := b.ListAccounts(name, nil)
if err == nil {
return nil, nil, nil,
fmt.Errorf("account '%s' already exists",
name)
}
if !waddrmgr.IsError(err, waddrmgr.ErrAccountNotFound) {
return nil, nil, nil, err
}
}
if !dryRun { if !dryRun {
accountProps, err := b.wallet.ImportAccount( accountProps, err := b.wallet.ImportAccount(
name, accountPubKey, masterKeyFingerprint, addrType, name, accountPubKey, masterKeyFingerprint, addrType,