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

The motivation for this addition was to unit test the function
wallet.cpp:ExtractPubKey() (see recent change in commit
798a589aff) 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
This commit is contained in:
Sebastian Falbesoner 2019-09-01 22:10:51 +02:00
parent d3e672119e
commit a57a1d42d5

View file

@ -334,6 +334,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: