Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
clientmodel.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <qt/clientmodel.h>
6
7#include <qt/bantablemodel.h>
8#include <qt/guiconstants.h>
9#include <qt/guiutil.h>
10#include <qt/peertablemodel.h>
12
13#include <clientversion.h>
14#include <common/args.h>
15#include <common/system.h>
16#include <interfaces/handler.h>
17#include <interfaces/node.h>
18#include <net.h>
19#include <netbase.h>
20#include <util/threadnames.h>
21#include <util/time.h>
22#include <validation.h>
23
24#include <cstdint>
25
26#include <QDebug>
27#include <QMetaObject>
28#include <QThread>
29#include <QTimer>
30
31static SteadyClock::time_point g_last_header_tip_update_notification{};
32static SteadyClock::time_point g_last_block_tip_update_notification{};
33
35 QObject(parent),
36 m_node(node),
37 optionsModel(_optionsModel),
38 m_thread(new QThread(this))
39{
42
46
48
49 QTimer* timer = new QTimer;
50 timer->setInterval(MODEL_UPDATE_DELAY);
51 connect(timer, &QTimer::timeout, [this] {
52 // no locking required at this point
53 // the following calls will acquire the required lock
56 });
57 connect(m_thread, &QThread::finished, timer, &QObject::deleteLater);
58 connect(m_thread, &QThread::started, [timer] { timer->start(); });
59 // move timer to thread so that polling doesn't disturb main event loop
60 timer->moveToThread(m_thread);
61 m_thread->start();
62 QTimer::singleShot(0, timer, []() {
63 util::ThreadRename("qt-clientmodl");
64 });
65
67}
68
70{
72
73 m_thread->quit();
74 m_thread->wait();
75}
76
81
95
97{
98 if (cachedBestHeaderHeight == -1) {
99 // make sure we initially populate the cache via a cs_main lock
100 // otherwise we need to wait for a tip update
101 int height;
103 if (m_node.getHeaderTip(height, blockTime)) {
104 cachedBestHeaderHeight = height;
106 }
107 }
109}
110
112{
113 if (cachedBestHeaderTime == -1) {
114 int height;
116 if (m_node.getHeaderTip(height, blockTime)) {
117 cachedBestHeaderHeight = height;
119 }
120 }
122}
123
124
125std::map<CNetAddr, LocalServiceInfo> ClientModel::getNetLocalAddresses() const
126{
128}
129
131{
133
134 if (!tip.IsNull()) {
135 return tip;
136 }
137
138 // Lock order must be: first `cs_main`, then `m_cached_tip_mutex`.
139 // The following will lock `cs_main` (and release it), so we must not
140 // own `m_cached_tip_mutex` here.
142
144 // We checked that `m_cached_tip_blocks` is not null above, but then we
145 // released the mutex `m_cached_tip_mutex`, so it could have changed in the
146 // meantime. Thus, check again.
147 if (m_cached_tip_blocks.IsNull()) {
149 }
150 return m_cached_tip_blocks;
151}
152
159
161{
162 return QString::fromStdString(m_node.getWarnings().translated);
163}
164
169
174
179
184
186{
187 return QString::fromStdString(FormatFullVersion());
188}
189
191{
192 return QString::fromStdString(strSubVersion);
193}
194
196{
197 return QDateTime::currentDateTime().addSecs(-TicksSeconds(GetUptime())).toString();
198}
199
204
209
211{
213 // cache best headers time and height to reduce future cs_main locks
214 cachedBestHeaderHeight = tip.block_height;
215 cachedBestHeaderTime = tip.block_time;
216 } else if (synctype == SyncType::BLOCK_SYNC) {
218 }
219
220 // Throttle GUI notifications about (a) blocks during initial sync, and (b) both blocks and headers during reindex.
222 const auto now{throttle ? SteadyClock::now() : SteadyClock::time_point{}};
225 return;
226 }
227
228 Q_EMIT numBlocksChanged(tip.block_height, QDateTime::fromSecsSinceEpoch(tip.block_time), verification_progress, synctype, sync_state);
230}
231
233{
235 [this](const std::string& title, int progress, [[maybe_unused]] bool resume_possible) {
236 Q_EMIT showProgress(QString::fromStdString(title), progress);
237 }));
239 [this](int new_num_connections) {
240 Q_EMIT numConnectionsChanged(new_num_connections);
241 }));
243 [this](bool network_active) {
244 Q_EMIT networkActiveChanged(network_active);
245 }));
247 [this]() {
248 qDebug() << "ClientModel: NotifyAlertChanged";
249 Q_EMIT alertsChanged(getStatusBarWarnings());
250 }));
252 [this]() {
253 qDebug() << "ClienModel: Requesting update for peer banlist";
254 QMetaObject::invokeMethod(banTableModel, [this] { banTableModel->refresh(); });
255 }));
256 m_event_handlers.emplace_back(m_node.handleNotifyBlockTip(
257 [this](SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress) {
258 TipChanged(sync_state, tip, verification_progress, SyncType::BLOCK_SYNC);
259 }));
260 m_event_handlers.emplace_back(m_node.handleNotifyHeaderTip(
262 TipChanged(sync_state, tip, /*verification_progress=*/0.0, presync ? SyncType::HEADER_PRESYNC : SyncType::HEADER_SYNC);
263 }));
264}
265
270
271bool ClientModel::getProxyInfo(std::string& ip_port) const
272{
273 const auto ipv4 = m_node.getProxy(NET_IPV4);
274 const auto ipv6 = m_node.getProxy(NET_IPV6);
275 if (ipv4 && ipv6) {
276 ip_port = ipv4->proxy.ToStringAddrPort();
277 return true;
278 }
279 return false;
280}
ArgsManager gArgs
Definition args.cpp:38
node::NodeContext m_node
int flags
fs::path GetBlocksDirPath() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get blocks directory path.
Definition args.cpp:298
fs::path GetDataDirNet() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get data directory path with appended network identifier.
Definition args.cpp:328
Qt model providing information about banned peers, similar to the "getpeerinfo" RPC call.
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut)
QString blocksDir() const
QString getStatusBarWarnings() const
Return warnings to be displayed in status bar.
std::vector< std::unique_ptr< interfaces::Handler > > m_event_handlers
std::map< CNetAddr, LocalServiceInfo > getNetLocalAddresses() const
int getHeaderTipHeight() const
std::atomic< int64_t > cachedBestHeaderTime
Definition clientmodel.h:94
interfaces::Node & m_node
Mutex m_cached_tip_mutex
Definition clientmodel.h:96
PeerTableModel * getPeerTableModel()
PeerTableSortProxy * peerTableSortProxy()
std::atomic< int > cachedBestHeaderHeight
Definition clientmodel.h:93
uint256 getBestBlockHash() EXCLUSIVE_LOCKS_REQUIRED(!m_cached_tip_mutex)
BlockSource getBlockSource() const
Returns the block source of the current importing/syncing state.
int64_t getHeaderTipTime() const
QString formatClientStartupTime() const
int getNumConnections(unsigned int flags=CONNECTIONS_ALL) const
Return number of connections, default is in- and outbound (total)
ClientModel(interfaces::Node &node, OptionsModel *optionsModel, QObject *parent=nullptr)
OptionsModel * optionsModel
BanTableModel * banTableModel
QThread *const m_thread
A thread to interact with m_node asynchronously.
BanTableModel * getBanTableModel()
void unsubscribeFromCoreSignals()
void numBlocksChanged(int count, const QDateTime &blockDate, double nVerificationProgress, SyncType header, SynchronizationState sync_state)
void TipChanged(SynchronizationState sync_state, interfaces::BlockTip tip, double verification_progress, SyncType synctype) EXCLUSIVE_LOCKS_REQUIRED(!m_cached_tip_mutex)
void mempoolSizeChanged(long count, size_t mempoolSizeInBytes, size_t mempoolMaxSizeInBytes)
QString dataDir() const
OptionsModel * getOptionsModel()
QString formatFullVersion() const
PeerTableModel * peerTableModel
PeerTableSortProxy * m_peer_table_sort_proxy
bool getProxyInfo(std::string &ip_port) const
QString formatSubVersion() const
void subscribeToCoreSignals()
Interface from Qt to configuration data structure for Bitcoin client.
Qt model providing information about connected peers, similar to the "getpeerinfo" RPC call.
Top-level interface for a bitcoin node (bitcoind process).
Definition node.h:66
virtual std::map< CNetAddr, LocalServiceInfo > getNetLocalAddresses()=0
Get network local addresses.
virtual std::unique_ptr< Handler > handleShowProgress(ShowProgressFn fn)=0
virtual bilingual_str getWarnings()=0
Get warnings.
virtual size_t getMempoolMaxUsage()=0
Get mempool maximum memory usage.
virtual std::unique_ptr< Handler > handleNotifyAlertChanged(NotifyAlertChangedFn fn)=0
virtual size_t getMempoolSize()=0
Get mempool size.
virtual bool isLoadingBlocks()=0
Is loading blocks.
virtual size_t getNodeCount(ConnectionDirection flags)=0
Get number of connections.
virtual bool getHeaderTip(int &height, int64_t &block_time)=0
Get header tip height and time.
virtual uint256 getBestBlockHash()=0
Get best block hash.
virtual std::optional< Proxy > getProxy(Network net)=0
Get proxy.
virtual int64_t getTotalBytesRecv()=0
Get total bytes recv.
virtual std::unique_ptr< Handler > handleBannedListChanged(BannedListChangedFn fn)=0
virtual std::unique_ptr< Handler > handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn)=0
virtual int64_t getTotalBytesSent()=0
Get total bytes sent.
virtual size_t getMempoolDynamicUsage()=0
Get mempool dynamic usage.
virtual std::unique_ptr< Handler > handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn)=0
256-bit opaque blob.
Definition uint256.h:196
static SteadyClock::time_point g_last_block_tip_update_notification
static SteadyClock::time_point g_last_header_tip_update_notification
SyncType
Definition clientmodel.h:42
@ HEADER_PRESYNC
@ CONNECTIONS_IN
Definition clientmodel.h:50
@ CONNECTIONS_OUT
Definition clientmodel.h:51
@ CONNECTIONS_ALL
Definition clientmodel.h:52
BlockSource
Definition clientmodel.h:36
std::string FormatFullVersion()
SteadyClock::duration GetUptime()
Monotonic uptime (not affected by system time changes).
Definition system.cpp:116
constexpr auto MODEL_UPDATE_DELAY
QString PathToQString(const fs::path &path)
Convert OS specific boost path to QString through UTF-8.
Definition guiutil.cpp:677
void ThreadRename(const std::string &)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
Definition net.cpp:121
@ NET_IPV6
IPv6.
Definition netaddress.h:41
@ NET_IPV4
IPv4.
Definition netaddress.h:38
ConnectionDirection
Definition netbase.h:35
std::string translated
Definition translation.h:26
Block tip (could be a header or not, depends on the subscribed signal).
Definition node.h:270
#define LOCK(cs)
Definition sync.h:268
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition sync.h:299
constexpr int64_t TicksSeconds(Duration d)
Definition time.h:88
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition validation.h:96