18 #include <test/util/logging.h> 19 #include <test/util/setup_common.h> 21 #include <validation.h> 25 #include <boost/test/unit_test.hpp> 46 std::vector<bilingual_str> warnings;
58 wallet->m_chain_notifications_handler.reset();
69 std::map<COutPoint, Coin> coins;
70 coins[mtx.
vin[0].prevout].out = from.
vout[index];
71 std::map<int, std::string> input_errors;
78 auto spk_man =
wallet.GetOrCreateLegacyScriptPubKeyMan();
80 spk_man->AddKeyPubKey(key, key.
GetPubKey());
200 wallet->SetupLegacyScriptPubKeyMan();
208 key.
pushKV(
"timestamp", 0);
225 strprintf(
"[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Rescan failed for key with creation " 226 "timestamp %d. There was an error reading a block from time %d, which is after or within %d " 227 "seconds of key creation, and could contain transactions pertaining to the key. As a result, " 228 "transactions and coins using this key may not appear in the wallet. This error could be caused " 229 "by pruning or data corruption (see bitcoind log for details) and could be dealt with by " 230 "downloading and rescanning the relevant blocks (see -reindex and -rescan " 231 "options).\"}},{\"success\":true}]",
245 const int64_t BLOCK_TIME =
m_node.
chainman->ActiveChain().Tip()->GetBlockTimeMax() + 5;
247 m_coinbase_txns.emplace_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
248 m_coinbase_txns.emplace_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
254 m_coinbase_txns.emplace_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
262 auto spk_man =
wallet->GetOrCreateLegacyScriptPubKeyMan();
264 spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
265 spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
283 wallet->SetupLegacyScriptPubKeyMan();
295 for (
size_t i = 0; i < m_coinbase_txns.size(); ++i) {
296 bool found =
wallet->GetWalletTx(m_coinbase_txns[i]->GetHash());
297 bool expected = i >= 100;
312 auto spk_man =
wallet.GetOrCreateLegacyScriptPubKeyMan();
319 wtx.m_confirm = confirm;
328 BOOST_CHECK(spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()));
343 const uint256& hash = inserted.first->first;
344 block = inserted.first->second;
345 block->
nTime = blockTime;
347 confirm = {CWalletTx::Status::CONFIRMED, block->
nHeight, hash, 0};
388 m_wallet.SetAddressUsed(batch, dest,
true);
389 m_wallet.SetAddressReceiveRequest(batch, dest,
"0",
"val_rr0");
390 m_wallet.SetAddressReceiveRequest(batch, dest,
"1",
"val_rr1");
392 auto values =
m_wallet.GetAddressReceiveRequests();
416 if (is_pubkey_fully_valid) {
427 if (is_pubkey_fully_valid) {
436 std::vector<unsigned char> pubkey_raw(pubkey.
begin(), pubkey.
end());
437 std::fill(pubkey_raw.begin()+1, pubkey_raw.end(), 0);
439 assert(!pubkey.IsFullyValid());
515 wallet->CommitTransaction(tx, {}, {});
525 auto it =
wallet->mapWallet.find(tx->GetHash());
528 it->second.m_confirm = confirm;
537 std::string coinbaseAddress = coinbaseKey.GetPubKey().GetID().ToString();
541 std::map<CTxDestination, std::vector<COutput>> list;
544 list =
wallet->ListCoins();
560 list =
wallet->ListCoins();
569 std::vector<COutput> available;
570 wallet->AvailableCoins(available);
573 for (
const auto& group : list) {
574 for (
const auto& coin : group.second) {
581 std::vector<COutput> available;
582 wallet->AvailableCoins(available);
589 list =
wallet->ListCoins();
599 wallet->SetupLegacyScriptPubKeyMan();
625 CScript script_pubkey =
CScript() << OP_HASH160 << std::vector<unsigned char>(script_id.begin(), script_id.end()) <<
OP_EQUAL;
630 keystore.AddKeyPubKey(key, pubkey);
653 std::string s(e.what());
654 return s.find(
"Missing checksum") != std::string::npos;
659 std::vector<unsigned char> malformed_record;
661 vw << std::string(
"notadescriptor");
704 DebugLogHelper addtx_counter(
"[default wallet] AddToWallet", [&](
const std::string* s) {
705 if (s) ++addtx_count;
710 bool rescan_completed =
false;
711 DebugLogHelper rescan_check(
"[default wallet] Rescan completed", [&](
const std::string* s) {
712 if (s) rescan_completed =
true;
720 std::promise<void> promise;
722 promise.get_future().wait();
725 m_coinbase_txns.push_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
727 m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
763 m_coinbase_txns.push_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
765 m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
802 m_coinbase_txns.push_back(CreateAndProcessBlock({},
GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
809 auto block_hash = block_tx.GetHash();
810 auto prev_hash = m_coinbase_txns[0]->GetHash();
816 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.
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 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...
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 RemoveWallet(const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
constexpr CAmount DEFAULT_TRANSACTION_MAXFEE
-maxtxfee default
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
RecursiveMutex cs_KeyStore
CPubKey GetPubKey() const
Compute the public key from a private key.
std::unique_ptr< ChainstateManager > chainman
std::optional< int > last_scanned_height
uint256 GetRandHash() noexcept
uint256 last_scanned_block
Hash and height of most recent block that was successfully scanned.
static const CAmount COIN
virtual bool AddCScript(const CScript &redeemScript)
std::shared_ptr< CWallet > m_wallet
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR
A signature creator that just produces 71-byte empty signatures.
std::unique_ptr< interfaces::Chain > chain
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...
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR
A signature creator that just produces 72-byte empty signatures.
FlatFilePos GetBlockPos() const
RecursiveMutex cs_wallets
static size_t CalculateNestedKeyhashInputSize(bool use_max_sig)
void ForceSetArg(const std::string &strArg, const std::string &strValue)
bool(* handler)(const std::any &context, HTTPRequest *req, const std::string &strReq)
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...
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
const unsigned char * begin() const
Access to the wallet database.
CWalletTx & AddTx(CRecipient recipient)
static void TestWatchOnlyPubKey(LegacyScriptPubKeyMan *spk_man, const CPubKey &add_pubkey)
int64_t CAmount
Amount in satoshis (Can be negative)
uint256 GetBlockHash() const
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
bool push_back(const UniValue &val)
static void AddKey(CWallet &wallet, const CKey &key)
int64_t GetVirtualTransactionInputSize(const CTxIn &txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)
const unsigned char * end() const
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
bool GetWatchPubKey(const CKeyID &address, CPubKey &pubkey_out) const
Fetches a pubkey from mapWatchKeys if it exists there.
#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.
std::unique_ptr< interfaces::Handler > HandleLoadWallet(LoadWalletFn load_wallet)
const uint256 & GetHash() const
An encapsulated public key.
Fillable signing provider that keeps keys in an address->secret map.
bool AddWallet(const std::shared_ptr< CWallet > &wallet)
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
const std::vector< CTxOut > vout
int64_t GetBlockTimeMax() const
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
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...
Descriptor with some wallet metadata.
An outpoint - a combination of a transaction hash and an index n into its vout.
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
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.
RPCHelpMan importwallet()
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.
BOOST_AUTO_TEST_CASE(ComputeTimeSmart)
A transaction with a bunch of additional info that only the owner cares about.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
static void TestUnloadWallet(std::shared_ptr< CWallet > &&wallet)
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
#define ENTER_CRITICAL_SECTION(cs)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
static const CAmount DEFAULT_TRANSACTION_MINFEE
-mintxfee default
static std::shared_ptr< CWallet > TestLoadWallet(interfaces::Chain *chain)
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
#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.
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()
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.
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.
static const CAmount WALLET_INCREMENTAL_RELAY_FEE
minimum recommended increment for BIP 125 replacement txs
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
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
Confirmation includes tx status and a triplet of {block height/block hash/tx index in block} at which...
UniValue HandleRequest(const JSONRPCRequest &request) const
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
bool error(const char *fmt, const Args &... args)
enum CWallet::ScanResult::@16 status
std::shared_ptr< CWallet > CreateWallet(interfaces::Chain &chain, const std::string &name, std::optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
virtual bool AddKey(const CKey &key)
#define Assert(val)
Identity function.
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
#define BOOST_CHECK(expr)
bool HaveWatchOnly(const CScript &dest) const
Returns whether the watch-only script is in the wallet.
bool IsCompressed() const
Check whether this is a compressed public key.
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