Skip to content

Commit 89899a3

Browse files
committed
Merge #19046: Replace CWallet::Set* functions that use memonly with Add/Load variants
3a9aba2 Split SetWalletFlags into Add/LoadWalletFlags (Andrew Chow) d9cd095 Split SetActiveScriptPubKeyMan into Add/LoadActiveScriptPubKeyMan (Andrew Chow) 0122fba Split SetHDChain into AddHDChain and LoadHDChain (Andrew Chow) Pull request description: `SetHDChaiin`, `SetActiveScriptPubKeyMan`, and `SetWalletFlags` have a `memonly` argument which is kind of confusing, as noted in bitcoin/bitcoin#17681 (comment). This PR replaces those functions with `Add*` and `Load*` variants so that they follow the pattern used elsewhere in the wallet. `AddHDChain`, `AddActiveScriptPubKeyMan`, and `AddWalletFlags` both set their respective variables in `CWallet` and writes them to disk. These functions are used by the actions which modify the wallet such as `sethdseed`, `importdescriptors`, and creating a new wallet. `LoadHDChain`, `LoadActiveScriptPubKeyMan`, and `LoadWalletFlags` just set the `CWallet` variables. These functions are used by `LoadWallet` when loading the wallet from disk. ACKs for top commit: jnewbery: Code review ACK 3a9aba2 ryanofsky: Code review ACK 3a9aba2. Only changes since last review tweaks making m_wallet_flags updates more safe meshcollider: utACK 3a9aba2 Tree-SHA512: 365aeaafc5ba42879c0eb797ec3beb29ab70e27f917dc880763f743420b3be6ddf797240996beed8a9ad70fb212c2590253c6b44c9dc244529c3939d9538983f
2 parents 4fc9224 + 3a9aba2 commit 89899a3

File tree

6 files changed

+61
-38
lines changed

6 files changed

+61
-38
lines changed

src/wallet/rpcdump.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1547,7 +1547,7 @@ static UniValue ProcessDescriptorImport(CWallet * const pwallet, const UniValue&
15471547
if (!w_desc.descriptor->GetOutputType()) {
15481548
warnings.push_back("Unknown output type, cannot set descriptor to active.");
15491549
} else {
1550-
pwallet->SetActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
1550+
pwallet->AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.descriptor->GetOutputType(), internal);
15511551
}
15521552
}
15531553

src/wallet/scriptpubkeyman.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -905,20 +905,22 @@ bool LegacyScriptPubKeyMan::AddWatchOnly(const CScript& dest, int64_t nCreateTim
905905
return AddWatchOnly(dest);
906906
}
907907

908-
void LegacyScriptPubKeyMan::SetHDChain(const CHDChain& chain, bool memonly)
908+
void LegacyScriptPubKeyMan::LoadHDChain(const CHDChain& chain)
909909
{
910910
LOCK(cs_KeyStore);
911-
// memonly == true means we are loading the wallet file
912-
// memonly == false means that the chain is actually being changed
913-
if (!memonly) {
914-
// Store the new chain
915-
if (!WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain)) {
916-
throw std::runtime_error(std::string(__func__) + ": writing chain failed");
917-
}
918-
// When there's an old chain, add it as an inactive chain as we are now rotating hd chains
919-
if (!m_hd_chain.seed_id.IsNull()) {
920-
AddInactiveHDChain(m_hd_chain);
921-
}
911+
m_hd_chain = chain;
912+
}
913+
914+
void LegacyScriptPubKeyMan::AddHDChain(const CHDChain& chain)
915+
{
916+
LOCK(cs_KeyStore);
917+
// Store the new chain
918+
if (!WalletBatch(m_storage.GetDatabase()).WriteHDChain(chain)) {
919+
throw std::runtime_error(std::string(__func__) + ": writing chain failed");
920+
}
921+
// When there's an old chain, add it as an inactive chain as we are now rotating hd chains
922+
if (!m_hd_chain.seed_id.IsNull()) {
923+
AddInactiveHDChain(m_hd_chain);
922924
}
923925

924926
m_hd_chain = chain;
@@ -1172,7 +1174,7 @@ void LegacyScriptPubKeyMan::SetHDSeed(const CPubKey& seed)
11721174
CHDChain newHdChain;
11731175
newHdChain.nVersion = m_storage.CanSupportFeature(FEATURE_HD_SPLIT) ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE;
11741176
newHdChain.seed_id = seed.GetID();
1175-
SetHDChain(newHdChain, false);
1177+
AddHDChain(newHdChain);
11761178
NotifyCanGetAddressesChanged();
11771179
WalletBatch batch(m_storage.GetDatabase());
11781180
m_storage.UnsetBlankWalletFlag(batch);

src/wallet/scriptpubkeyman.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,10 @@ class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProv
422422
//! Generate a new key
423423
CPubKey GenerateNewKey(WalletBatch& batch, CHDChain& hd_chain, bool internal = false) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);
424424

425-
/* Set the HD chain model (chain child index counters) */
426-
void SetHDChain(const CHDChain& chain, bool memonly);
425+
/* Set the HD chain model (chain child index counters) and writes it to the database */
426+
void AddHDChain(const CHDChain& chain);
427+
//! Load a HD chain model (used by LoadWallet)
428+
void LoadHDChain(const CHDChain& chain);
427429
const CHDChain& GetHDChain() const { return m_hd_chain; }
428430
void AddInactiveHDChain(const CHDChain& chain);
429431

src/wallet/wallet.cpp

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,19 +1422,28 @@ bool CWallet::IsWalletFlagSet(uint64_t flag) const
14221422
return (m_wallet_flags & flag);
14231423
}
14241424

1425-
bool CWallet::SetWalletFlags(uint64_t overwriteFlags, bool memonly)
1425+
bool CWallet::LoadWalletFlags(uint64_t flags)
14261426
{
14271427
LOCK(cs_wallet);
1428-
m_wallet_flags = overwriteFlags;
1429-
if (((overwriteFlags & KNOWN_WALLET_FLAGS) >> 32) ^ (overwriteFlags >> 32)) {
1428+
if (((flags & KNOWN_WALLET_FLAGS) >> 32) ^ (flags >> 32)) {
14301429
// contains unknown non-tolerable wallet flags
14311430
return false;
14321431
}
1433-
if (!memonly && !WalletBatch(*database).WriteWalletFlags(m_wallet_flags)) {
1432+
m_wallet_flags = flags;
1433+
1434+
return true;
1435+
}
1436+
1437+
bool CWallet::AddWalletFlags(uint64_t flags)
1438+
{
1439+
LOCK(cs_wallet);
1440+
// We should never be writing unknown onon-tolerable wallet flags
1441+
assert(!(((flags & KNOWN_WALLET_FLAGS) >> 32) ^ (flags >> 32)));
1442+
if (!WalletBatch(*database).WriteWalletFlags(flags)) {
14341443
throw std::runtime_error(std::string(__func__) + ": writing wallet flags failed");
14351444
}
14361445

1437-
return true;
1446+
return LoadWalletFlags(flags);
14381447
}
14391448

14401449
int64_t CWalletTx::GetTxTime() const
@@ -3798,7 +3807,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
37983807
// ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
37993808
walletInstance->SetMinVersion(FEATURE_LATEST);
38003809

3801-
walletInstance->SetWalletFlags(wallet_creation_flags, false);
3810+
walletInstance->AddWalletFlags(wallet_creation_flags);
38023811

38033812
// Only create LegacyScriptPubKeyMan when not descriptor wallet
38043813
if (!walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
@@ -4419,25 +4428,28 @@ void CWallet::SetupDescriptorScriptPubKeyMans()
44194428
spk_manager->SetupDescriptorGeneration(master_key, t);
44204429
uint256 id = spk_manager->GetID();
44214430
m_spk_managers[id] = std::move(spk_manager);
4422-
SetActiveScriptPubKeyMan(id, t, internal);
4431+
AddActiveScriptPubKeyMan(id, t, internal);
44234432
}
44244433
}
44254434
}
44264435

4427-
void CWallet::SetActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal, bool memonly)
4436+
void CWallet::AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
4437+
{
4438+
WalletBatch batch(*database);
4439+
if (!batch.WriteActiveScriptPubKeyMan(static_cast<uint8_t>(type), id, internal)) {
4440+
throw std::runtime_error(std::string(__func__) + ": writing active ScriptPubKeyMan id failed");
4441+
}
4442+
LoadActiveScriptPubKeyMan(id, type, internal);
4443+
}
4444+
4445+
void CWallet::LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal)
44284446
{
44294447
WalletLogPrintf("Setting spkMan to active: id = %s, type = %d, internal = %d\n", id.ToString(), static_cast<int>(type), static_cast<int>(internal));
44304448
auto& spk_mans = internal ? m_internal_spk_managers : m_external_spk_managers;
44314449
auto spk_man = m_spk_managers.at(id).get();
44324450
spk_man->SetInternal(internal);
44334451
spk_mans[type] = spk_man;
44344452

4435-
if (!memonly) {
4436-
WalletBatch batch(*database);
4437-
if (!batch.WriteActiveScriptPubKeyMan(static_cast<uint8_t>(type), id, internal)) {
4438-
throw std::runtime_error(std::string(__func__) + ": writing active ScriptPubKeyMan id failed");
4439-
}
4440-
}
44414453
NotifyCanGetAddressesChanged();
44424454
}
44434455

src/wallet/wallet.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,9 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
11761176

11771177
/** overwrite all flags by the given uint64_t
11781178
returns false if unknown, non-tolerable flags are present */
1179-
bool SetWalletFlags(uint64_t overwriteFlags, bool memOnly);
1179+
bool AddWalletFlags(uint64_t flags);
1180+
/** Loads the flags into the wallet. (used by LoadWallet) */
1181+
bool LoadWalletFlags(uint64_t flags);
11801182

11811183
/** Determine if we are a legacy wallet */
11821184
bool IsLegacy() const;
@@ -1254,12 +1256,17 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
12541256
//! Instantiate a descriptor ScriptPubKeyMan from the WalletDescriptor and load it
12551257
void LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor& desc);
12561258

1257-
//! Sets the active ScriptPubKeyMan for the specified type and internal
1259+
//! Adds the active ScriptPubKeyMan for the specified type and internal. Writes it to the wallet file
12581260
//! @param[in] id The unique id for the ScriptPubKeyMan
12591261
//! @param[in] type The OutputType this ScriptPubKeyMan provides addresses for
12601262
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
1261-
//! @param[in] memonly Whether to record this update to the database. Set to true for wallet loading, normally false when actually updating the wallet.
1262-
void SetActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal, bool memonly = false);
1263+
void AddActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal);
1264+
1265+
//! Loads an active ScriptPubKeyMan for the specified type and internal. (used by LoadWallet)
1266+
//! @param[in] id The unique id for the ScriptPubKeyMan
1267+
//! @param[in] type The OutputType this ScriptPubKeyMan provides addresses for
1268+
//! @param[in] internal Whether this ScriptPubKeyMan provides change addresses
1269+
void LoadActiveScriptPubKeyMan(uint256 id, OutputType type, bool internal);
12631270

12641271
//! Create new DescriptorScriptPubKeyMans and add them to the wallet
12651272
void SetupDescriptorScriptPubKeyMans();

src/wallet/walletdb.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,11 +539,11 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
539539
} else if (strType == DBKeys::HDCHAIN) {
540540
CHDChain chain;
541541
ssValue >> chain;
542-
pwallet->GetOrCreateLegacyScriptPubKeyMan()->SetHDChain(chain, true);
542+
pwallet->GetOrCreateLegacyScriptPubKeyMan()->LoadHDChain(chain);
543543
} else if (strType == DBKeys::FLAGS) {
544544
uint64_t flags;
545545
ssValue >> flags;
546-
if (!pwallet->SetWalletFlags(flags, true)) {
546+
if (!pwallet->LoadWalletFlags(flags)) {
547547
strErr = "Error reading wallet database: Unknown non-tolerable wallet flags found";
548548
return false;
549549
}
@@ -752,10 +752,10 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
752752

753753
// Set the active ScriptPubKeyMans
754754
for (auto spk_man_pair : wss.m_active_external_spks) {
755-
pwallet->SetActiveScriptPubKeyMan(spk_man_pair.second, spk_man_pair.first, /* internal */ false, /* memonly */ true);
755+
pwallet->LoadActiveScriptPubKeyMan(spk_man_pair.second, spk_man_pair.first, /* internal */ false);
756756
}
757757
for (auto spk_man_pair : wss.m_active_internal_spks) {
758-
pwallet->SetActiveScriptPubKeyMan(spk_man_pair.second, spk_man_pair.first, /* internal */ true, /* memonly */ true);
758+
pwallet->LoadActiveScriptPubKeyMan(spk_man_pair.second, spk_man_pair.first, /* internal */ true);
759759
}
760760

761761
// Set the descriptor caches

0 commit comments

Comments
 (0)