Skip to content

Commit 2bc4c3e

Browse files
committed
Notify the GUI that the keypool has changed to set the receive button
Whenever the keypool changes (new keys generated, new seed set, keypool runs out, etc.), notify the GUI that the keypool has changed. The receive button can then be enabled and disabled as necessary.
1 parent 14bcdbe commit 2bc4c3e

File tree

7 files changed

+37
-1
lines changed

7 files changed

+37
-1
lines changed

src/interfaces/wallet.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,10 @@ class WalletImpl : public Wallet
488488
{
489489
return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn));
490490
}
491+
std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) override
492+
{
493+
return MakeHandler(m_wallet.NotifyCanGetAddressesChanged.connect(fn));
494+
}
491495

492496
std::shared_ptr<CWallet> m_shared_wallet;
493497
CWallet& m_wallet;

src/interfaces/wallet.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ class Wallet
271271
//! Register handler for watchonly changed messages.
272272
using WatchOnlyChangedFn = std::function<void(bool have_watch_only)>;
273273
virtual std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) = 0;
274+
275+
//! Register handler for keypool changed messages.
276+
using CanGetAddressesChangedFn = std::function<void()>;
277+
virtual std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) = 0;
274278
};
275279

276280
//! Tracking object returned by CreateTransaction and passed to CommitTransaction.

src/qt/receivecoinsdialog.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,13 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
100100
ui->useBech32->setCheckState(Qt::Unchecked);
101101
}
102102

103-
// eventually disable the main receive button if private key operations are disabled
103+
// Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
104104
ui->receiveButton->setEnabled(model->canGetAddresses());
105+
106+
// Enable/disable the receive button if the wallet is now able/unable to give out new addresses.
107+
connect(model, &WalletModel::canGetAddressesChanged, [this] {
108+
ui->receiveButton->setEnabled(model->canGetAddresses());
109+
});
105110
}
106111
}
107112

src/qt/walletmodel.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,11 @@ static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly
423423
Q_ARG(bool, fHaveWatchonly));
424424
}
425425

426+
static void NotifyCanGetAddressesChanged(WalletModel* walletmodel)
427+
{
428+
QMetaObject::invokeMethod(walletmodel, "canGetAddressesChanged");
429+
}
430+
426431
void WalletModel::subscribeToCoreSignals()
427432
{
428433
// Connect signals to wallet
@@ -432,6 +437,7 @@ void WalletModel::subscribeToCoreSignals()
432437
m_handler_transaction_changed = m_wallet->handleTransactionChanged(std::bind(NotifyTransactionChanged, this, std::placeholders::_1, std::placeholders::_2));
433438
m_handler_show_progress = m_wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
434439
m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(std::bind(NotifyWatchonlyChanged, this, std::placeholders::_1));
440+
m_handler_can_get_addrs_changed = m_wallet->handleCanGetAddressesChanged(boost::bind(NotifyCanGetAddressesChanged, this));
435441
}
436442

437443
void WalletModel::unsubscribeFromCoreSignals()
@@ -443,6 +449,7 @@ void WalletModel::unsubscribeFromCoreSignals()
443449
m_handler_transaction_changed->disconnect();
444450
m_handler_show_progress->disconnect();
445451
m_handler_watch_only_changed->disconnect();
452+
m_handler_can_get_addrs_changed->disconnect();
446453
}
447454

448455
// WalletModel::UnlockContext implementation
@@ -573,6 +580,11 @@ bool WalletModel::privateKeysDisabled() const
573580

574581
bool WalletModel::canGetAddresses() const
575582
{
583+
// The wallet can provide a fresh address if:
584+
// * hdEnabled(): an HD seed is present; or
585+
// * it is a legacy wallet, because:
586+
// * !hdEnabled(): an HD seed is not present; and
587+
// * !IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS): private keys have not been disabled (which results in hdEnabled() == true)
576588
return m_wallet->hdEnabled() || (!m_wallet->hdEnabled() && !m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
577589
}
578590

src/qt/walletmodel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class WalletModel : public QObject
233233
std::unique_ptr<interfaces::Handler> m_handler_transaction_changed;
234234
std::unique_ptr<interfaces::Handler> m_handler_show_progress;
235235
std::unique_ptr<interfaces::Handler> m_handler_watch_only_changed;
236+
std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
236237
interfaces::Node& m_node;
237238

238239
bool fHaveWatchOnly;
@@ -284,6 +285,9 @@ class WalletModel : public QObject
284285
// Signal that wallet is about to be removed
285286
void unload();
286287

288+
// Notify that there are now keys in the keypool
289+
void canGetAddressesChanged();
290+
287291
public Q_SLOTS:
288292
/* Wallet status might have changed */
289293
void updateStatus();

src/wallet/wallet.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,7 @@ void CWallet::SetHDSeed(const CPubKey& seed)
14031403
newHdChain.nVersion = CanSupportFeature(FEATURE_HD_SPLIT) ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE;
14041404
newHdChain.seed_id = seed.GetID();
14051405
SetHDChain(newHdChain, false);
1406+
NotifyCanGetAddressesChanged();
14061407
}
14071408

14081409
void CWallet::SetHDChain(const CHDChain& chain, bool memonly)
@@ -3327,6 +3328,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
33273328
WalletLogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size() + set_pre_split_keypool.size(), setInternalKeyPool.size());
33283329
}
33293330
}
3331+
NotifyCanGetAddressesChanged();
33303332
return true;
33313333
}
33323334

@@ -3371,6 +3373,7 @@ bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
33713373
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
33723374
WalletLogPrintf("keypool reserve %d\n", nIndex);
33733375
}
3376+
NotifyCanGetAddressesChanged();
33743377
return true;
33753378
}
33763379

@@ -3395,6 +3398,7 @@ void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
33953398
setExternalKeyPool.insert(nIndex);
33963399
}
33973400
m_pool_key_to_index[pubkey.GetID()] = nIndex;
3401+
NotifyCanGetAddressesChanged();
33983402
}
33993403
WalletLogPrintf("keypool return %d\n", nIndex);
34003404
}

src/wallet/wallet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,9 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
10871087
/** Watch-only address added */
10881088
boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;
10891089

1090+
/** Keypool has new keys */
1091+
boost::signals2::signal<void ()> NotifyCanGetAddressesChanged;
1092+
10901093
/** Inquire whether this wallet broadcasts transactions. */
10911094
bool GetBroadcastTransactions() const { return fBroadcastTransactions; }
10921095
/** Set whether this wallet broadcasts transactions. */

0 commit comments

Comments
 (0)