Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/wallet/rpc/backup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1783,7 +1783,7 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
if (!w_desc.descriptor->GetOutputType()) {
warnings.push_back("Unknown output type, cannot set descriptor to active.");
} else {
wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), internal);
wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), internal ? InternalKey::Internal : InternalKey::External);
}
} else {
if (w_desc.descriptor->GetOutputType()) {
Expand Down Expand Up @@ -1976,6 +1976,7 @@ RPCHelpMan listdescriptors()
{RPCResult::Type::NUM, "timestamp", "The creation time of the descriptor"},
{RPCResult::Type::BOOL, "active", "Whether this descriptor is currently used to generate new addresses"},
{RPCResult::Type::BOOL, "internal", /*optional=*/true, "True if this descriptor is used to generate change addresses. False if this descriptor is used to generate receiving addresses; defined only for active descriptors"},
{RPCResult::Type::BOOL, "coinjoin", /*optional=*/true, "True if this descriptor is used to generate CoinJoin addresses. False if this descriptor is used to generate receiving addresses; defined only for active descriptors"},
{RPCResult::Type::ARR_FIXED, "range", /*optional=*/true, "Defined only for ranged descriptors", {
{RPCResult::Type::NUM, "", "Range start inclusive"},
{RPCResult::Type::NUM, "", "Range end inclusive"},
Expand Down Expand Up @@ -2034,7 +2035,10 @@ RPCHelpMan listdescriptors()
spk.pushKV("active", active);
const auto& type = wallet_descriptor.descriptor->GetOutputType();
if (active && type != std::nullopt) {
spk.pushKV("internal", wallet->GetScriptPubKeyMan(true) == desc_spk_man);
spk.pushKV("internal", wallet->GetScriptPubKeyMan(InternalKey::Internal) == desc_spk_man);
}
if (active && type != std::nullopt) {
spk.pushKV("coinjoin", wallet->GetScriptPubKeyMan(InternalKey::CoinJoin) == desc_spk_man);
}
if (wallet_descriptor.descriptor->IsRange()) {
UniValue range(UniValue::VARR);
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/rpc/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ static RPCHelpMan getwalletinfo()
{RPCResult::Type::NUM_TIME, "timefirstkey", "the " + UNIX_EPOCH_TIME + " of the oldest known key in the wallet"},
{RPCResult::Type::NUM_TIME, "keypoololdest", /* optional */ true, "the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool. Legacy wallets only"},
{RPCResult::Type::NUM, "keypoolsize", "how many new keys are pre-generated (only counts external keys)"},
{RPCResult::Type::NUM, "keypoolsize_hd_internal", /* optional */ true, "how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)"},
{RPCResult::Type::NUM, "keypoolsize_hd_internal", /* optional */ true, "how many new keys are pre-generated for internal use (used for change outputs and mobile coinjoin, only appears if the wallet is using this feature, otherwise external keys are used)"},
{RPCResult::Type::NUM, "keys_left", "how many new keys are left since last automatic backup"},
{RPCResult::Type::NUM_TIME, "unlocked_until", /* optional */ true, "the " + UNIX_EPOCH_TIME + " until which the wallet is unlocked for transfers, or 0 if the wallet is locked (only present for passphrase-encrypted wallets)"},
{RPCResult::Type::STR_AMOUNT, "paytxfee", "the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB"},
Expand Down
6 changes: 3 additions & 3 deletions src/wallet/scriptpubkeyman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2074,7 +2074,7 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
}
}

bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_key, const SecureString& secure_mnemonic, const SecureString& secure_mnemonic_passphrase, bool internal)
bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_key, const SecureString& secure_mnemonic, const SecureString& secure_mnemonic_passphrase, InternalKey internal)
{
LOCK(cs_desc_man);
assert(m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
Expand All @@ -2099,10 +2099,10 @@ bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_
std::string xpub = EncodeExtPubKey(master_key.Neuter());

// Build descriptor string
std::string desc_prefix = strprintf("pkh(%s/44'/%d'", xpub, Params().ExtCoinType());
std::string desc_prefix = strprintf("pkh(%s/%d'/%d'", xpub, internal == InternalKey::CoinJoin ? 9 : 44, Params().ExtCoinType());
std::string desc_suffix = "/*)";

std::string internal_path = internal ? "/1" : "/0";
std::string internal_path = (internal == InternalKey::Internal) ? "/1" : "/0";
std::string desc_str = desc_prefix + "/0'" + internal_path + desc_suffix;

// Make the descriptor
Expand Down
9 changes: 8 additions & 1 deletion src/wallet/scriptpubkeyman.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ class CKeyPool
}
};

enum class InternalKey : uint8_t
{
External,
Internal,
CoinJoin,
};

/*
* A class implementing ScriptPubKeyMan manages some (or all) scriptPubKeys used in a wallet.
* It contains the scripts and keys related to the scriptPubKeys it manages.
Expand Down Expand Up @@ -575,7 +582,7 @@ class DescriptorScriptPubKeyMan : public ScriptPubKeyMan
bool IsHDEnabled() const override;

//! Setup descriptors based on the given CExtkey
bool SetupDescriptorGeneration(const CExtKey& master_key, const SecureString& secure_mnemonic, const SecureString& secure_mnemonic_passphrase, bool internal);
bool SetupDescriptorGeneration(const CExtKey& master_key, const SecureString& secure_mnemonic, const SecureString& secure_mnemonic_passphrase, InternalKey internal);

bool HavePrivateKeys() const override;

Expand Down
64 changes: 44 additions & 20 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,7 @@ bool CWallet::CanGetAddresses(bool internal) const
{
LOCK(cs_wallet);
if (m_spk_managers.empty()) return false;
auto spk_man = GetScriptPubKeyMan(internal);
auto spk_man = GetScriptPubKeyMan(internal ? InternalKey::Internal : InternalKey::External);
if (spk_man && spk_man->CanGetAddresses(internal)) {
return true;
}
Expand Down Expand Up @@ -2354,7 +2354,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
util::Result<CTxDestination> CWallet::GetNewDestination(const std::string label)
{
LOCK(cs_wallet);
auto spk_man = GetScriptPubKeyMan(false /* internal */);
auto spk_man = GetScriptPubKeyMan(InternalKey::External);
if (!spk_man) {
return util::Error{_("Error: No addresses available.")};
}
Expand Down Expand Up @@ -2447,7 +2447,7 @@ std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) co

util::Result<CTxDestination> ReserveDestination::GetReservedDestination(bool fInternalIn)
{
m_spk_man = pwallet->GetScriptPubKeyMan(fInternalIn);
m_spk_man = pwallet->GetScriptPubKeyMan(fInternalIn ? InternalKey::Internal : InternalKey::External);
if (!m_spk_man) {
return util::Error{_("Error: No addresses available.")};
}
Expand Down Expand Up @@ -3638,7 +3638,7 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, b
std::set<ScriptPubKeyMan*> CWallet::GetActiveScriptPubKeyMans() const
{
std::set<ScriptPubKeyMan*> spk_mans;
for (bool internal : {false, true}) {
for (auto internal : {InternalKey::Internal, InternalKey::External, InternalKey::CoinJoin}) {
auto spk_man = GetScriptPubKeyMan(internal);
if (spk_man) {
spk_mans.insert(spk_man);
Expand All @@ -3656,13 +3656,18 @@ std::set<ScriptPubKeyMan*> CWallet::GetAllScriptPubKeyMans() const
return spk_mans;
}

ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(bool internal) const
ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(InternalKey internal) const
{
const auto spk_manager = internal ? m_internal_spk_managers : m_external_spk_managers;
if (spk_manager == nullptr) {
return nullptr;
}
return spk_manager;
switch (internal)
{
case InternalKey::Internal:
return m_internal_spk_managers;
case InternalKey::External:
return m_external_spk_managers;
case InternalKey::CoinJoin:
return m_coinjoin_spk_managers;
} // no default to let compiler warn us
return nullptr;
}

std::set<ScriptPubKeyMan*> CWallet::GetScriptPubKeyMans(const CScript& script, SignatureData& sigdata) const
Expand Down Expand Up @@ -3787,7 +3792,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans(const SecureString& mnemonic_arg,
CExtKey master_key;
master_key.SetSeed(MakeByteSpan(seed_key));

for (bool internal : {false, true}) {
for (auto internal : {InternalKey::External, InternalKey::Internal, InternalKey::CoinJoin}) {
{ // OUTPUT_TYPE is only one: LEGACY
auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this));
if (IsCrypted()) {
Expand All @@ -3806,7 +3811,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans(const SecureString& mnemonic_arg,
}
}

void CWallet::AddActiveScriptPubKeyMan(uint256 id, bool internal)
void CWallet::AddActiveScriptPubKeyMan(uint256 id, InternalKey internal)
{
WalletBatch batch(GetDatabase());
if (!batch.WriteActiveScriptPubKeyMan(id, internal)) {
Expand All @@ -3815,29 +3820,48 @@ void CWallet::AddActiveScriptPubKeyMan(uint256 id, bool internal)
LoadActiveScriptPubKeyMan(id, internal);
}

void CWallet::LoadActiveScriptPubKeyMan(uint256 id, bool internal)
void CWallet::LoadActiveScriptPubKeyMan(uint256 id, InternalKey internal)
{
// Activating ScriptPubKeyManager for a given output and change type is incompatible with legacy wallets.
// Legacy wallets have only one ScriptPubKeyManager and it's active for all output and change types.
Assert(IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));

WalletLogPrintf("Setting spkMan to active: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal ? "true" : "false");
auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
auto& spk_mans_other = internal ? m_external_spk_managers : m_internal_spk_managers;
WalletLogPrintf("Setting spkMan to active: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal == InternalKey::Internal ? "true" : "false");

auto spk_man = m_spk_managers.at(id).get();
spk_mans = spk_man;
switch (internal) {
case InternalKey::Internal:
m_internal_spk_managers = spk_man;
break;

if (spk_mans_other == spk_man) {
spk_mans_other = nullptr;
case InternalKey::External:
m_external_spk_managers = spk_man;
break;
case InternalKey::CoinJoin:
m_coinjoin_spk_managers = spk_man;
break;
}

// no default case to let compiler hint it
if (internal != InternalKey::Internal && m_internal_spk_managers == spk_man) {
m_internal_spk_managers = nullptr;
}

if (internal != InternalKey::External && m_external_spk_managers == spk_man) {
m_external_spk_managers = nullptr;
}
if (internal != InternalKey::CoinJoin && m_coinjoin_spk_managers == spk_man) {
m_coinjoin_spk_managers = nullptr;
}

NotifyCanGetAddressesChanged();

}

// TODO: probably need to support InternalKey here
void CWallet::DeactivateScriptPubKeyMan(uint256 id, bool internal)
{
auto spk_man = GetScriptPubKeyMan(internal);
auto spk_man = GetScriptPubKeyMan(internal ? InternalKey::Internal : InternalKey::External);
if (spk_man != nullptr && spk_man->GetID() == id) {
WalletLogPrintf("Deactivate spkMan: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal ? "true" : "false");
WalletBatch batch(GetDatabase());
Expand Down
7 changes: 4 additions & 3 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati

ScriptPubKeyMan* m_external_spk_managers{nullptr};
ScriptPubKeyMan* m_internal_spk_managers{nullptr};
ScriptPubKeyMan* m_coinjoin_spk_managers{nullptr};

// Indexed by a unique identifier produced by each ScriptPubKeyMan using
// ScriptPubKeyMan::GetID. In many cases it will be the hash of an internal structure
Expand Down Expand Up @@ -984,7 +985,7 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
std::set<ScriptPubKeyMan*> GetAllScriptPubKeyMans() const;

//! Get the ScriptPubKeyMan for internal/external chain.
ScriptPubKeyMan* GetScriptPubKeyMan(bool internal) const;
ScriptPubKeyMan* GetScriptPubKeyMan(InternalKey internal) const;

//! Get the ScriptPubKeyMan for a script
ScriptPubKeyMan* GetScriptPubKeyMan(const CScript& script) const;
Expand Down Expand Up @@ -1039,12 +1040,12 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
//! Adds the active ScriptPubKeyMan for the specified type and internal. Writes it to the wallet file
//! @param[in] id The unique id for the ScriptPubKeyMan
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
void AddActiveScriptPubKeyMan(uint256 id, bool internal);
void AddActiveScriptPubKeyMan(uint256 id, InternalKey internal);

//! Loads an active ScriptPubKeyMan for the specified type and internal. (used by LoadWallet)
//! @param[in] id The unique id for the ScriptPubKeyMan
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
void LoadActiveScriptPubKeyMan(uint256 id, bool internal);
void LoadActiveScriptPubKeyMan(uint256 id, InternalKey internal);

//! Remove specified ScriptPubKeyMan from set of active SPK managers. Writes the change to the wallet file.
//! @param[in] id The unique id for the ScriptPubKeyMan
Expand Down
32 changes: 26 additions & 6 deletions src/wallet/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace DBKeys {
const std::string ACENTRY{"acentry"};
const std::string ACTIVEEXTERNALSPK{"activeexternalspk"};
const std::string ACTIVEINTERNALSPK{"activeinternalspk"};
const std::string ACTIVECOINJOINSPK{"activecoinjoinspk"};
const std::string BESTBLOCK_NOMERKLE{"bestblock_nomerkle"};
const std::string BESTBLOCK{"bestblock"};
const std::string CRYPTED_KEY{"ckey"};
Expand Down Expand Up @@ -230,9 +231,23 @@ bool WalletBatch::WriteGovernanceObject(const Governance::Object& obj)
return WriteIC(std::make_pair(DBKeys::G_OBJECT, obj.GetHash()), obj, false);
}

bool WalletBatch::WriteActiveScriptPubKeyMan(const uint256& id, bool internal)
bool WalletBatch::WriteActiveScriptPubKeyMan(const uint256& id, InternalKey internal)
{
std::string key = internal ? DBKeys::ACTIVEINTERNALSPK : DBKeys::ACTIVEEXTERNALSPK;
std::string key;
switch (internal) {
case InternalKey::Internal:
key = DBKeys::ACTIVEINTERNALSPK;
break;
case InternalKey::External:
key = DBKeys::ACTIVEEXTERNALSPK;
break;
case InternalKey::CoinJoin:
key = DBKeys::ACTIVECOINJOINSPK;
break;
}
// no default to get a hint from a compiler
assert(!key.empty());

return WriteIC(key, id);
}

Expand Down Expand Up @@ -333,6 +348,7 @@ class CWalletScanState {
std::vector<uint256> vWalletUpgrade;
std::map<OutputType, uint256> m_active_external_spks;
std::map<OutputType, uint256> m_active_internal_spks;
std::map<OutputType, uint256> m_active_coinjoin_spks;
std::map<uint256, DescriptorCache> m_descriptor_caches;
std::map<std::pair<uint256, CKeyID>, CKey> m_descriptor_keys;
std::map<std::pair<uint256, CKeyID>, std::pair<CPubKey, std::vector<unsigned char>>> m_descriptor_crypt_keys;
Expand Down Expand Up @@ -614,12 +630,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
} else if (strType == DBKeys::OLD_KEY) {
strErr = "Found unsupported 'wkey' record, try loading with version 0.17";
return false;
} else if (strType == DBKeys::ACTIVEEXTERNALSPK || strType == DBKeys::ACTIVEINTERNALSPK) {
} else if (strType == DBKeys::ACTIVEEXTERNALSPK || strType == DBKeys::ACTIVEINTERNALSPK || strType == DBKeys::ACTIVEEXTERNALSPK) {
uint256 id;
ssValue >> id;

bool internal = strType == DBKeys::ACTIVEINTERNALSPK;
auto& spk_mans = internal ? wss.m_active_internal_spks : wss.m_active_external_spks;
bool coinjoin = strType == DBKeys::ACTIVECOINJOINSPK;
auto& spk_mans = internal ? wss.m_active_internal_spks : (coinjoin ? wss.m_active_coinjoin_spks : wss.m_active_external_spks);
const OutputType type = OutputType::LEGACY;
if (spk_mans.count(static_cast<OutputType>(type)) > 0) {
strErr = "Multiple ScriptPubKeyMans specified for a single type";
Expand Down Expand Up @@ -878,10 +895,13 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)

// Set the active ScriptPubKeyMans
for (auto spk_man : wss.m_active_external_spks) {
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, /* internal */ false);
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, InternalKey::External);
}
for (auto spk_man : wss.m_active_internal_spks) {
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, /* internal */ true);
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, InternalKey::Internal);
}
for (auto spk_man : wss.m_active_coinjoin_spks) {
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, InternalKey::CoinJoin);
}

// Set the descriptor caches
Expand Down
5 changes: 3 additions & 2 deletions src/wallet/walletdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class CMasterKey;
class CWallet;
class CWalletTx;
struct WalletContext;

enum class InternalKey : uint8_t;
/**
* Overview of wallet database classes:
*
Expand Down Expand Up @@ -61,6 +61,7 @@ namespace DBKeys {
extern const std::string ACENTRY;
extern const std::string ACTIVEEXTERNALSPK;
extern const std::string ACTIVEINTERNALSPK;
extern const std::string ACTIVECOINJOINSPK;
extern const std::string BESTBLOCK;
extern const std::string BESTBLOCK_NOMERKLE;
extern const std::string CRYPTED_HDCHAIN;
Expand Down Expand Up @@ -229,7 +230,7 @@ class WalletBatch
/// Erase destination data tuple from wallet database
bool EraseDestData(const std::string &address, const std::string &key);

bool WriteActiveScriptPubKeyMan(const uint256& id, bool internal);
bool WriteActiveScriptPubKeyMan(const uint256& id, InternalKey internal);
bool EraseActiveScriptPubKeyMan(bool internal);

Comment on lines +233 to 235
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

API inconsistency: EraseActiveScriptPubKeyMan still takes bool; cannot target CoinJoin.

Write-path now supports External/Internal/CoinJoin, but erase-path can only address a boolean (internal/external). This risks leaving stale ACTIVECOINJOINSPK entries.

-    bool WriteActiveScriptPubKeyMan(const uint256& id, InternalKey internal);
-    bool EraseActiveScriptPubKeyMan(bool internal);
+    bool WriteActiveScriptPubKeyMan(const uint256& id, InternalKey internal);
+    bool EraseActiveScriptPubKeyMan(InternalKey internal);

Outside this file (walletdb.cpp), mirror the switch used in WriteActiveScriptPubKeyMan:

bool WalletBatch::EraseActiveScriptPubKeyMan(InternalKey internal)
{
    std::string key;
    switch (internal) {
    case InternalKey::Internal: key = DBKeys::ACTIVEINTERNALSPK; break;
    case InternalKey::External: key = DBKeys::ACTIVEEXTERNALSPK; break;
    case InternalKey::CoinJoin: key = DBKeys::ACTIVECOINJOINSPK; break;
    }
    assert(!key.empty());
    return EraseIC(key);
}

🏁 Script executed:

#!/bin/bash
# Find erase callsites and confirm no assumptions on bool survive.
rg -n "EraseActiveScriptPubKeyMan\\(" -g src/wallet
rg -n "ACTIVECOINJOINSPK" -g src/wallet

Length of output: 390


🏁 Script executed:

#!/bin/bash
# Search for EraseActiveScriptPubKeyMan definitions and callsites across the repo
rg -n "EraseActiveScriptPubKeyMan\(" -C3 .

# Search for WriteActiveScriptPubKeyMan definitions and callsites across the repo
rg -n "WriteActiveScriptPubKeyMan\(" -C3 .

# Search for the CoinJoin key usage
rg -n "ACTIVECOINJOINSPK" -C3 .

Length of output: 5259


Refactor EraseActiveScriptPubKeyMan to use InternalKey
Signature in src/wallet/walletdb.h (line 234) and definition in src/wallet/walletdb.cpp (line 254) must accept InternalKey internal instead of bool internal; replicate the switch(internal) from WriteActiveScriptPubKeyMan to handle InternalKey::CoinJoin (DBKeys::ACTIVECOINJOINSPK) as well as External/Internal. Update the callsite in src/wallet/wallet.cpp (around line 3855) to pass the enum value rather than a bool, ensuring proper removal of coinjoin entries.

🤖 Prompt for AI Agents
In src/wallet/walletdb.h around lines 233-235, change the prototype of
EraseActiveScriptPubKeyMan to accept InternalKey internal (not bool) so it
matches the implementation; in src/wallet/walletdb.cpp around line 254, update
the function to switch(on internal) like WriteActiveScriptPubKeyMan and handle
InternalKey::CoinJoin by erasing DBKeys::ACTIVECOINJOINSPK in addition to
External/Internal keys; then update the callsite in src/wallet/wallet.cpp near
line 3855 to pass the appropriate InternalKey enum value instead of a bool so
CoinJoin entries are removed correctly (also ensure any needed includes or
forward declarations for InternalKey are present).

DBErrors LoadWallet(CWallet* pwallet);
Expand Down
3 changes: 2 additions & 1 deletion test/functional/tool_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ def test_tool_wallet_create_on_existing_wallet(self):
shasum_before = self.wallet_shasum()
timestamp_before = self.wallet_timestamp()
self.log.debug('Wallet file timestamp before calling create: {}'.format(timestamp_before))
out = "Topping up keypool...\n" + self.get_expected_info_output(name="foo", keypool=2000)
keypool_size = 3000 if self.options.descriptors else 2000
out = "Topping up keypool...\n" + self.get_expected_info_output(name="foo", keypool=keypool_size)
self.assert_tool_output(out, '-wallet=foo', 'create')
shasum_after = self.wallet_shasum()
timestamp_after = self.wallet_timestamp()
Expand Down
3 changes: 2 additions & 1 deletion test/functional/wallet_createwallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,10 @@ def run_test(self):
# There should only be 1 key for legacy, 1 for descriptors (dash has only one type of addresses)
walletinfo = w6.getwalletinfo()
keys = 1 if self.options.descriptors else 1
cj_keys = 1 if self.options.descriptors else 0
assert_equal(walletinfo['keypoolsize'], keys)
# hd_internals are not refilled by default for descriptor wallets atm
assert_equal(walletinfo['keypoolsize_hd_internal'], keys)
assert_equal(walletinfo['keypoolsize_hd_internal'], keys + cj_keys)
# Allow empty passphrase, but there should be a warning
resp = self.nodes[0].createwallet(wallet_name='w7', disable_private_keys=False, blank=False, passphrase='')
assert 'Empty string given as passphrase, wallet will not be encrypted.' in resp['warning']
Expand Down
Loading
Loading