| 1285 | } |
| 1286 | |
| 1287 | bool LegacyScriptPubKeyMan::TopUpChain(CHDChain& chain, unsigned int kpSize) |
| 1288 | { |
| 1289 | LOCK(cs_KeyStore); |
| 1290 | |
| 1291 | if (m_storage.IsLocked()) return false; |
| 1292 | |
| 1293 | // Top up key pool |
| 1294 | unsigned int nTargetSize; |
| 1295 | if (kpSize > 0) { |
| 1296 | nTargetSize = kpSize; |
| 1297 | } else { |
| 1298 | nTargetSize = std::max(gArgs.GetIntArg("-keypool", DEFAULT_KEYPOOL_SIZE), int64_t{0}); |
| 1299 | } |
| 1300 | int64_t target = std::max((int64_t) nTargetSize, int64_t{1}); |
| 1301 | |
| 1302 | // count amount of available keys (internal, external) |
| 1303 | // make sure the keypool of external and internal keys fits the user selected target (-keypool) |
| 1304 | int64_t missingExternal; |
| 1305 | int64_t missingInternal; |
| 1306 | if (chain == m_hd_chain) { |
| 1307 | missingExternal = std::max(target - (int64_t)setExternalKeyPool.size(), int64_t{0}); |
| 1308 | missingInternal = std::max(target - (int64_t)setInternalKeyPool.size(), int64_t{0}); |
| 1309 | } else { |
| 1310 | missingExternal = std::max(target - (chain.nExternalChainCounter - chain.m_next_external_index), int64_t{0}); |
| 1311 | missingInternal = std::max(target - (chain.nInternalChainCounter - chain.m_next_internal_index), int64_t{0}); |
| 1312 | } |
| 1313 | |
| 1314 | if (!IsHDEnabled() || !m_storage.CanSupportFeature(FEATURE_HD_SPLIT)) { |
| 1315 | // don't create extra internal keys |
| 1316 | missingInternal = 0; |
| 1317 | } |
| 1318 | bool internal = false; |
| 1319 | WalletBatch batch(m_storage.GetDatabase()); |
| 1320 | for (int64_t i = missingInternal + missingExternal; i--;) { |
| 1321 | if (i < missingInternal) { |
| 1322 | internal = true; |
| 1323 | } |
| 1324 | |
| 1325 | CPubKey pubkey(GenerateNewKey(batch, chain, internal)); |
| 1326 | if (chain == m_hd_chain) { |
| 1327 | AddKeypoolPubkeyWithDB(pubkey, internal, batch); |
| 1328 | } |
| 1329 | } |
| 1330 | if (missingInternal + missingExternal > 0) { |
| 1331 | if (chain == m_hd_chain) { |
| 1332 | 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()); |
| 1333 | } else { |
| 1334 | WalletLogPrintf("inactive seed with id %s added %d external keys, %d internal keys\n", HexStr(chain.seed_id), missingExternal, missingInternal); |
| 1335 | } |
| 1336 | } |
| 1337 | return true; |
| 1338 | } |
| 1339 | |
| 1340 | void LegacyScriptPubKeyMan::AddKeypoolPubkeyWithDB(const CPubKey& pubkey, const bool internal, WalletBatch& batch) |
| 1341 | { |