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());
93 LOCK(wallet.cs_wallet);
96 AddKey(wallet, coinbaseKey);
99 CWallet::ScanResult result = wallet.ScanForWalletTransactions({} , 0 , {} , reserver,
false );
112 LOCK(wallet.cs_wallet);
115 AddKey(wallet, coinbaseKey);
138 LOCK(wallet.cs_wallet);
141 AddKey(wallet, coinbaseKey);
163 LOCK(wallet.cs_wallet);
166 AddKey(wallet, coinbaseKey);
201 wallet->SetupLegacyScriptPubKeyMan();
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());
327 LOCK2(wallet.cs_wallet, spk_man->cs_KeyStore);
331 wtx.m_confirm = confirm;
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);
454 assert(!pubkey.IsFullyValid());
455 assert(pubkey.IsValid());
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();
576 LOCK(wallet->cs_wallet);
577 list = wallet->ListCoins();
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();
618 wallet->SetupLegacyScriptPubKeyMan();
644 CScript script_pubkey =
CScript() << OP_HASH160 << std::vector<unsigned char>(script_id.begin(), script_id.end()) <<
OP_EQUAL;
649 keystore.AddKeyPubKey(key, pubkey);
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);
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;
std::shared_ptr< const CTransaction > CTransactionRef
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.
bool malformed_descriptor(std::ios_base::failure e)
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
std::shared_ptr< CWallet > m_wallet
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.
std::deque< CInv >::iterator it
constexpr CAmount DEFAULT_TRANSACTION_MAXFEE
-maxtxfee default
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
#define BOOST_AUTO_TEST_CASE(funcName)
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
bool AddWallet(const std::shared_ptr< CWallet > &wallet)
RecursiveMutex cs_KeyStore
std::unique_ptr< interfaces::Chain > m_chain
uint256 GetRandHash() noexcept
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
static const CAmount COIN
UniValue HandleRequest(const JSONRPCRequest &request)
virtual bool AddCScript(const CScript &redeemScript)
static CTransactionRef MakeTransactionRef()
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.
static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP...
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
static auto & nullopt
Substitute for C++17 std::nullopt.
static size_t CalculateNestedKeyhashInputSize(bool use_max_sig)
static std::shared_ptr< CWallet > TestLoadWallet(interfaces::Chain &chain)
FlatFilePos GetBlockPos() const
bool RemoveWatchOnly(const CScript &dest)
Remove a watch only script from the keystore.
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
std::unique_ptr< Chain > MakeChain(NodeContext &node)
Return implementation of Chain interface.
Access to the wallet database.
CWalletTx & AddTx(CRecipient recipient)
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 HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
static void TestWatchOnlyPubKey(LegacyScriptPubKeyMan *spk_man, const CPubKey &add_pubkey)
int64_t CAmount
Amount in satoshis (Can be negative)
int64_t GetBlockTimeMax() const
void SetMockTime(int64_t nMockTimeIn)
For testing.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
bool error(const char *fmt, const Args &...args)
ChainstateManager * chainman
bool push_back(const UniValue &val)
static void AddKey(CWallet &wallet, const CKey &key)
NodeContext struct containing references to chain state and connection state.
int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
#define LEAVE_CRITICAL_SECTION(cs)
std::unique_ptr< CWallet > wallet
Minimal stream for reading from an existing vector by reference.
An input of a transaction.
CPubKey GetPubKey() const
Compute the public key from a private key.
An encapsulated public key.
Fillable signing provider that keeps keys in an address->secret map.
const fs::path & GetDataDir(bool fNetSpecific)
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
const std::vector< CTxOut > vout
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
std::unique_ptr< interfaces::Handler > HandleLoadWallet(LoadWalletFn load_wallet)
RPCHelpMan importwallet()
LegacyScriptPubKeyMan * GetOrCreateLegacyScriptPubKeyMan()
bool pushKV(const std::string &key, const UniValue &val)
std::unique_ptr< WalletDatabase > CreateDummyWalletDatabase()
Return object for accessing dummy database with no read/write capabilities.
void CallFunctionInValidationInterfaceQueue(std::function< void()> func)
Pushes a function to callback onto the notification queue, guaranteeing any callbacks generated prior...
bool RemoveWallet(const std::shared_ptr< CWallet > &wallet, Optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
CWalletTx * AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation &confirm, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true)
Descriptor with some wallet metadata.
An outpoint - a combination of a transaction hash and an index n into its vout.
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
std::vector< CTxOut > vout
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
static void PollutePubKey(CPubKey &pubkey)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
const unsigned char * begin() const
Type-safe dynamic reference.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
RAII object to check and reserve a wallet rescan.
A transaction with a bunch of additional info that only the owner cares about.
static void TestUnloadWallet(std::shared_ptr< CWallet > &&wallet)
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
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)
bool IsCompressed() const
Check whether this is a compressed public key.
#define ENTER_CRITICAL_SECTION(cs)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
static const CAmount DEFAULT_TRANSACTION_MINFEE
-mintxfee default
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Testing setup and teardown for wallet.
#define BOOST_CHECK_EQUAL(v1, v2)
The block chain is a tree shaped structure starting with the genesis block at the root...
Serialized script, used inside transaction inputs and outputs.
bool(* handler)(const util::Ref &context, HTTPRequest *req, const std::string &strReq)
enum CWallet::ScanResult::@15 status
static int64_t AddTx(ChainstateManager &chainman, CWallet &wallet, uint32_t lockTime, int64_t mockTime, int64_t blockTime)
A reference to a CKey: the Hash160 of its serialized public key.
void UpdateInput(CTxIn &input, const SignatureData &data)
#define BOOST_AUTO_TEST_SUITE_END()
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
static CMutableTransaction TestSimpleSpend(const CTransaction &from, uint32_t index, const CKey &key, const CScript &pubkey)
BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
Optional< int > last_scanned_height
A mutable version of CTransaction.
uint256 last_failed_block
Height of the most recent block that could not be scanned due to read errors or pruning.
const uint256 & GetHash() const
static const CAmount WALLET_INCREMENTAL_RELAY_FEE
minimum recommended increment for BIP 125 replacement txs
An encapsulated private key.
The basic transaction that is broadcasted on the network and contained in blocks. ...
int nHeight
height of the entry in the chain. The genesis block has height 0
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
const unsigned char * end() const
virtual bool AddKey(const CKey &key)
#define Assert(val)
Identity function.
uint256 GetBlockHash() const
#define BOOST_CHECK(expr)
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
BlockMap & BlockIndex() EXCLUSIVE_LOCKS_REQUIRED(
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE
Pre-calculated constants for input size estimation in virtual size