Skip to content

Commit

Permalink
Merge 15428 via tor_gui_pairing-28+knots
Browse files Browse the repository at this point in the history
  • Loading branch information
luke-jr committed Feb 14, 2025
2 parents 95bfdf5 + 66870ea commit b7af4e6
Show file tree
Hide file tree
Showing 16 changed files with 251 additions and 10 deletions.
5 changes: 4 additions & 1 deletion src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ QT_MOC_CPP = \
qt/moc_optionsdialog.cpp \
qt/moc_optionsmodel.cpp \
qt/moc_overviewpage.cpp \
qt/moc_pairingpage.cpp \
qt/moc_peertablemodel.cpp \
qt/moc_peertablesortproxy.cpp \
qt/moc_paymentserver.cpp \
Expand Down Expand Up @@ -140,6 +141,7 @@ BITCOIN_QT_H = \
qt/optionsdialog.h \
qt/optionsmodel.h \
qt/overviewpage.h \
qt/pairingpage.h \
qt/paymentserver.h \
qt/peertablemodel.h \
qt/peertablesortproxy.h \
Expand Down Expand Up @@ -243,9 +245,11 @@ BITCOIN_QT_BASE_CPP = \
qt/notificator.cpp \
qt/optionsdialog.cpp \
qt/optionsmodel.cpp \
qt/pairingpage.cpp \
qt/peertablemodel.cpp \
qt/peertablesortproxy.cpp \
qt/platformstyle.cpp \
qt/qrimagewidget.cpp \
qt/qvalidatedlineedit.cpp \
qt/qvaluecombobox.cpp \
qt/rpcconsole.cpp \
Expand All @@ -267,7 +271,6 @@ BITCOIN_QT_WALLET_CPP = \
qt/overviewpage.cpp \
qt/paymentserver.cpp \
qt/psbtoperationsdialog.cpp \
qt/qrimagewidget.cpp \
qt/receivecoinsdialog.cpp \
qt/receiverequestdialog.cpp \
qt/recentrequeststablemodel.cpp \
Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ class Node
using NotifyNetworkActiveChangedFn = std::function<void(bool network_active)>;
virtual std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) = 0;

//! Register handler for network local changed messages.
using NotifyNetworkLocalChangedFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleNotifyNetworkLocalChanged(NotifyNetworkLocalChangedFn fn) = 0;

//! Register handler for notify alert messages.
using NotifyAlertChangedFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) = 0;
Expand Down
15 changes: 12 additions & 3 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,16 +278,22 @@ bool AddLocal(const CService& addr_, int nScore)

LogPrintf("AddLocal(%s,%i)\n", addr.ToStringAddrPort(), nScore);

bool fAlready;
{
LOCK(g_maplocalhost_mutex);
const auto [it, is_newly_added] = mapLocalHost.emplace(addr, LocalServiceInfo());
fAlready = !is_newly_added;
LocalServiceInfo &info = it->second;
if (is_newly_added || nScore >= info.nScore) {
info.nScore = nScore + (is_newly_added ? 0 : 1);
info.nPort = addr.GetPort();
}
}

if (!fAlready) {
uiInterface.NotifyNetworkLocalChanged();
}

return true;
}

Expand All @@ -298,9 +304,12 @@ bool AddLocal(const CNetAddr &addr, int nScore)

void RemoveLocal(const CService& addr)
{
LOCK(g_maplocalhost_mutex);
LogPrintf("RemoveLocal(%s)\n", addr.ToStringAddrPort());
mapLocalHost.erase(addr);
{
LOCK(g_maplocalhost_mutex);
LogPrintf("RemoveLocal(%s)\n", addr.ToStringAddrPort());
mapLocalHost.erase(addr);
}
uiInterface.NotifyNetworkLocalChanged();
}

/** vote for a local address */
Expand Down
3 changes: 3 additions & 0 deletions src/node/interface_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct UISignals {
boost::signals2::signal<CClientUIInterface::InitWalletSig> InitWallet;
boost::signals2::signal<CClientUIInterface::NotifyNumConnectionsChangedSig> NotifyNumConnectionsChanged;
boost::signals2::signal<CClientUIInterface::NotifyNetworkActiveChangedSig> NotifyNetworkActiveChanged;
boost::signals2::signal<CClientUIInterface::NotifyNetworkLocalChangedSig> NotifyNetworkLocalChanged;
boost::signals2::signal<CClientUIInterface::NotifyAlertChangedSig> NotifyAlertChanged;
boost::signals2::signal<CClientUIInterface::ShowProgressSig> ShowProgress;
boost::signals2::signal<CClientUIInterface::NotifyBlockTipSig> NotifyBlockTip;
Expand All @@ -41,6 +42,7 @@ ADD_SIGNALS_IMPL_WRAPPER(InitMessage);
ADD_SIGNALS_IMPL_WRAPPER(InitWallet);
ADD_SIGNALS_IMPL_WRAPPER(NotifyNumConnectionsChanged);
ADD_SIGNALS_IMPL_WRAPPER(NotifyNetworkActiveChanged);
ADD_SIGNALS_IMPL_WRAPPER(NotifyNetworkLocalChanged);
ADD_SIGNALS_IMPL_WRAPPER(NotifyAlertChanged);
ADD_SIGNALS_IMPL_WRAPPER(ShowProgress);
ADD_SIGNALS_IMPL_WRAPPER(NotifyBlockTip);
Expand All @@ -53,6 +55,7 @@ void CClientUIInterface::InitMessage(const std::string& message) { return g_ui_s
void CClientUIInterface::InitWallet() { return g_ui_signals.InitWallet(); }
void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); }
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
void CClientUIInterface::NotifyNetworkLocalChanged() { return g_ui_signals.NotifyNetworkLocalChanged(); }
void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertChanged(); }
void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); }
void CClientUIInterface::NotifyBlockTip(SynchronizationState s, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(s, i); }
Expand Down
3 changes: 3 additions & 0 deletions src/node/interface_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ class CClientUIInterface
/** Network activity state changed. */
ADD_SIGNALS_DECL_WRAPPER(NotifyNetworkActiveChanged, void, bool networkActive);

/** Network local addresses changed. */
ADD_SIGNALS_DECL_WRAPPER(NotifyNetworkLocalChanged, void, );

/**
* Status bar alerts changed.
*/
Expand Down
4 changes: 4 additions & 0 deletions src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,10 @@ class NodeImpl : public Node
{
return MakeSignalHandler(::uiInterface.NotifyNetworkActiveChanged_connect(fn));
}
std::unique_ptr<Handler> handleNotifyNetworkLocalChanged(NotifyNetworkLocalChangedFn fn) override
{
return MakeSignalHandler(::uiInterface.NotifyNetworkLocalChanged_connect(fn));
}
std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) override
{
return MakeSignalHandler(::uiInterface.NotifyAlertChanged_connect(fn));
Expand Down
18 changes: 17 additions & 1 deletion src/qt/bitcoingui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
/* When compiled without wallet or -disablewallet is provided,
* the central widget is the rpc console.
*/
rpcConsole->addPairingTab();
setCentralWidget(rpcConsole);
Q_EMIT consoleShown(rpcConsole);
}
Expand Down Expand Up @@ -280,6 +281,13 @@ void BitcoinGUI::createActions()
historyAction->setShortcut(QKeySequence(QStringLiteral("Alt+4")));
tabGroup->addAction(historyAction);

m_action_pairing = new QAction(platformStyle->SingleColorIcon(":/icons/connect_1"), tr("&Pairing"), this);
m_action_pairing->setStatusTip(tr("Pair other software or devices with your node"));
m_action_pairing->setToolTip(m_action_pairing->statusTip());
m_action_pairing->setCheckable(true);
m_action_pairing->setShortcut(QKeySequence(QStringLiteral("Alt+5")));
tabGroup->addAction(m_action_pairing);

#ifdef ENABLE_WALLET
// These showNormalIfMinimized are needed because Send Coins and Receive Coins
// can be triggered from the tray menu, and need to show the GUI to be useful.
Expand All @@ -291,6 +299,8 @@ void BitcoinGUI::createActions()
connect(receiveCoinsAction, &QAction::triggered, this, &BitcoinGUI::gotoReceiveCoinsPage);
connect(historyAction, &QAction::triggered, [this]{ showNormalIfMinimized(); });
connect(historyAction, &QAction::triggered, this, &BitcoinGUI::gotoHistoryPage);
connect(m_action_pairing, &QAction::triggered, this, [this]{ showNormalIfMinimized(); });
connect(m_action_pairing, &QAction::triggered, this, &BitcoinGUI::gotoPairingPage);
#endif // ENABLE_WALLET

quitAction = new QAction(tr("E&xit"), this);
Expand Down Expand Up @@ -615,6 +625,7 @@ void BitcoinGUI::createToolBars()
toolbar->addAction(sendCoinsAction);
toolbar->addAction(receiveCoinsAction);
toolbar->addAction(historyAction);
toolbar->addAction(m_action_pairing);
overviewAction->setChecked(true);

#ifdef ENABLE_WALLET
Expand Down Expand Up @@ -839,7 +850,6 @@ void BitcoinGUI::removeAllWallets()

void BitcoinGUI::setWalletActionsEnabled(bool enabled)
{
overviewAction->setEnabled(enabled);
sendCoinsAction->setEnabled(enabled);
receiveCoinsAction->setEnabled(enabled);
historyAction->setEnabled(enabled && !isPrivacyModeActivated());
Expand Down Expand Up @@ -1022,6 +1032,12 @@ void BitcoinGUI::gotoOverviewPage()
if (walletFrame) walletFrame->gotoOverviewPage();
}

void BitcoinGUI::gotoPairingPage()
{
m_action_pairing->setChecked(true);
if (walletFrame) walletFrame->gotoPairingPage();
}

void BitcoinGUI::gotoHistoryPage()
{
historyAction->setChecked(true);
Expand Down
3 changes: 3 additions & 0 deletions src/qt/bitcoingui.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class BitcoinGUI : public QMainWindow
QMenuBar* appMenuBar = nullptr;
QToolBar* appToolBar = nullptr;
QAction* overviewAction = nullptr;
QAction* m_action_pairing = nullptr;
QAction* historyAction = nullptr;
QAction* quitAction = nullptr;
QAction* sendCoinsAction = nullptr;
Expand Down Expand Up @@ -283,6 +284,8 @@ public Q_SLOTS:
#ifdef ENABLE_WALLET
/** Switch to overview (home) page */
void gotoOverviewPage();
/** Switch to pairing page */
void gotoPairingPage();
/** Switch to history (transactions) page */
void gotoHistoryPage();
/** Switch to receive coins page */
Expand Down
15 changes: 15 additions & 0 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ void ClientModel::subscribeToCoreSignals()
[this](bool network_active) {
Q_EMIT networkActiveChanged(network_active);
}));
m_event_handlers.emplace_back(m_node.handleNotifyNetworkLocalChanged(
[this]() {
Q_EMIT networkLocalChanged();
}));
m_event_handlers.emplace_back(m_node.handleNotifyAlertChanged(
[this]() {
qDebug() << "ClientModel: NotifyAlertChanged";
Expand Down Expand Up @@ -304,6 +308,17 @@ bool ClientModel::getProxyInfo(std::string& ip_port) const
return false;
}

bool ClientModel::getTorInfo(QString& out_onion) const
{
for (const auto& [addr, info] : m_node.getNetLocalAddresses()) {
if (addr.IsTor()) {
out_onion = QString::fromStdString(addr.ToStringAddr());
return true;
}
}
return false;
}

mempoolSamples_t ClientModel::getMempoolStatsInRange(QDateTime &from, QDateTime &to)
{
// get stats from the core stats model
Expand Down
2 changes: 2 additions & 0 deletions src/qt/clientmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class ClientModel : public QObject
QString blocksDir() const;

bool getProxyInfo(std::string& ip_port) const;
bool getTorInfo(QString& out_onion) const;

// caches for the best header: hash, number of blocks and block time
mutable std::atomic<int> cachedBestHeaderHeight;
Expand Down Expand Up @@ -124,6 +125,7 @@ class ClientModel : public QObject
void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress, SyncType header, SynchronizationState sync_state);
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes, size_t mempoolMaxSizeInBytes);
void networkActiveChanged(bool networkActive);
void networkLocalChanged();
void alertsChanged(const QString &warnings);
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);

Expand Down
78 changes: 78 additions & 0 deletions src/qt/pairingpage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <qt/clientmodel.h>
#include <qt/pairingpage.h>
#include <qt/qrimagewidget.h>

#include <QFormLayout>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>

PairingPage::PairingPage(QWidget *parent) :
QWidget(parent)
{
QVBoxLayout *layout = new QVBoxLayout(this);

QLabel *label_experimental = new QLabel(this);
label_experimental->setStyleSheet("QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; }");
label_experimental->setMargin(3);
label_experimental->setTextInteractionFlags(Qt::TextSelectableByMouse);
label_experimental->setWordWrap(true);
label_experimental->setText(tr("Pairing is an experimental feature that currently only works when Tor is enabled. It is expected that the pairing address below will change with future updates, and you may need to re-pair after upgrading."));
layout->addWidget(label_experimental);

QLabel *label_summary = new QLabel(this);
label_summary->setText(tr("Below you will find information to pair other software or devices with this node:"));
layout->addWidget(label_summary);

QFormLayout *form_layout = new QFormLayout();
m_onion_address = new QLineEdit(this);
m_onion_address->setReadOnly(true);
form_layout->addRow(tr("Onion address: "), m_onion_address);

layout->addLayout(form_layout);

m_qrcode = new QRImageWidget(this);
#ifdef USE_QRCODE
layout->addWidget(m_qrcode);
#endif

layout->addStretch();

refresh();
}

void PairingPage::setClientModel(ClientModel *client_model)
{
if (m_client_model) {
disconnect(m_client_model, &ClientModel::networkLocalChanged, this, &PairingPage::refresh);
}
m_client_model = client_model;
if (client_model) {
connect(client_model, &ClientModel::networkLocalChanged, this, &PairingPage::refresh);
}
refresh();
}

void PairingPage::refresh()
{
QString onion;
if (m_client_model && m_client_model->getTorInfo(onion)) {
m_onion_address->setText(onion);
m_onion_address->setEnabled(true);
QString uri = QString("bitcoin-p2p://") + onion;
m_qrcode->setQR(uri);
m_qrcode->setVisible(true);
} else {
m_onion_address->setText(tr("(not connected)"));
m_onion_address->setEnabled(false);
m_qrcode->setVisible(false);
}
}
35 changes: 35 additions & 0 deletions src/qt/pairingpage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_QT_PAIRINGPAGE_H
#define BITCOIN_QT_PAIRINGPAGE_H

#include <QWidget>

class ClientModel;
class QRImageWidget;

QT_BEGIN_NAMESPACE
class QLineEdit;
QT_END_NAMESPACE

class PairingPage : public QWidget
{
Q_OBJECT

public:
explicit PairingPage(QWidget *parent = nullptr);

void setClientModel(ClientModel *);

public Q_SLOTS:
void refresh();

private:
ClientModel *m_client_model{nullptr};
QLineEdit *m_onion_address{nullptr};
QRImageWidget *m_qrcode{nullptr};
};

#endif // BITCOIN_QT_PAIRINGPAGE_H
Loading

0 comments on commit b7af4e6

Please sign in to comment.