diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 7f6f1310d..c8911888a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -522,7 +522,11 @@ std::pair CWallet::GenerateNewUnifie while (true) { auto accountId = hdChain.GetAccountCounter(); auto generated = GenerateUnifiedSpendingKeyForAccount(accountId); - hdChain.IncrementAccountCounter(); + auto account = hdChain.IncrementAccountCounter(); + if (!account.has_value()) { + throw std::runtime_error( + "CWallet::GenerateNewUnifiedSpendingKey(): Account counter overflowed (2^31 - 1)."); + } if (generated.has_value()) { // Update the persisted chain information diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index d26d0f3c7..3288d2d4e 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -11,6 +11,7 @@ #include "key.h" #include "keystore.h" #include "zcash/Address.hpp" +#include "zcash/address/zip32.h" #include #include @@ -103,9 +104,16 @@ public: return accountCounter; } - void IncrementAccountCounter() { - // TODO: We should check for overflow somewhere and handle it. - accountCounter += 1; + /** Increments the account counter by 1 and returns it. Returns std::nullopt + * if the increment operation would cause an overflow. */ + std::optional IncrementAccountCounter() { + auto newAccountCounter = accountCounter + 1; + if (newAccountCounter > (HARDENED_KEY_LIMIT - 1)) { + return std::nullopt; + } else { + accountCounter = newAccountCounter; + return newAccountCounter; + } } uint32_t GetLegacyTKeyCounter(bool external) {