Skip to content

Commit abce367

Browse files
committed
poc: Load snapshot through the options dialog
This is a quick and dirty POC to showcase and test the load snapshot functionality. This is by no means meant to be a robust approach...
1 parent 5e0b38e commit abce367

File tree

5 files changed

+111
-0
lines changed

5 files changed

+111
-0
lines changed

src/qt/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ add_library(bitcoinqt STATIC EXCLUDE_FROM_ALL
116116
qvaluecombobox.h
117117
rpcconsole.cpp
118118
rpcconsole.h
119+
snapshotmodel.cpp
120+
snapshotmodel.h
119121
splashscreen.cpp
120122
splashscreen.h
121123
trafficgraphwidget.cpp

src/qt/optionsdialog.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <qt/guiconstants.h>
1313
#include <qt/guiutil.h>
1414
#include <qt/optionsmodel.h>
15+
#include <qt/snapshotmodel.h>
1516

1617
#include <common/system.h>
1718
#include <interfaces/node.h>
@@ -25,6 +26,7 @@
2526
#include <QApplication>
2627
#include <QDataWidgetMapper>
2728
#include <QDir>
29+
#include <QFileDialog>
2830
#include <QFontDialog>
2931
#include <QIntValidator>
3032
#include <QLocale>
@@ -121,6 +123,10 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet)
121123
connect(ui->connectSocksTor, &QPushButton::toggled, ui->proxyPortTor, &QWidget::setEnabled);
122124
connect(ui->connectSocksTor, &QPushButton::toggled, this, &OptionsDialog::updateProxyValidationState);
123125

126+
QPushButton* loadSnapshotButton = new QPushButton(tr("Load Snapshot..."), this);
127+
ui->verticalLayout_Main->insertWidget(ui->verticalLayout_Main->indexOf(ui->enableServer) + 1, loadSnapshotButton);
128+
connect(loadSnapshotButton, &QPushButton::clicked, this, &OptionsDialog::on_loadSnapshotButton_clicked);
129+
124130
/* Window elements init */
125131
#ifdef Q_OS_MACOS
126132
/* remove Window tab on Mac */
@@ -400,6 +406,34 @@ void OptionsDialog::on_showTrayIcon_stateChanged(int state)
400406
}
401407
}
402408

409+
void OptionsDialog::on_loadSnapshotButton_clicked()
410+
{
411+
QString snapshotFile = QFileDialog::getOpenFileName(this,
412+
tr("Select Snapshot File"), "",
413+
tr("Bitcoin Snapshot Files (*.dat);;All Files (*)"));
414+
415+
if (snapshotFile.isEmpty())
416+
return;
417+
418+
QMessageBox::StandardButton reply = QMessageBox::question(this,
419+
tr("Load Snapshot"),
420+
tr("Loading a snapshot will require restarting Bitcoin. The current blockchain data will be replaced with the snapshot data. Are you sure you want to proceed?"),
421+
QMessageBox::Yes|QMessageBox::No);
422+
423+
if (reply == QMessageBox::Yes) {
424+
SnapshotModel snapshotModel(model->node(), snapshotFile);
425+
if (snapshotModel.processPath()) {
426+
QMessageBox::information(this,
427+
tr("Snapshot loaded successfully"),
428+
tr("The snapshot has been loaded successfully. You can now start the client with the new snapshot."));
429+
} else {
430+
QMessageBox::critical(this,
431+
tr("Error"),
432+
tr("Failed to load the snapshot. Please ensure the file is a valid snapshot and try again."));
433+
}
434+
}
435+
}
436+
403437
void OptionsDialog::togglePruneWarning(bool enabled)
404438
{
405439
ui->pruneWarning->setVisible(!ui->pruneWarning->isVisible());

src/qt/optionsdialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ private Q_SLOTS:
5858
void on_openBitcoinConfButton_clicked();
5959
void on_okButton_clicked();
6060
void on_cancelButton_clicked();
61+
void on_loadSnapshotButton_clicked();
62+
6163

6264
void on_showTrayIcon_stateChanged(int state);
6365

src/qt/snapshotmodel.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2024 - present The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qt/snapshotmodel.h>
6+
7+
#include <interfaces/node.h>
8+
#include <node/context.h>
9+
#include <node/utxo_snapshot.h>
10+
#include <clientversion.h>
11+
#include <validation.h>
12+
#include <util/fs.h>
13+
#include <util/fs_helpers.h>
14+
15+
SnapshotModel::SnapshotModel(interfaces::Node& node, QString path)
16+
: m_node(node), m_path(path) {}
17+
18+
bool SnapshotModel::processPath()
19+
{
20+
ChainstateManager& chainman = *m_node.context()->chainman;
21+
const fs::path snapshot_path = fs::u8path(m_path.toStdString());
22+
if (!fs::exists(snapshot_path)) {
23+
return false;
24+
}
25+
26+
FILE* snapshot_file{fsbridge::fopen(snapshot_path, "rb")};
27+
AutoFile coins_file{snapshot_file};
28+
if (coins_file.IsNull()) {
29+
return false;
30+
}
31+
32+
node::SnapshotMetadata metadata{chainman.GetParams().MessageStart()};
33+
try {
34+
coins_file >> metadata;
35+
} catch (const std::exception& e) {
36+
return false;
37+
}
38+
39+
bool result = m_node.loadSnapshot(coins_file, metadata, false);
40+
if (!result) {
41+
return false;
42+
}
43+
44+
return true;
45+
}

src/qt/snapshotmodel.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2024 - present The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QT_SNAPSHOTMODEL_H
6+
#define BITCOIN_QT_SNAPSHOTMODEL_H
7+
8+
#include <QObject>
9+
#include <interfaces/node.h>
10+
#include <node/context.h>
11+
#include <node/utxo_snapshot.h>
12+
13+
/** Model for snapshot operations. */
14+
class SnapshotModel : public QObject
15+
{
16+
Q_OBJECT
17+
18+
public:
19+
SnapshotModel(interfaces::Node& node, QString path);
20+
21+
bool processPath();
22+
23+
private:
24+
interfaces::Node& m_node;
25+
QString m_path;
26+
};
27+
28+
#endif // BITCOIN_QT_SNAPSHOTMODEL_H

0 commit comments

Comments
 (0)