Skip to content

Commit

Permalink
test: rewrite rpc_wallet_encrypted_wallet_sapzkeys unit test as funct…
Browse files Browse the repository at this point in the history
…ional test

As it requires a complete real wallet, and not a mocked one, in order to perform the encryption checks, it's by definition a functional test.
  • Loading branch information
furszy committed Jan 14, 2022
1 parent 2f8a034 commit 13bb5c1
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 71 deletions.
71 changes: 0 additions & 71 deletions src/test/librust/sapling_rpc_wallet_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,77 +498,6 @@ BOOST_AUTO_TEST_CASE(rpc_shieldsendmany_taddr_to_sapling)
vpwallets.erase(vpwallets.begin());
}

struct RealWalletTestingSetup : public WalletTestingSetupBase
{
RealWalletTestingSetup() : WalletTestingSetupBase(CBaseChainParams::MAIN,
"test_wallet",
WalletDatabase::Create(fs::absolute("test_wallet", GetWalletDir()))) {};
};

BOOST_FIXTURE_TEST_CASE(rpc_wallet_encrypted_wallet_sapzkeys, RealWalletTestingSetup)
{
UniValue retValue;
int n = 100;

{
LOCK(m_wallet.cs_wallet);
m_wallet.SetMinVersion(FEATURE_SAPLING);
m_wallet.SetupSPKM(false);
}
vpwallets.insert(vpwallets.begin(), &m_wallet);

// wallet should currently be empty
std::set<libzcash::SaplingPaymentAddress> addrs;
m_wallet.GetSaplingPaymentAddresses(addrs);
BOOST_CHECK(addrs.empty());

// create keys
for (int i = 0; i < n; i++) {
CallRPC("getnewshieldaddress");
}

// Verify we can list the keys imported
BOOST_CHECK_NO_THROW(retValue = CallRPC("listshieldaddresses"));
UniValue arr = retValue.get_array();
BOOST_CHECK((int) arr.size() == n);

// Verify that the wallet encryption RPC is disabled
// TODO: We don't have the experimental mode to disable the encryptwallet disable.
//BOOST_CHECK_THROW(CallRPC("encryptwallet passphrase"), std::runtime_error);

// Encrypt the wallet (we can't call RPC encryptwallet as that shuts down node)
SecureString strWalletPass;
strWalletPass.reserve(100);
strWalletPass = "hello";

PushCurrentDirectory push_dir(gArgs.GetArg("-datadir","/tmp/thisshouldnothappen"));
BOOST_CHECK(m_wallet.EncryptWallet(strWalletPass));
BOOST_CHECK(m_wallet.IsCrypted());

// Verify we can still list the keys imported
BOOST_CHECK_NO_THROW(retValue = CallRPC("listshieldaddresses"));
arr = retValue.get_array();
BOOST_CHECK((int) arr.size() == n);

// Try to add a new key, but we can't as the wallet is locked
BOOST_CHECK_THROW(CallRPC("getnewshieldaddress"), std::runtime_error);

// We can't call RPC walletpassphrase as that invokes RPCRunLater which breaks tests.
// So we manually unlock.
BOOST_CHECK(m_wallet.Unlock(strWalletPass));
BOOST_CHECK(m_wallet.IsCrypted());

// Now add a key
BOOST_CHECK_NO_THROW(CallRPC("getnewshieldaddress"));

// Verify the key has been added
BOOST_CHECK_NO_THROW(retValue = CallRPC("listshieldaddresses"));
arr = retValue.get_array();
BOOST_CHECK((int) arr.size() == n+1);

vpwallets.erase(vpwallets.begin());
}

BOOST_AUTO_TEST_CASE(rpc_listshieldunspent_parameters)
{
{
Expand Down
62 changes: 62 additions & 0 deletions test/functional/sapling_wallet_encryption.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env python3
# Copyright (c) 2021 The PIVX developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php .

from test_framework.test_framework import PivxTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
assert_true
)

# Test encrypted wallet behaviour with Sapling addresses
class WalletSaplingTest(PivxTestFramework):

def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True

def run_test(self):
node = self.nodes[0]
node.generate(1)

# wallet should currently be empty
assert_equal(len(node.listshieldaddresses()), 0)
# create 100 keys
keys_to_generate = 100
for _ in range (keys_to_generate):
node.getnewshieldaddress()
# Verify we can list the created addresses
addr_list = node.listshieldaddresses()
assert_equal(len(addr_list), keys_to_generate)

password = "hello"
node.encryptwallet(password)
# assert that the wallet is encrypted
assert_raises_rpc_error(-15, "Error: running with an encrypted wallet, but encryptwallet was called.", node.encryptwallet, 'ff')

# now verify addresses again
addr_list_post_encryption = node.listshieldaddresses()
assert_equal(len(addr_list_post_encryption), keys_to_generate)
assert_equal(addr_list, addr_list_post_encryption)

# try to add a new key, but we can't as the wallet is locked
assert_raises_rpc_error(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.", node.getnewshieldaddress)

# now unlock the wallet and try to generate the key again
node.walletpassphrase(password, 12000)
new_addr = node.getnewshieldaddress()
assert(new_addr is not None)

# and verify that the key has been added
found = False
addr_list_post_encryption = node.listshieldaddresses()
assert_equal(len(addr_list_post_encryption), keys_to_generate + 1)
for addr in addr_list_post_encryption:
if addr == new_addr:
found = True
assert_true(found, "error: shield address not found in encrypted wallet")

if __name__ == '__main__':
WalletSaplingTest().main()
1 change: 1 addition & 0 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
'rpc_deprecated.py', # ~ 80 sec
'interface_bitcoin_cli.py', # ~ 80 sec
'mempool_packages.py', # ~ 63 sec
'sapling_wallet_encryption.py',

# vv Tests less than 60s vv
'rpc_users.py',
Expand Down

0 comments on commit 13bb5c1

Please sign in to comment.