mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
[wallet] Cache keyid -> keypool id mappings
This commit is contained in:
parent
83f1ec33ce
commit
f2123e3a7b
@ -619,9 +619,8 @@ UniValue dumpwallet(const JSONRPCRequest& request)
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
|
||||||
|
|
||||||
std::map<CTxDestination, int64_t> mapKeyBirth;
|
std::map<CTxDestination, int64_t> mapKeyBirth;
|
||||||
std::set<CKeyID> setKeyPool;
|
const std::map<CKeyID, int64_t>& mapKeyPool = pwallet->GetAllReserveKeys();
|
||||||
pwallet->GetKeyBirthTimes(mapKeyBirth);
|
pwallet->GetKeyBirthTimes(mapKeyBirth);
|
||||||
pwallet->GetAllReserveKeys(setKeyPool);
|
|
||||||
|
|
||||||
// sort time/key pairs
|
// sort time/key pairs
|
||||||
std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
|
std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
|
||||||
@ -666,7 +665,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
|
|||||||
file << strprintf("label=%s", EncodeDumpString(pwallet->mapAddressBook[keyid].name));
|
file << strprintf("label=%s", EncodeDumpString(pwallet->mapAddressBook[keyid].name));
|
||||||
} else if (keyid == masterKeyID) {
|
} else if (keyid == masterKeyID) {
|
||||||
file << "hdmaster=1";
|
file << "hdmaster=1";
|
||||||
} else if (setKeyPool.count(keyid)) {
|
} else if (mapKeyPool.count(keyid)) {
|
||||||
file << "reserve=1";
|
file << "reserve=1";
|
||||||
} else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "m") {
|
} else if (pwallet->mapKeyMetadata[keyid].hdKeypath == "m") {
|
||||||
file << "inactivehdmaster=1";
|
file << "inactivehdmaster=1";
|
||||||
|
@ -3077,6 +3077,7 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
|||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
setInternalKeyPool.clear();
|
setInternalKeyPool.clear();
|
||||||
setExternalKeyPool.clear();
|
setExternalKeyPool.clear();
|
||||||
|
m_pool_key_to_index.clear();
|
||||||
// Note: can't top-up keypool here, because wallet is locked.
|
// Note: can't top-up keypool here, because wallet is locked.
|
||||||
// User will be prompted to unlock wallet the next operation
|
// User will be prompted to unlock wallet the next operation
|
||||||
// that requires a new key.
|
// that requires a new key.
|
||||||
@ -3106,6 +3107,7 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
|
|||||||
{
|
{
|
||||||
setInternalKeyPool.clear();
|
setInternalKeyPool.clear();
|
||||||
setExternalKeyPool.clear();
|
setExternalKeyPool.clear();
|
||||||
|
m_pool_key_to_index.clear();
|
||||||
// Note: can't top-up keypool here, because wallet is locked.
|
// Note: can't top-up keypool here, because wallet is locked.
|
||||||
// User will be prompted to unlock wallet the next operation
|
// User will be prompted to unlock wallet the next operation
|
||||||
// that requires a new key.
|
// that requires a new key.
|
||||||
@ -3132,6 +3134,7 @@ DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
|
|||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
setInternalKeyPool.clear();
|
setInternalKeyPool.clear();
|
||||||
setExternalKeyPool.clear();
|
setExternalKeyPool.clear();
|
||||||
|
m_pool_key_to_index.clear();
|
||||||
// Note: can't top-up keypool here, because wallet is locked.
|
// Note: can't top-up keypool here, because wallet is locked.
|
||||||
// User will be prompted to unlock wallet the next operation
|
// User will be prompted to unlock wallet the next operation
|
||||||
// that requires a new key.
|
// that requires a new key.
|
||||||
@ -3226,6 +3229,8 @@ bool CWallet::NewKeyPool()
|
|||||||
}
|
}
|
||||||
setExternalKeyPool.clear();
|
setExternalKeyPool.clear();
|
||||||
|
|
||||||
|
m_pool_key_to_index.clear();
|
||||||
|
|
||||||
if (!TopUpKeyPool()) {
|
if (!TopUpKeyPool()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3242,12 +3247,14 @@ size_t CWallet::KeypoolCountExternalKeys()
|
|||||||
|
|
||||||
void CWallet::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
|
void CWallet::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet);
|
||||||
if (keypool.fInternal) {
|
if (keypool.fInternal) {
|
||||||
setInternalKeyPool.insert(nIndex);
|
setInternalKeyPool.insert(nIndex);
|
||||||
} else {
|
} else {
|
||||||
setExternalKeyPool.insert(nIndex);
|
setExternalKeyPool.insert(nIndex);
|
||||||
}
|
}
|
||||||
m_max_keypool_index = std::max(m_max_keypool_index, 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 a default with the pool key's
|
// If no metadata exists yet, create a default with the pool key's
|
||||||
// creation time. Note that this may be overwritten by actually
|
// creation time. Note that this may be overwritten by actually
|
||||||
@ -3293,7 +3300,8 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
|
|||||||
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
|
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
|
||||||
int64_t index = ++m_max_keypool_index;
|
int64_t index = ++m_max_keypool_index;
|
||||||
|
|
||||||
if (!walletdb.WritePool(index, CKeyPool(GenerateNewKey(walletdb, internal), internal))) {
|
CPubKey pubkey(GenerateNewKey(walletdb, internal));
|
||||||
|
if (!walletdb.WritePool(index, CKeyPool(pubkey, internal))) {
|
||||||
throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
|
throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3302,6 +3310,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
|
|||||||
} else {
|
} else {
|
||||||
setExternalKeyPool.insert(index);
|
setExternalKeyPool.insert(index);
|
||||||
}
|
}
|
||||||
|
m_pool_key_to_index[pubkey.GetID()] = index;
|
||||||
}
|
}
|
||||||
if (missingInternal + missingExternal > 0) {
|
if (missingInternal + missingExternal > 0) {
|
||||||
LogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size(), setInternalKeyPool.size());
|
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(keypool.vchPubKey.IsValid());
|
assert(keypool.vchPubKey.IsValid());
|
||||||
|
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
|
||||||
LogPrintf("keypool reserve %d\n", nIndex);
|
LogPrintf("keypool reserve %d\n", nIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3355,7 +3365,7 @@ void CWallet::KeepKey(int64_t nIndex)
|
|||||||
LogPrintf("keypool keep %d\n", nIndex);
|
LogPrintf("keypool keep %d\n", nIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::ReturnKey(int64_t nIndex, bool fInternal)
|
void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
|
||||||
{
|
{
|
||||||
// Return to key pool
|
// Return to key pool
|
||||||
{
|
{
|
||||||
@ -3365,6 +3375,7 @@ void CWallet::ReturnKey(int64_t nIndex, bool fInternal)
|
|||||||
} else {
|
} else {
|
||||||
setExternalKeyPool.insert(nIndex);
|
setExternalKeyPool.insert(nIndex);
|
||||||
}
|
}
|
||||||
|
m_pool_key_to_index[pubkey.GetID()] = nIndex;
|
||||||
}
|
}
|
||||||
LogPrintf("keypool return %d\n", nIndex);
|
LogPrintf("keypool return %d\n", nIndex);
|
||||||
}
|
}
|
||||||
@ -3594,41 +3605,12 @@ void CReserveKey::KeepKey()
|
|||||||
void CReserveKey::ReturnKey()
|
void CReserveKey::ReturnKey()
|
||||||
{
|
{
|
||||||
if (nIndex != -1) {
|
if (nIndex != -1) {
|
||||||
pwallet->ReturnKey(nIndex, fInternal);
|
pwallet->ReturnKey(nIndex, fInternal, vchPubKey);
|
||||||
}
|
}
|
||||||
nIndex = -1;
|
nIndex = -1;
|
||||||
vchPubKey = CPubKey();
|
vchPubKey = CPubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadReserveKeysToSet(std::set<CKeyID>& setAddress, const std::set<int64_t>& setKeyPool, CWalletDB& walletdb) {
|
|
||||||
for (const int64_t& id : setKeyPool)
|
|
||||||
{
|
|
||||||
CKeyPool keypool;
|
|
||||||
if (!walletdb.ReadPool(id, keypool))
|
|
||||||
throw std::runtime_error(std::string(__func__) + ": read failed");
|
|
||||||
assert(keypool.vchPubKey.IsValid());
|
|
||||||
CKeyID keyID = keypool.vchPubKey.GetID();
|
|
||||||
setAddress.insert(keyID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWallet::GetAllReserveKeys(std::set<CKeyID>& setAddress) const
|
|
||||||
{
|
|
||||||
setAddress.clear();
|
|
||||||
|
|
||||||
CWalletDB walletdb(*dbw);
|
|
||||||
|
|
||||||
LOCK2(cs_main, cs_wallet);
|
|
||||||
LoadReserveKeysToSet(setAddress, setInternalKeyPool, walletdb);
|
|
||||||
LoadReserveKeysToSet(setAddress, setExternalKeyPool, walletdb);
|
|
||||||
|
|
||||||
for (const CKeyID& keyID : setAddress) {
|
|
||||||
if (!HaveKey(keyID)) {
|
|
||||||
throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)
|
void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)
|
||||||
{
|
{
|
||||||
std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this);
|
std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this);
|
||||||
|
@ -704,6 +704,7 @@ private:
|
|||||||
std::set<int64_t> setInternalKeyPool;
|
std::set<int64_t> setInternalKeyPool;
|
||||||
std::set<int64_t> setExternalKeyPool;
|
std::set<int64_t> setExternalKeyPool;
|
||||||
int64_t m_max_keypool_index;
|
int64_t m_max_keypool_index;
|
||||||
|
std::map<CKeyID, int64_t> m_pool_key_to_index;
|
||||||
|
|
||||||
int64_t nTimeFirstKey;
|
int64_t nTimeFirstKey;
|
||||||
|
|
||||||
@ -973,10 +974,10 @@ public:
|
|||||||
bool TopUpKeyPool(unsigned int kpSize = 0);
|
bool TopUpKeyPool(unsigned int kpSize = 0);
|
||||||
void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
|
void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
|
||||||
void KeepKey(int64_t nIndex);
|
void KeepKey(int64_t nIndex);
|
||||||
void ReturnKey(int64_t nIndex, bool fInternal);
|
void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey);
|
||||||
bool GetKeyFromPool(CPubKey &key, bool internal = false);
|
bool GetKeyFromPool(CPubKey &key, bool internal = false);
|
||||||
int64_t GetOldestKeyPoolTime();
|
int64_t GetOldestKeyPoolTime();
|
||||||
void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
|
const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; }
|
||||||
|
|
||||||
std::set< std::set<CTxDestination> > GetAddressGroupings();
|
std::set< std::set<CTxDestination> > GetAddressGroupings();
|
||||||
std::map<CTxDestination, CAmount> GetAddressBalances();
|
std::map<CTxDestination, CAmount> GetAddressBalances();
|
||||||
|
Loading…
Reference in New Issue
Block a user