diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/scriptpubkeyman.cpp | 106 | ||||
-rw-r--r-- | src/wallet/scriptpubkeyman.h | 1 | ||||
-rw-r--r-- | src/wallet/walletdb.h | 2 |
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; |