Skip to content

Commit 9d999e5

Browse files
committed
feat: descriptor wallets by default create spk for mobile derivation path for CJ
1 parent 489c5f0 commit 9d999e5

14 files changed

+109
-50
lines changed

src/wallet/rpc/backup.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,7 @@ static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, c
17831783
if (!w_desc.descriptor->GetOutputType()) {
17841784
warnings.push_back("Unknown output type, cannot set descriptor to active.");
17851785
} else {
1786-
wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), internal);
1786+
wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), internal ? InternalKey::Internal : InternalKey::External);
17871787
}
17881788
} else {
17891789
if (w_desc.descriptor->GetOutputType()) {
@@ -1976,6 +1976,7 @@ RPCHelpMan listdescriptors()
19761976
{RPCResult::Type::NUM, "timestamp", "The creation time of the descriptor"},
19771977
{RPCResult::Type::BOOL, "active", "Whether this descriptor is currently used to generate new addresses"},
19781978
{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"},
1979+
{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"},
19791980
{RPCResult::Type::ARR_FIXED, "range", /*optional=*/true, "Defined only for ranged descriptors", {
19801981
{RPCResult::Type::NUM, "", "Range start inclusive"},
19811982
{RPCResult::Type::NUM, "", "Range end inclusive"},
@@ -2034,7 +2035,10 @@ RPCHelpMan listdescriptors()
20342035
spk.pushKV("active", active);
20352036
const auto& type = wallet_descriptor.descriptor->GetOutputType();
20362037
if (active && type != std::nullopt) {
2037-
spk.pushKV("internal", wallet->GetScriptPubKeyMan(true) == desc_spk_man);
2038+
spk.pushKV("internal", wallet->GetScriptPubKeyMan(InternalKey::Internal) == desc_spk_man);
2039+
}
2040+
if (active && type != std::nullopt) {
2041+
spk.pushKV("coinjoin", wallet->GetScriptPubKeyMan(InternalKey::CoinJoin) == desc_spk_man);
20382042
}
20392043
if (wallet_descriptor.descriptor->IsRange()) {
20402044
UniValue range(UniValue::VARR);

src/wallet/rpc/wallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static RPCHelpMan getwalletinfo()
168168
{RPCResult::Type::NUM_TIME, "timefirstkey", "the " + UNIX_EPOCH_TIME + " of the oldest known key in the wallet"},
169169
{RPCResult::Type::NUM_TIME, "keypoololdest", /* optional */ true, "the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool. Legacy wallets only"},
170170
{RPCResult::Type::NUM, "keypoolsize", "how many new keys are pre-generated (only counts external keys)"},
171-
{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)"},
171+
{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)"},
172172
{RPCResult::Type::NUM, "keys_left", "how many new keys are left since last automatic backup"},
173173
{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)"},
174174
{RPCResult::Type::STR_AMOUNT, "paytxfee", "the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB"},

src/wallet/scriptpubkeyman.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,7 +2081,7 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
20812081
}
20822082
}
20832083

2084-
bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_key, const SecureString& secure_mnemonic, const SecureString& secure_mnemonic_passphrase, bool internal)
2084+
bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_key, const SecureString& secure_mnemonic, const SecureString& secure_mnemonic_passphrase, InternalKey internal)
20852085
{
20862086
LOCK(cs_desc_man);
20872087
assert(m_storage.IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
@@ -2106,10 +2106,10 @@ bool DescriptorScriptPubKeyMan::SetupDescriptorGeneration(const CExtKey& master_
21062106
std::string xpub = EncodeExtPubKey(master_key.Neuter());
21072107

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

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

21152115
// Make the descriptor

src/wallet/scriptpubkeyman.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ class CKeyPool
146146
}
147147
};
148148

149+
enum class InternalKey
150+
{
151+
External,
152+
Internal,
153+
CoinJoin,
154+
};
155+
149156
/*
150157
* A class implementing ScriptPubKeyMan manages some (or all) scriptPubKeys used in a wallet.
151158
* It contains the scripts and keys related to the scriptPubKeys it manages.
@@ -574,7 +581,7 @@ class DescriptorScriptPubKeyMan : public ScriptPubKeyMan
574581
bool IsHDEnabled() const override;
575582

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

579586
bool HavePrivateKeys() const override;
580587

src/wallet/wallet.cpp

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,7 @@ bool CWallet::CanGetAddresses(bool internal) const
14711471
{
14721472
LOCK(cs_wallet);
14731473
if (m_spk_managers.empty()) return false;
1474-
auto spk_man = GetScriptPubKeyMan(internal);
1474+
auto spk_man = GetScriptPubKeyMan(internal ? InternalKey::Internal : InternalKey::External);
14751475
if (spk_man && spk_man->CanGetAddresses(internal)) {
14761476
return true;
14771477
}
@@ -2351,7 +2351,7 @@ bool CWallet::GetNewDestination(const std::string label, CTxDestination& dest, b
23512351
bool result = false;
23522352

23532353
LOCK(cs_wallet);
2354-
auto spk_man = GetScriptPubKeyMan(false /* internal */);
2354+
auto spk_man = GetScriptPubKeyMan(InternalKey::External);
23552355
if (spk_man) {
23562356
spk_man->TopUp();
23572357
result = spk_man->GetNewDestination(dest, error);
@@ -2448,7 +2448,7 @@ std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) co
24482448

24492449
bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool fInternalIn)
24502450
{
2451-
m_spk_man = pwallet->GetScriptPubKeyMan(fInternalIn);
2451+
m_spk_man = pwallet->GetScriptPubKeyMan(fInternalIn ? InternalKey::Internal : InternalKey::External);
24522452
if (!m_spk_man) {
24532453
return false;
24542454
}
@@ -3625,7 +3625,7 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, b
36253625
std::set<ScriptPubKeyMan*> CWallet::GetActiveScriptPubKeyMans() const
36263626
{
36273627
std::set<ScriptPubKeyMan*> spk_mans;
3628-
for (bool internal : {false, true}) {
3628+
for (auto internal : {InternalKey::Internal, InternalKey::External, InternalKey::CoinJoin}) {
36293629
auto spk_man = GetScriptPubKeyMan(internal);
36303630
if (spk_man) {
36313631
spk_mans.insert(spk_man);
@@ -3643,13 +3643,18 @@ std::set<ScriptPubKeyMan*> CWallet::GetAllScriptPubKeyMans() const
36433643
return spk_mans;
36443644
}
36453645

3646-
ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(bool internal) const
3646+
ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(InternalKey internal) const
36473647
{
3648-
const auto spk_manager = internal ? m_internal_spk_managers : m_external_spk_managers;
3649-
if (spk_manager == nullptr) {
3650-
return nullptr;
3651-
}
3652-
return spk_manager;
3648+
switch (internal)
3649+
{
3650+
case InternalKey::Internal:
3651+
return m_internal_spk_managers;
3652+
case InternalKey::External:
3653+
return m_external_spk_managers;
3654+
case InternalKey::CoinJoin:
3655+
return m_coinjoin_spk_managers;
3656+
} // no default to let compiler warn us
3657+
return nullptr;
36533658
}
36543659

36553660
std::set<ScriptPubKeyMan*> CWallet::GetScriptPubKeyMans(const CScript& script, SignatureData& sigdata) const
@@ -3774,7 +3779,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans(const SecureString& mnemonic_arg,
37743779
CExtKey master_key;
37753780
master_key.SetSeed(MakeByteSpan(seed_key));
37763781

3777-
for (bool internal : {false, true}) {
3782+
for (auto internal : {InternalKey::External, InternalKey::Internal, InternalKey::CoinJoin}) {
37783783
{ // OUTPUT_TYPE is only one: LEGACY
37793784
auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this));
37803785
if (IsCrypted()) {
@@ -3793,7 +3798,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans(const SecureString& mnemonic_arg,
37933798
}
37943799
}
37953800

3796-
void CWallet::AddActiveScriptPubKeyMan(uint256 id, bool internal)
3801+
void CWallet::AddActiveScriptPubKeyMan(uint256 id, InternalKey internal)
37973802
{
37983803
WalletBatch batch(GetDatabase());
37993804
if (!batch.WriteActiveScriptPubKeyMan(id, internal)) {
@@ -3802,29 +3807,48 @@ void CWallet::AddActiveScriptPubKeyMan(uint256 id, bool internal)
38023807
LoadActiveScriptPubKeyMan(id, internal);
38033808
}
38043809

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

3811-
WalletLogPrintf("Setting spkMan to active: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal ? "true" : "false");
3812-
auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
3813-
auto& spk_mans_other = internal ? m_external_spk_managers : m_internal_spk_managers;
3816+
WalletLogPrintf("Setting spkMan to active: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal == InternalKey::Internal ? "true" : "false");
3817+
38143818
auto spk_man = m_spk_managers.at(id).get();
3815-
spk_mans = spk_man;
3819+
switch (internal) {
3820+
case InternalKey::Internal:
3821+
m_internal_spk_managers = spk_man;
3822+
break;
38163823

3817-
if (spk_mans_other == spk_man) {
3818-
spk_mans_other = nullptr;
3824+
case InternalKey::External:
3825+
m_external_spk_managers = spk_man;
3826+
break;
3827+
case InternalKey::CoinJoin:
3828+
m_coinjoin_spk_managers = spk_man;
3829+
break;
3830+
}
3831+
3832+
// no default case to let compiler hint it
3833+
if (internal != InternalKey::Internal && m_internal_spk_managers == spk_man) {
3834+
m_internal_spk_managers = nullptr;
3835+
}
3836+
3837+
if (internal != InternalKey::External && m_external_spk_managers == spk_man) {
3838+
m_external_spk_managers = nullptr;
3839+
}
3840+
if (internal != InternalKey::CoinJoin && m_coinjoin_spk_managers == spk_man) {
3841+
m_coinjoin_spk_managers = nullptr;
38193842
}
38203843

38213844
NotifyCanGetAddressesChanged();
38223845

38233846
}
38243847

3848+
// TODO: probably need to support InternalKey here
38253849
void CWallet::DeactivateScriptPubKeyMan(uint256 id, bool internal)
38263850
{
3827-
auto spk_man = GetScriptPubKeyMan(internal);
3851+
auto spk_man = GetScriptPubKeyMan(internal ? InternalKey::Internal : InternalKey::External);
38283852
if (spk_man != nullptr && spk_man->GetID() == id) {
38293853
WalletLogPrintf("Deactivate spkMan: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal ? "true" : "false");
38303854
WalletBatch batch(GetDatabase());

src/wallet/wallet.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
392392

393393
ScriptPubKeyMan* m_external_spk_managers{nullptr};
394394
ScriptPubKeyMan* m_internal_spk_managers{nullptr};
395+
ScriptPubKeyMan* m_coinjoin_spk_managers{nullptr};
395396

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

984985
//! Get the ScriptPubKeyMan for internal/external chain.
985-
ScriptPubKeyMan* GetScriptPubKeyMan(bool internal) const;
986+
ScriptPubKeyMan* GetScriptPubKeyMan(InternalKey internal) const;
986987

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

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

10471048
//! Remove specified ScriptPubKeyMan from set of active SPK managers. Writes the change to the wallet file.
10481049
//! @param[in] id The unique id for the ScriptPubKeyMan

src/wallet/walletdb.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace DBKeys {
3434
const std::string ACENTRY{"acentry"};
3535
const std::string ACTIVEEXTERNALSPK{"activeexternalspk"};
3636
const std::string ACTIVEINTERNALSPK{"activeinternalspk"};
37+
const std::string ACTIVECOINJOINSPK{"activecoinjoinspk"};
3738
const std::string BESTBLOCK_NOMERKLE{"bestblock_nomerkle"};
3839
const std::string BESTBLOCK{"bestblock"};
3940
const std::string CRYPTED_KEY{"ckey"};
@@ -230,9 +231,23 @@ bool WalletBatch::WriteGovernanceObject(const Governance::Object& obj)
230231
return WriteIC(std::make_pair(DBKeys::G_OBJECT, obj.GetHash()), obj, false);
231232
}
232233

233-
bool WalletBatch::WriteActiveScriptPubKeyMan(const uint256& id, bool internal)
234+
bool WalletBatch::WriteActiveScriptPubKeyMan(const uint256& id, InternalKey internal)
234235
{
235-
std::string key = internal ? DBKeys::ACTIVEINTERNALSPK : DBKeys::ACTIVEEXTERNALSPK;
236+
std::string key;
237+
switch (internal) {
238+
case InternalKey::Internal:
239+
key = DBKeys::ACTIVEINTERNALSPK;
240+
break;
241+
case InternalKey::External:
242+
key = DBKeys::ACTIVEEXTERNALSPK;
243+
break;
244+
case InternalKey::CoinJoin:
245+
key = DBKeys::ACTIVECOINJOINSPK;
246+
break;
247+
}
248+
// no default to get a hint from a compiler
249+
assert(!key.empty());
250+
236251
return WriteIC(key, id);
237252
}
238253

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

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

879896
// Set the active ScriptPubKeyMans
880897
for (auto spk_man : wss.m_active_external_spks) {
881-
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, /* internal */ false);
898+
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, InternalKey::External);
882899
}
883900
for (auto spk_man : wss.m_active_internal_spks) {
884-
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, /* internal */ true);
901+
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, InternalKey::Internal);
902+
}
903+
for (auto spk_man : wss.m_active_coinjoin_spks) {
904+
pwallet->LoadActiveScriptPubKeyMan(spk_man.second, InternalKey::CoinJoin);
885905
}
886906

887907
// Set the descriptor caches

src/wallet/walletdb.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class CMasterKey;
3131
class CWallet;
3232
class CWalletTx;
3333
struct WalletContext;
34-
34+
enum class InternalKey;
3535
/**
3636
* Overview of wallet database classes:
3737
*
@@ -61,6 +61,7 @@ namespace DBKeys {
6161
extern const std::string ACENTRY;
6262
extern const std::string ACTIVEEXTERNALSPK;
6363
extern const std::string ACTIVEINTERNALSPK;
64+
extern const std::string ACTIVECOINJOINSPK;
6465
extern const std::string BESTBLOCK;
6566
extern const std::string BESTBLOCK_NOMERKLE;
6667
extern const std::string CRYPTED_HDCHAIN;
@@ -229,7 +230,7 @@ class WalletBatch
229230
/// Erase destination data tuple from wallet database
230231
bool EraseDestData(const std::string &address, const std::string &key);
231232

232-
bool WriteActiveScriptPubKeyMan(const uint256& id, bool internal);
233+
bool WriteActiveScriptPubKeyMan(const uint256& id, InternalKey internal);
233234
bool EraseActiveScriptPubKeyMan(bool internal);
234235

235236
DBErrors LoadWallet(CWallet* pwallet);

test/functional/tool_wallet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ def test_tool_wallet_create_on_existing_wallet(self):
266266
shasum_before = self.wallet_shasum()
267267
timestamp_before = self.wallet_timestamp()
268268
self.log.debug('Wallet file timestamp before calling create: {}'.format(timestamp_before))
269-
out = "Topping up keypool...\n" + self.get_expected_info_output(name="foo", keypool=2000)
269+
out = "Topping up keypool...\n" + self.get_expected_info_output(name="foo", keypool=3000)
270270
self.assert_tool_output(out, '-wallet=foo', 'create')
271271
shasum_after = self.wallet_shasum()
272272
timestamp_after = self.wallet_timestamp()

test/functional/wallet_createwallet.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,10 @@ def run_test(self):
152152
# There should only be 1 key for legacy, 1 for descriptors (dash has only one type of addresses)
153153
walletinfo = w6.getwalletinfo()
154154
keys = 1 if self.options.descriptors else 1
155+
cj_keys = 1 if self.options.descriptors else 0
155156
assert_equal(walletinfo['keypoolsize'], keys)
156157
# hd_internals are not refilled by default for descriptor wallets atm
157-
assert_equal(walletinfo['keypoolsize_hd_internal'], keys)
158+
assert_equal(walletinfo['keypoolsize_hd_internal'], keys + cj_keys)
158159
# Allow empty passphrase, but there should be a warning
159160
resp = self.nodes[0].createwallet(wallet_name='w7', disable_private_keys=False, blank=False, passphrase='')
160161
assert 'Empty string given as passphrase, wallet will not be encrypted.' in resp['warning']

0 commit comments

Comments
 (0)