aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/scriptpubkeyman.cpp106
-rw-r--r--src/wallet/scriptpubkeyman.h1
-rw-r--r--src/wallet/walletdb.h2
3 files changed, 61 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;
}
diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h
index ebe064fa0a..e97f0bb40c 100644
--- a/src/wallet/scriptpubkeyman.h
+++ b/src/wallet/scriptpubkeyman.h
@@ -354,6 +354,7 @@ private:
*/
bool TopUpInactiveHDChain(const CKeyID seed_id, int64_t index, bool internal);
+ bool TopUpChain(CHDChain& chain, unsigned int size);
public:
using ScriptPubKeyMan::ScriptPubKeyMan;
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index 9c752623b3..428f3d36ec 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -90,6 +90,8 @@ public:
uint32_t nExternalChainCounter;
uint32_t nInternalChainCounter;
CKeyID seed_id; //!< seed hash160
+ int64_t m_next_external_index{0}; // Next index in the keypool to be used. Memory only.
+ int64_t m_next_internal_index{0}; // Next index in the keypool to be used. Memory only.
static const int VERSION_HD_BASE = 1;
static const int VERSION_HD_CHAIN_SPLIT = 2;