diff --git a/atomic_defi_design/qml/Portfolio/Portfolio.qml b/atomic_defi_design/qml/Portfolio/Portfolio.qml index 25e9ee8eea..b0d81f09e9 100644 --- a/atomic_defi_design/qml/Portfolio/Portfolio.qml +++ b/atomic_defi_design/qml/Portfolio/Portfolio.qml @@ -199,6 +199,8 @@ Item { text: qsTr("Show only coins with balance") + " %1".arg(qsTr("(%1/%2)").arg(coinsList.innerList.count).arg(portfolio_mdl.length)) checked: portfolio_coins.with_balance onCheckedChanged: portfolio_coins.with_balance = checked + + Component.onDestruction: portfolio_coins.with_balance = false } } } diff --git a/atomic_defi_design/qml/Screens/Dashboard.qml b/atomic_defi_design/qml/Screens/Dashboard.qml index 2c2df092b6..c0afdc5f96 100644 --- a/atomic_defi_design/qml/Screens/Dashboard.qml +++ b/atomic_defi_design/qml/Screens/Dashboard.qml @@ -199,6 +199,7 @@ Item { anchors.fill: parent transformOrigin: Item.Center + asynchronous: true sourceComponent: { switch (current_page) { @@ -399,4 +400,4 @@ Item { return qsTr(event_name) } } -} \ No newline at end of file +} diff --git a/atomic_defi_design/qml/Screens/InitialLoading.qml b/atomic_defi_design/qml/Screens/InitialLoading.qml index 0548b3bb6d..5e6086b7ef 100644 --- a/atomic_defi_design/qml/Screens/InitialLoading.qml +++ b/atomic_defi_design/qml/Screens/InitialLoading.qml @@ -17,7 +17,7 @@ SetupPage { readonly property string current_status: API.app.wallet_mgr.initial_loading_status onCurrent_statusChanged: { - if (current_status === "complete") + if (current_status === "enabling_coins") onLoaded() } @@ -47,4 +47,4 @@ SetupPage { current_status === "enabling_coins" ? qsTr("Enabling assets") : qsTr("Getting ready")) + "..." } } -} \ No newline at end of file +} diff --git a/src/app/app.cpp b/src/app/app.cpp index d67244ad28..ec9c69f28d 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -82,7 +82,7 @@ namespace atomic_dex if (coin_info.has_parent_fees_ticker && coin_info.ticker != coin_info.fees_ticker) { auto coin_parent_info = mm2.get_coin_info(coin_info.fees_ticker); - if (extra_coins.insert(coin_parent_info.ticker).second) + if (!coin_parent_info.currently_enabled && !coin_parent_info.active && extra_coins.insert(coin_parent_info.ticker).second) { SPDLOG_INFO("Adding extra coin: {} to enable", coin_parent_info.ticker); } diff --git a/src/core/atomicdex/managers/qt.wallet.manager.cpp b/src/core/atomicdex/managers/qt.wallet.manager.cpp index 6c29772b69..9352542fea 100644 --- a/src/core/atomicdex/managers/qt.wallet.manager.cpp +++ b/src/core/atomicdex/managers/qt.wallet.manager.cpp @@ -338,6 +338,7 @@ namespace atomic_dex { this->m_current_status = std::move(status); emit onStatusChanged(); + SPDLOG_INFO("Set status: {}", m_current_status.toStdString()); } bool diff --git a/src/core/atomicdex/models/qt.portfolio.model.cpp b/src/core/atomicdex/models/qt.portfolio.model.cpp index 794f8f40a2..0a45e0173c 100644 --- a/src/core/atomicdex/models/qt.portfolio.model.cpp +++ b/src/core/atomicdex/models/qt.portfolio.model.cpp @@ -30,6 +30,7 @@ #include "atomicdex/utilities/global.utilities.hpp" #include "atomicdex/utilities/qt.utilities.hpp" #include "qt.portfolio.model.hpp" +#include "atomicdex/managers/qt.wallet.manager.hpp" namespace atomic_dex { @@ -135,10 +136,11 @@ namespace atomic_dex auto&& [prev_balance, new_balance, is_change_b] = update_value(BalanceRole, balance, idx, *this); const QString display = QString::fromStdString(coin.ticker) + " (" + balance + ")"; update_value(Display, display, idx, *this); - if (is_change_b) - { - balance_update_handler(prev_balance.toString(), new_balance.toString(), QString::fromStdString(ticker)); - } + // Not a good way to trigger notification, use websocket instead in the future. New was of enabling coins is not compatible. + // if (is_change_b && m_system_manager.has_system() && m_system_manager.get_system().get_status() == "complete") + // { + // balance_update_handler(prev_balance.toString(), new_balance.toString(), QString::fromStdString(ticker)); + // } QJsonArray trend = nlohmann_json_array_to_qt_json_array(coingecko.get_ticker_historical(ticker)); update_value(Trend7D, trend, idx, *this); // SPDLOG_DEBUG("updated currency values of: {}", ticker); @@ -153,9 +155,13 @@ namespace atomic_dex bool portfolio_model::update_balance_values(const std::vector& tickers) { - //SPDLOG_INFO("update_balance_values"); + SPDLOG_INFO("update_balance_values"); for (auto&& ticker: tickers) { + if (ticker.empty()) + { + return false; + } if (m_ticker_registry.find(ticker) == m_ticker_registry.end()) { SPDLOG_WARN("ticker: {} not inserted yet in the model, skipping", ticker); @@ -185,10 +191,11 @@ namespace atomic_dex update_value(Display, display, idx, *this); QString change24_h = retrieve_change_24h(coingecko, coin, *m_config, m_system_manager); update_value(Change24H, change24_h, idx, *this); - if (is_change_b) - { - balance_update_handler(prev_balance.toString(), new_balance.toString(), QString::fromStdString(ticker)); - } + // Not a good way to trigger notification, use websocket instead in the future. New was of enabling coins is not compatible. + // if (is_change_b && m_system_manager.has_system() && m_system_manager.get_system().get_status() == "complete") + // { + // balance_update_handler(prev_balance.toString(), new_balance.toString(), QString::fromStdString(ticker)); + // } QJsonArray trend = nlohmann_json_array_to_qt_json_array(coingecko.get_ticker_historical(ticker)); update_value(Trend7D, trend, idx, *this); if (ticker == mm2_system.get_current_ticker() && (is_change_b || is_change_mc || is_change_mcpfo)) diff --git a/src/core/atomicdex/pages/qt.portfolio.page.cpp b/src/core/atomicdex/pages/qt.portfolio.page.cpp index c6591b41f0..7801751ba2 100644 --- a/src/core/atomicdex/pages/qt.portfolio.page.cpp +++ b/src/core/atomicdex/pages/qt.portfolio.page.cpp @@ -167,6 +167,7 @@ namespace atomic_dex void portfolio_page::initialize_portfolio(const std::vector& tickers) { + SPDLOG_INFO("initialize_portfolio with tickers: {}", fmt::join(tickers, ", ")); m_portfolio_mdl->initialize_portfolio(tickers); m_global_cfg_mdl->update_status(tickers, true); } diff --git a/src/core/atomicdex/pages/qt.wallet.page.cpp b/src/core/atomicdex/pages/qt.wallet.page.cpp index 3f39bf4898..f1ea0899e2 100644 --- a/src/core/atomicdex/pages/qt.wallet.page.cpp +++ b/src/core/atomicdex/pages/qt.wallet.page.cpp @@ -566,8 +566,22 @@ namespace atomic_dex this->set_send_busy(false); }; + auto error_functor = [this](pplx::task previous_task) { + try + { + previous_task.wait(); + } + catch (const std::exception& e) + { + SPDLOG_ERROR("error caught in send: {}", e.what()); + auto error_json = QJsonObject({{"error_code", 500}, {"error_message", QString::fromStdString(e.what())}}); + this->set_rpc_send_data(error_json); + this->set_send_busy(false); + } + }; + //! Process - mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(&handle_exception_pplx_task); + mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(error_functor); } void @@ -645,7 +659,20 @@ namespace atomic_dex this->set_broadcast_busy(false); }; - mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(&handle_exception_pplx_task); + auto error_functor = [this](pplx::task previous_task) { + try + { + previous_task.wait(); + } + catch (const std::exception& e) + { + SPDLOG_ERROR("error caught in broadcast finished: {}", e.what()); + this->set_rpc_broadcast_data(QString::fromStdString(e.what())); + this->set_broadcast_busy(false); + } + }; + + mm2_system.get_mm2_client().async_rpc_batch_standalone(batch).then(answer_functor).then(error_functor); } void diff --git a/src/core/atomicdex/services/mm2/mm2.service.cpp b/src/core/atomicdex/services/mm2/mm2.service.cpp index ec4eb793cd..538e202e11 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.cpp +++ b/src/core/atomicdex/services/mm2/mm2.service.cpp @@ -18,9 +18,9 @@ #include ///! Qt +#include #include #include -#include //! Project Headers #include "atomicdex/api/mm2/mm2.constants.hpp" @@ -28,6 +28,7 @@ #include "atomicdex/api/mm2/rpc.enable.hpp" #include "atomicdex/api/mm2/rpc.min.volume.hpp" #include "atomicdex/api/mm2/rpc.tx.history.hpp" +#include "atomicdex/pages/qt.portfolio.page.hpp" #include "atomicdex/config/mm2.cfg.hpp" #include "atomicdex/managers/qt.wallet.manager.hpp" #include "atomicdex/services/internet/internet.checker.service.hpp" @@ -69,7 +70,7 @@ namespace //! New cfg to ifs fs::path actual_version_filepath = cfg_path / (std::string(atomic_dex::get_raw_version()) + "-coins."s + wallet_name + ".json"s); LOG_PATH("opening file: {}", actual_version_filepath); - QFile actual_version_ifs; + QFile actual_version_ifs; actual_version_ifs.setFileName(atomic_dex::std_path_to_qstring(actual_version_filepath)); actual_version_ifs.open(QIODevice::Text | QIODevice::ReadOnly); nlohmann::json actual_config_data = nlohmann::json::parse(QString(actual_version_ifs.readAll()).toStdString()); @@ -127,7 +128,7 @@ namespace const std::string& wallet_name, const std::vector& tickers, bool status, atomic_dex::t_coins_registry& registry, std::shared_mutex& registry_mtx, std::string field_name = "active") { - SPDLOG_INFO("Update coins status to: {} - field_name: {}", status, field_name); + SPDLOG_INFO("Update coins status to: {} - field_name: {} - tickers: {}", status, field_name, fmt::join(tickers, ", ")); fs::path cfg_path = atomic_dex::utils::get_atomic_dex_config_folder(); std::string filename = std::string(atomic_dex::get_raw_version()) + "-coins." + wallet_name + ".json"; std::string custom_tokens_filename = "custom-tokens." + wallet_name + ".json"; @@ -164,8 +165,11 @@ namespace } if (field_name == "active") { + SPDLOG_INFO("ticker: {} status active: {}", ticker, status); registry[ticker].active = status; - } else if (field_name == "is_segwit_on") { + } + else if (field_name == "is_segwit_on") + { registry[ticker].is_segwit_on = status; } } @@ -469,17 +473,18 @@ namespace atomic_dex mm2_service::batch_balance_and_tx(bool is_a_reset, std::vector tickers, bool is_during_enabling, bool only_tx) { // SPDLOG_INFO("batch_balance_and_tx"); + (void)tickers; + (void)is_during_enabling; auto&& [batch_array, tickers_idx, tokens_to_fetch] = prepare_batch_balance_and_tx(only_tx); return m_mm2_client.async_rpc_batch_standalone(batch_array) .then( - [this, tickers_idx = tickers_idx, tokens_to_fetch = tokens_to_fetch, is_a_reset, tickers, is_during_enabling](web::http::http_response resp) + [this, tokens_to_fetch = tokens_to_fetch, is_a_reset, tickers](web::http::http_response resp) { try { auto answers = ::mm2::api::basic_batch_answer(resp); if (not answers.contains("error")) { - std::size_t idx = 0; for (auto&& answer: answers) { if (answer.contains("balance")) @@ -501,15 +506,9 @@ namespace atomic_dex //! Emit error for UI Change } } - ++idx; } for (auto&& coin: tokens_to_fetch) { process_tx_tokenscan(coin, is_a_reset); } - this->dispatcher_.trigger(tickers_idx); - if (is_during_enabling) - { - dispatcher_.trigger(tickers); - } } } catch (const std::exception& error) @@ -595,11 +594,12 @@ namespace atomic_dex { coin_config coin_info = get_coin_info(g_second_primary_dex_coin); t_electrum_request request{.coin_name = coin_info.ticker, .servers = coin_info.electrum_urls.value(), .with_tx_history = true}; - if (coin_info.segwit && coin_info.is_segwit_on) { - request.address_format = nlohmann::json::object(); + if (coin_info.segwit && coin_info.is_segwit_on) + { + request.address_format = nlohmann::json::object(); request.address_format.value()["format"] = "segwit"; } - nlohmann::json j = ::mm2::api::template_request("electrum"); + nlohmann::json j = ::mm2::api::template_request("electrum"); ::mm2::api::to_json(j, request); btc_kmd_batch.push_back(j); coin_info = get_coin_info(g_primary_dex_coin); @@ -633,8 +633,9 @@ namespace atomic_dex .coin_type = coin_info.coin_type, .is_testnet = coin_info.is_testnet.value_or(false), .with_tx_history = true}; - if (coin_info.segwit && coin_info.is_segwit_on) { - request.address_format = nlohmann::json::object(); + if (coin_info.segwit && coin_info.is_segwit_on) + { + request.address_format = nlohmann::json::object(); request.address_format.value()["format"] = "segwit"; } nlohmann::json j = ::mm2::api::template_request("electrum"); @@ -687,37 +688,56 @@ namespace atomic_dex for (auto&& answer: answers) { auto [res, error] = this->process_batch_enable_answer(answer); - if (not res && idx < tickers.size()) + if (!res) { SPDLOG_DEBUG( "bad answer for: [{}] -> removing it from enabling, idx: {}, tickers size: {}, answers size: {}", tickers[idx], idx, tickers.size(), answers.size()); this->dispatcher_.trigger(tickers[idx], error); to_remove.emplace(tickers[idx]); + if (error.find("already initialized") == std::string::npos) + { + SPDLOG_WARN("Should set to false the active field in cfg for: {} - reason: {}", tickers[idx], error); + } } idx += 1; + if (res) + { + this->process_balance_answer(answer); + } } for (auto&& t: to_remove) { tickers.erase(std::remove(tickers.begin(), tickers.end(), t), tickers.end()); } - if (not tickers.empty()) + if (!tickers.empty()) { if (tickers == g_default_coins) { + SPDLOG_INFO("Trigger default_coins_enabled"); this->dispatcher_.trigger(); + batch_balance_and_tx(false, tickers, true); } - batch_balance_and_tx(false, tickers, true); + dispatcher_.trigger(tickers); + if (tickers.size() == 1) + { + fetch_single_balance(get_coin_info(tickers[0])); + } + // batch_balance_and_tx(false, tickers, true); } } } catch (const std::exception& error) { SPDLOG_ERROR("exception caught in batch_enable_coins: {}", error.what()); + //update_coin_status(this->m_current_wallet_name, tickers, false, m_coins_informations, m_coin_cfg_mutex); //! Emit event here } }) - .then([this, batch_array](pplx::task previous_task) - { this->handle_exception_pplx_task(previous_task, "batch_enable_coins", batch_array); }); + .then([this, tickers, batch_array](pplx::task previous_task) + { + this->handle_exception_pplx_task(previous_task, "batch_enable_coins", batch_array); + //update_coin_status(this->m_current_wallet_name, tickers, false, m_coins_informations, m_coin_cfg_mutex); + }); }; SPDLOG_DEBUG("starting async enabling coin"); @@ -727,9 +747,15 @@ namespace atomic_dex functor(btc_kmd_batch, g_default_coins); } - if (not batch_array.empty()) + if (!batch_array.empty()) { - functor(batch_array, copy_tickers); + for (std::size_t idx = 0; idx < batch_array.size(); ++idx) + { + nlohmann::json single_batch = nlohmann::json::array(); + single_batch.push_back(batch_array.at(idx)); + functor(single_batch, {copy_tickers[idx]}); + } + // functor(batch_array, copy_tickers); } } @@ -773,7 +799,7 @@ namespace atomic_dex nlohmann::json mm2_service::prepare_batch_orderbook(bool is_a_reset) { - //SPDLOG_INFO("is_a_reset: {}", is_a_reset); + // SPDLOG_INFO("is_a_reset: {}", is_a_reset); auto&& [base, rel] = m_synchronized_ticker_pair.get(); if (rel.empty()) return nlohmann::json::array(); @@ -794,7 +820,7 @@ namespace atomic_dex generate_req("min_trading_vol", t_min_volume_request{.coin = base}); generate_req("min_trading_vol", t_min_volume_request{.coin = rel}); } - //SPDLOG_INFO("batch max: {}", batch.dump(4)); + // SPDLOG_INFO("batch max: {}", batch.dump(4)); return batch; } @@ -805,12 +831,12 @@ namespace atomic_dex if (batch.empty()) return; // SPDLOG_DEBUG("batch request: {}", batch.dump(4)); - //auto&& [base, rel] = m_synchronized_ticker_pair.get(); + // auto&& [base, rel] = m_synchronized_ticker_pair.get(); auto answer_functor = [this, is_a_reset](web::http::http_response resp) { auto&& [base, rel] = m_synchronized_ticker_pair.get(); - auto answer = ::mm2::api::basic_batch_answer(resp); + auto answer = ::mm2::api::basic_batch_answer(resp); if (answer.is_array()) { auto orderbook_answer = ::mm2::api::rpc_process_answer_batch(answer[0], "orderbook"); @@ -824,9 +850,9 @@ namespace atomic_dex { this->m_synchronized_max_taker_vol->first = base_max_taker_vol_answer.result.value(); } - //t_float_50 base_res = t_float_50(this->m_synchronized_max_taker_vol->first.decimal) * m_balance_factor; - //this->m_synchronized_max_taker_vol->first.decimal = base_res.str(8); - //SPDLOG_INFO("max_taker_vol: {}", answer[1].dump(4)); + // t_float_50 base_res = t_float_50(this->m_synchronized_max_taker_vol->first.decimal) * m_balance_factor; + // this->m_synchronized_max_taker_vol->first.decimal = base_res.str(8); + // SPDLOG_INFO("max_taker_vol: {}", answer[1].dump(4)); } auto rel_max_taker_vol_answer = ::mm2::api::rpc_process_answer_batch<::mm2::api::max_taker_vol_answer>(answer[2], "max_taker_vol"); @@ -836,8 +862,8 @@ namespace atomic_dex { this->m_synchronized_max_taker_vol->second = rel_max_taker_vol_answer.result.value(); } - //t_float_50 rel_res = t_float_50(this->m_synchronized_max_taker_vol->second.decimal) * m_balance_factor; - //this->m_synchronized_max_taker_vol->second.decimal = rel_res.str(8); + // t_float_50 rel_res = t_float_50(this->m_synchronized_max_taker_vol->second.decimal) * + // m_balance_factor; this->m_synchronized_max_taker_vol->second.decimal = rel_res.str(8); } auto base_min_taker_vol_answer = ::mm2::api::rpc_process_answer_batch(answer[3], "min_trading_vol"); @@ -881,11 +907,55 @@ namespace atomic_dex } void - mm2_service::fetch_infos_thread(bool is_a_refresh, bool only_tx) + mm2_service::fetch_single_balance(const coin_config& cfg_infos) { - // SPDLOG_INFO("fetch_infos_thread"); + nlohmann::json batch_array = nlohmann::json::array(); + if (is_pin_cfg_enabled()) + { + std::shared_lock lock(m_balance_mutex); ///< shared_lock + if (m_balance_informations.find(cfg_infos.ticker) != m_balance_informations.cend()) + { + return; + } + } + t_balance_request balance_request{.coin = cfg_infos.ticker}; + nlohmann::json j = ::mm2::api::template_request("my_balance"); + ::mm2::api::to_json(j, balance_request); + batch_array.push_back(j); + auto answer_functor = [this](web::http::http_response resp) + { + try + { + auto answers = ::mm2::api::basic_batch_answer(resp); + if (!answers.contains("error") && !answers[0].contains("error")) + { + this->process_balance_answer(answers[0]); + } + } + catch (const std::exception& error) + { + SPDLOG_ERROR("exception in fetch_single_balance: {}", error.what()); + } + }; + auto error_functor = [this, batch = batch_array](pplx::task previous_task) + { this->handle_exception_pplx_task(previous_task, "fetch_single_balance", batch); }; + m_mm2_client.async_rpc_batch_standalone(batch_array).then(answer_functor).then(error_functor); + } - batch_balance_and_tx(is_a_refresh, {}, false, only_tx); + void + mm2_service::fetch_infos_thread(bool is_a_refresh, bool only_tx) + { + SPDLOG_INFO("fetch_infos_thread"); + if (only_tx) + { + batch_balance_and_tx(is_a_refresh, {}, false, only_tx); + } + else + { + const auto& enabled_coins = get_enabled_coins(); + for (auto&& coin: enabled_coins) { fetch_single_balance(coin); } + batch_balance_and_tx(is_a_refresh, {}, false, true); + } } void @@ -913,7 +983,6 @@ namespace atomic_dex ofs.close(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - ; env.insert("MM_CONF_PATH", std_path_to_qstring(mm2_cfg_path)); env.insert("MM_LOG", std_path_to_qstring(utils::get_mm2_atomic_dex_current_log_file())); env.insert("MM_COINS_PATH", std_path_to_qstring((utils::get_current_configs_path() / "coins.json"))); @@ -1456,10 +1525,12 @@ namespace atomic_dex t_float_50 result = t_float_50(answer_r.balance) * m_balance_factor; answer_r.balance = result.str(8, std::ios_base::fixed); + //auto copy_coin = answer_r.coin; { std::unique_lock lock(m_balance_mutex); m_balance_informations[answer_r.coin] = std::move(answer_r); } + //m_system_manager.get_system().get_portfolio()->update_balance_values({copy_coin}); } mm2_client& @@ -1673,16 +1744,17 @@ namespace atomic_dex } catch (const std::exception& e) { - if (std::string(e.what()).find("mutex lock failed") != std::string::npos) { + if (std::string(e.what()).find("mutex lock failed") != std::string::npos) + { return; } for (auto&& cur: request) cur["userpass"] = ""; SPDLOG_ERROR("pplx task error: {} from: {}, request: {}", e.what(), from, request.dump(4)); - this->dispatcher_.trigger(from, e.what()); + //this->dispatcher_.trigger(from, e.what()); -#if defined(linux) || defined(__APPLE__) - SPDLOG_ERROR("stacktrace: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); -#endif +//#if defined(linux) || defined(__APPLE__) + //SPDLOG_ERROR("stacktrace: {}", boost::stacktrace::to_string(boost::stacktrace::stacktrace())); +//#endif if (std::string(e.what()).find("Failed to read HTTP status line") != std::string::npos || std::string(e.what()).find("WinHttpReceiveResponse: 12002: The operation timed out") != std::string::npos) { diff --git a/src/core/atomicdex/services/mm2/mm2.service.hpp b/src/core/atomicdex/services/mm2/mm2.service.hpp index c7d280494a..654a4b7fbd 100644 --- a/src/core/atomicdex/services/mm2/mm2.service.hpp +++ b/src/core/atomicdex/services/mm2/mm2.service.hpp @@ -135,6 +135,7 @@ namespace atomic_dex void process_balance_answer(const nlohmann::json& answer); void process_tx_answer(const nlohmann::json& answer_json); void process_tx_tokenscan(const std::string& ticker, bool is_a_refresh); + void fetch_single_balance(const coin_config& cfg_infos); //! std::pair process_batch_enable_answer(const nlohmann::json& answer); diff --git a/src/core/atomicdex/services/price/coingecko/coingecko.provider.cpp b/src/core/atomicdex/services/price/coingecko/coingecko.provider.cpp index b225475f6d..30ff10debd 100644 --- a/src/core/atomicdex/services/price/coingecko/coingecko.provider.cpp +++ b/src/core/atomicdex/services/price/coingecko/coingecko.provider.cpp @@ -49,8 +49,12 @@ namespace atomic_dex void coingecko_provider::on_coin_enabled(const coin_enabled& evt) { + SPDLOG_INFO("coin_enabled: {}", fmt::join(evt.tickers, ", ")); dispatcher_.trigger(evt.tickers); - this->update_ticker_and_provider(); + if (evt.tickers.size() > 1) + { + this->update_ticker_and_provider(); + } } void diff --git a/src/core/atomicdex/services/price/global.provider.cpp b/src/core/atomicdex/services/price/global.provider.cpp index d411856067..e204672634 100644 --- a/src/core/atomicdex/services/price/global.provider.cpp +++ b/src/core/atomicdex/services/price/global.provider.cpp @@ -388,7 +388,7 @@ namespace atomic_dex if (t_ec) { ec = t_ec; - SPDLOG_ERROR("my_balance error: {}", t_ec.message()); + //SPDLOG_ERROR("my_balance error: {} {}", t_ec.message(), ticker); return "0.00"; }