Skip to content

Commit

Permalink
Merge pull request #2469 from KomodoPlatform/enhance/time-sync-warning
Browse files Browse the repository at this point in the history
Enhance/time sync warning
  • Loading branch information
smk762 authored Aug 23, 2024
2 parents 5583759 + 8ea79d5 commit eeb767c
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 4 deletions.
4 changes: 2 additions & 2 deletions atomic_defi_design/Dex/Exchange/Trade/FeeIcon.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ DefaultText {
visible: mouse_area.containsMouse

contentItem: ColumnLayout {
DefaultText {
DexLabel {
id: tx_fee_text
text_value: General.txFeeText(trade_info, base, false)
font.pixelSize: Style.textSizeSmall4
}
DefaultText {
DexLabel {
text_value: General.tradingFeeText(trade_info, base, false)
font.pixelSize: tx_fee_text.font.pixelSize
}
Expand Down
24 changes: 23 additions & 1 deletion atomic_defi_design/Dex/Sidebar/Center.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@ MouseArea
height: lineHeight * 5
hoverEnabled: true

Connections
{
target: API.app.timesyncCheckerService

function onTimesyncInfoChanged()
{
if (!API.app.timesyncCheckerService.timesyncInfo)
{
_dexLine.timesyncInfo = false
if (currentLineType === Main.LineType.DEX) currentLineType = Main.LineType.Portfolio
root.lineSelected(Main.LineType.Portfolio);
}
else
{
_dexLine.timesyncInfo = true
}
}
}

Connections
{
target: parent.parent
Expand Down Expand Up @@ -84,12 +103,15 @@ MouseArea
FigurativeLine
{
id: _dexLine
property var timesyncInfo: API.app.timesyncCheckerService.timesyncInfo

Layout.fillWidth: true
type: Main.LineType.DEX
label.color: timesyncInfo ? Dex.CurrentTheme.foregroundColor : Dex.CurrentTheme.textDisabledColor
label.text: qsTr("DEX") // isExpanded ? qsTr("DEX") : ""
icon.source: General.image_path + "menu-exchange-white.svg"
onClicked: lineSelected(type)
onClicked: timesyncInfo ? lineSelected(type) : null
disabled_tt_text: timesyncInfo ? "" : qsTr("DEX is disabled due to system clock synchronization issues. Please check your device time settings.")
}

FigurativeLine
Expand Down
11 changes: 11 additions & 0 deletions atomic_defi_design/Dex/Sidebar/FigurativeLine.qml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import QtQuick 2.12

import "../Components"
import "../Constants"
import Dex.Themes 1.0 as Dex

// FigurativeLine acts the same as Line but contains a figurative icon on the left of its label
Line
{
property alias icon: _icon
property string disabled_tt_text: ""

DefaultImage
{
Expand All @@ -26,4 +28,13 @@ Line
currentLineType === type && type != Main.LineType.Support ? Dex.CurrentTheme.sidebarLineTextSelected :
Dex.CurrentTheme.foregroundColor
}

DexTooltip
{
visible: mouseArea.containsMouse && disabled_tt_text
delay: 500
timeout: 5000
text: disabled_tt_text
font.pixelSize: Style.textSizeSmall4
}
}
15 changes: 14 additions & 1 deletion src/app/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "atomicdex/services/price/komodo_prices/komodo.prices.provider.hpp"
#include "atomicdex/services/price/coingecko/coingecko.wallet.charts.hpp"
#include "atomicdex/services/price/orderbook.scanner.service.hpp"
#include "atomicdex/services/sync/timesync.checker.service.hpp"

namespace
{
Expand Down Expand Up @@ -498,6 +499,7 @@ namespace atomic_dex
system_manager_.create_system<orderbook_scanner_service>(system_manager_);
system_manager_.create_system<komodo_prices_provider>();
system_manager_.create_system<update_checker_service>();
system_manager_.create_system<timesync_checker_service>();
system_manager_.create_system<coingecko_wallet_charts_service>(system_manager_);
system_manager_.create_system<exporter_service>(system_manager_);
system_manager_.create_system<trading_page>(
Expand Down Expand Up @@ -910,7 +912,18 @@ namespace atomic_dex
}
} // namespace atomic_dex

//! update checker
//! time sync checker
namespace atomic_dex
{
timesync_checker_service* application::get_timesync_checker_service() const
{
auto ptr = const_cast<timesync_checker_service*>(std::addressof(system_manager_.get_system<timesync_checker_service>()));
assert(ptr != nullptr);
return ptr;
}
} // namespace atomic_dex

//! zcash_params checker
namespace atomic_dex
{
zcash_params_service* application::get_zcash_params_service() const
Expand Down
4 changes: 4 additions & 0 deletions src/app/app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "atomicdex/services/price/global.provider.hpp"
#include "atomicdex/services/update/update.checker.service.hpp"
#include "atomicdex/services/update/zcash.params.service.hpp"
#include "atomicdex/services/sync/timesync.checker.service.hpp"
#include "atomicdex/utilities/qt.utilities.hpp"

namespace ag = antara::gaming;
Expand All @@ -75,6 +76,7 @@ namespace atomic_dex
Q_PROPERTY(settings_page* settings_pg READ get_settings_page NOTIFY settingsPageChanged)
Q_PROPERTY(qt_wallet_manager* wallet_mgr READ get_wallet_mgr NOTIFY walletMgrChanged)
Q_PROPERTY(update_checker_service* updateCheckerService READ get_update_checker_service NOTIFY updateCheckerServiceChanged)
Q_PROPERTY(timesync_checker_service* timesyncCheckerService READ get_timesync_checker_service NOTIFY timesyncCheckerServiceChanged)
Q_PROPERTY(zcash_params_service* zcash_params READ get_zcash_params_service NOTIFY zcashParamsServiceChanged)

//! Private function
Expand Down Expand Up @@ -135,6 +137,7 @@ namespace atomic_dex
qt_wallet_manager* get_wallet_mgr() const;
internet_service_checker* get_internet_checker() const;
update_checker_service* get_update_checker_service() const;
timesync_checker_service* get_timesync_checker_service() const;
[[nodiscard]] zcash_params_service* get_zcash_params_service() const;
exporter_service* get_exporter_service() const;

Expand Down Expand Up @@ -180,6 +183,7 @@ namespace atomic_dex
void walletPageChanged();
void ordersChanged();
void updateCheckerServiceChanged();
void timesyncCheckerServiceChanged();
void zcashParamsServiceChanged();
void tradingPageChanged();
void settingsPageChanged();
Expand Down
118 changes: 118 additions & 0 deletions src/core/atomicdex/services/sync/timesync.checker.service.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/******************************************************************************
* Copyright © 2013-2024 The Komodo Platform Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* Komodo Platform software, including this file may be copied, modified, *
* propagated or distributed except according to the terms contained in the *
* LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/

#include <nlohmann/json.hpp>
#include "atomicdex/services/sync/timesync.checker.service.hpp"
#include "atomicdex/utilities/cpprestsdk.utilities.hpp"

namespace
{
constexpr const char* g_timesync_endpoint = "https://worldtimeapi.org";
web::http::client::http_client_config g_timesync_cfg{[]()
{
web::http::client::http_client_config cfg;
cfg.set_validate_certificates(false);
cfg.set_timeout(std::chrono::seconds(5));
return cfg;
}()};
t_http_client_ptr g_timesync_client = std::make_unique<web::http::client::http_client>(FROM_STD_STR(g_timesync_endpoint), g_timesync_cfg);
pplx::cancellation_token_source g_synctoken_source;

pplx::task<web::http::http_response>
async_fetch_timesync()
{
web::http::http_request req;
req.set_method(web::http::methods::GET);
req.set_request_uri(FROM_STD_STR("api/timezone/UTC"));
return g_timesync_client->request(req, g_synctoken_source.get_token());
}

bool get_timesync_info_rpc(web::http::http_response resp_http)
{
using namespace std::string_literals;
nlohmann::json resp;
bool sync_ok = false;
std::string resp_str = TO_STD_STR(resp_http.extract_string(true).get());
if (resp_http.status_code() != 200)
{
SPDLOG_ERROR("Cannot reach the endpoint [{}]: {}", g_timesync_endpoint);
}
else
{
resp = nlohmann::json::parse(resp_str);
int64_t epoch_ts = resp["unixtime"];
int64_t current_ts = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
int64_t ts_diff = epoch_ts - current_ts;
if (abs(ts_diff) < 60)
{
sync_ok = true;
}
}
return sync_ok;
}
} // namespace


namespace atomic_dex
{
timesync_checker_service::timesync_checker_service(entt::registry& registry, QObject* parent) : QObject(parent), system(registry)
{
m_timesync_clock = std::chrono::high_resolution_clock::now();
m_timesync_status = true;
fetch_timesync_status();
}

void timesync_checker_service::update()
{
using namespace std::chrono_literals;

int64_t m_timesync_clock_ts = std::chrono::duration_cast<std::chrono::seconds>(m_timesync_clock.time_since_epoch()).count();
int64_t now_ts = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
int64_t ts_diff = now_ts - m_timesync_clock_ts;
if (abs(ts_diff) >= 60)
{
fetch_timesync_status();
m_timesync_clock = std::chrono::high_resolution_clock::now();
}
}

void timesync_checker_service::fetch_timesync_status()
{
if (is_timesync_fetching)
{
return;
}
is_timesync_fetching = true;
emit isTimesyncFetchingChanged();
async_fetch_timesync()
.then([this](web::http::http_response resp) {
this->m_timesync_status = get_timesync_info_rpc(resp);
emit timesyncInfoChanged();
})
.then(&handle_exception_pplx_task);
is_timesync_fetching = false;
emit isTimesyncFetchingChanged();

}

bool timesync_checker_service::get_timesync_info() const
{
return *m_timesync_status;
}

} // namespace atomic_dex


60 changes: 60 additions & 0 deletions src/core/atomicdex/services/sync/timesync.checker.service.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/******************************************************************************
* Copyright © 2013-2024 The Komodo Platform Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* Komodo Platform software, including this file may be copied, modified, *
* propagated or distributed except according to the terms contained in the *
* LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/

#pragma once

#include <QObject>
#include <QVariant>

#include <boost/thread/synchronized_value.hpp>
#include <nlohmann/json_fwd.hpp>

#include <antara/gaming/ecs/system.hpp>

namespace atomic_dex
{
class timesync_checker_service final : public QObject, public ag::ecs::pre_update_system<timesync_checker_service>
{
Q_OBJECT

Q_PROPERTY(QVariant timesyncInfo READ get_timesync_info NOTIFY timesyncInfoChanged)
Q_PROPERTY(bool isTimesyncFetching READ get_is_timesync_fetching NOTIFY isTimesyncFetchingChanged)

using t_timesync_time_point = std::chrono::high_resolution_clock::time_point;
using t_bool_synchronized = boost::synchronized_value<bool>;

t_bool_synchronized m_timesync_status;
t_timesync_time_point m_timesync_clock;
t_bool_synchronized is_timesync_fetching;

void fetch_timesync_status();

public:
explicit timesync_checker_service(entt::registry& registry, QObject* parent = nullptr);
~timesync_checker_service() final = default;

void update() final;

[[nodiscard]] bool get_timesync_info() const;
[[nodiscard]] bool get_is_timesync_fetching() const noexcept { return *is_timesync_fetching; }

signals:
void timesyncInfoChanged();
void isTimesyncFetchingChanged();
};
} // namespace atomic_dex

REFL_AUTO(type(atomic_dex::timesync_checker_service))

0 comments on commit eeb767c

Please sign in to comment.