Browse Source

No longer ever reuse keypool indexes

This fixes an issue where you could reserve a keypool entry, then
top up the keypool, writing out a new key at the given index, then
return they key from the pool. This isnt likely to cause issues,
but given there is no reason to ever re-use keypool indexes
(they're 64 bits...), best to avoid it alltogether.
0.15
Matt Corallo 7 years ago
parent
commit
1fc8c3de0c
  1. 14
      src/wallet/wallet.cpp
  2. 5
      src/wallet/wallet.h

14
src/wallet/wallet.cpp

@ -3211,21 +3211,17 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
internal = true; internal = true;
} }
if (!setInternalKeyPool.empty()) { assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
nEnd = *(setInternalKeyPool.rbegin()) + 1; int64_t index = ++m_max_keypool_index;
}
if (!setExternalKeyPool.empty()) {
nEnd = std::max(nEnd, *(setExternalKeyPool.rbegin()) + 1);
}
if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey(walletdb, internal), internal))) { if (!walletdb.WritePool(index, CKeyPool(GenerateNewKey(walletdb, internal), internal))) {
throw std::runtime_error(std::string(__func__) + ": writing generated key failed"); throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
} }
if (internal) { if (internal) {
setInternalKeyPool.insert(nEnd); setInternalKeyPool.insert(index);
} else { } else {
setExternalKeyPool.insert(nEnd); setExternalKeyPool.insert(index);
} }
} }
if (missingInternal + missingExternal > 0) { if (missingInternal + missingExternal > 0) {

5
src/wallet/wallet.h

@ -701,6 +701,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 nTimeFirstKey; int64_t nTimeFirstKey;
@ -743,13 +744,14 @@ public:
} }
} }
void LoadKeyPool(int nIndex, const CKeyPool &keypool) void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
{ {
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);
// 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
@ -795,6 +797,7 @@ public:
nAccountingEntryNumber = 0; nAccountingEntryNumber = 0;
nNextResend = 0; nNextResend = 0;
nLastResend = 0; nLastResend = 0;
m_max_keypool_index = 0;
nTimeFirstKey = 0; nTimeFirstKey = 0;
fBroadcastTransactions = false; fBroadcastTransactions = false;
nRelockTime = 0; nRelockTime = 0;

Loading…
Cancel
Save