Skip to content

Commit b8c1d66

Browse files
laanwjPastaPastaPasta
authored andcommitted
Merge bitcoin#10795: No longer ever reuse keypool indexes
1fc8c3d No longer ever reuse keypool indexes (Matt Corallo) Pull request description: 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. Builds on bitcoin#10235, should probably get a 15 tag. Tree-SHA512: c13a18a90f1076fb74307f2d64e9d80149811524c6bda259698ff2c65adaf8c6c3f2a3a07a5f4bf03251bc942ba8f5fd33a4427aa4256748c40b062991682caf
1 parent d04633d commit b8c1d66

File tree

2 files changed

+11
-11
lines changed

2 files changed

+11
-11
lines changed

src/wallet/wallet.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4333,21 +4333,18 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
43334333
if (i < missingInternal) {
43344334
fInternal = true;
43354335
}
4336-
if (!setInternalKeyPool.empty()) {
4337-
nEnd = *(--setInternalKeyPool.end()) + 1;
4338-
}
4339-
if (!setExternalKeyPool.empty()) {
4340-
nEnd = std::max(nEnd, *(--setExternalKeyPool.end()) + 1);
4341-
}
4342-
// TODO: implement keypools for all accounts?
4343-
if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey(walletdb, 0, fInternal), fInternal))) {
4336+
4337+
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
4338+
int64_t index = ++m_max_keypool_index;
4339+
4340+
if (!walletdb.WritePool(index, CKeyPool(GenerateNewKey(walletdb, internal), internal))) {
43444341
throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
43454342
}
43464343

43474344
if (fInternal) {
4348-
setInternalKeyPool.insert(nEnd);
4345+
setInternalKeyPool.insert(index);
43494346
} else {
4350-
setExternalKeyPool.insert(nEnd);
4347+
setExternalKeyPool.insert(index);
43514348
}
43524349

43534350
if (missingInternal + missingExternal > 0) {

src/wallet/wallet.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
753753

754754
std::set<int64_t> setInternalKeyPool;
755755
std::set<int64_t> setExternalKeyPool;
756+
int64_t m_max_keypool_index;
756757

757758
int64_t nTimeFirstKey;
758759

@@ -799,13 +800,14 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
799800
}
800801
}
801802

802-
void LoadKeyPool(int nIndex, const CKeyPool &keypool)
803+
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
803804
{
804805
if (keypool.fInternal) {
805806
setInternalKeyPool.insert(nIndex);
806807
} else {
807808
setExternalKeyPool.insert(nIndex);
808809
}
810+
m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
809811

810812
// If no metadata exists yet, create a default with the pool key's
811813
// creation time. Note that this may be overwritten by actually
@@ -851,6 +853,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
851853
nAccountingEntryNumber = 0;
852854
nNextResend = 0;
853855
nLastResend = 0;
856+
m_max_keypool_index = 0;
854857
nTimeFirstKey = 0;
855858
fBroadcastTransactions = false;
856859
nRelockTime = 0;

0 commit comments

Comments
 (0)