From ee6456a43082ea5ba75e57deddb048f325987c85 Mon Sep 17 00:00:00 2001 From: levoncrypto Date: Mon, 5 Aug 2024 22:50:59 +0400 Subject: [PATCH] Wallet scan optimisation --- src/qt/forms/notifymnemonic.ui | 12 +++++- src/qt/forms/recover.ui | 67 +++++++++++++++++++++++++--------- src/qt/notifymnemonic.cpp | 6 +++ src/qt/recover.cpp | 20 ++++++++++ src/qt/recover.h | 1 + src/wallet/wallet.cpp | 36 ++++++++++++++++-- src/wallet/wallet.h | 1 + 7 files changed, 122 insertions(+), 21 deletions(-) diff --git a/src/qt/forms/notifymnemonic.ui b/src/qt/forms/notifymnemonic.ui index 7a47de8f6f..837e02e9b0 100644 --- a/src/qt/forms/notifymnemonic.ui +++ b/src/qt/forms/notifymnemonic.ui @@ -108,11 +108,21 @@ + + + + + + + + true + + - Please write down these recovery seed phrase and keep them in a secure location. + Please write down these recovery seed phrase and wallet birth date and keep them in a secure location. Specifying the wallet's birth date when restoring your wallet speeds up and optimizes the scanning of your wallet. true diff --git a/src/qt/forms/recover.ui b/src/qt/forms/recover.ui index f8a3db384b..f10691d2ef 100644 --- a/src/qt/forms/recover.ui +++ b/src/qt/forms/recover.ui @@ -41,6 +41,7 @@ You can also choose to further encrypt your recovery seed phrase with an additio You will need to save this passphrase as well with the recovery seed phrase. Failing to save the passphrase will lead to your funds being irrecoverable. If you have an existing recovery seed phrase, please select "Recover existing wallet". If you have secured your recovery seed phrase with an additional passphrase, enter it too. +Also you can choose wallet birth date for more faster and optimised wallet scan. @@ -134,20 +135,58 @@ If you have an existing recovery seed phrase, please select "Recover existing wa - + - - - Input recovery seed phrase here: - - - true - - + + + + + Input recovery seed phrase here: + + + true + + + + + + + - - + + + + + Choose the wallet creation date: + + + true + + + + + + + Enable Date Selection + + + + + + + true + + + dd-MM-yyyy + + + + + + + + @@ -234,12 +273,6 @@ If you have an existing recovery seed phrase, please select "Recover existing wa - - - - - color:red; - diff --git a/src/qt/notifymnemonic.cpp b/src/qt/notifymnemonic.cpp index 92ee78f37f..118cb868b3 100644 --- a/src/qt/notifymnemonic.cpp +++ b/src/qt/notifymnemonic.cpp @@ -13,6 +13,7 @@ #include #include #include +#include NotifyMnemonic::NotifyMnemonic(QWidget *parent) : QWizard(parent), @@ -36,6 +37,10 @@ void NotifyMnemonic::cancelEvent() } } +QString getCurrentDate() { + return QDate::currentDate().toString("dd-MM-yyyy"); +} + void NotifyMnemonic::notify() { #ifdef ENABLE_WALLET @@ -44,6 +49,7 @@ void NotifyMnemonic::notify() NotifyMnemonic notify; notify.setWindowIcon(QIcon(":icons/firo")); notify.show(); + notify.ui->walletBirthDate->setText("Wallet creation date: " + getCurrentDate()); notify.ui->mnemonic->setText(mnemonic.c_str()); notify.restart(); while(true) diff --git a/src/qt/recover.cpp b/src/qt/recover.cpp index ba0611bebf..3e5c20da58 100644 --- a/src/qt/recover.cpp +++ b/src/qt/recover.cpp @@ -31,6 +31,8 @@ Recover::Recover(QWidget *parent) : connect(this, &Recover::stopThread, thread, &QThread::quit); thread->start(); + + connect(ui->enableDateSelection, &QCheckBox::toggled, this, &Recover::updateDateInputState); } Recover::~Recover() @@ -47,6 +49,9 @@ void Recover::setCreateNew() ui->textLabel2->setEnabled(false); ui->mnemonicWords->setEnabled(false); ui->mnemonicWords->clear(); + ui->dateInput->setEnabled(false); + ui->dateInput->clear(); + ui->enableDateSelection->setEnabled(false); ui->use24->setChecked(true); ui->usePassphrase->setChecked(false); ui->textLabel3->setEnabled(false); @@ -55,6 +60,13 @@ void Recover::setCreateNew() ui->mnemonicPassPhrase2->setEnabled(false); } +void Recover::updateDateInputState(bool checked) { + ui->dateInput->setEnabled(checked); + if (checked) { + ui->dateInput->setMinimumDate(QDate(2020, 3, 23)); + } +} + void Recover::on_createNew_clicked() { setCreateNew(); @@ -64,6 +76,9 @@ void Recover::on_recoverExisting_clicked() { ui->textLabel2->setEnabled(true); ui->mnemonicWords->setEnabled(true); + ui->dateInput->setEnabled(true); + ui->dateInput->setEnabled(ui->enableDateSelection->isChecked()); + ui->enableDateSelection->setEnabled(true); } void Recover::on_usePassphrase_clicked() @@ -106,6 +121,11 @@ bool Recover::askRecover(bool& newWallet) if(recover.ui->recoverExisting->isChecked()) { newWallet = false; std::string mnemonic = recover.ui->mnemonicWords->text().toStdString(); + if (recover.ui->enableDateSelection->isChecked()) { + SoftSetArg("-wcdate", recover.ui->dateInput->text().toStdString()); + } else { + SoftSetArg("-wcdate", ""); + } const char* str = mnemonic.c_str(); bool space = true; int n = 0; diff --git a/src/qt/recover.h b/src/qt/recover.h index d91321e27b..2b918883d9 100644 --- a/src/qt/recover.h +++ b/src/qt/recover.h @@ -22,6 +22,7 @@ class Recover : public QDialog void stopThread(); private Q_SLOTS: + void updateDateInputState(bool checked); void on_createNew_clicked(); void on_recoverExisting_clicked(); void on_usePassphrase_clicked(); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 03bc7e6c52..6cb3962300 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2364,6 +2364,28 @@ void CWalletTx::GetAmounts(std::list& listReceived, } +static std::time_t parseDate(const std::string& dateStr) { + std::tm tm = {}; + std::istringstream ss(dateStr); + ss >> std::get_time(&tm, "%d-%m-%Y"); + return std::mktime(&tm); +} + +int CWallet::GetBlockHeightByDate(CBlockIndex* pindexStart, const std::string& dateStr) { + std::time_t targetTimestamp = parseDate(dateStr); + + CBlockIndex* pindex = pindexStart; + + while (pindex) { + if (pindex->GetBlockTime() > targetTimestamp) { + return pindex->nHeight - 200; + } + pindex = chainActive.Next(pindex); + } + + return chainActive.Tip()->nHeight; +} + /** * Scan the block chain (starting in pindexStart) for transactions * from or to us. If fUpdate is true, found transactions that already @@ -2387,9 +2409,17 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex *pindexStart, bool f // our wallet birthday (as adjusted for block time variability) // if you are recovering wallet with mnemonics start rescan from block when mnemonics implemented in Firo if (fRecoverMnemonic) { - pindex = chainActive[chainParams.GetConsensus().nMnemonicBlock]; - if (pindex == NULL) - pindex = chainActive.Tip(); + std::string wcdate = GetArg("-wcdate", ""); + CBlockIndex* mnemonicStartBlock = chainActive[chainParams.GetConsensus().nMnemonicBlock]; + if (!wcdate.empty()) { + int targetHeight = GetBlockHeightByDate(mnemonicStartBlock, wcdate); + if (targetHeight <= 0) { + targetHeight = chainParams.GetConsensus().nMnemonicBlock; + } + pindex = chainActive[targetHeight]; + } else { + pindex = mnemonicStartBlock; + } } else while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200))) pindex = chainActive.Next(pindex); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index ab6e98fd7d..1d53bf3a23 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -929,6 +929,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock) override; bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate); CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false, bool fRecoverMnemonic = false); + int GetBlockHeightByDate(CBlockIndex* pindexStart, const std::string& dateStr); void ReacceptWalletTransactions(); void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override; std::vector ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman);