Skip to content

Commit 2abdc78

Browse files
committed
feat: descriptor wallets by default create spk for mobile derivation path for CJ
1 parent e23a658 commit 2abdc78

14 files changed

+110
-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
@@ -2074,7 +2074,7 @@ bool DescriptorScriptPubKeyMan::AddDescriptorKeyWithDB(WalletBatch& batch, const
20742074
}
20752075
}
20762076

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

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

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

21082108
// Make the descriptor

src/wallet/scriptpubkeyman.h

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

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

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

580587
bool HavePrivateKeys() const override;
581588

src/wallet/wallet.cpp

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,7 @@ bool CWallet::CanGetAddresses(bool internal) const
14771477
{
14781478
LOCK(cs_wallet);
14791479
if (m_spk_managers.empty()) return false;
1480-
auto spk_man = GetScriptPubKeyMan(internal);
1480+
auto spk_man = GetScriptPubKeyMan(internal ? InternalKey::Internal : InternalKey::External);
14811481
if (spk_man && spk_man->CanGetAddresses(internal)) {
14821482
return true;
14831483
}
@@ -2354,7 +2354,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
23542354
util::Result<CTxDestination> CWallet::GetNewDestination(const std::string label)
23552355
{
23562356
LOCK(cs_wallet);
2357-
auto spk_man = GetScriptPubKeyMan(false /* internal */);
2357+
auto spk_man = GetScriptPubKeyMan(InternalKey::External);
23582358
if (!spk_man) {
23592359
return util::Error{_("Error: No addresses available.")};
23602360
}
@@ -2447,7 +2447,7 @@ std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) co
24472447

24482448
util::Result<CTxDestination> ReserveDestination::GetReservedDestination(bool fInternalIn)
24492449
{
2450-
m_spk_man = pwallet->GetScriptPubKeyMan(fInternalIn);
2450+
m_spk_man = pwallet->GetScriptPubKeyMan(fInternalIn ? InternalKey::Internal : InternalKey::External);
24512451
if (!m_spk_man) {
24522452
return util::Error{_("Error: No addresses available.")};
24532453
}
@@ -3638,7 +3638,7 @@ bool CWallet::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, b
36383638
std::set<ScriptPubKeyMan*> CWallet::GetActiveScriptPubKeyMans() const
36393639
{
36403640
std::set<ScriptPubKeyMan*> spk_mans;
3641-
for (bool internal : {false, true}) {
3641+
for (auto internal : {InternalKey::Internal, InternalKey::External, InternalKey::CoinJoin}) {
36423642
auto spk_man = GetScriptPubKeyMan(internal);
36433643
if (spk_man) {
36443644
spk_mans.insert(spk_man);
@@ -3656,13 +3656,18 @@ std::set<ScriptPubKeyMan*> CWallet::GetAllScriptPubKeyMans() const
36563656
return spk_mans;
36573657
}
36583658

3659-
ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(bool internal) const
3659+
ScriptPubKeyMan* CWallet::GetScriptPubKeyMan(InternalKey internal) const
36603660
{
3661-
const auto spk_manager = internal ? m_internal_spk_managers : m_external_spk_managers;
3662-
if (spk_manager == nullptr) {
3663-
return nullptr;
3664-
}
3665-
return spk_manager;
3661+
switch (internal)
3662+
{
3663+
case InternalKey::Internal:
3664+
return m_internal_spk_managers;
3665+
case InternalKey::External:
3666+
return m_external_spk_managers;
3667+
case InternalKey::CoinJoin:
3668+
return m_coinjoin_spk_managers;
3669+
} // no default to let compiler warn us
3670+
return nullptr;
36663671
}
36673672

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

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

3809-
void CWallet::AddActiveScriptPubKeyMan(uint256 id, bool internal)
3814+
void CWallet::AddActiveScriptPubKeyMan(uint256 id, InternalKey internal)
38103815
{
38113816
WalletBatch batch(GetDatabase());
38123817
if (!batch.WriteActiveScriptPubKeyMan(id, internal)) {
@@ -3815,29 +3820,48 @@ void CWallet::AddActiveScriptPubKeyMan(uint256 id, bool internal)
38153820
LoadActiveScriptPubKeyMan(id, internal);
38163821
}
38173822

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

3824-
WalletLogPrintf("Setting spkMan to active: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal ? "true" : "false");
3825-
auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
3826-
auto& spk_mans_other = internal ? m_external_spk_managers : m_internal_spk_managers;
3829+
WalletLogPrintf("Setting spkMan to active: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal == InternalKey::Internal ? "true" : "false");
3830+
38273831
auto spk_man = m_spk_managers.at(id).get();
3828-
spk_mans = spk_man;
3832+
switch (internal) {
3833+
case InternalKey::Internal:
3834+
m_internal_spk_managers = spk_man;
3835+
break;
38293836

3830-
if (spk_mans_other == spk_man) {
3831-
spk_mans_other = nullptr;
3837+
case InternalKey::External:
3838+
m_external_spk_managers = spk_man;
3839+
break;
3840+
case InternalKey::CoinJoin:
3841+
m_coinjoin_spk_managers = spk_man;
3842+
break;
3843+
}
3844+
3845+
// no default case to let compiler hint it
3846+
if (internal != InternalKey::Internal && m_internal_spk_managers == spk_man) {
3847+
m_internal_spk_managers = nullptr;
3848+
}
3849+
3850+
if (internal != InternalKey::External && m_external_spk_managers == spk_man) {
3851+
m_external_spk_managers = nullptr;
3852+
}
3853+
if (internal != InternalKey::CoinJoin && m_coinjoin_spk_managers == spk_man) {
3854+
m_coinjoin_spk_managers = nullptr;
38323855
}
38333856

38343857
NotifyCanGetAddressesChanged();
38353858

38363859
}
38373860

3861+
// TODO: probably need to support InternalKey here
38383862
void CWallet::DeactivateScriptPubKeyMan(uint256 id, bool internal)
38393863
{
3840-
auto spk_man = GetScriptPubKeyMan(internal);
3864+
auto spk_man = GetScriptPubKeyMan(internal ? InternalKey::Internal : InternalKey::External);
38413865
if (spk_man != nullptr && spk_man->GetID() == id) {
38423866
WalletLogPrintf("Deactivate spkMan: id = %s, type = %s, internal = %s\n", id.ToString(), FormatOutputType(OutputType::LEGACY), internal ? "true" : "false");
38433867
WalletBatch batch(GetDatabase());

src/wallet/wallet.h

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

395395
ScriptPubKeyMan* m_external_spk_managers{nullptr};
396396
ScriptPubKeyMan* m_internal_spk_managers{nullptr};
397+
ScriptPubKeyMan* m_coinjoin_spk_managers{nullptr};
397398

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

986987
//! Get the ScriptPubKeyMan for internal/external chain.
987-
ScriptPubKeyMan* GetScriptPubKeyMan(bool internal) const;
988+
ScriptPubKeyMan* GetScriptPubKeyMan(InternalKey internal) const;
988989

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

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

10491050
//! Remove specified ScriptPubKeyMan from set of active SPK managers. Writes the change to the wallet file.
10501051
//! @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: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ 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+
keypool_size = 3000 if self.options.descriptors else 2000
270+
out = "Topping up keypool...\n" + self.get_expected_info_output(name="foo", keypool=keypool_size)
270271
self.assert_tool_output(out, '-wallet=foo', 'create')
271272
shasum_after = self.wallet_shasum()
272273
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)