Skip to content

Conversation

@theStack
Copy link
Contributor

@theStack theStack commented Sep 1, 2019

The motivation for this addition was to unit test the function wallet.cpp:ExtractPubKey() (see recent change in commit 798a589) which is however static and only indirectly available via the public methods AddWatchOnly(), LoadWatchOnly() and RemoveWatchOnly(). Since the first of those methods also stores the addresses to the disk, the second, simpler one was chosen which only operates in memory.

@fanquake
Copy link
Member

fanquake commented Sep 3, 2019

This is currently failing on Travis:

wallet/test/wallet_tests.cpp(381): Entering test case "WatchOnlyPubKeys"
Assertion failed: lock cs_wallet not held in wallet/wallet.cpp:578; locks held:
unknown location(0): fatal error: in "wallet_tests/WatchOnlyPubKeys": signal: SIGABRT (application abort requested)
wallet/test/wallet_tests.cpp(357): last checkpoint
wallet/test/wallet_tests.cpp(381): Leaving test case "WatchOnlyPubKeys"; testing time: 138195us
wallet/test/wallet_tests.cpp:362:5: error: calling function 'RemoveWatchOnly' requires holding mutex 'wallet.cs_wallet' exclusively [-Werror,-Wthread-safety-analysis]
    wallet.RemoveWatchOnly(p2pk);
    ^
1 error generated.

You'll need to add some locking LOCK(wallet->cs_wallet);

@theStack
Copy link
Contributor Author

theStack commented Sep 3, 2019

This is currently failing on Travis:
...
You'll need to add some locking LOCK(wallet->cs_wallet);

Thanks, done (f74dc7ea05cf466077c6f46910ae4228373656e4). It took me quite a while to reproduce this warning, obviously it only appears compiling with clang (which makes sense after looking at src/threadsafety.h, where all the defines like e.g. EXCLUSIVE_LOCKS_REQUIRED are empty for g++).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also assert what found_pubkey ends up being in this situation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found_pubkey isn't touched when no PubKey is found, but of course this fact can be tested as well by asserting it to be a newly constructed (and thus invalid) PubKey.

@instagibbs
Copy link
Member

you should just squash the 2 commits together

@theStack theStack force-pushed the add_wallet_watchpubkey_unit_test branch from f74dc7e to d0e1d33 Compare September 3, 2019 14:17
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: braces

As above, you should also check that found_pubkey is the default CPubKey.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since GetWatchPubKey doesn't modify the passed PubKey if it returns false, it would still have the same contents as before, so in this case the correct assertion would be found_pubkey == add_pubkey. To not confuse the reader (one could wrongly assume that this assert checks for an explicit modification by the function in this case as well), I add the comment // passed key is unchanged for those two cases.

@theStack theStack force-pushed the add_wallet_watchpubkey_unit_test branch from d613804 to 3a219e8 Compare September 7, 2019 13:43
Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

Copy link
Member

@achow101 achow101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review ACK 3a219e82304c7f62d75369d6ee55111f601cc892

The motivation for this addition was to unit test the function
wallet.cpp:ExtractPubKey() (see recent change in commit
798a589) which is however static and only
indirectly available via the public methods AddWatchOnly(), LoadWatchOnly() and
RemoveWatchOnly(). Since the first of those methods also stores the addresses
to the disk, the second, simpler one was chosen which only operates in memory.

test: add missing wallet lock for test case WatchOnlyPubKeys

test: test case WatchOnlyPubKeys, suggested review changes by instagibbs

test: test case WatchOnlyPubKeys, suggested review changes by achow101

test: test case WatchOnlyPubKeys, s/isPubKeyFullyValid/is_pubkey_fully_valid
@theStack theStack force-pushed the add_wallet_watchpubkey_unit_test branch from 601698c to a57a1d4 Compare September 16, 2019 21:24
@theStack
Copy link
Contributor Author

@instagibbs @achow101 Thanks for your reviews!

@Sjors
Copy link
Member

Sjors commented Sep 19, 2019

ACK a57a1d4

As an aside, in case anyone wants to test P2PK functionality (on testnet), here's a fun tool: https://github.com/dianerey/bech32p2pkaddress (no need to provide inputs in the Python script, just use fundrawtransaction and signrawtransactionwithwallet).

When you import a pubkey using importpubkey, the wallet watches for P2PK transactions as well. It also happily imports invalid pubkeys to watch. The same goes for importaddress 21PUBKEYac (P2PK script). The wallet also happily signs raw transactions to such keys, which should make anyone appreciate checksums.

Although the above scenarios are rather contrived, should we have some RPC methods check if a pubkey is on a curve?

@theStack
Copy link
Contributor Author

@Sjors: Thanks for the review!

When you import a pubkey using importpubkey, the wallet watches for P2PK transactions as well. It also happily imports invalid pubkeys to watch. The same goes for importaddress 21PUBKEYac (P2PK script). The wallet also happily signs raw transactions to such keys, which should make anyone appreciate checksums.

Are you sure that importpubkey imports invalid pubkeys? Can you give an example? Looking at wallet/rpcdump.cpp:importpubkey() there is a check if the given pubkey is on the curve, throwing an error if it isn't:

if (!pubKey.IsFullyValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key");

@Sjors
Copy link
Member

Sjors commented Sep 19, 2019

Oops, I just changed one character in the pubkey hex thinking that would do the trick, but of course with a compressed pubkey such a tweaked point is most likely still on the curve.

importpubkey 020000000000000000000000000000000000000000000000000000000000000000 indeed throws. importaddress 21020000000000000000000000000000000000000000000000000000000000000000ac does work.

@theStack
Copy link
Contributor Author

Oops, I just changed one character in the pubkey hex thinking that would do the trick, but of course with a compressed pubkey such a tweaked point is most likely still on the curve.

Okay 👍

importpubkey 020000000000000000000000000000000000000000000000000000000000000000 indeed throws. importaddress 21020000000000000000000000000000000000000000000000000000000000000000ac does work.

Looking at the code, importaddress doesn't try to interpret (or validate) the contents of the passed hex-encoded script in any way but rather passes it to the wallet directly via ImportScripts() and ImportScriptPubKeys(). The RPC manual says to this call "If you have the full public key, you should call importpubkey instead of this.", so I guess it is okay that there is no on-the-curve check here for pubkeys contained in P2PK scripts.

@theStack
Copy link
Contributor Author

Since there has been no activity for three weeks: is there anything else I can do for this PR?

@instagibbs
Copy link
Member

reACK a57a1d4

just squashed

Copy link
Member

@Sjors Sjors left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re-ACK a57a1d4

maflcko pushed a commit that referenced this pull request Oct 10, 2019
…ving PubKeys

a57a1d4 test: add unit test for wallet watch-only methods involving PubKeys (Sebastian Falbesoner)

Pull request description:

  The motivation for this addition was to unit test the function `wallet.cpp:ExtractPubKey()` (see recent change in commit 798a589) which is however static and only indirectly available via the public methods `AddWatchOnly()`, `LoadWatchOnly()` and `RemoveWatchOnly()`. Since the first of those methods also stores the addresses to the disk, the second, simpler one was chosen which only operates in memory.

ACKs for top commit:
  Sjors:
    ACK a57a1d4
  instagibbs:
    reACK a57a1d4
  Sjors:
    re-ACK a57a1d4

Tree-SHA512: 92a242204ab533022cd848662997372c41815b1265d07b3d96305697f801db29a5ba5668337faf4bea702bec1451972529afd6665927fb142aaf91700a338b26
@maflcko maflcko merged commit a57a1d4 into bitcoin:master Oct 10, 2019
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 11, 2019
…s involving PubKeys

a57a1d4 test: add unit test for wallet watch-only methods involving PubKeys (Sebastian Falbesoner)

Pull request description:

  The motivation for this addition was to unit test the function `wallet.cpp:ExtractPubKey()` (see recent change in commit 798a589) which is however static and only indirectly available via the public methods `AddWatchOnly()`, `LoadWatchOnly()` and `RemoveWatchOnly()`. Since the first of those methods also stores the addresses to the disk, the second, simpler one was chosen which only operates in memory.

ACKs for top commit:
  Sjors:
    ACK a57a1d4
  instagibbs:
    reACK bitcoin@a57a1d4
  Sjors:
    re-ACK a57a1d4

Tree-SHA512: 92a242204ab533022cd848662997372c41815b1265d07b3d96305697f801db29a5ba5668337faf4bea702bec1451972529afd6665927fb142aaf91700a338b26
@theStack theStack deleted the add_wallet_watchpubkey_unit_test branch December 1, 2020 09:59
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Sep 11, 2021
…s involving PubKeys

a57a1d4 test: add unit test for wallet watch-only methods involving PubKeys (Sebastian Falbesoner)

Pull request description:

  The motivation for this addition was to unit test the function `wallet.cpp:ExtractPubKey()` (see recent change in commit 798a589) which is however static and only indirectly available via the public methods `AddWatchOnly()`, `LoadWatchOnly()` and `RemoveWatchOnly()`. Since the first of those methods also stores the addresses to the disk, the second, simpler one was chosen which only operates in memory.

ACKs for top commit:
  Sjors:
    ACK a57a1d4
  instagibbs:
    reACK bitcoin@a57a1d4
  Sjors:
    re-ACK a57a1d4

Tree-SHA512: 92a242204ab533022cd848662997372c41815b1265d07b3d96305697f801db29a5ba5668337faf4bea702bec1451972529afd6665927fb142aaf91700a338b26
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants