Skip to content

Commit f2123e3

Browse files
committed
[wallet] Cache keyid -> keypool id mappings
1 parent 83f1ec3 commit f2123e3

File tree

3 files changed

+19
-37
lines changed

3 files changed

+19
-37
lines changed

src/wallet/rpcdump.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,8 @@ UniValue dumpwallet(const JSONRPCRequest& request)
619619
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
620620

621621
std::map<CTxDestination, int64_t> mapKeyBirth;
622-
std::set<CKeyID> setKeyPool;
622+
const std::map<CKeyID, int64_t>& mapKeyPool = pwallet->GetAllReserveKeys();
623623
pwallet->GetKeyBirthTimes(mapKeyBirth);
624-
pwallet->GetAllReserveKeys(setKeyPool);
625624

626625
// sort time/key pairs
627626
std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
@@ -666,7 +665,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
666665
file << strprintf("label=%s", EncodeDumpString(pwallet->mapAddressBook[keyid].name));
667666
} else if (keyid == masterKeyID) {
668667
file << "hdmaster=1";
669-
} else if (setKeyPool.count(keyid)) {
668+
} else if (mapKeyPool.count(keyid)) {
670669
file << "reserve=1";
671670
} else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "m") {
672671
file << "inactivehdmaster=1";

src/wallet/wallet.cpp

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,6 +3077,7 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
30773077
LOCK(cs_wallet);
30783078
setInternalKeyPool.clear();
30793079
setExternalKeyPool.clear();
3080+
m_pool_key_to_index.clear();
30803081
// Note: can't top-up keypool here, because wallet is locked.
30813082
// User will be prompted to unlock wallet the next operation
30823083
// that requires a new key.
@@ -3106,6 +3107,7 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
31063107
{
31073108
setInternalKeyPool.clear();
31083109
setExternalKeyPool.clear();
3110+
m_pool_key_to_index.clear();
31093111
// Note: can't top-up keypool here, because wallet is locked.
31103112
// User will be prompted to unlock wallet the next operation
31113113
// that requires a new key.
@@ -3132,6 +3134,7 @@ DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
31323134
LOCK(cs_wallet);
31333135
setInternalKeyPool.clear();
31343136
setExternalKeyPool.clear();
3137+
m_pool_key_to_index.clear();
31353138
// Note: can't top-up keypool here, because wallet is locked.
31363139
// User will be prompted to unlock wallet the next operation
31373140
// that requires a new key.
@@ -3226,6 +3229,8 @@ bool CWallet::NewKeyPool()
32263229
}
32273230
setExternalKeyPool.clear();
32283231

3232+
m_pool_key_to_index.clear();
3233+
32293234
if (!TopUpKeyPool()) {
32303235
return false;
32313236
}
@@ -3242,12 +3247,14 @@ size_t CWallet::KeypoolCountExternalKeys()
32423247

32433248
void CWallet::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
32443249
{
3250+
AssertLockHeld(cs_wallet);
32453251
if (keypool.fInternal) {
32463252
setInternalKeyPool.insert(nIndex);
32473253
} else {
32483254
setExternalKeyPool.insert(nIndex);
32493255
}
32503256
m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
3257+
m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;
32513258

32523259
// If no metadata exists yet, create a default with the pool key's
32533260
// creation time. Note that this may be overwritten by actually
@@ -3293,7 +3300,8 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
32933300
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
32943301
int64_t index = ++m_max_keypool_index;
32953302

3296-
if (!walletdb.WritePool(index, CKeyPool(GenerateNewKey(walletdb, internal), internal))) {
3303+
CPubKey pubkey(GenerateNewKey(walletdb, internal));
3304+
if (!walletdb.WritePool(index, CKeyPool(pubkey, internal))) {
32973305
throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
32983306
}
32993307

@@ -3302,6 +3310,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
33023310
} else {
33033311
setExternalKeyPool.insert(index);
33043312
}
3313+
m_pool_key_to_index[pubkey.GetID()] = index;
33053314
}
33063315
if (missingInternal + missingExternal > 0) {
33073316
LogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size(), setInternalKeyPool.size());
@@ -3343,6 +3352,7 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
33433352
}
33443353

33453354
assert(keypool.vchPubKey.IsValid());
3355+
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
33463356
LogPrintf("keypool reserve %d\n", nIndex);
33473357
}
33483358
}
@@ -3355,7 +3365,7 @@ void CWallet::KeepKey(int64_t nIndex)
33553365
LogPrintf("keypool keep %d\n", nIndex);
33563366
}
33573367

3358-
void CWallet::ReturnKey(int64_t nIndex, bool fInternal)
3368+
void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
33593369
{
33603370
// Return to key pool
33613371
{
@@ -3365,6 +3375,7 @@ void CWallet::ReturnKey(int64_t nIndex, bool fInternal)
33653375
} else {
33663376
setExternalKeyPool.insert(nIndex);
33673377
}
3378+
m_pool_key_to_index[pubkey.GetID()] = nIndex;
33683379
}
33693380
LogPrintf("keypool return %d\n", nIndex);
33703381
}
@@ -3594,41 +3605,12 @@ void CReserveKey::KeepKey()
35943605
void CReserveKey::ReturnKey()
35953606
{
35963607
if (nIndex != -1) {
3597-
pwallet->ReturnKey(nIndex, fInternal);
3608+
pwallet->ReturnKey(nIndex, fInternal, vchPubKey);
35983609
}
35993610
nIndex = -1;
36003611
vchPubKey = CPubKey();
36013612
}
36023613

3603-
static void LoadReserveKeysToSet(std::set<CKeyID>& setAddress, const std::set<int64_t>& setKeyPool, CWalletDB& walletdb) {
3604-
for (const int64_t& id : setKeyPool)
3605-
{
3606-
CKeyPool keypool;
3607-
if (!walletdb.ReadPool(id, keypool))
3608-
throw std::runtime_error(std::string(__func__) + ": read failed");
3609-
assert(keypool.vchPubKey.IsValid());
3610-
CKeyID keyID = keypool.vchPubKey.GetID();
3611-
setAddress.insert(keyID);
3612-
}
3613-
}
3614-
3615-
void CWallet::GetAllReserveKeys(std::set<CKeyID>& setAddress) const
3616-
{
3617-
setAddress.clear();
3618-
3619-
CWalletDB walletdb(*dbw);
3620-
3621-
LOCK2(cs_main, cs_wallet);
3622-
LoadReserveKeysToSet(setAddress, setInternalKeyPool, walletdb);
3623-
LoadReserveKeysToSet(setAddress, setExternalKeyPool, walletdb);
3624-
3625-
for (const CKeyID& keyID : setAddress) {
3626-
if (!HaveKey(keyID)) {
3627-
throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
3628-
}
3629-
}
3630-
}
3631-
36323614
void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)
36333615
{
36343616
std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this);

src/wallet/wallet.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
704704
std::set<int64_t> setInternalKeyPool;
705705
std::set<int64_t> setExternalKeyPool;
706706
int64_t m_max_keypool_index;
707+
std::map<CKeyID, int64_t> m_pool_key_to_index;
707708

708709
int64_t nTimeFirstKey;
709710

@@ -973,10 +974,10 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
973974
bool TopUpKeyPool(unsigned int kpSize = 0);
974975
void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
975976
void KeepKey(int64_t nIndex);
976-
void ReturnKey(int64_t nIndex, bool fInternal);
977+
void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey);
977978
bool GetKeyFromPool(CPubKey &key, bool internal = false);
978979
int64_t GetOldestKeyPoolTime();
979-
void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
980+
const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }
980981

981982
std::set< std::set<CTxDestination> > GetAddressGroupings();
982983
std::map<CTxDestination, CAmount> GetAddressBalances();

0 commit comments

Comments
 (0)