void CWallet::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) { AssertLockHeld(cs_wallet); if (keypool.internal) { setInternalKeyPool.insert(nIndex); } else { setExternalKeyPool.insert(nIndex); } m_max_keypool_index = std::max(m_max_keypool_index, nIndex); m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex; // If no metadata exists yet, create
| 3615 | } |
| 3616 | */ |
| 3617 | bool CWallet::TopUpKeyPool(unsigned int kpSize) |
| 3618 | { |
| 3619 | { |
| 3620 | LOCK(cs_wallet); |
| 3621 | |
| 3622 | if (IsLocked()) |
| 3623 | return false; |
| 3624 | |
| 3625 | // Top up key pool |
| 3626 | unsigned int nTargetSize; |
| 3627 | if (kpSize > 0) |
| 3628 | nTargetSize = kpSize; |
| 3629 | else |
| 3630 | nTargetSize = std::max(GetArg("-keypool", 100), (int64_t) 0); |
| 3631 | |
| 3632 | // count amount of available keys (internal, external) |
| 3633 | // make sure the keypool of external and internal keys fits the user selected target (-keypool) |
| 3634 | int64_t amountExternal = setExternalKeyPool.size(); |
| 3635 | int64_t amountInternal = setInternalKeyPool.size(); |
| 3636 | int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - amountExternal, (int64_t) 0); |
| 3637 | int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - amountInternal, (int64_t) 0); |
| 3638 | |
| 3639 | if (!IsHDEnabled()) |
| 3640 | { |
| 3641 | // don't create extra internal keys |
| 3642 | missingInternal = 0; |
| 3643 | } else { |
| 3644 | nTargetSize *= 2; |
| 3645 | } |
| 3646 | bool internal = false; |
| 3647 | CWalletDB walletdb(strWalletFile); |
| 3648 | for (int64_t i = missingInternal + missingExternal; i--;) { |
| 3649 | int64_t nEnd = 1; |
| 3650 | if (i < missingInternal) |
| 3651 | internal = true; |
| 3652 | if (!setInternalKeyPool.empty()) { |
| 3653 | nEnd = *(--setInternalKeyPool.end()) + 1; |
| 3654 | } |
| 3655 | if (!setExternalKeyPool.empty()) { |
| 3656 | nEnd = std::max(nEnd, *(--setExternalKeyPool.end()) + 1); |
| 3657 | } |
| 3658 | // assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys? |
| 3659 | // int64_t index = ++m_max_keypool_index; |
| 3660 | |
| 3661 | if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey(0, internal), internal))) |
| 3662 | throw runtime_error("TopUpKeyPool(): writing generated key failed"); |
| 3663 | |
| 3664 | if (internal) { |
| 3665 | setInternalKeyPool.insert(nEnd); |
| 3666 | } else { |
| 3667 | setExternalKeyPool.insert(nEnd); |
| 3668 | } |
| 3669 | LogPrintf("keypool added key %d, size=%u, internal=%d\n", nEnd, setInternalKeyPool.size() + setExternalKeyPool.size(), internal); |
| 3670 | |
| 3671 | double dProgress = 100.f * nEnd / (nTargetSize + 1); |
| 3672 | if (dProgress < 100.1) { |
| 3673 | std::string strMsg = strprintf(_("Loading wallet... (%3.2f %%)"), dProgress); |
| 3674 | uiInterface.InitMessage(strMsg); |
no test coverage detected