Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] WIP QML Load Snapshot Signet (160,000 height) #424

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -337,11 +337,14 @@ QML_RES_ICONS = \
qml/res/icons/caret-left.png \
qml/res/icons/caret-right.png \
qml/res/icons/check.png \
qml/res/icons/circle-file.png \
qml/res/icons/circle-green-check.png \
qml/res/icons/cross.png \
qml/res/icons/error.png \
qml/res/icons/export.png \
qml/res/icons/gear.png \
qml/res/icons/gear-outline.png \
qml/res/icons/green-check.png \
qml/res/icons/hidden.png \
qml/res/icons/info.png \
qml/res/icons/minus.png \
Expand Down Expand Up @@ -373,6 +376,7 @@ QML_RES_QML = \
qml/components/NetworkIndicator.qml \
qml/components/ProxySettings.qml \
qml/components/Separator.qml \
qml/components/SnapshotSettings.qml \
qml/components/StorageLocations.qml \
qml/components/StorageOptions.qml \
qml/components/StorageSettings.qml \
Expand Down Expand Up @@ -428,6 +432,7 @@ QML_RES_QML = \
qml/pages/settings/SettingsDeveloper.qml \
qml/pages/settings/SettingsDisplay.qml \
qml/pages/settings/SettingsProxy.qml \
qml/pages/settings/SettingsSnapshot.qml \
qml/pages/settings/SettingsStorage.qml \
qml/pages/settings/SettingsTheme.qml \
qml/pages/wallet/CreateBackup.qml \
Expand Down
6 changes: 6 additions & 0 deletions src/interfaces/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ class Node
//! List rpc commands.
virtual std::vector<std::string> listRpcCommands() = 0;

//! Load UTXO Snapshot.
virtual bool snapshotLoad(const std::string& path_string) = 0;

//! Get snapshot progress.
virtual double getSnapshotProgress() = 0;

//! Set RPC timer interface if unset.
virtual void rpcSetTimerInterfaceIfUnset(RPCTimerInterface* iface) = 0;

Expand Down
7 changes: 7 additions & 0 deletions src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,13 @@ class SigNetParams : public CChainParams {

vFixedSeeds.clear();

m_assumeutxo_data = MapAssumeutxo{
{
160000,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8beb50a: the signet snapshot was merged into Bitcoin Core more than a year ago in bitcoin/bitcoin@edbed31. This also seems to be using the older serialization format from before bitcoin/bitcoin#29612.

I guess that's all fine for a proof of concept, but it would be better if the main branch of this repo was more up to date.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Sjors! Thanks for taking a look and yes completely agree with:

it would be better if the main branch of this repo was more up to date

We are currently taking steps to sync with upstream, meanwhile I wanted to get the ball rolling, although I will pull in the update versions of the assume utxo functionality so that when the sync happens this PR can be merged with minimal refactoring.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing you could do is look into making a PR to the Bitcoin Core repo with your proposed interface changes. One way to go about that is to somehow use them in existing or a new RPC method. E.g. snapshot load progress is probably useful to have available.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing you could do is look into making a PR to the Bitcoin Core repo with your proposed interface changes.

That's the current medium term plan, once we have an implementation that works and makes sense here we plan to go upstream (bitcoin/bitcoin) and open a PR there.

{AssumeutxoHash{uint256S("0x5225141cb62dee63ab3be95f9b03d60801f264010b1816d4bd00618b2736e7be")}, 1278002},
},
};

base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,111);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
Expand Down
36 changes: 35 additions & 1 deletion src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <node/context.h>
#include <node/interface_ui.h>
#include <node/transaction.h>
#include <node/utxo_snapshot.h>
#include <policy/feerate.h>
#include <policy/fees.h>
#include <policy/policy.h>
Expand Down Expand Up @@ -395,9 +396,42 @@ class NodeImpl : public Node
{
m_context = context;
}
double getSnapshotProgress() override { return m_snapshot_progress.load(); }
bool snapshotLoad(const std::string& path_string) override
{
const fs::path path = fs::u8path(path_string);
if (!fs::exists(path)) { return false; }

AutoFile afile{fsbridge::fopen(path, "rb")};
if (afile.IsNull()) { return false; }

SnapshotMetadata metadata;
try {
afile >> metadata;
} catch (const std::exception& e) { return false; }

const uint256& base_blockhash = metadata.m_base_blockhash;

if (!m_context->chainman) { return false; }

ChainstateManager& chainman = *m_context->chainman;
CBlockIndex* snapshot_start_block = nullptr;

// Wait for the block to appear in the block index
//TODO: remove this once another method is implemented
constexpr int max_wait_seconds = 600; // 10 minutes
for (int i = 0; i < max_wait_seconds; ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have a blocking component here. If there are any issues we should just fail.

snapshot_start_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(base_blockhash));
if (snapshot_start_block) break;
std::this_thread::sleep_for(std::chrono::seconds(1));
}

return chainman.ActivateSnapshot(afile, metadata, false);
}
ArgsManager& args() { return *Assert(Assert(m_context)->args); }
ChainstateManager& chainman() { return *Assert(m_context->chainman); }
NodeContext* m_context{nullptr};
std::atomic<double> m_snapshot_progress{0.0};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine the actual progress should be owned by the object in charge of doing the processing. ChainStateManager?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Will set it up so that the handler notifies the snapshot progress and that ownership belongs to ChainstateManager.

};

bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active, const BlockManager& blockman)
Expand Down Expand Up @@ -510,7 +544,7 @@ class RpcHandlerImpl : public Handler
class ChainImpl : public Chain
{
public:
explicit ChainImpl(NodeContext& node) : m_node(node) {}
explicit ChainImpl(node::NodeContext& node) : m_node(node) {}
std::optional<int> getHeight() override
{
const int height{WITH_LOCK(::cs_main, return chainman().ActiveChain().Height())};
Expand Down
6 changes: 6 additions & 0 deletions src/qml/bitcoin_qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<file>components/ProxySettings.qml</file>
<file>components/StorageLocations.qml</file>
<file>components/Separator.qml</file>
<file>components/SnapshotSettings.qml</file>
<file>components/StorageOptions.qml</file>
<file>components/StorageSettings.qml</file>
<file>components/ThemeSettings.qml</file>
Expand All @@ -25,6 +26,7 @@
<file>controls/CoreTextField.qml</file>
<file>controls/ExternalLink.qml</file>
<file>controls/FocusBorder.qml</file>
<file>controls/GreenCheckIcon.qml</file>
<file>controls/Header.qml</file>
<file>controls/Icon.qml</file>
<file>controls/InformationPage.qml</file>
Expand Down Expand Up @@ -68,6 +70,7 @@
<file>pages/settings/SettingsDeveloper.qml</file>
<file>pages/settings/SettingsDisplay.qml</file>
<file>pages/settings/SettingsProxy.qml</file>
<file>pages/settings/SettingsSnapshot.qml</file>
<file>pages/settings/SettingsStorage.qml</file>
<file>pages/settings/SettingsTheme.qml</file>
<file>pages/wallet/CreateBackup.qml</file>
Expand All @@ -93,11 +96,14 @@
<file alias="caret-left">res/icons/caret-left.png</file>
<file alias="caret-right">res/icons/caret-right.png</file>
<file alias="check">res/icons/check.png</file>
<file alias="circle-file">res/icons/circle-file.png</file>
<file alias="circle-green-check">res/icons/circle-green-check.png</file>
<file alias="cross">res/icons/cross.png</file>
<file alias="error">res/icons/error.png</file>
<file alias="export">res/icons/export.png</file>
<file alias="gear">res/icons/gear.png</file>
<file alias="gear-outline">res/icons/gear-outline.png</file>
<file alias="green-check">res/icons/green-check.png</file>
<file alias="hidden">res/icons/hidden.png</file>
<file alias="info">res/icons/info.png</file>
<file alias="minus">res/icons/minus.png</file>
Expand Down
39 changes: 39 additions & 0 deletions src/qml/components/ConnectionSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,46 @@ import "../controls"
ColumnLayout {
id: root
signal next
signal gotoSnapshot
property bool snapshotImportCompleted: false
property bool onboarding: false

Component.onCompleted: {
if (!onboarding) {
snapshotImportCompleted = chainModel.isSnapshotActive
} else {
snapshotImportCompleted = false
}
}

spacing: 4
Setting {
id: gotoSnapshot
visible: !root.onboarding
Layout.fillWidth: true
header: qsTr("Load snapshot")
description: qsTr("Instant use with background sync")
actionItem: Item {
width: 26
height: 26
CaretRightIcon {
anchors.centerIn: parent
visible: !snapshotImportCompleted
color: gotoSnapshot.stateColor
}
GreenCheckIcon {
anchors.centerIn: parent
visible: snapshotImportCompleted
color: Theme.color.transparent
size: 30
}
}
onClicked: root.gotoSnapshot()
}
Separator {
visible: !root.onboarding
Layout.fillWidth: true
}
Setting {
Layout.fillWidth: true
header: qsTr("Enable listening")
Expand Down
Loading
Loading