16 #include <test/util/logging.h>
17 #include <test/util/setup_common.h>
20 #include <validation.h>
24 #include <boost/test/unit_test.hpp>
43 std::vector<bilingual_str> warnings;
46 wallet->postInitProcess();
53 wallet->m_chain_notifications_handler.reset();
64 std::map<COutPoint, Coin> coins;
65 coins[mtx.
vin[0].prevout].out = from.
vout[index];
66 std::map<int, std::string> input_errors;
75 spk_man->AddKeyPubKey(key, key.
GetPubKey());
96 AddKey(wallet, coinbaseKey);
115 AddKey(wallet, coinbaseKey);
141 AddKey(wallet, coinbaseKey);
166 AddKey(wallet, coinbaseKey);
201 wallet->SetupLegacyScriptPubKeyMan();
202 WITH_LOCK(wallet->cs_wallet, wallet->SetLastBlockProcessed(newTip->nHeight, newTip->GetBlockHash()));
209 key.
pushKV(
"timestamp", 0);
227 strprintf(
"[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Rescan failed for key with creation "
228 "timestamp %d. There was an error reading a block from time %d, which is after or within %d "
229 "seconds of key creation, and could contain transactions pertaining to the key. As a result, "
230 "transactions and coins using this key may not appear in the wallet. This error could be caused "
231 "by pruning or data corruption (see bitcoind log for details) and could be dealt with by "
232 "downloading and rescanning the relevant blocks (see -reindex and -rescan "
233 "options).\"}},{\"success\":true}]",
249 m_coinbase_txns.emplace_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
250 m_coinbase_txns.emplace_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
256 m_coinbase_txns.emplace_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
261 std::string backup_file = (
GetDataDir() /
"wallet.backup").
string();
267 auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan();
268 LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
269 spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
270 spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
288 LOCK(wallet->cs_wallet);
289 wallet->SetupLegacyScriptPubKeyMan();
302 for (
size_t i = 0; i < m_coinbase_txns.size(); ++i) {
303 bool found = wallet->GetWalletTx(m_coinbase_txns[i]->GetHash());
304 bool expected = i >= 100;
325 CWalletTx wtx(&wallet, m_coinbase_txns.back());
340 BOOST_CHECK(spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()));
354 assert(inserted.second);
355 const uint256& hash = inserted.first->first;
356 block = inserted.first->second;
357 block->
nTime = blockTime;
359 confirm = {CWalletTx::Status::CONFIRMED, block->
nHeight, hash, 0};
403 m_wallet.AddDestData(batch, dest,
"misc",
"val_misc");
404 m_wallet.AddDestData(batch, dest,
"rr0",
"val_rr0");
405 m_wallet.AddDestData(batch, dest,
"rr1",
"val_rr1");
407 auto values =
m_wallet.GetDestValues(
"rr");
431 if (is_pubkey_fully_valid) {
442 if (is_pubkey_fully_valid) {
451 std::vector<unsigned char> pubkey_raw(pubkey.
begin(), pubkey.
end());
452 std::fill(pubkey_raw.begin()+1, pubkey_raw.end(), 0);
504 wallet->LoadWallet(firstRun);
531 wallet->CommitTransaction(tx, {}, {});
541 auto it =
wallet->mapWallet.find(tx->GetHash());
544 it->second.m_confirm = confirm;
554 std::string coinbaseAddress = coinbaseKey.GetPubKey().GetID().ToString();
558 std::map<CTxDestination, std::vector<COutput>> list;
560 LOCK(wallet->cs_wallet);
561 list = wallet->ListCoins();
564 BOOST_CHECK_EQUAL(boost::get<PKHash>(list.begin()->first).ToString(), coinbaseAddress);
576 LOCK(wallet->cs_wallet);
577 list = wallet->ListCoins();
580 BOOST_CHECK_EQUAL(boost::get<PKHash>(list.begin()->first).ToString(), coinbaseAddress);
585 LOCK(wallet->cs_wallet);
586 std::vector<COutput> available;
587 wallet->AvailableCoins(available);
590 for (
const auto& group : list) {
591 for (
const auto& coin : group.second) {
592 LOCK(wallet->cs_wallet);
593 wallet->LockCoin(
COutPoint(coin.tx->GetHash(), coin.i));
597 LOCK(wallet->cs_wallet);
598 std::vector<COutput> available;
599 wallet->AvailableCoins(available);
605 LOCK(wallet->cs_wallet);
606 list = wallet->ListCoins();
609 BOOST_CHECK_EQUAL(boost::get<PKHash>(list.begin()->first).ToString(), coinbaseAddress);
618 wallet->SetupLegacyScriptPubKeyMan();
672 std::string s(e.what());
673 return s.find(
"Missing checksum") != std::string::npos;
678 std::vector<unsigned char> malformed_record;
680 vw << std::string(
"notadescriptor");
723 DebugLogHelper addtx_counter(
"[default wallet] AddToWallet", [&](
const std::string* s) {
724 if (s) ++addtx_count;
729 bool rescan_completed =
false;
730 DebugLogHelper rescan_check(
"[default wallet] Rescan completed", [&](
const std::string* s) {
731 if (s) rescan_completed =
true;
739 std::promise<void> promise;
741 promise.get_future().wait();
744 m_coinbase_txns.push_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
746 m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
757 LOCK(wallet->cs_wallet);
781 BOOST_CHECK(rescan_completed);
782 m_coinbase_txns.push_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
784 m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
794 LOCK(wallet->cs_wallet);
812 m_coinbase_txns.push_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
819 auto block_hash = block_tx.GetHash();
820 auto prev_hash = m_coinbase_txns[0]->GetHash();
822 LOCK(wallet->cs_wallet);
826 std::vector<uint256> vHashIn{ block_hash }, vHashOut;
int64_t CAmount
Amount in satoshis (Can be negative)
static const CAmount COIN
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
#define Assert(val)
Identity function.
unsigned int nSize
number of used bytes of block file
The block chain is a tree shaped structure starting with the genesis block at the root,...
FlatFilePos GetBlockPos() const
uint256 GetBlockHash() const
int64_t GetBlockTimeMax() const
int nHeight
height of the entry in the chain. The genesis block has height 0
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
An encapsulated private key.
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
CPubKey GetPubKey() const
Compute the public key from a private key.
A reference to a CKey: the Hash160 of its serialized public key.
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
const unsigned char * end() const
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
const unsigned char * begin() const
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxOut > vout
const uint256 & GetHash() const
An input of a transaction.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
static std::shared_ptr< CWallet > Create(interfaces::Chain &chain, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bilingual_str &error, std::vector< bilingual_str > &warnings)
void SetLastBlockProcessed(int block_height, uint256 block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Set last block processed height, currently only use in unit test.
A transaction with a bunch of additional info that only the owner cares about.
void MarkDirty()
make sure balances are recalculated
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey)
virtual bool AddCScript(const CScript &redeemScript)
virtual bool AddKey(const CKey &key)
RecursiveMutex cs_KeyStore
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
std::unique_ptr< interfaces::Chain > m_chain
std::unique_ptr< CWallet > wallet
CWalletTx & AddTx(CRecipient recipient)
UniValue HandleRequest(const JSONRPCRequest &request)
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool push_back(const UniValue &val)
bool pushKV(const std::string &key, const UniValue &val)
Minimal stream for reading from an existing vector by reference.
Access to the wallet database.
Descriptor with some wallet metadata.
RAII object to check and reserve a wallet rescan.
Type-safe dynamic reference.
Balance GetBalance(int min_depth=0, bool avoid_reuse=true) const
CAmount GetImmatureCredit(bool fUseCache=true) const
ScanResult ScanForWalletTransactions(const uint256 &start_block, int start_height, Optional< int > max_height, const WalletRescanReserver &reserver, bool fUpdate)
Scan the block chain (starting in start_block) for transactions from or to us.
CWalletTx * AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation &confirm, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true)
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
std::shared_ptr< CWallet > m_wallet
std::unique_ptr< Chain > MakeChain(NodeContext &node)
Return implementation of Chain interface.
std::deque< CInv >::iterator it
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
#define BOOST_AUTO_TEST_SUITE_END()
#define BOOST_FIXTURE_TEST_SUITE(a, b)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static auto & nullopt
Substitute for C++17 std::nullopt.
int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP...
static CTransactionRef MakeTransactionRef()
std::shared_ptr< const CTransaction > CTransactionRef
uint256 GetRandHash() noexcept
void SignTransaction(CMutableTransaction &mtx, const SigningProvider *keystore, const std::map< COutPoint, Coin > &coins, const UniValue &hashType, UniValue &result)
Sign a transaction with the given keystore and previous transactions.
bool(* handler)(const util::Ref &context, HTTPRequest *req, const std::string &strReq)
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
void UpdateInput(CTxIn &input, const SignatureData &data)
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
A mutable version of CTransaction.
std::vector< CTxOut > vout
CAmount m_mine_immature
Immature coinbases in the main chain.
Optional< int > last_scanned_height
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
enum CWallet::ScanResult::@15 status
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
NodeContext struct containing references to chain state and connection state.
ChainstateManager * chainman
Testing setup and teardown for wallet.
#define ENTER_CRITICAL_SECTION(cs)
#define LEAVE_CRITICAL_SECTION(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
const fs::path & GetDataDir(bool fNetSpecific)
bool error(const char *fmt, const Args &... args)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
void SetMockTime(int64_t nMockTimeIn)
For testing.
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
void CallFunctionInValidationInterfaceQueue(std::function< void()> func)
Pushes a function to callback onto the notification queue, guaranteeing any callbacks generated prior...
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
std::unique_ptr< interfaces::Handler > HandleLoadWallet(LoadWalletFn load_wallet)
bool RemoveWallet(const std::shared_ptr< CWallet > &wallet, Optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
std::shared_ptr< CWallet > CreateWallet(interfaces::Chain &chain, const std::string &name, Optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
bool AddWallet(const std::shared_ptr< CWallet > &wallet)
static const CAmount WALLET_INCREMENTAL_RELAY_FEE
minimum recommended increment for BIP 125 replacement txs
constexpr CAmount DEFAULT_TRANSACTION_MAXFEE
-maxtxfee default
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE
Pre-calculated constants for input size estimation in virtual size
static const CAmount DEFAULT_TRANSACTION_MINFEE
-mintxfee default
static void PollutePubKey(CPubKey &pubkey)
static std::shared_ptr< CWallet > TestLoadWallet(interfaces::Chain &chain)
static void TestUnloadWallet(std::shared_ptr< CWallet > &&wallet)
static size_t CalculateNestedKeyhashInputSize(bool use_max_sig)
RPCHelpMan importwallet()
static CMutableTransaction TestSimpleSpend(const CTransaction &from, uint32_t index, const CKey &key, const CScript &pubkey)
BOOST_AUTO_TEST_CASE(ComputeTimeSmart)
static int64_t AddTx(ChainstateManager &chainman, CWallet &wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime)
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
static void AddKey(CWallet &wallet, const CKey &key)
static void TestWatchOnlyPubKey(LegacyScriptPubKeyMan *spk_man, const CPubKey &add_pubkey)
bool malformed_descriptor(std::ios_base::failure e)
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.
std::unique_ptr< WalletDatabase > CreateDummyWalletDatabase()
Return object for accessing dummy database with no read/write capabilities.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS