Skip to content

[DO NOT MERGE] 148 rebased over recent changes #208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ QT_FORMS_UI = \

QT_MOC_CPP = \
qml/moc_appmode.cpp \
qml/moc_chainmodel.cpp \
qml/moc_nodemodel.cpp \
qml/moc_options_model.cpp \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_askpassphrasedialog.cpp \
Expand Down Expand Up @@ -110,8 +112,10 @@ QT_QRC_LOCALE = qt/bitcoin_locale.qrc
BITCOIN_QT_H = \
qml/appmode.h \
qml/bitcoin.h \
qml/chainmodel.h \
qml/imageprovider.h \
qml/nodemodel.h \
qml/options_model.h \
qml/util.h \
qt/addressbookpage.h \
qt/addresstablemodel.h \
Expand Down Expand Up @@ -289,8 +293,10 @@ BITCOIN_QT_WALLET_CPP = \

BITCOIN_QML_BASE_CPP = \
qml/bitcoin.cpp \
qml/chainmodel.cpp \
qml/imageprovider.cpp \
qml/nodemodel.cpp \
qml/options_model.cpp \
qml/util.cpp

QML_RES_FONTS = \
Expand All @@ -305,6 +311,7 @@ QML_RES_ICONS = \
qml/res/icons/blocktime-light.png \
qml/res/icons/caret-left.png \
qml/res/icons/caret-right.png \
qml/res/icons/check.png \
qml/res/icons/cross.png \
qml/res/icons/export.png \
qml/res/icons/gear.png \
Expand All @@ -319,12 +326,15 @@ QML_QRC = qml/bitcoin_qml.qrc
QML_RES_QML = \
qml/components/AboutOptions.qml \
qml/components/BlockCounter.qml \
qml/components/BlockClockComponent.qml \
qml/components/ConnectionOptions.qml \
qml/components/ConnectionSettings.qml \
qml/components/DeveloperOptions.qml \
qml/components/PeersIndicator.qml \
qml/components/StorageLocations.qml \
qml/components/StorageOptions.qml \
qml/components/StorageSettings.qml \
qml/controls/BlockClock.qml \
qml/controls/ContinueButton.qml \
qml/controls/ExternalLink.qml \
qml/controls/Header.qml \
Expand All @@ -343,6 +353,8 @@ QML_RES_QML = \
qml/controls/ValueInput.qml \
qml/pages/initerrormessage.qml \
qml/pages/main.qml \
qml/pages/node/NodeRunner.qml \
qml/pages/node/NodeSettings.qml \
qml/pages/onboarding/OnboardingBlockclock.qml \
qml/pages/onboarding/OnboardingConnection.qml \
qml/pages/onboarding/OnboardingCover.qml \
Expand Down
3 changes: 3 additions & 0 deletions src/interfaces/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ class Chain
//! Get block hash. Height must be valid or this function will abort.
virtual uint256 getBlockHash(int height) = 0;

//! Get block time, Height must be valid or this function will abort.
virtual int64_t getBlockTime(int height) = 0;

//! Check that the block is available on disk (i.e. has not been
//! pruned), and contains transactions.
virtual bool haveBlockOnDisk(int height) = 0;
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum class SynchronizationState;
enum class TransactionError;
struct CNodeStateStats;
struct bilingual_str;
struct PeersNumByType;
namespace node {
struct NodeContext;
} // namespace node
Expand Down Expand Up @@ -238,7 +239,7 @@ class Node
virtual std::unique_ptr<Handler> handleInitWallet(InitWalletFn fn) = 0;

//! Register handler for number of connections changed messages.
using NotifyNumConnectionsChangedFn = std::function<void(int new_num_connections)>;
using NotifyNumConnectionsChangedFn = std::function<void(PeersNumByType new_num_connections)>;
virtual std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) = 0;

//! Register handler for network active messages.
Expand Down
42 changes: 37 additions & 5 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1133,15 +1133,47 @@ void CConnman::DisconnectNodes()

void CConnman::NotifyNumConnectionsChanged()
{
size_t nodes_size;
decltype(m_nodes) nodes_copy;
{
LOCK(m_nodes_mutex);
nodes_size = m_nodes.size();
nodes_copy = m_nodes;
}
if(nodes_size != nPrevNodeCount) {
nPrevNodeCount = nodes_size;

int num_outbound_full_relay{0};
int num_block_relay{0};
int num_manual{0};
int num_inbound{0};
for (const auto* node : nodes_copy) {
switch (node->m_conn_type) {
case ConnectionType::OUTBOUND_FULL_RELAY:
++num_outbound_full_relay;
break;
case ConnectionType::BLOCK_RELAY:
++num_block_relay;
break;
case ConnectionType::MANUAL:
++num_manual;
break;
case ConnectionType::INBOUND:
++num_inbound;
break;
case ConnectionType::FEELER:
case ConnectionType::ADDR_FETCH:
break;
}
}

if (num_outbound_full_relay != m_num_outbound_full_relay ||
num_block_relay != m_num_block_relay ||
num_manual != m_num_manual ||
num_inbound != m_num_inbound) {
m_num_outbound_full_relay = num_outbound_full_relay;
m_num_block_relay = num_block_relay;
m_num_manual = num_manual;
m_num_inbound = num_inbound;
if (m_client_interface) {
m_client_interface->NotifyNumConnectionsChanged(nodes_size);
m_client_interface->NotifyNumConnectionsChanged(
{num_outbound_full_relay, num_block_relay, num_manual, num_inbound, static_cast<int>(nodes_copy.size())});
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class BanMan;
class CNode;
class CScheduler;
struct bilingual_str;
struct PeersNumByType;

/** Default for -whitelistrelay. */
static const bool DEFAULT_WHITELISTRELAY = true;
Expand Down Expand Up @@ -1010,7 +1011,11 @@ class CConnman
std::list<CNode*> m_nodes_disconnected;
mutable RecursiveMutex m_nodes_mutex;
std::atomic<NodeId> nLastNodeId{0};
unsigned int nPrevNodeCount{0};
int m_num_outbound_full_relay{0};
int m_num_block_relay{0};
int m_num_manual{0};
int m_num_inbound{0};


/**
* Cache responses to addr requests to minimize privacy leak.
Expand Down
2 changes: 1 addition & 1 deletion src/node/interface_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ bool CClientUIInterface::ThreadSafeMessageBox(const bilingual_str& message, cons
bool CClientUIInterface::ThreadSafeQuestion(const bilingual_str& message, const std::string& non_interactive_message, const std::string& caption, unsigned int style) { return g_ui_signals.ThreadSafeQuestion(message, non_interactive_message, caption, style).value_or(false);}
void CClientUIInterface::InitMessage(const std::string& message) { return g_ui_signals.InitMessage(message); }
void CClientUIInterface::InitWallet() { return g_ui_signals.InitWallet(); }
void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); }
void CClientUIInterface::NotifyNumConnectionsChanged(PeersNumByType newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); }
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
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); }
Expand Down
10 changes: 9 additions & 1 deletion src/node/interface_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class connection;
}
} // namespace boost

struct PeersNumByType {
int outbound_full_relay{0};
int block_relay{0};
int manual{0};
int inbound{0};
int total{0};
};

/** Signals for UI communication. */
class CClientUIInterface
{
Expand Down Expand Up @@ -85,7 +93,7 @@ class CClientUIInterface
ADD_SIGNALS_DECL_WRAPPER(InitWallet, void, );

/** Number of network connections changed. */
ADD_SIGNALS_DECL_WRAPPER(NotifyNumConnectionsChanged, void, int newNumConnections);
ADD_SIGNALS_DECL_WRAPPER(NotifyNumConnectionsChanged, void, PeersNumByType newNumConnections);

/** Network activity state changed. */
ADD_SIGNALS_DECL_WRAPPER(NotifyNetworkActiveChanged, void, bool networkActive);
Expand Down
5 changes: 5 additions & 0 deletions src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,11 @@ class ChainImpl : public Chain
LOCK(::cs_main);
return Assert(chainman().ActiveChain()[height])->GetBlockHash();
}
int64_t getBlockTime(int height) override
{
LOCK(::cs_main);
return Assert(chainman().ActiveChain()[height])->GetBlockTime();
}
bool haveBlockOnDisk(int height) override
{
LOCK(::cs_main);
Expand Down
13 changes: 13 additions & 0 deletions src/qml/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@

#include <chainparams.h>
#include <init.h>
#include <interfaces/chain.h>
#include <interfaces/init.h>
#include <interfaces/node.h>
#include <logging.h>
#include <node/interface_ui.h>
#include <noui.h>
#include <qml/appmode.h>
#include <qml/chainmodel.h>
#include <qml/imageprovider.h>
#include <qml/nodemodel.h>
#include <qml/options_model.h>
#include <qml/util.h>
#include <qt/guiconstants.h>
#include <qt/guiutil.h>
Expand Down Expand Up @@ -154,6 +157,7 @@ int QmlGuiMain(int argc, char* argv[])
GUIUtil::LogQtInfo();

std::unique_ptr<interfaces::Node> node = init->makeNode();
std::unique_ptr<interfaces::Chain> chain = init->makeChain();
if (!node->baseInitialize()) {
// A dialog with detailed error will have been shown by InitError().
return EXIT_FAILURE;
Expand Down Expand Up @@ -185,6 +189,15 @@ int QmlGuiMain(int argc, char* argv[])

engine.rootContext()->setContextProperty("nodeModel", &node_model);

OptionsQmlModel options_model{*node};
engine.rootContext()->setContextProperty("options", &options_model);

ChainModel chain_model{*chain};
engine.rootContext()->setContextProperty("chainModel", &chain_model);

QObject::connect(&node_model, &NodeModel::setTimeRatioList, &chain_model, &ChainModel::setTimeRatioList);
QObject::connect(&node_model, &NodeModel::setTimeRatioListInitial, &chain_model, &ChainModel::setTimeRatioListInitial);

#ifdef __ANDROID__
AppMode app_mode(AppMode::MOBILE);
#else
Expand Down
6 changes: 6 additions & 0 deletions src/qml/bitcoin_qml.qrc
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/qml">
<file>components/AboutOptions.qml</file>
<file>components/BlockClockComponent.qml</file>
<file>components/BlockCounter.qml</file>
<file>components/ConnectionOptions.qml</file>
<file>components/ConnectionSettings.qml</file>
<file>components/DeveloperOptions.qml</file>
<file>components/PeersIndicator.qml</file>
<file>components/StorageLocations.qml</file>
<file>components/StorageOptions.qml</file>
<file>components/StorageSettings.qml</file>
<file>controls/BlockClock.qml</file>
<file>controls/ContinueButton.qml</file>
<file>controls/ExternalLink.qml</file>
<file>controls/Header.qml</file>
Expand All @@ -26,6 +29,8 @@
<file>controls/ValueInput.qml</file>
<file>pages/initerrormessage.qml</file>
<file>pages/main.qml</file>
<file>pages/node/NodeRunner.qml</file>
<file>pages/node/NodeSettings.qml</file>
<file>pages/onboarding/OnboardingBlockclock.qml</file>
<file>pages/onboarding/OnboardingConnection.qml</file>
<file>pages/onboarding/OnboardingCover.qml</file>
Expand All @@ -46,6 +51,7 @@
<file alias="bitcoin">../qt/res/icons/bitcoin.png</file>
<file alias="caret-left">res/icons/caret-left.png</file>
<file alias="caret-right">res/icons/caret-right.png</file>
<file alias="check">res/icons/check.png</file>
<file alias="cross">res/icons/cross.png</file>
<file alias="export">res/icons/export.png</file>
<file alias="gear">res/icons/gear.png</file>
Expand Down
75 changes: 75 additions & 0 deletions src/qml/chainmodel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qml/chainmodel.h>

#include <QDateTime>
#include <QThread>
#include <QTime>
#include <interfaces/chain.h>

ChainModel::ChainModel(interfaces::Chain& chain)
: m_chain{chain}
{
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &ChainModel::setCurrentTimeRatio);
timer->start(1000);

QThread* timer_thread = new QThread;
timer->moveToThread(timer_thread);
timer_thread->start();
}

void ChainModel::setTimeRatioList(int new_time)
{
int timeAtMeridian = timestampAtMeridian();

if (new_time < timeAtMeridian) {
return;
}

m_time_ratio_list.push_back(double(new_time - timeAtMeridian) / SECS_IN_12_HOURS);

Q_EMIT timeRatioListChanged();
}

int ChainModel::timestampAtMeridian()
{
int secsSinceMeridian = (QTime::currentTime().msecsSinceStartOfDay() / 1000) % SECS_IN_12_HOURS;
int currentTimestamp = QDateTime::currentSecsSinceEpoch();

return currentTimestamp - secsSinceMeridian;
}

void ChainModel::setTimeRatioListInitial()
{
int timeAtMeridian = timestampAtMeridian();
int first_block_height;
int active_chain_height = m_chain.getHeight().value();
bool success = m_chain.findFirstBlockWithTimeAndHeight(/*min_time=*/timeAtMeridian, /*min_height=*/0, interfaces::FoundBlock().height(first_block_height));

if (!success) {
return;
}

m_time_ratio_list.clear();
m_time_ratio_list.push_back(double(QDateTime::currentSecsSinceEpoch() - timeAtMeridian) / SECS_IN_12_HOURS);

for (int height = first_block_height; height < active_chain_height + 1; height++) {
m_time_ratio_list.push_back(double(m_chain.getBlockTime(height) - timeAtMeridian) / SECS_IN_12_HOURS);
}

Q_EMIT timeRatioListChanged();
}

void ChainModel::setCurrentTimeRatio()
{
int secsSinceMeridian = (QTime::currentTime().msecsSinceStartOfDay() / 1000) % SECS_IN_12_HOURS;
double currentTimeRatio = double(secsSinceMeridian) / SECS_IN_12_HOURS;

if (currentTimeRatio < m_time_ratio_list[0].toDouble()) { // That means time has crossed a meridian
m_time_ratio_list.erase(m_time_ratio_list.begin() + 1, m_time_ratio_list.end());
}
m_time_ratio_list[0] = currentTimeRatio;
}
Loading