-
Notifications
You must be signed in to change notification settings - Fork 600
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
Import external watch-only addresses #204
base: master
Are you sure you want to change the base?
Conversation
1a1eb59
to
7f91bd7
Compare
7f91bd7
to
cfbd1cb
Compare
@@ -549,14 +581,14 @@ func putNumAccounts(tx walletdb.Tx, numAccounts uint32) error { | |||
// the common parts. | |||
func deserializeAddressRow(addressID, serializedAddress []byte) (*dbAddressRow, error) { | |||
// The serialized address format is: | |||
// <addrType><account><addedTime><syncStatus><rawdata> | |||
// <addrType><account><addedTime><syncStatus><watchingOnly><rawdata> |
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.
Why do we need a watching only flag as well as an adtWatching
address type? It would be ideal to avoid changing this format because, if you do, you'll have to write upgrade code and modify every existing address in the database which I think we really don't want to do.
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.
After thinking about it some more, I think having the extra field is more flexible. However, at the moment there is some redundancy with the adtWatching
type that doesn't quite feel right.
If we look at it from the perspective of what a user will need to do for watching-only purposes:
- Import BIP0032 public key chains
- Import "loose" public keys (those which are not a part of BIP0032 key chain)
- Import the hash160 associated with a pay-to-script-hash
Considering that, the first case is an adtChain
with a watching-only flag, the second is an adtImport
with a watching-only flag, and the third is an adtScript
with a watching-only flag.
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.
Updated to only use the watchingOnly
flag and removed adtWatching
type. Importing "loose" public keys and P2SH hashes works using the importpubkey
and importaddress
commands. Now working on importing public key chains.
Now working on importing BIP0032 public key chains.
cfbd1cb
to
a04ef44
Compare
3e647c4
to
7d2bf04
Compare
internal bool | ||
compressed bool | ||
used bool | ||
publicAddress |
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.
What is the purpose of splitting this out?
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 thought it might be logical to separate the structs for loose vs keychain addrs for future e.g if we wanted to add a method specific to loose addrs.
Since the format of existing addresses in the db is being changed here, the db version needs to be bumped and it needs upgrade code to handle the new serialization. You should be able to do it without requiring the private passphrase by specifically targetting the new field offset. |
348af4d
to
c634317
Compare
Yeah, we will need a upgrade to initialize the |
3a3c1eb
to
b0e29ec
Compare
@davecgh Added upgrade path, addressed items reviewed above. Tested that we support importing pubkeys, p2pkh and p2sh addresses now. |
0d839f6
to
4f843cb
Compare
@@ -902,35 +927,48 @@ func deserializeImportedAddress(row *dbAddressRow) (*dbImportedAddressRow, error | |||
dbAddressRow: *row, | |||
} | |||
|
|||
pubLen := binary.LittleEndian.Uint32(row.rawData[0:4]) | |||
pkHashLen := binary.LittleEndian.Uint32(row.rawData[0:4]) |
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.
Please stick with the existing offset approach. There is less chance of error when updating the code with that approach.
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.
Reminder to take care of this. I don't particularly care for offset variables, but to be consistent with the rest of the package, it should create the offset var first, and then slice between [offset:offset+fieldlen]
.
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.
They are superior to 4+4+8+len(thing)+x+y+len(z.foo). And then each field has to repeat that from the last, etc.
EDIT: The recent conversation from the ppcd folks having to deal with all those magic offsets everywhere is a prime example of how they help as well.
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.
With variable-sized data I agree
8ea8bed
to
8847744
Compare
@@ -62,11 +65,11 @@ type ManagedPubKeyAddress interface { | |||
ManagedAddress | |||
|
|||
// PubKey returns the public key associated with the address. | |||
PubKey() *btcec.PublicKey | |||
PubKey() (*btcec.PublicKey, error) |
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 we should change the signature not to introduce an error (for the not-exists case) but to return the public key and a boolean for whether the pubkey is compressed or not. Since watching addresses can be imported without the pubkey, not having the pubkey exist is now a totally valid state, and the caller must determine whether not existing is an error or not.
For the not-exists case, we would either need another (a second) bool return, or return a nil pubkey. I'm leaning towards the additional return to avoid situations where the caller forgets to check for the nil case, since the Go type system isn't strong enough to enforce this.
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.
OK, we already have a db field called compressed
on managedAddress
which we are using for determining whether the pubkey is compressed or not. If we change the signature we might want to remove that field to avoid ambiguity.
Also, the PubKey
signature is consistent with PrivKey
which returns ErrWatchingOnly
when private key is not available.
} | ||
|
||
var compressed bool | ||
switch n := len(pubKeyBytes); n { |
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 this whole switch can be removed. The correct length is checked by ParsePubKey
below. All you would need to pass to ImportPubKey
is the bool len(pubKeyBytes) == btcec.PubKeyBytesLenCompressed
.
I kind of think that the btcec type should save whether the pubkey was compressed or not, but oh well.
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.
Thanks, removed the swtich and simplified this.
1019144
to
7b3e16f
Compare
OK, updated |
c1be9db
to
e670502
Compare
The changed methods need better documentation to describe what all the return values are. Either the interface definition can use named returns to document the values, or comments should be added to describe what each bool means. |
Thanks, using named returns in the interface and also updated docs about the return values. |
c8edcc6
to
3d6cc83
Compare
In 6ee1f9b, Manager.Address was updated to convert PK addr to PKH addr so that the db is always keyed by script hash. This commit fixes ImportAddress to use the same key while fetching the addr from the db.
ba7c06e
to
1444b51
Compare
What's the status on this? The corresponding PRs btcsuite/btcd#279 and btcsuite/btcjson#41 were merged a long time ago. Did #192 "supersede" this PR? |
There are several conflicts preventing this from being merged. There will be even more conflicts if decred/dcrwallet#315 is backported to btcwallet. We're also moving away from the idea of importing keys into a HD wallet, both to simplify our code and to make the entire wallet recoverable from just the seed. Would need a discussion about if we still even want this feature. |
Added RPC commands to import external watch-only addresses both with and without pubkeys. WIP on finishing test coverage and docs.
Refs #192