Skip to content

Commit

Permalink
Notify the GUI that the keypool has changed to set the receive button
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
achow101 committed Jan 23, 2019
1 parent 14bcdbe commit 2bc4c3e
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/interfaces/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,10 @@ class WalletImpl : public Wallet
{
return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn));
}
std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) override
{
return MakeHandler(m_wallet.NotifyCanGetAddressesChanged.connect(fn));
}

std::shared_ptr<CWallet> m_shared_wallet;
CWallet& m_wallet;
Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ class Wallet
//! Register handler for watchonly changed messages.
using WatchOnlyChangedFn = std::function<void(bool have_watch_only)>;
virtual std::unique_ptr<Handler> handleWatchOnlyChanged(WatchOnlyChangedFn fn) = 0;

//! Register handler for keypool changed messages.
using CanGetAddressesChangedFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleCanGetAddressesChanged(CanGetAddressesChangedFn fn) = 0;
};

//! Tracking object returned by CreateTransaction and passed to CommitTransaction.
Expand Down
7 changes: 6 additions & 1 deletion src/qt/receivecoinsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,13 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
ui->useBech32->setCheckState(Qt::Unchecked);
}

// eventually disable the main receive button if private key operations are disabled
// Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
ui->receiveButton->setEnabled(model->canGetAddresses());

// Enable/disable the receive button if the wallet is now able/unable to give out new addresses.
connect(model, &WalletModel::canGetAddressesChanged, [this] {
ui->receiveButton->setEnabled(model->canGetAddresses());
});
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,11 @@ static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly
Q_ARG(bool, fHaveWatchonly));
}

static void NotifyCanGetAddressesChanged(WalletModel* walletmodel)
{
QMetaObject::invokeMethod(walletmodel, "canGetAddressesChanged");
}

void WalletModel::subscribeToCoreSignals()
{
// Connect signals to wallet
Expand All @@ -432,6 +437,7 @@ void WalletModel::subscribeToCoreSignals()
m_handler_transaction_changed = m_wallet->handleTransactionChanged(std::bind(NotifyTransactionChanged, this, std::placeholders::_1, std::placeholders::_2));
m_handler_show_progress = m_wallet->handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2));
m_handler_watch_only_changed = m_wallet->handleWatchOnlyChanged(std::bind(NotifyWatchonlyChanged, this, std::placeholders::_1));
m_handler_can_get_addrs_changed = m_wallet->handleCanGetAddressesChanged(boost::bind(NotifyCanGetAddressesChanged, this));
}

void WalletModel::unsubscribeFromCoreSignals()
Expand All @@ -443,6 +449,7 @@ void WalletModel::unsubscribeFromCoreSignals()
m_handler_transaction_changed->disconnect();
m_handler_show_progress->disconnect();
m_handler_watch_only_changed->disconnect();
m_handler_can_get_addrs_changed->disconnect();
}

// WalletModel::UnlockContext implementation
Expand Down Expand Up @@ -573,6 +580,11 @@ bool WalletModel::privateKeysDisabled() const

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

Expand Down
4 changes: 4 additions & 0 deletions src/qt/walletmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class WalletModel : public QObject
std::unique_ptr<interfaces::Handler> m_handler_transaction_changed;
std::unique_ptr<interfaces::Handler> m_handler_show_progress;
std::unique_ptr<interfaces::Handler> m_handler_watch_only_changed;
std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
interfaces::Node& m_node;

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

// Notify that there are now keys in the keypool
void canGetAddressesChanged();

public Q_SLOTS:
/* Wallet status might have changed */
void updateStatus();
Expand Down
4 changes: 4 additions & 0 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,7 @@ void CWallet::SetHDSeed(const CPubKey& seed)
newHdChain.nVersion = CanSupportFeature(FEATURE_HD_SPLIT) ? CHDChain::VERSION_HD_CHAIN_SPLIT : CHDChain::VERSION_HD_BASE;
newHdChain.seed_id = seed.GetID();
SetHDChain(newHdChain, false);
NotifyCanGetAddressesChanged();
}

void CWallet::SetHDChain(const CHDChain& chain, bool memonly)
Expand Down Expand Up @@ -3327,6 +3328,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
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());
}
}
NotifyCanGetAddressesChanged();
return true;
}

Expand Down Expand Up @@ -3371,6 +3373,7 @@ bool CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
WalletLogPrintf("keypool reserve %d\n", nIndex);
}
NotifyCanGetAddressesChanged();
return true;
}

Expand All @@ -3395,6 +3398,7 @@ void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
setExternalKeyPool.insert(nIndex);
}
m_pool_key_to_index[pubkey.GetID()] = nIndex;
NotifyCanGetAddressesChanged();
}
WalletLogPrintf("keypool return %d\n", nIndex);
}
Expand Down
3 changes: 3 additions & 0 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,9 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
/** Watch-only address added */
boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;

/** Keypool has new keys */
boost::signals2::signal<void ()> NotifyCanGetAddressesChanged;

/** Inquire whether this wallet broadcasts transactions. */
bool GetBroadcastTransactions() const { return fBroadcastTransactions; }
/** Set whether this wallet broadcasts transactions. */
Expand Down

0 comments on commit 2bc4c3e

Please sign in to comment.