fix rescan crash: use clear+resync instead of reinitializing lightclient
This commit is contained in:
@@ -14,5 +14,5 @@
|
||||
|
||||
| File | SHA-256 |
|
||||
|---|---|
|
||||
| `SilentDragonXLite` (Linux) | `bc5e0020d784a905e2d461ccb5b4c5da4436072245370ec9e09a17e9e7ad0307` |
|
||||
| `SilentDragonXLite.exe` (Windows) | `47f45ff44521eb46ee87189ee2318d0ca61f44b39c2a9d875e1a3d7329700df8` |
|
||||
| `SilentDragonXLite` (Linux) | `9f60380b66bbe10366f216457273e648c50831ee8da3b8486ca87a21629a4b22` |
|
||||
| `SilentDragonXLite.exe` (Windows) | `26f05e534e4337fac48f6fd36ba17a7de80571e1e565944a7d104ef9419d5efb` |
|
||||
|
||||
Binary file not shown.
@@ -160,148 +160,18 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
// Rescan
|
||||
QObject::connect(ui->actionRescan, &QAction::triggered, [=]() {
|
||||
DEBUG("rescan action triggered");
|
||||
Ui_Restore restoreSeed;
|
||||
QDialog dialog(this);
|
||||
restoreSeed.setupUi(&dialog);
|
||||
Settings::saveRestore(&dialog);
|
||||
|
||||
rpc->fetchSeed([=](json reply) {
|
||||
if (isJsonError(reply)) {
|
||||
return;
|
||||
}
|
||||
|
||||
restoreSeed.seed->setReadOnly(true);
|
||||
restoreSeed.seed->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap);
|
||||
QString seedJson = QString::fromStdString(reply["seed"].get<json::string_t>());
|
||||
restoreSeed.seed->setPlainText(seedJson);
|
||||
|
||||
QString birthday = QString::number(reply["birthday"].get<json::number_unsigned_t>());
|
||||
restoreSeed.birthday->setPlainText(birthday);
|
||||
});
|
||||
|
||||
QObject::connect(restoreSeed.restore, &QPushButton::clicked, [&](){
|
||||
|
||||
QString seed = restoreSeed.seed->toPlainText();
|
||||
if (seed.trimmed().split(" ").length() != 24) {
|
||||
QMessageBox::warning(this, tr("Failed to restore wallet"),
|
||||
tr("SilentDragonXLite needs 24 words to restore wallet"),
|
||||
QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 2. Validate birthday
|
||||
QString birthday_str = restoreSeed.birthday->toPlainText().trimmed();
|
||||
bool ok;
|
||||
qint64 birthday = 0;
|
||||
if (birthday_str.isEmpty()) {
|
||||
ok = true;
|
||||
} else {
|
||||
birthday = birthday_str.toUInt(&ok);
|
||||
}
|
||||
if (!ok) {
|
||||
QMessageBox::warning(this, tr("Failed to parse wallet birthday"),
|
||||
tr("Couldn't understand wallet birthday. This should be a block height from where to rescan the wallet. You can leave it as '0' if you don't know what it should be."),
|
||||
QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QString number_str = restoreSeed.quantity->text();
|
||||
qint64 number = number_str.toUInt();
|
||||
|
||||
auto config = std::shared_ptr<ConnectionConfig>(new ConnectionConfig());
|
||||
config->server = Settings::getInstance()->getSettings().server;
|
||||
// 3. Attempt to restore wallet with the seed phrase
|
||||
{
|
||||
QString reply = "";
|
||||
try {
|
||||
char* resp = litelib_initialize_new_from_phrase(config->dangerous, config->server.toStdString().c_str(),
|
||||
seed.toStdString().c_str(), birthday, number, true);
|
||||
reply = litelib_process_response(resp);
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
|
||||
}
|
||||
|
||||
if (reply.toUpper().trimmed() != "OK") {
|
||||
qDebug() << "Lite server " << config->server << " is down, getting a random one";
|
||||
config->server = Settings::getRandomServer();
|
||||
qDebug() << __func__ << ": new server is " << config->server;
|
||||
// retry with the new server
|
||||
char* resp = litelib_initialize_new_from_phrase(config->dangerous,config->server.toStdString().c_str(),
|
||||
seed.toStdString().c_str(), birthday, number, true);
|
||||
reply = litelib_process_response(resp);
|
||||
}
|
||||
|
||||
if (reply.toUpper().trimmed() != "OK") {
|
||||
QMessageBox::warning(this, tr("Failed to restore wallet"),
|
||||
tr("Couldn't restore the wallet") + "\n" + "server=" + config->server + "\n" + reply,
|
||||
QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Finally attempt to save the wallet
|
||||
{
|
||||
QString reply = "";
|
||||
try {
|
||||
char* resp = litelib_execute("save", "");
|
||||
QString reply = litelib_process_response(resp);
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << __func__ << ": caught an exception, ignoring: " << e.what();
|
||||
}
|
||||
|
||||
if (reply.isEmpty()) {
|
||||
qDebug() << "Lite server " << config->server << " is down, getting a random one";
|
||||
config->server = Settings::getRandomServer();
|
||||
qDebug() << __func__ << ": new server is " << config->server;
|
||||
// make a new connection to the new server
|
||||
char* resp = litelib_initialize_new_from_phrase(config->dangerous,config->server.toStdString().c_str(),
|
||||
seed.toStdString().c_str(), birthday, number, true);
|
||||
reply = litelib_process_response(resp);
|
||||
|
||||
// retry with the new server
|
||||
try {
|
||||
resp = litelib_execute("save", "");
|
||||
reply = litelib_process_response(resp);
|
||||
} catch (const std::exception& e) {
|
||||
qDebug() << __func__ << ": caught an exception with new server, something is fucky: " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QByteArray ba_reply = reply.toUtf8();
|
||||
QJsonDocument jd_reply = QJsonDocument::fromJson(ba_reply);
|
||||
QJsonObject parsed = jd_reply.object();
|
||||
|
||||
if (parsed.isEmpty() || parsed["result"].isNull()) {
|
||||
QMessageBox::warning(this, tr("Failed to save wallet"),
|
||||
tr("Couldn't save the wallet") + "\n" + "server=" + config->server + "\n" + reply,
|
||||
QMessageBox::Ok);
|
||||
|
||||
} else {
|
||||
qDebug() << __func__ << ": saved wallet correctly";
|
||||
}
|
||||
|
||||
dialog.close();
|
||||
// To rescan, we clear the wallet state, and then reload the connection
|
||||
// This will start a sync, and show the scanning status.
|
||||
this->getRPC()->clearWallet([=] (auto) {
|
||||
qDebug() << "Clearing wallet...";
|
||||
// Save the wallet
|
||||
// Clear the wallet state and resync from the birthday height.
|
||||
// This uses the existing LightClient — no need to reinitialize.
|
||||
this->getRPC()->clearWallet([=] (auto) {
|
||||
qDebug() << "Clearing wallet state for rescan...";
|
||||
this->getRPC()->saveWallet([=] (auto) {
|
||||
qDebug() << "Saving wallet...";
|
||||
// Then reload the connection. The ConnectionLoader deletes itself.
|
||||
auto cl = new ConnectionLoader(this, rpc);
|
||||
cl->loadConnection();
|
||||
qDebug() << "Saved cleared wallet, reloading connection to start rescan...";
|
||||
auto cl = new ConnectionLoader(this, rpc);
|
||||
cl->loadConnection();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
dialog.exec();
|
||||
}); // actionReason
|
||||
}); // actionRescan
|
||||
|
||||
// Import Privkey
|
||||
QObject::connect(ui->actionImport_Privatkey, &QAction::triggered, this, &MainWindow::importPrivKey);
|
||||
|
||||
Reference in New Issue
Block a user