Merge #16786: test: add unit test for wallet watch-only methods involving PubKeys

a57a1d42d52fe51e5b413a1fd3a5ef2b7a2120e3 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 798a589aff64b83a0844688a661f4bd987c3340c) 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 a57a1d42d5
  Sjors:
    re-ACK a57a1d4

Tree-SHA512: 92a242204ab533022cd848662997372c41815b1265d07b3d96305697f801db29a5ba5668337faf4bea702bec1451972529afd6665927fb142aaf91700a338b26
This commit is contained in:
MarcoFalke 2019-10-10 12:09:25 -04:00 committed by PastaPastaPasta
parent 3f491fa7cb
commit a6d4946580

View File

@ -498,6 +498,84 @@ BOOST_AUTO_TEST_CASE(LoadReceiveRequests)
BOOST_CHECK_EQUAL(values[1], "val_rr1");
}
// Test some watch-only wallet methods by the procedure of loading (LoadWatchOnly),
// checking (HaveWatchOnly), getting (GetWatchPubKey) and removing (RemoveWatchOnly) a
// given PubKey, resp. its corresponding P2PK Script. Results of the the impact on
// the address -> PubKey map is dependent on whether the PubKey is a point on the curve
static void TestWatchOnlyPubKey(CWallet& wallet, const CPubKey& add_pubkey)
{
CScript p2pk = GetScriptForRawPubKey(add_pubkey);
CKeyID add_address = add_pubkey.GetID();
CPubKey found_pubkey;
LOCK(wallet.cs_wallet);
// all Scripts (i.e. also all PubKeys) are added to the general watch-only set
BOOST_CHECK(!wallet.HaveWatchOnly(p2pk));
wallet.LoadWatchOnly(p2pk);
BOOST_CHECK(wallet.HaveWatchOnly(p2pk));
// only PubKeys on the curve shall be added to the watch-only address -> PubKey map
bool is_pubkey_fully_valid = add_pubkey.IsFullyValid();
if (is_pubkey_fully_valid) {
BOOST_CHECK(wallet.GetWatchPubKey(add_address, found_pubkey));
BOOST_CHECK(found_pubkey == add_pubkey);
} else {
BOOST_CHECK(!wallet.GetWatchPubKey(add_address, found_pubkey));
BOOST_CHECK(found_pubkey == CPubKey()); // passed key is unchanged
}
wallet.RemoveWatchOnly(p2pk);
BOOST_CHECK(!wallet.HaveWatchOnly(p2pk));
if (is_pubkey_fully_valid) {
BOOST_CHECK(!wallet.GetWatchPubKey(add_address, found_pubkey));
BOOST_CHECK(found_pubkey == add_pubkey); // passed key is unchanged
}
}
// Cryptographically invalidate a PubKey whilst keeping length and first byte
static void PollutePubKey(CPubKey& pubkey)
{
std::vector<unsigned char> pubkey_raw(pubkey.begin(), pubkey.end());
std::fill(pubkey_raw.begin()+1, pubkey_raw.end(), 0);
pubkey = CPubKey(pubkey_raw);
assert(!pubkey.IsFullyValid());
assert(pubkey.IsValid());
}
// Test watch-only wallet logic for PubKeys
BOOST_AUTO_TEST_CASE(WatchOnlyPubKeys)
{
CKey key;
CPubKey pubkey;
BOOST_CHECK(!m_wallet.HaveWatchOnly());
// uncompressed valid PubKey
key.MakeNewKey(false);
pubkey = key.GetPubKey();
assert(!pubkey.IsCompressed());
TestWatchOnlyPubKey(m_wallet, pubkey);
// uncompressed cryptographically invalid PubKey
PollutePubKey(pubkey);
TestWatchOnlyPubKey(m_wallet, pubkey);
// compressed valid PubKey
key.MakeNewKey(true);
pubkey = key.GetPubKey();
assert(pubkey.IsCompressed());
TestWatchOnlyPubKey(m_wallet, pubkey);
// compressed cryptographically invalid PubKey
PollutePubKey(pubkey);
TestWatchOnlyPubKey(m_wallet, pubkey);
// invalid empty PubKey
pubkey = CPubKey();
TestWatchOnlyPubKey(m_wallet, pubkey);
}
class ListCoinsTestingSetup : public TestChain100Setup
{
public: