diff --git a/src/interfaces/node.h b/src/interfaces/node.h index b9b2306ce3b4c..81844c61856fa 100644 --- a/src/interfaces/node.h +++ b/src/interfaces/node.h @@ -171,6 +171,9 @@ class Node //! Get num blocks. virtual int getNumBlocks() = 0; + //! Get network local addresses. + virtual std::map getNetLocalAddresses() = 0; + //! Get best block hash. virtual uint256 getBestBlockHash() = 0; diff --git a/src/net.cpp b/src/net.cpp index 3d3f9f4ba7d05..4ade0a1889a67 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -3550,6 +3550,13 @@ size_t CConnman::GetNodeCount(ConnectionDirection flags) const return nNum; } + +std::map CConnman::getNetLocalAddresses() const +{ + LOCK(g_maplocalhost_mutex); + return mapLocalHost; +} + uint32_t CConnman::GetMappedAS(const CNetAddr& addr) const { return m_netgroupman.GetMappedAS(addr); diff --git a/src/net.h b/src/net.h index a4e4b5036072d..8449a90b72237 100644 --- a/src/net.h +++ b/src/net.h @@ -1205,6 +1205,7 @@ class CConnman bool AddConnection(const std::string& address, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex); size_t GetNodeCount(ConnectionDirection) const; + std::map getNetLocalAddresses() const; uint32_t GetMappedAS(const CNetAddr& addr) const; void GetNodeStats(std::vector& vstats) const; bool DisconnectNode(const std::string& node); diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 46d36f83f84f1..9fe08eb3dd3d4 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -290,6 +290,13 @@ class NodeImpl : public Node } return false; } + std::map getNetLocalAddresses() override + { + if (m_context->connman) + return m_context->connman->getNetLocalAddresses(); + else + return {}; + } int getNumBlocks() override { LOCK(::cs_main); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 0b03e3071cadb..5c70c2695c581 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -123,6 +123,13 @@ int64_t ClientModel::getHeaderTipTime() const return cachedBestHeaderTime; } + +std::map ClientModel::getNetLocalAddresses() const +{ + return m_node.getNetLocalAddresses(); +} + + int ClientModel::getNumBlocks() const { if (m_cached_num_blocks == -1) { diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 7727359f99518..7d0e35e7f9638 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -13,12 +13,15 @@ #include #include +#include + class BanTableModel; class CBlockIndex; class OptionsModel; class PeerTableModel; class PeerTableSortProxy; enum class SynchronizationState; +struct LocalServiceInfo; namespace interfaces { class Handler; @@ -68,6 +71,7 @@ class ClientModel : public QObject //! Return number of connections, default is in- and outbound (total) int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const; + std::map getNetLocalAddresses() const; int getNumBlocks() const; uint256 getBestBlockHash() EXCLUSIVE_LOCKS_REQUIRED(!m_cached_tip_mutex); int getHeaderTipHeight() const; diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index 10c923db72671..eccea14318955 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -249,6 +249,41 @@ + + + Local Addresses + + + + + + + IBeamCursor + + + true + + + + 0 + 0 + + + + N/A + + + Qt::PlainText + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + Network addresses that your Bitcoin node is currently using to communicate with other nodes. + + + + @@ -261,14 +296,14 @@ - + Current block height - + IBeamCursor @@ -284,14 +319,14 @@ - + Last block time - + IBeamCursor @@ -307,7 +342,7 @@ - + @@ -320,14 +355,14 @@ - + Current number of transactions - + IBeamCursor @@ -343,14 +378,14 @@ - + Memory usage - + IBeamCursor @@ -366,7 +401,7 @@ - + 3 @@ -406,7 +441,7 @@ - + Qt::Vertical diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 8735f9637f4bc..ae3f9aa686d9f 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -978,6 +978,18 @@ void RPCConsole::updateNetworkState() } ui->numberOfConnections->setText(connections); + + QString local_addresses; + std::map hosts = clientModel->getNetLocalAddresses(); + for (const auto& [addr, info] : hosts) { + local_addresses += QString::fromStdString(addr.ToStringAddr()); + if (!addr.IsI2P()) local_addresses += ":" + QString::number(info.nPort); + local_addresses += ", "; + } + local_addresses.chop(2); // remove last ", " + if (local_addresses.isEmpty()) local_addresses = tr("None"); + + ui->localAddresses->setText(local_addresses); } void RPCConsole::setNumConnections(int count)