Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/test/wallet_tests.cpp
Show All 39 Lines | BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) { | ||||
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | ||||
CBlockIndex *newTip = ::ChainActive().Tip(); | CBlockIndex *newTip = ::ChainActive().Tip(); | ||||
LockAnnotation lock(::cs_main); | LockAnnotation lock(::cs_main); | ||||
auto locked_chain = chain->lock(); | auto locked_chain = chain->lock(); | ||||
// Verify ScanForWalletTransactions accommodates a null start block. | // Verify ScanForWalletTransactions accommodates a null start block. | ||||
{ | { | ||||
CWallet wallet(Params(), *chain, WalletLocation(), | CWallet wallet(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | WalletDatabase::CreateDummy()); | ||||
AddKey(wallet, coinbaseKey); | AddKey(wallet, coinbaseKey); | ||||
WalletRescanReserver reserver(&wallet); | WalletRescanReserver reserver(&wallet); | ||||
reserver.reserve(); | reserver.reserve(); | ||||
CWallet::ScanResult result = wallet.ScanForWalletTransactions( | CWallet::ScanResult result = wallet.ScanForWalletTransactions( | ||||
BlockHash(), BlockHash(), reserver, false /* update */); | BlockHash(), BlockHash(), reserver, false /* update */); | ||||
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); | BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); | ||||
BOOST_CHECK(result.last_failed_block.IsNull()); | BOOST_CHECK(result.last_failed_block.IsNull()); | ||||
BOOST_CHECK(result.last_scanned_block.IsNull()); | BOOST_CHECK(result.last_scanned_block.IsNull()); | ||||
BOOST_CHECK(!result.last_scanned_height); | BOOST_CHECK(!result.last_scanned_height); | ||||
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, Amount::zero()); | BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, Amount::zero()); | ||||
} | } | ||||
// Verify ScanForWalletTransactions picks up transactions in both the old | // Verify ScanForWalletTransactions picks up transactions in both the old | ||||
// and new block files. | // and new block files. | ||||
{ | { | ||||
CWallet wallet(Params(), *chain, WalletLocation(), | CWallet wallet(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | WalletDatabase::CreateDummy()); | ||||
AddKey(wallet, coinbaseKey); | AddKey(wallet, coinbaseKey); | ||||
WalletRescanReserver reserver(&wallet); | WalletRescanReserver reserver(&wallet); | ||||
reserver.reserve(); | reserver.reserve(); | ||||
CWallet::ScanResult result = wallet.ScanForWalletTransactions( | CWallet::ScanResult result = wallet.ScanForWalletTransactions( | ||||
oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */); | oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */); | ||||
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); | BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); | ||||
BOOST_CHECK(result.last_failed_block.IsNull()); | BOOST_CHECK(result.last_failed_block.IsNull()); | ||||
BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash()); | BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash()); | ||||
BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight); | BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight); | ||||
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 100 * COIN); | BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 100 * COIN); | ||||
} | } | ||||
// Prune the older block file. | // Prune the older block file. | ||||
PruneOneBlockFile(oldTip->GetBlockPos().nFile); | PruneOneBlockFile(oldTip->GetBlockPos().nFile); | ||||
UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); | UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); | ||||
// Verify ScanForWalletTransactions only picks transactions in the new block | // Verify ScanForWalletTransactions only picks transactions in the new block | ||||
// file. | // file. | ||||
{ | { | ||||
CWallet wallet(Params(), *chain, WalletLocation(), | CWallet wallet(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | WalletDatabase::CreateDummy()); | ||||
AddKey(wallet, coinbaseKey); | AddKey(wallet, coinbaseKey); | ||||
WalletRescanReserver reserver(&wallet); | WalletRescanReserver reserver(&wallet); | ||||
reserver.reserve(); | reserver.reserve(); | ||||
CWallet::ScanResult result = wallet.ScanForWalletTransactions( | CWallet::ScanResult result = wallet.ScanForWalletTransactions( | ||||
oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */); | oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */); | ||||
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE); | BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE); | ||||
BOOST_CHECK_EQUAL(result.last_failed_block, oldTip->GetBlockHash()); | BOOST_CHECK_EQUAL(result.last_failed_block, oldTip->GetBlockHash()); | ||||
BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash()); | BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash()); | ||||
BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight); | BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight); | ||||
BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 50 * COIN); | BOOST_CHECK_EQUAL(wallet.GetBalance().m_mine_immature, 50 * COIN); | ||||
} | } | ||||
// Prune the remaining block file. | // Prune the remaining block file. | ||||
PruneOneBlockFile(newTip->GetBlockPos().nFile); | PruneOneBlockFile(newTip->GetBlockPos().nFile); | ||||
UnlinkPrunedFiles({newTip->GetBlockPos().nFile}); | UnlinkPrunedFiles({newTip->GetBlockPos().nFile}); | ||||
// Verify ScanForWalletTransactions scans no blocks. | // Verify ScanForWalletTransactions scans no blocks. | ||||
{ | { | ||||
CWallet wallet(Params(), *chain, WalletLocation(), | CWallet wallet(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | WalletDatabase::CreateDummy()); | ||||
AddKey(wallet, coinbaseKey); | AddKey(wallet, coinbaseKey); | ||||
WalletRescanReserver reserver(&wallet); | WalletRescanReserver reserver(&wallet); | ||||
reserver.reserve(); | reserver.reserve(); | ||||
CWallet::ScanResult result = wallet.ScanForWalletTransactions( | CWallet::ScanResult result = wallet.ScanForWalletTransactions( | ||||
oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */); | oldTip->GetBlockHash(), BlockHash(), reserver, false /* update */); | ||||
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE); | BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::FAILURE); | ||||
BOOST_CHECK_EQUAL(result.last_failed_block, newTip->GetBlockHash()); | BOOST_CHECK_EQUAL(result.last_failed_block, newTip->GetBlockHash()); | ||||
Show All 18 Lines | BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) { | ||||
// Prune the older block file. | // Prune the older block file. | ||||
PruneOneBlockFile(oldTip->GetBlockPos().nFile); | PruneOneBlockFile(oldTip->GetBlockPos().nFile); | ||||
UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); | UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); | ||||
// Verify importmulti RPC returns failure for a key whose creation time is | // Verify importmulti RPC returns failure for a key whose creation time is | ||||
// before the missing block, and success for a key whose creation time is | // before the missing block, and success for a key whose creation time is | ||||
// after. | // after. | ||||
{ | { | ||||
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>( | std::shared_ptr<CWallet> wallet = | ||||
Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy()); | std::make_shared<CWallet>(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | |||||
AddWallet(wallet); | AddWallet(wallet); | ||||
UniValue keys; | UniValue keys; | ||||
keys.setArray(); | keys.setArray(); | ||||
UniValue key; | UniValue key; | ||||
key.setObject(); | key.setObject(); | ||||
key.pushKV("scriptPubKey", | key.pushKV("scriptPubKey", | ||||
HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey()))); | HexStr(GetScriptForRawPubKey(coinbaseKey.GetPubKey()))); | ||||
key.pushKV("timestamp", 0); | key.pushKV("timestamp", 0); | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | m_coinbase_txns.emplace_back( | ||||
.vtx[0]); | .vtx[0]); | ||||
auto locked_chain = chain->lock(); | auto locked_chain = chain->lock(); | ||||
std::string backup_file = (GetDataDir() / "wallet.backup").string(); | std::string backup_file = (GetDataDir() / "wallet.backup").string(); | ||||
// Import key into wallet and call dumpwallet to create backup file. | // Import key into wallet and call dumpwallet to create backup file. | ||||
{ | { | ||||
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>( | std::shared_ptr<CWallet> wallet = | ||||
Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy()); | std::make_shared<CWallet>(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | |||||
LOCK(wallet->cs_wallet); | LOCK(wallet->cs_wallet); | ||||
wallet->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = | wallet->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = | ||||
KEY_TIME; | KEY_TIME; | ||||
wallet->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); | wallet->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); | ||||
JSONRPCRequest request; | JSONRPCRequest request; | ||||
request.params.setArray(); | request.params.setArray(); | ||||
request.params.push_back(backup_file); | request.params.push_back(backup_file); | ||||
AddWallet(wallet); | AddWallet(wallet); | ||||
::dumpwallet(GetConfig(), request); | ::dumpwallet(GetConfig(), request); | ||||
RemoveWallet(wallet); | RemoveWallet(wallet); | ||||
} | } | ||||
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME | // Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME | ||||
// were scanned, and no prior blocks were scanned. | // were scanned, and no prior blocks were scanned. | ||||
{ | { | ||||
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>( | std::shared_ptr<CWallet> wallet = | ||||
Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy()); | std::make_shared<CWallet>(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | |||||
JSONRPCRequest request; | JSONRPCRequest request; | ||||
request.params.setArray(); | request.params.setArray(); | ||||
request.params.push_back(backup_file); | request.params.push_back(backup_file); | ||||
AddWallet(wallet); | AddWallet(wallet); | ||||
::importwallet(GetConfig(), request); | ::importwallet(GetConfig(), request); | ||||
RemoveWallet(wallet); | RemoveWallet(wallet); | ||||
Show All 11 Lines | |||||
// Check that GetImmatureCredit() returns a newly calculated value instead of | // Check that GetImmatureCredit() returns a newly calculated value instead of | ||||
// the cached value after a MarkDirty() call. | // the cached value after a MarkDirty() call. | ||||
// | // | ||||
// This is a regression test written to verify a bugfix for the immature credit | // This is a regression test written to verify a bugfix for the immature credit | ||||
// function. Similar tests probably should be written for the other credit and | // function. Similar tests probably should be written for the other credit and | ||||
// debit functions. | // debit functions. | ||||
BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup) { | ||||
auto chain = interfaces::MakeChain(); | auto chain = interfaces::MakeChain(); | ||||
CWallet wallet(Params(), *chain, WalletLocation(), | CWallet wallet(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | WalletDatabase::CreateDummy()); | ||||
CWalletTx wtx(&wallet, m_coinbase_txns.back()); | CWalletTx wtx(&wallet, m_coinbase_txns.back()); | ||||
auto locked_chain = chain->lock(); | auto locked_chain = chain->lock(); | ||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
wtx.hashBlock = ::ChainActive().Tip()->GetBlockHash(); | wtx.hashBlock = ::ChainActive().Tip()->GetBlockHash(); | ||||
wtx.nIndex = 0; | wtx.nIndex = 0; | ||||
// Call GetImmatureCredit() once before adding the key to the wallet to | // Call GetImmatureCredit() once before adding the key to the wallet to | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(LoadReceiveRequests) { | ||||
BOOST_CHECK_EQUAL(values[1], "val_rr1"); | BOOST_CHECK_EQUAL(values[1], "val_rr1"); | ||||
} | } | ||||
class ListCoinsTestingSetup : public TestChain100Setup { | class ListCoinsTestingSetup : public TestChain100Setup { | ||||
public: | public: | ||||
ListCoinsTestingSetup() { | ListCoinsTestingSetup() { | ||||
CreateAndProcessBlock({}, | CreateAndProcessBlock({}, | ||||
GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | ||||
wallet = std::make_unique<CWallet>(Params(), *m_chain, WalletLocation(), | wallet = | ||||
std::make_unique<CWallet>(Params(), m_chain.get(), WalletLocation(), | |||||
WalletDatabase::CreateMock()); | WalletDatabase::CreateMock()); | ||||
bool firstRun; | bool firstRun; | ||||
wallet->LoadWallet(firstRun); | wallet->LoadWallet(firstRun); | ||||
AddKey(*wallet, coinbaseKey); | AddKey(*wallet, coinbaseKey); | ||||
WalletRescanReserver reserver(wallet.get()); | WalletRescanReserver reserver(wallet.get()); | ||||
reserver.reserve(); | reserver.reserve(); | ||||
CWallet::ScanResult result = wallet->ScanForWalletTransactions( | CWallet::ScanResult result = wallet->ScanForWalletTransactions( | ||||
::ChainActive().Genesis()->GetBlockHash(), BlockHash(), reserver, | ::ChainActive().Genesis()->GetBlockHash(), BlockHash(), reserver, | ||||
false /* update */); | false /* update */); | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(ListCoins, ListCoinsTestingSetup) { | ||||
BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), | BOOST_CHECK_EQUAL(boost::get<CKeyID>(list.begin()->first).ToString(), | ||||
coinbaseAddress); | coinbaseAddress); | ||||
BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U); | BOOST_CHECK_EQUAL(list.begin()->second.size(), 2U); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup) { | ||||
auto chain = interfaces::MakeChain(); | auto chain = interfaces::MakeChain(); | ||||
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>( | std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>( | ||||
Params(), *chain, WalletLocation(), WalletDatabase::CreateDummy()); | Params(), chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); | ||||
wallet->SetMinVersion(FEATURE_LATEST); | wallet->SetMinVersion(FEATURE_LATEST); | ||||
wallet->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS); | wallet->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS); | ||||
BOOST_CHECK(!wallet->TopUpKeyPool(1000)); | BOOST_CHECK(!wallet->TopUpKeyPool(1000)); | ||||
CPubKey pubkey; | CPubKey pubkey; | ||||
BOOST_CHECK(!wallet->GetKeyFromPool(pubkey, false)); | BOOST_CHECK(!wallet->GetKeyFromPool(pubkey, false)); | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |