Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/test/wallet_tests.cpp
// Copyright (c) 2012-2016 The Bitcoin Core developers | // Copyright (c) 2012-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <chain.h> | #include <chain.h> | ||||
#include <chainparams.h> | #include <chainparams.h> | ||||
#include <config.h> | #include <config.h> | ||||
#include <consensus/validation.h> | #include <consensus/validation.h> | ||||
#include <interfaces/chain.h> | #include <interfaces/chain.h> | ||||
#include <policy/policy.h> | |||||
#include <rpc/server.h> | #include <rpc/server.h> | ||||
#include <validation.h> | #include <validation.h> | ||||
#include <wallet/coincontrol.h> | #include <wallet/coincontrol.h> | ||||
#include <wallet/rpcdump.h> | #include <wallet/rpcdump.h> | ||||
#include <wallet/wallet.h> | #include <wallet/wallet.h> | ||||
#include <test/setup_common.h> | #include <test/setup_common.h> | ||||
#include <wallet/test/wallet_test_fixture.h> | #include <wallet/test/wallet_test_fixture.h> | ||||
Show All 9 Lines | |||||
BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) | BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) | ||||
static void AddKey(CWallet &wallet, const CKey &key) { | static void AddKey(CWallet &wallet, const CKey &key) { | ||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
wallet.AddKeyPubKey(key, key.GetPubKey()); | wallet.AddKeyPubKey(key, key.GetPubKey()); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) { | ||||
auto chain = interfaces::MakeChain(); | |||||
// Cap last block file size, and mine new block in a new block file. | // Cap last block file size, and mine new block in a new block file. | ||||
CBlockIndex *oldTip = ::ChainActive().Tip(); | CBlockIndex *oldTip = ::ChainActive().Tip(); | ||||
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; | GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; | ||||
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | ||||
CBlockIndex *newTip = ::ChainActive().Tip(); | CBlockIndex *newTip = ::ChainActive().Tip(); | ||||
LockAnnotation lock(::cs_main); | auto chain = interfaces::MakeChain(); | ||||
auto locked_chain = chain->lock(); | auto locked_chain = chain->lock(); | ||||
LockAnnotation lock(::cs_main); | |||||
// Verify ScanForWalletTransactions accommodates a null start block. | // Verify ScanForWalletTransactions accommodates a null start block. | ||||
{ | { | ||||
CWallet wallet(Params(), chain.get(), 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(); | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | // Verify ScanForWalletTransactions scans no blocks. | ||||
BOOST_CHECK_EQUAL(result.last_failed_block, newTip->GetBlockHash()); | BOOST_CHECK_EQUAL(result.last_failed_block, newTip->GetBlockHash()); | ||||
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()); | ||||
} | } | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) { | ||||
auto chain = interfaces::MakeChain(); | |||||
// Cap last block file size, and mine new block in a new block file. | // Cap last block file size, and mine new block in a new block file. | ||||
CBlockIndex *oldTip = ::ChainActive().Tip(); | CBlockIndex *oldTip = ::ChainActive().Tip(); | ||||
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; | GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; | ||||
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | ||||
CBlockIndex *newTip = ::ChainActive().Tip(); | CBlockIndex *newTip = ::ChainActive().Tip(); | ||||
LockAnnotation lock(::cs_main); | auto chain = interfaces::MakeChain(); | ||||
auto locked_chain = chain->lock(); | auto locked_chain = chain->lock(); | ||||
LockAnnotation lock(::cs_main); | |||||
// 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. | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) { | ||||
} | } | ||||
} | } | ||||
// Verify importwallet RPC starts rescan at earliest block with timestamp | // Verify importwallet RPC starts rescan at earliest block with timestamp | ||||
// greater or equal than key birthday. Previously there was a bug where | // greater or equal than key birthday. Previously there was a bug where | ||||
// importwallet RPC would start the scan at the latest block with timestamp less | // importwallet RPC would start the scan at the latest block with timestamp less | ||||
// than or equal to key birthday. | // than or equal to key birthday. | ||||
BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) { | ||||
auto chain = interfaces::MakeChain(); | |||||
// Create two blocks with same timestamp to verify that importwallet rescan | // Create two blocks with same timestamp to verify that importwallet rescan | ||||
// will pick up both blocks, not just the first. | // will pick up both blocks, not just the first. | ||||
const int64_t BLOCK_TIME = ::ChainActive().Tip()->GetBlockTimeMax() + 5; | const int64_t BLOCK_TIME = ::ChainActive().Tip()->GetBlockTimeMax() + 5; | ||||
SetMockTime(BLOCK_TIME); | SetMockTime(BLOCK_TIME); | ||||
m_coinbase_txns.emplace_back( | m_coinbase_txns.emplace_back( | ||||
CreateAndProcessBlock({}, | CreateAndProcessBlock({}, | ||||
GetScriptForRawPubKey(coinbaseKey.GetPubKey())) | GetScriptForRawPubKey(coinbaseKey.GetPubKey())) | ||||
.vtx[0]); | .vtx[0]); | ||||
m_coinbase_txns.emplace_back( | m_coinbase_txns.emplace_back( | ||||
CreateAndProcessBlock({}, | CreateAndProcessBlock({}, | ||||
GetScriptForRawPubKey(coinbaseKey.GetPubKey())) | GetScriptForRawPubKey(coinbaseKey.GetPubKey())) | ||||
.vtx[0]); | .vtx[0]); | ||||
// Set key birthday to block time increased by the timestamp window, so | // Set key birthday to block time increased by the timestamp window, so | ||||
// rescan will start at the block time. | // rescan will start at the block time. | ||||
const int64_t KEY_TIME = BLOCK_TIME + TIMESTAMP_WINDOW; | const int64_t KEY_TIME = BLOCK_TIME + TIMESTAMP_WINDOW; | ||||
SetMockTime(KEY_TIME); | SetMockTime(KEY_TIME); | ||||
m_coinbase_txns.emplace_back( | m_coinbase_txns.emplace_back( | ||||
CreateAndProcessBlock({}, | CreateAndProcessBlock({}, | ||||
GetScriptForRawPubKey(coinbaseKey.GetPubKey())) | GetScriptForRawPubKey(coinbaseKey.GetPubKey())) | ||||
.vtx[0]); | .vtx[0]); | ||||
auto chain = interfaces::MakeChain(); | |||||
auto locked_chain = chain->lock(); | auto locked_chain = chain->lock(); | ||||
LockAnnotation lock(::cs_main); | |||||
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::shared_ptr<CWallet> wallet = | ||||
std::make_shared<CWallet>(Params(), chain.get(), WalletLocation(), | std::make_shared<CWallet>(Params(), chain.get(), WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | WalletDatabase::CreateDummy()); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
// 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.get(), 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(); | ||||
LockAnnotation lock(::cs_main); | |||||
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 | ||||
// cache the current immature credit amount, which is 0. | // cache the current immature credit amount, which is 0. | ||||
BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(*locked_chain), Amount::zero()); | BOOST_CHECK_EQUAL(wtx.GetImmatureCredit(*locked_chain), Amount::zero()); | ||||
// Invalidate the cached value, add the key, and make sure a new immature | // Invalidate the cached value, add the key, and make sure a new immature | ||||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | CWalletTx &AddTx(CRecipient recipient) { | ||||
CMutableTransaction blocktx; | CMutableTransaction blocktx; | ||||
{ | { | ||||
LOCK(wallet->cs_wallet); | LOCK(wallet->cs_wallet); | ||||
blocktx = | blocktx = | ||||
CMutableTransaction(*wallet->mapWallet.at(tx->GetId()).tx); | CMutableTransaction(*wallet->mapWallet.at(tx->GetId()).tx); | ||||
} | } | ||||
CreateAndProcessBlock({CMutableTransaction(blocktx)}, | CreateAndProcessBlock({CMutableTransaction(blocktx)}, | ||||
GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | ||||
LOCK(cs_main); | |||||
LOCK(wallet->cs_wallet); | LOCK(wallet->cs_wallet); | ||||
auto it = wallet->mapWallet.find(tx->GetId()); | auto it = wallet->mapWallet.find(tx->GetId()); | ||||
BOOST_CHECK(it != wallet->mapWallet.end()); | BOOST_CHECK(it != wallet->mapWallet.end()); | ||||
it->second.SetMerkleBranch(::ChainActive().Tip()->GetBlockHash(), 1); | it->second.SetMerkleBranch(::ChainActive().Tip()->GetBlockHash(), 1); | ||||
return it->second; | return it->second; | ||||
} | } | ||||
std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain(); | std::unique_ptr<interfaces::Chain> m_chain = interfaces::MakeChain(); | ||||
▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines |