aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/scriptpubkeyman.cpp
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2021-10-18 15:27:27 -0400
committerAndrew Chow <achow101-github@achow101.com>2022-01-14 15:03:15 -0500
commit8077862c5e8a3ed501f0baabc33536eb16922ceb (patch)
tree5affda338dde813a50971d6ad31b67d5766c6c24 /src/wallet/scriptpubkeyman.cpp
parent70134eb34f58f0c572e7c3775e292d408f03b5ab (diff)
downloadbitcoin-8077862c5e8a3ed501f0baabc33536eb16922ceb.tar.xz
wallet: Refactor TopUp to be able to top up inactive chains too
Refactors TopUp so that it also tops up inactive chains. The bulk of TopUp is moved to TopUpChain. CHDChain also has 2 new in memory variables to track its highest used indexes. This is used only for inactive hd chains so that they can be topped up later in the same session (e.g. if the wallet is encrypted and not unlocked at the time of MarkUnusedAddresses).
Diffstat (limited to 'src/wallet/scriptpubkeyman.cpp')
-rw-r--r--src/wallet/scriptpubkeyman.cpp106
1 files changed, 58 insertions, 48 deletions
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index 7cca5fba20..507951134b 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -321,8 +321,6 @@ bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t i
{
LOCK(cs_KeyStore);
- if (m_storage.IsLocked()) return false;
-
auto it = m_inactive_hd_chains.find(seed_id);
if (it == m_inactive_hd_chains.end()) {
return false;
@@ -330,27 +328,14 @@ bool LegacyScriptPubKeyMan::TopUpInactiveHDChain(const CKeyID seed_id, int64_t i
CHDChain& chain = it->second;
- // Top up key pool
- int64_t target_size = std::max(gArgs.GetIntArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 1);
-
- // "size" of the keypools. Not really the size, actually the difference between index and the chain counter
- // Since chain counter is 1 based and index is 0 based, one of them needs to be offset by 1.
- int64_t kp_size = (internal ? chain.nInternalChainCounter : chain.nExternalChainCounter) - (index + 1);
+ if (internal) {
+ chain.m_next_internal_index = std::max(chain.m_next_internal_index, index + 1);
+ } else {
+ chain.m_next_external_index = std::max(chain.m_next_external_index, index + 1);
+ }
- // make sure the keypool fits the user-selected target (-keypool)
- int64_t missing = std::max(target_size - kp_size, (int64_t) 0);
+ TopUpChain(chain, 0);
- if (missing > 0) {
- WalletBatch batch(m_storage.GetDatabase());
- for (int64_t i = missing; i > 0; --i) {
- GenerateNewKey(batch, chain, internal);
- }
- if (internal) {
- WalletLogPrintf("inactive seed with id %s added %d internal keys\n", HexStr(seed_id), missing);
- } else {
- WalletLogPrintf("inactive seed with id %s added %d keys\n", HexStr(seed_id), missing);
- }
- }
return true;
}
@@ -1273,44 +1258,69 @@ bool LegacyScriptPubKeyMan::TopUp(unsigned int kpSize)
if (!CanGenerateKeys()) {
return false;
}
- {
- LOCK(cs_KeyStore);
- if (m_storage.IsLocked()) return false;
+ if (!TopUpChain(m_hd_chain, kpSize)) {
+ return false;
+ }
+ for (auto& [chain_id, chain] : m_inactive_hd_chains) {
+ if (!TopUpChain(chain, kpSize)) {
+ return false;
+ }
+ }
+ NotifyCanGetAddressesChanged();
+ return true;
+}
- // Top up key pool
- unsigned int nTargetSize;
- if (kpSize > 0)
- nTargetSize = kpSize;
- else
- nTargetSize = std::max(gArgs.GetIntArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0);
+bool LegacyScriptPubKeyMan::TopUpChain(CHDChain& chain, unsigned int kpSize)
+{
+ LOCK(cs_KeyStore);
- // count amount of available keys (internal, external)
- // make sure the keypool of external and internal keys fits the user selected target (-keypool)
- int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setExternalKeyPool.size(), (int64_t) 0);
- int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setInternalKeyPool.size(), (int64_t) 0);
+ if (m_storage.IsLocked()) return false;
- if (!IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD_SPLIT))
- {
- // don't create extra internal keys
- missingInternal = 0;
+ // Top up key pool
+ unsigned int nTargetSize;
+ if (kpSize > 0) {
+ nTargetSize = kpSize;
+ } else {
+ nTargetSize = std::max(gArgs.GetIntArg("-keypool", DEFAULT_KEYPOOL_SIZE), int64_t{0});
+ }
+ int64_t target = std::max((int64_t) nTargetSize, int64_t{1});
+
+ // count amount of available keys (internal, external)
+ // make sure the keypool of external and internal keys fits the user selected target (-keypool)
+ int64_t missingExternal;
+ int64_t missingInternal;
+ if (chain == m_hd_chain) {
+ missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0});
+ missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0});
+ } else {
+ missingExternal = std::max(target - (chain.nExternalChainCounter - chain.m_next_external_index), int64_t{0});
+ missingInternal = std::max(target - (chain.nInternalChainCounter - chain.m_next_internal_index), int64_t{0});
+ }
+
+ if (!IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) {
+ // don't create extra internal keys
+ missingInternal = 0;
+ }
+ bool internal = false;
+ WalletBatch batch(m_storage.GetDatabase());
+ for (int64_t i = missingInternal + missingExternal; i--;) {
+ if (i < missingInternal) {
+ internal = true;
}
- bool internal = false;
- WalletBatch batch(m_storage.GetDatabase());
- for (int64_t i = missingInternal + missingExternal; i--;)
- {
- if (i < missingInternal) {
- internal = true;
- }
- CPubKey pubkey(GenerateNewKey(batch, m_hd_chain, internal));
+ CPubKey pubkey(GenerateNewKey(batch, chain, internal));
+ if (chain == m_hd_chain) {
AddKeypoolPubkeyWithDB(pubkey, internal, batch);
}
- if (missingInternal + missingExternal > 0) {
+ }
+ if (missingInternal + missingExternal > 0) {
+ if (chain == m_hd_chain) {
WalletLogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(), setInternalKeyPool.size());
+ } else {
+ WalletLogPrintf("inactive seed with id %s added %d external keys, %d internal keys\n", HexStr(chain.seed_id), missingExternal, missingInternal);
}
}
- NotifyCanGetAddressesChanged();
return true;
}