Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 3,653 Lines • ▼ Show 20 Lines | if (missingInternal + missingExternal > 0) { | ||||
setInternalKeyPool.size() + setExternalKeyPool.size() + | setInternalKeyPool.size() + setExternalKeyPool.size() + | ||||
set_pre_split_keypool.size(), | set_pre_split_keypool.size(), | ||||
setInternalKeyPool.size()); | setInternalKeyPool.size()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
void CWallet::ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, | bool CWallet::ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, | ||||
bool fRequestedInternal) { | bool fRequestedInternal) { | ||||
nIndex = -1; | nIndex = -1; | ||||
keypool.vchPubKey = CPubKey(); | keypool.vchPubKey = CPubKey(); | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
if (!IsLocked()) { | if (!IsLocked()) { | ||||
TopUpKeyPool(); | TopUpKeyPool(); | ||||
} | } | ||||
bool fReturningInternal = IsHDEnabled() && | bool fReturningInternal = IsHDEnabled() && | ||||
CanSupportFeature(FEATURE_HD_SPLIT) && | CanSupportFeature(FEATURE_HD_SPLIT) && | ||||
fRequestedInternal; | fRequestedInternal; | ||||
bool use_split_keypool = set_pre_split_keypool.empty(); | |||||
std::set<int64_t> &setKeyPool = | std::set<int64_t> &setKeyPool = | ||||
set_pre_split_keypool.empty() | use_split_keypool | ||||
? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) | ? (fReturningInternal ? setInternalKeyPool : setExternalKeyPool) | ||||
: set_pre_split_keypool; | : set_pre_split_keypool; | ||||
// Get the oldest key | // Get the oldest key | ||||
if (setKeyPool.empty()) { | if (setKeyPool.empty()) { | ||||
return; | return false; | ||||
} | } | ||||
WalletBatch batch(*database); | WalletBatch batch(*database); | ||||
auto it = setKeyPool.begin(); | auto it = setKeyPool.begin(); | ||||
nIndex = *it; | nIndex = *it; | ||||
setKeyPool.erase(it); | setKeyPool.erase(it); | ||||
if (!batch.ReadPool(nIndex, keypool)) { | if (!batch.ReadPool(nIndex, keypool)) { | ||||
throw std::runtime_error(std::string(__func__) + ": read failed"); | throw std::runtime_error(std::string(__func__) + ": read failed"); | ||||
} | } | ||||
if (!HaveKey(keypool.vchPubKey.GetID())) { | if (!HaveKey(keypool.vchPubKey.GetID())) { | ||||
throw std::runtime_error(std::string(__func__) + | throw std::runtime_error(std::string(__func__) + | ||||
": unknown key in key pool"); | ": unknown key in key pool"); | ||||
} | } | ||||
// If the key was pre-split keypool, we don't care about what type it is | // If the key was pre-split keypool, we don't care about what type it is | ||||
if (set_pre_split_keypool.size() == 0 && | if (use_split_keypool && keypool.fInternal != fReturningInternal) { | ||||
keypool.fInternal != fReturningInternal) { | |||||
throw std::runtime_error(std::string(__func__) + | throw std::runtime_error(std::string(__func__) + | ||||
": keypool entry misclassified"); | ": keypool entry misclassified"); | ||||
} | } | ||||
if (!keypool.vchPubKey.IsValid()) { | |||||
throw std::runtime_error(std::string(__func__) + | |||||
": keypool entry invalid"); | |||||
} | |||||
assert(keypool.vchPubKey.IsValid()); | |||||
m_pool_key_to_index.erase(keypool.vchPubKey.GetID()); | m_pool_key_to_index.erase(keypool.vchPubKey.GetID()); | ||||
LogPrintf("keypool reserve %d\n", nIndex); | LogPrintf("keypool reserve %d\n", nIndex); | ||||
return true; | |||||
} | } | ||||
void CWallet::KeepKey(int64_t nIndex) { | void CWallet::KeepKey(int64_t nIndex) { | ||||
// Remove from key pool. | // Remove from key pool. | ||||
WalletBatch batch(*database); | WalletBatch batch(*database); | ||||
batch.ErasePool(nIndex); | batch.ErasePool(nIndex); | ||||
LogPrintf("keypool keep %d\n", nIndex); | LogPrintf("keypool keep %d\n", nIndex); | ||||
} | } | ||||
Show All 13 Lines | void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey &pubkey) { | ||||
} | } | ||||
LogPrintf("keypool return %d\n", nIndex); | LogPrintf("keypool return %d\n", nIndex); | ||||
} | } | ||||
bool CWallet::GetKeyFromPool(CPubKey &result, bool internal) { | bool CWallet::GetKeyFromPool(CPubKey &result, bool internal) { | ||||
CKeyPool keypool; | CKeyPool keypool; | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
int64_t nIndex = 0; | int64_t nIndex; | ||||
ReserveKeyFromKeyPool(nIndex, keypool, internal); | if (!ReserveKeyFromKeyPool(nIndex, keypool, internal)) { | ||||
if (nIndex == -1) { | |||||
if (IsLocked()) { | if (IsLocked()) { | ||||
return false; | return false; | ||||
} | } | ||||
WalletBatch batch(*database); | WalletBatch batch(*database); | ||||
result = GenerateNewKey(batch, internal); | result = GenerateNewKey(batch, internal); | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | CWallet::GetLabelAddresses(const std::string &label) const { | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
bool CReserveKey::GetReservedKey(CPubKey &pubkey, bool internal) { | bool CReserveKey::GetReservedKey(CPubKey &pubkey, bool internal) { | ||||
if (nIndex == -1) { | if (nIndex == -1) { | ||||
CKeyPool keypool; | CKeyPool keypool; | ||||
pwallet->ReserveKeyFromKeyPool(nIndex, keypool, internal); | if (!pwallet->ReserveKeyFromKeyPool(nIndex, keypool, internal)) { | ||||
if (nIndex == -1) { | |||||
return false; | return false; | ||||
} | } | ||||
vchPubKey = keypool.vchPubKey; | vchPubKey = keypool.vchPubKey; | ||||
fInternal = keypool.fInternal; | fInternal = keypool.fInternal; | ||||
} | } | ||||
assert(vchPubKey.IsValid()); | assert(vchPubKey.IsValid()); | ||||
▲ Show 20 Lines • Show All 883 Lines • Show Last 20 Lines |