Skip to content
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

Enhance/time sync warning #2469

Merged
merged 6 commits into from
Aug 23, 2024
Merged
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
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ FetchContent_MakeAvailable(kdf jl777-coins qmaterial)
if (UNIX)
configure_file(${jl777-coins_SOURCE_DIR}/utils/coins_config_tcp.json ${CMAKE_CURRENT_SOURCE_DIR}/assets/config/${PROJECT_VERSION}-coins.json COPYONLY)
configure_file(${jl777-coins_SOURCE_DIR}/coins ${CMAKE_CURRENT_SOURCE_DIR}/assets/tools/kdf/coins COPYONLY)
configure_file(${kdf_SOURCE_DIR}/kdf ${CMAKE_CURRENT_SOURCE_DIR}/assets/tools/kdf/${DEX_API} COPYONLY)
configure_file(${kdf_SOURCE_DIR}/mm2 ${CMAKE_CURRENT_SOURCE_DIR}/assets/tools/kdf/${DEX_API} COPYONLY)
file(COPY ${jl777-coins_SOURCE_DIR}/icons/ DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/atomic_defi_design/assets/images/coins/)
else ()
configure_file(${jl777-coins_SOURCE_DIR}/utils/coins_config_tcp.json ${CMAKE_BINARY_DIR}/bin/assets/config/${PROJECT_VERSION}-coins.json COPYONLY)
configure_file(${jl777-coins_SOURCE_DIR}/coins ${CMAKE_BINARY_DIR}/bin/assets/tools/kdf/coins COPYONLY)
configure_file(${kdf_SOURCE_DIR}/kdf.exe ${CMAKE_BINARY_DIR}/bin/assets/tools/kdf/${DEX_API}.exe COPYONLY)
configure_file(${kdf_SOURCE_DIR}/mm2.exe ${CMAKE_BINARY_DIR}/bin/assets/tools/kdf/${DEX_API}.exe COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ci_tools_atomic_dex/windows_misc/msvcp140.dll ${CMAKE_BINARY_DIR}/bin/assets/tools/kdf/msvcp140.dll COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ci_tools_atomic_dex/windows_misc/vcruntime140.dll ${CMAKE_BINARY_DIR}/bin/assets/tools/kdf/vcruntime140.dll COPYONLY)
endif ()
Expand Down
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))
Loading