Skip to content

QML Snapshot Load#488

Open
D33r-Gee wants to merge 3 commits intobitcoin-core:qt6from
D33r-Gee:alt-qml-snapshotload
Open

QML Snapshot Load#488
D33r-Gee wants to merge 3 commits intobitcoin-core:qt6from
D33r-Gee:alt-qml-snapshotload

Conversation

@D33r-Gee
Copy link
Copy Markdown
Contributor

@D33r-Gee D33r-Gee commented Jul 31, 2025

This is an re-opened PR based on #424 and #449. It's an alternate to #485 that uses a different /bitcoin branch instead of a patch.

UTXO Snapshot Loading

Overview

This PR enables loading UTXO snapshots both during and after the initial onboarding process.

What This PR Does

  1. Adds a basic GUI interface for loading UTXO snapshots via the Connection Settings panel
  2. Enables snapshot selection during onboarding, with loading when headers are synced
  3. Implements non-blocking snapshot loading via QT Thread
  4. Provides visual confirmation of snapshot activation
  5. Adds a snapshot progress notifications accessible via a handler

Implementation Details

Core Components Modified

  1. CPP Backend (qml/models/nodemodel.cpp)
  • Manages snapshot loading state and progress
  • Uses Qt's thread system to prevent UI blocking
  • Provides progress updates via Qt signals
  • Adds support for storing snapshot file path during onboarding
  • Implements automatic snapshot loading once headers are synced
  1. UI Components (qml/components/SnapshotLoadSettings.qml, src/qml/components/ConnectionSettings.qml)
  • File selection dialog with onboarding awareness
  • Snapshot verification status
  • Progress tracking and visualization
  • Updated visibility conditions to enable loading during onboarding
  1. Snapshot Qml Model (qml/models/snapshotqml.cpp)
  • Introduces a worker class to manage snapshot metadata

Key Design Decisions

  1. Onboarding Integration
  • Allows users to select snapshot during setup
  • Delayed loading until headers are synced
  • Proper state handling between onboarding and regular modes

Testing Instructions

  1. Build
  2. Launch Bitcoin Core QML GUI
  3. Navigate to Connection Settings
  4. Test with different snapshots:
mainnet: magnet:?xt=urn:btih:559bd78170502971e15e97d7572e4c824f033492&dn=utxo-880000.dat&tr=udp%3A%2F%2Ftracker.bitcoin.sprovoost.nl%3A6969

alternatively, you can use the following link to download the mainnet snapshot: https://bitcoin-snapshots.jaonoctus.dev/

signet: https://drive.google.com/file/d/1VJeeGQncrs4xZhh6kU5IwkyatXVM4SOm/view?usp=sharing
  1. Test onboarding flow:

    • Select a snapshot file during initial setup
    • Verify it loads automatically after headers sync
  2. Verify (see screenshots below):

    • "Snapshot Loaded" confirmation appears
    • For errors, check debug.log for [snapshot]
Ubuntu 22.04 Screenshots

Screenshot 2025-05-05 154558
Screenshot 2025-05-05 154615
qt6_loading_snapshot_dialog
Screenshot 2025-05-05 154703
Screenshot 2025-05-05 154720
Screenshot 2025-07-30 103140

Expected Behavior

  • File selection dialog works
  • Node becomes usable while background validation continues
  • When selected during onboarding, snapshot loads after headers sync
Success/failure state properly displayed Screenshot 2025-07-30 101752

feedback welcome on the approach and implementation details.

@D33r-Gee D33r-Gee force-pushed the alt-qml-snapshotload branch 3 times, most recently from 26a2e0f to 5e561ef Compare August 1, 2025 16:48
@D33r-Gee D33r-Gee changed the title ALT QML Snapshot Load QML Snapshot Load Aug 4, 2025
@pinheadmz
Copy link
Copy Markdown
Contributor

I don't know why CI is able to build, I am failing locally which makes sense because .gitmodules is still pointing at bitcoin core:

--> cat .gitmodules 
[submodule "bitcoin"]
	path = bitcoin
	url = https://github.com/bitcoin/bitcoin

but your commit is not part of that repo, so I get:

--> git submodule update --init
Submodule 'bitcoin' (https://github.com/bitcoin/bitcoin) registered for path 'bitcoin'
Cloning into '/Users/matthewzipkin/Desktop/work/gui-qml/bitcoin'...
fatal: transport 'file' not allowed
fatal: Fetched in submodule path 'bitcoin', but it did not contain c29a5df51402b85fb335b0d16e3016e984224d90. Direct fetching of that commit failed.

I am still trying to figure out what the "file" protocol message is about but otherwise I sort of expected to see this error in CI as well. ChatGPT suspects that the github "checkout" action may have access to some huge github-wide cache and is somehow able to look up c29a... even though it actually lives in https://github.com/D33r-Gee/bitcoin/tree/interface-load-snapshot

@pinheadmz
Copy link
Copy Markdown
Contributor

The fix for me locally which I think should be part of the PR is:

diff --git a/.gitmodules b/.gitmodules
index fabdfe506..03c475675 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
 [submodule "bitcoin"]
        path = bitcoin
-       url = https://github.com/bitcoin/bitcoin
+       url = https://github.com/D33r-Gee/bitcoin

Then I executed:

git submodule sync
git submodule update --init

This tells git to re-read .gitmodules so it sees the new repo, then the update command pulls that and can fetch the specified commit:

Submodule path 'bitcoin': checked out 'c29a5df51402b85fb335b0d16e3016e984224d90'

@pinheadmz
Copy link
Copy Markdown
Contributor

concept and tested ACK, no code review yet

Screenshot 2025-08-04 at 1 45 27 PM
--> bitcoin-cli -datadir=/Users/matthewzipkin/Desktop/asutxo/ gettxoutsetinfo
{
  "height": 880355,
  "bestblock": "000000000000000000027d56fb62e21d05bc0626334ece51e780bc68b5e7e1ea",
  "txouts": 184590802,
  "bogosize": 14352668388,
  "hash_serialized_3": "fd3028844649c086e0223880e3b1f8b271775a549598c22ad12792c27553c98f",
  "total_amount": 19813391.91492533,
  "transactions": 128585770,
  "disk_size": 12552553130
}

@D33r-Gee
Copy link
Copy Markdown
Contributor Author

D33r-Gee commented Aug 5, 2025

concept and tested ACK, no code review yet

Thanks for testing @pinheadmz !

As you saw currently updating the upstream portion which will impact code review here.

Ultimately, the snapshot processing (path → file & metadata) will be moved there. Once the flow is more solid in that location, I’ll update the code here accordingly by removing the models/snapshotqml files and updating the snapshot info retrieval method.

@D33r-Gee D33r-Gee force-pushed the alt-qml-snapshotload branch 2 times, most recently from daf644c to a05e12c Compare August 7, 2025 18:42
@D33r-Gee
Copy link
Copy Markdown
Contributor Author

D33r-Gee commented Aug 7, 2025

with a05e12c addresses @pinheadmz comment about pointing the submodule url to my repo

daf644c squashed the snapshot loading functionality into one commit and has been updated with new interface from upstream (bitcoin/bitcoin PR#33117)

@pinheadmz
Copy link
Copy Markdown
Contributor

Reviewing bitcoin/bitcoin#33117 along with this but theres a new issue building QML with bitcoin core as a subtree.

From ChatGPT:

This is a classic Qt MOC vs modern C++ (concepts) incompatibility issue.
What’s happening
The error:
usr/include/c++/12/concept:46:1: error: Parse error at "std"
comes from Qt’s moc (Meta-Object Compiler), not your compiler.
moc is trying to parse a header that includes or indirectly pulls in (C++20), which it does not fully understand.

from the compiler:

[ 88%] Automatic MOC and UIC for target bitcoinqml

AutoMoc subprocess error
------------------------
The moc process failed to compile
  "SRC:/qml/models/chainmodel.h"
into
  "SRC:/build/bitcoinqml_autogen/THJWCQWZAR/moc_chainmodel.cpp"

Command
-------
/usr/lib/qt6/libexec/moc -DBOOST_ALL_NO_LIB -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_NO_CXX98_FUNCTION_BASE -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_NO_DEBUG -
DQT_NO_KEYWORDS -DQT_OPENGL_LIB -DQT_QMLINTEGRATION_LIB -DQT_QMLMODELS_LIB -DQT_QML_LIB -DQT_QUICKCONTROLS2_LIB -DQT_QUICK_LIB -DQT_USE_QSTRINGBUILDER -DQT_WIDGETS_LIB -I/mnt/massive/work/gui-qml -I/mnt/massive/work/gui-qml/bitcoin/src -I/mnt/massive/work/gui-qml/bitcoin/src/qt -I/mnt/massive/work/gui-qml/build/bitcoin/src -I/mnt/massive/work/gui-qml/bitcoin/src/univalue/include -I/usr/include/x86_64-linux-gnu/qt6/QtQml -I/usr/include/x86_64-linux-gnu/qt6 -I/usr/include/x86_64-linux-gnu/qt6/QtCore -I/usr/lib/x86_64-linux-gnu/qt6/mkspecs/linux-g++ -I/usr/include/x86_64-linux-gnu/qt6/QtQmlIntegration -I/usr/include/x86_64-linux-gnu/qt6/QtNetwork -I/usr/include/x86_64-linux-gnu/qt6/QtQuick -I/usr/include/x86_64-linux-gnu/qt6/QtGui -I/usr/include/x86_64-linux-gnu/qt6/QtQmlModels -I/usr/include/x86_64-linux-gnu/qt6/QtOpenGL -I/usr/include/x86_64-linux-gnu/qt6/QtQuickControls2 -I/usr/include/x86_64-linux-gnu/qt6/QtWidgets -I/usr/include -I/usr/include/c++/12 -I/usr/include/x86_64-linux-gnu/c++/12 -I/usr/include/c++/12/backward -I/usr/lib/gcc/x86_64-linux-gnu/12/include -I/usr/local/include -I/usr/include/x86_64-linux-gnu --include /mnt/massive/work/gui-qml/build/bitcoinqml_autogen/moc_predefs.h -I/mnt/massive/work/gui-qml/qml --output-dep-file -o /mnt/massive/work/gui-qml/build/bitcoinqml_autogen/THJWCQWZAR/moc_chainmodel.cpp /mnt/massive/work/gui-qml/qml/models/chainmodel.h

Output
------
usr/include/c++/12/concept:46:1: error: Parse error at "std"

gmake[2]: *** [CMakeFiles/bitcoinqml_autogen.dir/build.make:71: CMakeFiles/bitcoinqml_autogen] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:491: CMakeFiles/bitcoinqml_autogen.dir/all] Error 2
gmake[1]: *** Waiting for unfinished jobs....

D33r-Gee added 2 commits April 2, 2026 14:17
- This introduce the UI flow to load a AssumeUTXO snapshot
- It modifies the connection settings
- Adds a SnapshotLoadSettings file, Icon, and modified progress
bar.
- Also it adds error page on snapshotloading failure
	-Also pointing url to D33r-Gee /bitcoin repository
@D33r-Gee D33r-Gee force-pushed the alt-qml-snapshotload branch 2 times, most recently from c42ad64 to 72c1458 Compare April 3, 2026 19:38
Addresses multiple compilation and runtime issues introduced by incoming interface updates:

- qml/bitcoin.cpp: Update ThreadSafeMessageBox UI callback signature and switch LogPrintf to LogInfo.
- qml/models/chainmodel.cpp: Avoid calling getBlockHash on a hardcoded snapshot height that is not yet locally fetched; use AssumeutxoData.blockhash natively to prevent out-of-bound crashes.
- qml/models/chainmodel.h: Guard out chain headers with Q_MOC_RUN to avoid standard-concept parser errors inside QT automoc.
- qml/models/options_model.cpp: Add inline SettingToInt/SettingToBool helpers to operate safely over common::SettingsValue.
- qml/models/peerdetailsmodel.h: Fallback to the new presync_height field dynamically inside CNodeStateStats as m_starting_height has been deprecated.
- qml/models/walletqmlmodel.cpp: Supply std::nullopt to correctly satisfy the modernized interfaces::Wallet::createTransaction 4-argument parameters interface.
- qml/models/transaction.cpp & walletqmlmodel.cpp: Drop obsolete uint256::FromUint256 wrappers in favor of executing the respective Txid.ToUint256() functionality.
- qml/peerstatsutil.cpp: Add missing PRIVATE_BROADCAST enum handling inside ConnectionTypeToQString mapping.
- test/mocks/mocknode.h: Update getProxy signature and insert missing snapshot & handleSnapshotLoadProgress mock definitions.
- qml/walletqmlcontroller.cpp: Provide true for the trailing `load_after_restore` argument on interfaces::WalletLoader::restoreWallet.
- qml/models/walletqmlmodel.cpp: Drop trailing nullptr (purpose) as the updated interfaces::Wallet::getAddress now strictly asks for 3 parameters.
@D33r-Gee D33r-Gee force-pushed the alt-qml-snapshotload branch from 72c1458 to a904558 Compare April 3, 2026 20:34
@D33r-Gee
Copy link
Copy Markdown
Contributor Author

D33r-Gee commented Apr 6, 2026

with a904558 addressed the rebasing upstream issues that @pinheadmz brought up (Thanks for that)

Also added a commit to address the discrepancies between the qt6 submodule branch and upstream.

Regarding the macos-14 CLI failure, not quite sure how to address that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants