From b8c1d66fb9a12379e2c5ab0dc6ef7e792a01a322 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 18 Jul 2017 09:30:24 +0200 Subject: [PATCH] Merge #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 #10235, should probably get a 15 tag. Tree-SHA512: c13a18a90f1076fb74307f2d64e9d80149811524c6bda259698ff2c65adaf8c6c3f2a3a07a5f4bf03251bc942ba8f5fd33a4427aa4256748c40b062991682caf --- src/wallet/wallet.cpp | 17 +++++++---------- src/wallet/wallet.h | 5 ++++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 279d670878..7cfb4b4d6a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4333,21 +4333,18 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize) if (i < missingInternal) { fInternal = true; } - if (!setInternalKeyPool.empty()) { - nEnd = *(--setInternalKeyPool.end()) + 1; - } - if (!setExternalKeyPool.empty()) { - nEnd = std::max(nEnd, *(--setExternalKeyPool.end()) + 1); - } - // TODO: implement keypools for all accounts? - if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey(walletdb, 0, fInternal), fInternal))) { + + assert(m_max_keypool_index < std::numeric_limits::max()); // How in the hell did you use so many keys? + int64_t index = ++m_max_keypool_index; + + if (!walletdb.WritePool(index, CKeyPool(GenerateNewKey(walletdb, internal), internal))) { throw std::runtime_error(std::string(__func__) + ": writing generated key failed"); } if (fInternal) { - setInternalKeyPool.insert(nEnd); + setInternalKeyPool.insert(index); } else { - setExternalKeyPool.insert(nEnd); + setExternalKeyPool.insert(index); } if (missingInternal + missingExternal > 0) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index df33fc64d8..97e758e6c4 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -753,6 +753,7 @@ private: std::set setInternalKeyPool; std::set setExternalKeyPool; + int64_t m_max_keypool_index; int64_t nTimeFirstKey; @@ -799,13 +800,14 @@ public: } } - void LoadKeyPool(int nIndex, const CKeyPool &keypool) + void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool) { if (keypool.fInternal) { setInternalKeyPool.insert(nIndex); } else { 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 // creation time. Note that this may be overwritten by actually @@ -851,6 +853,7 @@ public: nAccountingEntryNumber = 0; nNextResend = 0; nLastResend = 0; + m_max_keypool_index = 0; nTimeFirstKey = 0; fBroadcastTransactions = false; nRelockTime = 0;