From 2fabc1ec8dc8b40de91f09c4c8c4c5c79d32ee1c Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Thu, 24 Oct 2019 19:16:37 -0700 Subject: [PATCH] Show syncing progress at startup --- lib/Cargo.lock | 4 +-- lib/Cargo.toml | 2 +- lib/src/lib.rs | 27 +++++++++++------- src/connection.cpp | 63 +++++++++++++++++++++++++++++++---------- src/connection.h | 2 ++ src/controller.cpp | 12 +++++--- src/firsttimewizard.cpp | 2 +- 7 files changed, 77 insertions(+), 35 deletions(-) diff --git a/lib/Cargo.lock b/lib/Cargo.lock index 6f29205..4326aef 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -1051,7 +1051,7 @@ version = "0.1.0" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "zecwalletlitelib 0.1.0 (git+https://github.com/adityapk00/zecwallet-light-cli?rev=6dc22e4d74e9cec458d279d793477dea3bfe27e5)", + "zecwalletlitelib 0.1.0", ] [[package]] @@ -2266,7 +2266,6 @@ dependencies = [ [[package]] name = "zecwalletlitelib" version = "0.1.0" -source = "git+https://github.com/adityapk00/zecwallet-light-cli?rev=6dc22e4d74e9cec458d279d793477dea3bfe27e5#6dc22e4d74e9cec458d279d793477dea3bfe27e5" dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bellman 0.1.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)", @@ -2562,4 +2561,3 @@ dependencies = [ "checksum zcash_client_backend 0.0.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)" = "" "checksum zcash_primitives 0.0.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)" = "" "checksum zcash_proofs 0.0.0 (git+https://github.com/adityapk00/librustzcash.git?rev=188537ea025fcb7fbdfc11266f307a084a5451e4)" = "" -"checksum zecwalletlitelib 0.1.0 (git+https://github.com/adityapk00/zecwallet-light-cli?rev=6dc22e4d74e9cec458d279d793477dea3bfe27e5)" = "" diff --git a/lib/Cargo.toml b/lib/Cargo.toml index e028166..12dee93 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -11,4 +11,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" lazy_static = "1.4.0" -zecwalletlitelib = { git = "https://github.com/adityapk00/zecwallet-light-cli", rev = "6dc22e4d74e9cec458d279d793477dea3bfe27e5" } +zecwalletlitelib = { path="../../lightwallet/lightwalletclient/lib/" } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index d9cbf5a..98b03fa 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -4,7 +4,7 @@ extern crate lazy_static; use libc::{c_char}; use std::ffi::{CStr, CString}; -use std::sync::{Mutex}; +use std::sync::{Mutex, Arc}; use std::cell::RefCell; use zecwalletlitelib::{commands, lightclient::{LightClient, LightClientConfig}}; @@ -13,7 +13,7 @@ use zecwalletlitelib::{commands, lightclient::{LightClient, LightClientConfig}}; // so we don't have to keep creating it. We need to store it here, in rust // because we can't return such a complex structure back to C++ lazy_static! { - static ref LIGHTCLIENT: Mutex>> = Mutex::new(RefCell::new(None)); + static ref LIGHTCLIENT: Mutex>>> = Mutex::new(RefCell::new(None)); } // Check if there is an existing wallet @@ -65,7 +65,7 @@ pub extern fn litelib_initialize_new(dangerous: bool, server: *const c_char) -> } }; - LIGHTCLIENT.lock().unwrap().replace(Some(lightclient)); + LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient))); // Return the wallet's seed let s_str = CString::new(seed).unwrap(); @@ -113,7 +113,7 @@ pub extern fn litelib_initialize_new_from_phrase(dangerous: bool, server: *const } }; - LIGHTCLIENT.lock().unwrap().replace(Some(lightclient)); + LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient))); let c_str = CString::new("OK").unwrap(); return c_str.into_raw(); @@ -145,7 +145,7 @@ pub extern fn litelib_initialize_existing(dangerous: bool, server: *const c_char } }; - LIGHTCLIENT.lock().unwrap().replace(Some(lightclient)); + LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient))); let c_str = CString::new("OK").unwrap(); return c_str.into_raw(); @@ -167,16 +167,21 @@ pub extern fn litelib_execute(cmd: *const c_char, args: *const c_char) -> *mut c let resp: String; { - let lc = LIGHTCLIENT.lock().unwrap(); + let lightclient: Arc; + { + let lc = LIGHTCLIENT.lock().unwrap(); - if lc.borrow().is_none() { - let e_str = CString::new("Error: Light Client is not initialized").unwrap(); - return e_str.into_raw(); - } + if lc.borrow().is_none() { + let e_str = CString::new("Error: Light Client is not initialized").unwrap(); + return e_str.into_raw(); + } + + lightclient = lc.borrow().as_ref().unwrap().clone(); + }; let args = if arg_str.is_empty() { vec![] } else { vec![arg_str.as_ref()] }; - resp = commands::do_user_command(&cmd_str, &args, lc.borrow().as_ref().unwrap()).clone(); + resp = commands::do_user_command(&cmd_str, &args, lightclient.as_ref()).clone(); }; let c_str = CString::new(resp.as_bytes()).unwrap(); diff --git a/src/connection.cpp b/src/connection.cpp index 0e93778..46f290e 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -58,10 +58,53 @@ void ConnectionLoader::doAutoConnect() { // After the lib is initialized, try to do get info connection->doRPC("info", "", [=](auto reply) { - // If success, set the connection + // If success, set the connection main->logger->write("Connection is online."); - this->doRPCSetConnection(connection); - }, [=](auto err) {}); + + QAtomicInteger* isSyncing = new QAtomicInteger(); + isSyncing->store(true); + + // Do a sync at startup + syncTimer = new QTimer(main); + connection->doRPCWithDefaultErrorHandling("sync", "", [=](auto) { + isSyncing->store(false); + + // Cancel the timer + syncTimer->deleteLater(); + + // When sync is done, set the connection + this->doRPCSetConnection(connection); + }); + + // While it is syncing, we'll show the status updates while it is alive. + QObject::connect(syncTimer, &QTimer::timeout, [=]() { + qDebug() << "Sync timer" << isSyncing->load(); + // Check the sync status + if (isSyncing->load()) { + // Get the sync status + connection->doRPC("syncstatus", "", [=](json reply) { + qDebug() << QString::fromStdString("Sync statys = ") << QString::fromStdString(reply.dump()); + + if (isSyncing->load() && reply.find("synced_blocks") != reply.end()) { + qint64 synced = reply["synced_blocks"].get(); + qint64 total = reply["total_blocks"].get(); + showInformation("Synced " + QString::number(synced) + " / " + QString::number(total)); + } + }, + [=](QString err) { + qDebug() << "Sync error" << err; + }); + } else { + delete isSyncing; + } + }); + + syncTimer->setInterval(1* 1000); + syncTimer->start(1000); + + }, [=](QString err) { + showError(err); + }); } void ConnectionLoader::createOrRestore(bool dangerous, QString server) { @@ -75,6 +118,7 @@ void ConnectionLoader::createOrRestore(bool dangerous, QString server) { } void ConnectionLoader::doRPCSetConnection(Connection* conn) { + qDebug() << "Connectionloader finished, setting connection"; rpc->setConnection(conn); d->accept(); @@ -88,20 +132,9 @@ Connection* ConnectionLoader::makeConnection(std::shared_ptr c // Update the UI with the status void ConnectionLoader::showInformation(QString info, QString detail) { - static int rescanCount = 0; - if (detail.toLower().startsWith("rescan")) { - rescanCount++; - } - - if (rescanCount > 10) { - detail = detail + "\n" + QObject::tr("This may take several hours"); - } - + qDebug() << "Showing info " << info << ":" << detail; connD->status->setText(info); connD->statusDetail->setText(detail); - - if (rescanCount < 10) - main->logger->write(info + ":" + detail); } /** diff --git a/src/connection.h b/src/connection.h index 34dd416..970d6af 100644 --- a/src/connection.h +++ b/src/connection.h @@ -40,6 +40,8 @@ private: void doRPCSetConnection(Connection* conn); + QTimer* syncTimer; + QDialog* d; Ui_ConnectionDialog* connD; diff --git a/src/controller.cpp b/src/controller.cpp index 2462c69..0f8bc7c 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -161,21 +161,25 @@ void Controller::getInfoThenRefresh(bool force) { prevCallSucceeded = true; // Testnet? + QString chainName; if (!reply["chain_name"].is_null()) { - Settings::getInstance()->setTestnet(reply["chain_name"].get() == "test"); + chainName = QString::fromStdString(reply["chain_name"].get()); + Settings::getInstance()->setTestnet(chainName == "test"); }; // Recurring pamynets are testnet only if (!Settings::getInstance()->isTestnet()) main->disableRecurring(); + static int lastBlock = 0; + int curBlock = reply["latest_block_height"].get(); + model->setLatestBlock(curBlock); + // Connected, so display checkmark. QIcon i(":/icons/res/connected.gif"); + main->statusLabel->setText(chainName + "(" + QString::number(curBlock) + ")"); main->statusIcon->setPixmap(i.pixmap(16, 16)); - static int lastBlock = 0; - int curBlock = reply["latest_block_height"].get(); - model->setLatestBlock(curBlock); //int version = reply["version"].get(); int version = 1; Settings::getInstance()->setZcashdVersion(version); diff --git a/src/firsttimewizard.cpp b/src/firsttimewizard.cpp index b3cf8a2..b72c373 100644 --- a/src/firsttimewizard.cpp +++ b/src/firsttimewizard.cpp @@ -127,7 +127,7 @@ RestoreSeedPage::RestoreSeedPage(FirstTimeWizard *parent) : QWizardPage(parent) bool RestoreSeedPage::validatePage() { // 1. Validate that we do have 24 words - QString seed = form.txtSeed->toPlainText().replace(QRegExp("[ \n\r]+"), " "); + QString seed = form.txtSeed->toPlainText().replace(QRegExp("[ \n\r\t]+"), " "); if (seed.trimmed().split(" ").length() != 24) { QMessageBox::warning(this, tr("Failed to restore wallet"), tr("Zecwallet needs 24 words to restore wallet"),