-
Notifications
You must be signed in to change notification settings - Fork 812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wallet: add "accountPath" attribute to handle edges cases with watch-only accountKeys #689
base: master
Are you sure you want to change the base?
Conversation
Motivation: In case of watch-only wallets, accountIndex is "arbitrary". It simply maps to internal walletdb account instead of BIP44 account path as defined in original accountKey. It is important to return the actual accountIndex for use-cases such as hardware-wallets, so clients can easily reproduce the original path for this account. To maintain backwards compatbility with existing wallets, it is easiest to add this as a separate accountPath field instead of refactoring all the existing uses of accountIndex.
|
||
account.accountPath = childIndex ^ HDCommon.HARDENED; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the account key's child index is already hardened, and therefore already > 0x80000000
so I think this xor is redundant. And actually if the imported xpub for whatever reason is not hardened, we probably need to leave it that way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This returns the expected value for hardened keys, which should always be the case with xpubs. (eg, returns accountPath '1' instead of '2147483649`). Perhaps there are edge cases of non-hardened xpubs, but not sure how to handle that one...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see its an xor
not or
so the constant gets cancelled out 👍
@braydonf @tuxcanfly @nodar-chkuaselidze @boymanjor |
So I think that this is likely a validation issue for watch-only wallet and account creation: The accountKey (the xpub) for wallet creation is not validated to be the BIP44 Because the account key is hardened ( When creating accounts for that wallet, I was also able to create an account for the wallet derived at The fingerprint in the account xpub can be used to verify that this is a derived xpub of the wallet, and further that the account of the xpub matches what is expected. Being able to import arbitrary account numbers into the wallet could potentially lead to issues during recovery of the wallet from the seed, as there could be around |
When importing xpub, you are expected to import You must not import To limit wallet to one Master, you could use As for bcoin.index <-> xpub.index mapping, it will need bigger refactor. wallet will need to allow gaps defined by users. As for recovering from the seed, I believe user is in charge of naming/creating those accounts, without naming them accounts are not much of use. Unfortunately, current API wont allow to use arbitrary number as a accountIndex, even if you want to have indexes - 0, 100, 1000 only. (Only way to use it this way would be watchOnly) |
Regarding gaps between accounts:
|
Then, simplest solution for this problem would be to enforce importing xpubs from 0.
-- edit: |
Okay here are the test cases that demonstrate the issues: #696 |
I don't completely follow the case with gaps between accounts for the purposes of running on different machines. Consider this case:
That creates the case that deviates from what BIP44 specifies, and in an attempt to rescan based on the original mnemonic phrase could miss potential coins. |
When you are importing Account gap that you mean is when you have Master key available and if we supported automatic account creation on master key import (that's not the case and I don't think it should be, you can't recover names, better create those accounts one by one (meaning derive next account, accountDepth in our case)). In that case you CANT skip account, so bip44 rule is still preserved, you have to create one by one. If I only want import watchOnly xpub with account index 10 - let's say I use it for something specific, I don't care anything else (on this machine or maybe right now), I should not have to import xpubs as watchOnly I don't care about. |
The wallet has the perspective of many accounts as a whole organized set, for example a BIP44 wallet. In the case the wallet has a master private seed, it can derive all accounts. In the case of watch-only, that derivation has to be done externally. The external derivation is unaware of which accounts do or do not have transactions (no access to chain or block data), and is unable to apply the BIP44 logic that "Software should prevent a creation of an account if a previous account does not have a transaction history". Thus the watch-only wallet needs to take care of that. |
I've created an issue specifically for the gaps between accounts: #698 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Motivation:
In case of watch-only wallets, accountIndex is "arbitrary".
It simply maps to internal walletdb account instead of
BIP44 account path as defined in original accountKey.
It is important to return the actual accountIndex for use-cases
such as hardware-wallets, so clients can easily reproduce the
original path for this account.
To maintain backwards compatbility with existing wallets,
it is easiest to add this as a separate accountPath field
instead of refactoring all the existing uses of accountIndex.
Note: This was discussed out-of-band and after many iterations we decided adding a new field is probably the simplest solution. At the very least it results in the fewest code changes.