Bitcoin Core  31.0.0
P2P Digital Currency
walletload_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2022-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://www.opensource.org/licenses/mit-license.php.
4 
5 #include <wallet/test/util.h>
6 #include <wallet/wallet.h>
7 #include <test/util/common.h>
8 #include <test/util/logging.h>
10 
11 #include <boost/test/unit_test.hpp>
12 
13 namespace wallet {
14 
15 BOOST_AUTO_TEST_SUITE(walletload_tests)
16 
17 class DummyDescriptor final : public Descriptor {
18 private:
19  std::string desc;
20 public:
21  explicit DummyDescriptor(const std::string& descriptor) : desc(descriptor) {};
22  ~DummyDescriptor() = default;
23 
24  std::string ToString(bool compat_format) const override { return desc; }
25  std::optional<OutputType> GetOutputType() const override { return OutputType::UNKNOWN; }
26 
27  bool IsRange() const override { return false; }
28  bool IsSolvable() const override { return false; }
29  bool IsSingleType() const override { return true; }
30  bool HavePrivateKeys(const SigningProvider&) const override { return false; }
31  bool ToPrivateString(const SigningProvider& provider, std::string& out) const override { return false; }
32  bool ToNormalizedString(const SigningProvider& provider, std::string& out, const DescriptorCache* cache = nullptr) const override { return false; }
33  bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const override { return false; };
34  bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const override { return false; }
35  void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const override {}
36  std::optional<int64_t> ScriptSize() const override { return {}; }
37  std::optional<int64_t> MaxSatisfactionWeight(bool) const override { return {}; }
38  std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }
39  void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override {}
40  std::vector<std::string> Warnings() const override { return {}; }
41  uint32_t GetMaxKeyExpr() const override { return 0; }
42  size_t GetKeyCount() const override { return 0; }
43 };
44 
45 BOOST_FIXTURE_TEST_CASE(wallet_load_descriptors, TestingSetup)
46 {
47  bilingual_str _error;
48  std::vector<bilingual_str> _warnings;
49  std::unique_ptr<WalletDatabase> database = CreateMockableWalletDatabase();
50  {
51  // Write unknown active descriptor
52  WalletBatch batch(*database);
53  std::string unknown_desc = "trx(tpubD6NzVbkrYhZ4Y4S7m6Y5s9GD8FqEMBy56AGphZXuagajudVZEnYyBahZMgHNCTJc2at82YX6s8JiL1Lohu5A3v1Ur76qguNH4QVQ7qYrBQx/86'/1'/0'/0/*)#8pn8tzdt";
54  WalletDescriptor wallet_descriptor(std::make_shared<DummyDescriptor>(unknown_desc), 0, 0, 0, 0);
55  BOOST_CHECK(batch.WriteDescriptor(uint256(), wallet_descriptor));
56  BOOST_CHECK(batch.WriteActiveScriptPubKeyMan(static_cast<uint8_t>(OutputType::UNKNOWN), uint256(), false));
57  }
58 
59  {
60  // Now try to load the wallet and verify the error.
61  const std::shared_ptr<CWallet> wallet(new CWallet(m_node.chain.get(), "", std::move(database)));
62  BOOST_CHECK_EQUAL(wallet->PopulateWalletFromDB(_error, _warnings), DBErrors::UNKNOWN_DESCRIPTOR);
63  }
64 
65  // Test 2
66  // Now write a valid descriptor with an invalid ID.
67  // As the software produces another ID for the descriptor, the loading process must be aborted.
68  database = CreateMockableWalletDatabase();
69 
70  // Verify the error
71  bool found = false;
72  DebugLogHelper logHelper("The descriptor ID calculated by the wallet differs from the one in DB", [&](const std::string* s) {
73  found = true;
74  return false;
75  });
76 
77  {
78  // Write valid descriptor with invalid ID
79  WalletBatch batch(*database);
80  std::string desc = "wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#cjjspncu";
81  WalletDescriptor wallet_descriptor(std::make_shared<DummyDescriptor>(desc), 0, 0, 0, 0);
82  BOOST_CHECK(batch.WriteDescriptor(uint256::ONE, wallet_descriptor));
83  }
84 
85  {
86  // Now try to load the wallet and verify the error.
87  const std::shared_ptr<CWallet> wallet(new CWallet(m_node.chain.get(), "", std::move(database)));
88  BOOST_CHECK_EQUAL(wallet->PopulateWalletFromDB(_error, _warnings), DBErrors::CORRUPT);
89  BOOST_CHECK(found); // The error must be logged
90  }
91 }
92 
94 } // namespace wallet
bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const override
Expand a descriptor at a specified position.
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:76
static const uint256 ONE
Definition: uint256.h:204
bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const override
Convert the descriptor to a normalized string.
bool IsSolvable() const override
Whether this descriptor has all information about signing ignoring lack of private keys...
Bilingual messages:
Definition: translation.h:24
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
std::string ToString(bool compat_format) const override
Convert the descriptor back to a string, undoing parsing.
std::optional< int64_t > MaxSatisfactionWeight(bool) const override
Get the maximum size of a satisfaction for this descriptor, in weight units.
Access to the wallet database.
Definition: walletdb.h:192
bool WriteDescriptor(const uint256 &desc_id, const WalletDescriptor &descriptor)
Definition: walletdb.cpp:234
void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const override
Return all (extended) public keys for this descriptor, including any from subdescriptors.
std::optional< int64_t > MaxSatisfactionElems() const override
Get the maximum size number of stack elements for satisfying this descriptor.
size_t GetKeyCount() const override
Get the number of key expressions in this descriptor.
bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const override
Expand a descriptor at a specified position using cached expansion data.
bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256 &id, bool internal)
Definition: walletdb.cpp:205
BOOST_AUTO_TEST_SUITE_END()
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:309
std::optional< int64_t > ScriptSize() const override
Get the size of the scriptPubKey for this descriptor.
uint32_t GetMaxKeyExpr() const override
Get the maximum key expression index.
bool IsSingleType() const override
Whether this descriptor will return one scriptPubKey or multiple (aka is or is not combo) ...
Descriptor with some wallet metadata.
Definition: walletutil.h:63
BOOST_FIXTURE_TEST_CASE(wallet_coinsresult_test, BasicTestingSetup)
256-bit opaque blob.
Definition: uint256.h:195
std::unique_ptr< WalletDatabase > CreateMockableWalletDatabase(MockableData records)
Definition: util.cpp:211
An interface to be implemented by keystores that support signing.
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
Cache for single descriptor&#39;s derived extended pubkeys.
Definition: descriptor.h:19
DummyDescriptor(const std::string &descriptor)
bool IsRange() const override
Whether the expansion of this descriptor depends on the position.
bool ToPrivateString(const SigningProvider &provider, std::string &out) const override
Convert the descriptor to a private string.
std::optional< OutputType > GetOutputType() const override
bool HavePrivateKeys(const SigningProvider &) const override
Whether the given provider has all private keys required by this descriptor.
std::vector< std::string > Warnings() const override
Semantic/safety warnings (includes subdescriptors).
void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const override
Expand the private key for a descriptor at a specified position, if possible.
Testing setup that configures a complete environment.
Definition: setup_common.h:121
Interface for parsed descriptor objects.
Definition: descriptor.h:98
#define BOOST_CHECK(expr)
Definition: object.cpp:16