diff options
author | Jonas Schnelli <dev@jonasschnelli.ch> | 2019-09-12 14:59:58 +0200 |
---|---|---|
committer | Jonas Schnelli <dev@jonasschnelli.ch> | 2019-09-12 15:00:51 +0200 |
commit | 884f7cc81b478b599ed8d43ebe80578ea9cdb279 (patch) | |
tree | e2f765704678317f217c4df6ecc5e077f2c847a9 /src/qt | |
parent | ca97d292ce60f672cc71610c9e2fb76f57d768fc (diff) | |
parent | 9924bce317b96ab0c57efb99330abd11b6f16b9a (diff) |
Merge #16714: gui: add prune to intro screen with smart default
9924bce317b96ab0c57efb99330abd11b6f16b9a [gui] intro: enable pruning by default unless disk is big (Sjors Provoost)
c8de347a9d6c88fe67d77aba6fcce1b7fd66791c [gui] intro: add prune preference (Sjors Provoost)
1bbc49d2078ee53488e214d00eb47462687b05c5 [gui] intro: inform caller if intro was shown (Sjors Provoost)
1957103786f97135f35ababc97efa1b481865eb0 [gui] add explicit prune setter (Sjors Provoost)
1bccf6a52d7fc08d8f605cfb2edc3277ec299c72 [node] add forceSetArg to interface (Sjors Provoost)
Pull request description:
This adds a checkbox to the intro screen to enable pruning from the get go.
If the user has plenty of space, it's unchecked by default:
<img width="671" alt="big" src="https://user-images.githubusercontent.com/10217/63641289-10339000-c6ac-11e9-98d7-caf64dff0da6.png">
If the user has insufficient space it's checked by default:
<img width="897" alt="low" src="https://user-images.githubusercontent.com/10217/63641276-d4002f80-c6ab-11e9-9f5b-a53472f814ff.png">
When the user has barely enough space and is likely to need pruning in the near future, this is shown in yellow and we also check the prune box:
<img width="662" alt="medium" src="https://user-images.githubusercontent.com/10217/63641294-1c1f5200-c6ac-11e9-8ecb-6b69e42b1ece.png">
The cut-off for this 10 GB above `m_assumed_blockchain_size` (`=240` in `chainparams.cpp`).
If the user launches the first time with `-prune=...` then we disable the check box and display the correct size (rounded to GB):
<img width="658" alt="Schermafbeelding 2019-08-24 om 20 23 14" src="https://user-images.githubusercontent.com/10217/63641351-09594d00-c6ad-11e9-94fe-fe5ed562e109.png">
The 2 GB default matches the settings default. The user can't change it in the intro screen, but can change it later. I'm tempted to increase that default to 10 GB, and then have the intro screen reduce it if space is really tight.
Tips for testing:
* move your existing data dir elsewhere
* wipe data dir at every restart (behavior is different if it exists)
* launch with `bitcoin-qt -resetguisettings -lang=en` (there's some space issues in different languages)
* fake your free space by changing `intro.cpp` line 90: `freeBytesAvailable = 5000000000; // 5 GB`
* try both testnet and mainnet, because settings are seperate. In particular note how step 7 in `GuiMain` switches where `QTSettings settings` points to; this had me thoroughly confused on testnet, because I was setting them too early.
ACKs for top commit:
jonasschnelli:
Tested ACK 9924bce317b96ab0c57efb99330abd11b6f16b9a
ryanofsky:
utACK 9924bce317b96ab0c57efb99330abd11b6f16b9a. The changes are very logical, and implement the feature in a clean that way that doesn't add a lot of complication and shouldn't interfere with future improvements. I looked at Luke's branch too, and I think there's also a lot of great stuff there that seems fully compatible with this change.
Tree-SHA512: 9523961451c53aebd347716976bc3a4a398f989dc21e9bbbd357060bd11a8f46c435f068bd421bb31ccb08e55445ef67bc347d8d19a4fb8fde9d6d3f9a3bcbb0
Diffstat (limited to 'src/qt')
-rw-r--r-- | src/qt/bitcoin.cpp | 15 | ||||
-rw-r--r-- | src/qt/bitcoin.h | 2 | ||||
-rw-r--r-- | src/qt/forms/intro.ui | 10 | ||||
-rw-r--r-- | src/qt/intro.cpp | 18 | ||||
-rw-r--r-- | src/qt/intro.h | 3 | ||||
-rw-r--r-- | src/qt/optionsmodel.cpp | 22 | ||||
-rw-r--r-- | src/qt/optionsmodel.h | 3 |
7 files changed, 64 insertions, 9 deletions
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index adc4827e63..46f8deee57 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -282,6 +282,10 @@ void BitcoinApplication::parameterSetup() m_node.initParameterInteraction(); } +void BitcoinApplication::SetPrune(bool prune, bool force) { + optionsModel->SetPrune(prune, force); +} + void BitcoinApplication::requestInitialize() { qDebug() << __func__ << ": Requesting initialize"; @@ -487,8 +491,10 @@ int GuiMain(int argc, char* argv[]) /// 5. Now that settings and translations are available, ask user for data directory // User language is set up: pick a data directory - if (!Intro::pickDataDirectory(*node)) - return EXIT_SUCCESS; + bool did_show_intro = false; + bool prune = false; // Intro dialog prune check box + // Gracefully exit if the user cancels + if (!Intro::showIfNeeded(*node, did_show_intro, prune)) return EXIT_SUCCESS; /// 6. Determine availability of data directory and parse bitcoin.conf /// - Do not call GetDataDir(true) before this step finishes @@ -562,6 +568,11 @@ int GuiMain(int argc, char* argv[]) // Load GUI settings from QSettings app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false)); + if (did_show_intro) { + // Store intro dialog settings other than datadir (network specific) + app.SetPrune(prune, true); + } + if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false)) app.createSplashScreen(networkStyle.data()); diff --git a/src/qt/bitcoin.h b/src/qt/bitcoin.h index 3869193a3a..8c77fd8a7d 100644 --- a/src/qt/bitcoin.h +++ b/src/qt/bitcoin.h @@ -67,6 +67,8 @@ public: void parameterSetup(); /// Create options model void createOptionsModel(bool resetSettings); + /// Update prune value + void SetPrune(bool prune, bool force = false); /// Create main window void createWindow(const NetworkStyle *networkStyle); /// Create splash screen diff --git a/src/qt/forms/intro.ui b/src/qt/forms/intro.ui index cfdd8482e3..f27a4ebe44 100644 --- a/src/qt/forms/intro.ui +++ b/src/qt/forms/intro.ui @@ -211,6 +211,16 @@ </widget> </item> <item> + <widget class="QCheckBox" name="prune"> + <property name="toolTip"> + <string>Reverting this setting requires re-downloading the entire blockchain. It is faster to download the full chain first and prune it later. Disables some advanced features.</string> + </property> + <property name="text"> + <string></string> + </property> + </widget> + </item> + <item> <widget class="QLabel" name="lblExplanation2"> <property name="text"> <string>This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off.</string> diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp index 102e37e471..9e05c63aa0 100644 --- a/src/qt/intro.cpp +++ b/src/qt/intro.cpp @@ -131,6 +131,11 @@ Intro::Intro(QWidget *parent, uint64_t blockchain_size, uint64_t chain_state_siz ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(PACKAGE_NAME)); uint64_t pruneTarget = std::max<int64_t>(0, gArgs.GetArg("-prune", 0)); + if (pruneTarget > 1) { // -prune=1 means enabled, above that it's a size in MB + ui->prune->setChecked(true); + ui->prune->setEnabled(false); + } + ui->prune->setText(tr("Discard blocks after verification, except most recent %1 GB (prune)").arg(pruneTarget ? pruneTarget / 1000 : 2)); requiredSpace = m_blockchain_size; QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time."); if (pruneTarget) { @@ -180,8 +185,10 @@ void Intro::setDataDirectory(const QString &dataDir) } } -bool Intro::pickDataDirectory(interfaces::Node& node) +bool Intro::showIfNeeded(interfaces::Node& node, bool& did_show_intro, bool& prune) { + did_show_intro = false; + QSettings settings; /* If data directory provided on command line, no need to look at settings or show a picking dialog */ @@ -205,6 +212,7 @@ bool Intro::pickDataDirectory(interfaces::Node& node) Intro intro(0, node.getAssumedBlockchainSize(), node.getAssumedChainStateSize()); intro.setDataDirectory(dataDir); intro.setWindowIcon(QIcon(":icons/bitcoin")); + did_show_intro = true; while(true) { @@ -227,6 +235,9 @@ bool Intro::pickDataDirectory(interfaces::Node& node) } } + // Additional preferences: + prune = intro.ui->prune->isChecked(); + settings.setValue("strDataDir", dataDir); settings.setValue("fReset", false); } @@ -263,6 +274,11 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable { freeString += " " + tr("(of %n GB needed)", "", requiredSpace); ui->freeSpace->setStyleSheet("QLabel { color: #800000 }"); + ui->prune->setChecked(true); + } else if (bytesAvailable / GB_BYTES - requiredSpace < 10) { + freeString += " " + tr("(%n GB needed for full chain)", "", requiredSpace); + ui->freeSpace->setStyleSheet("QLabel { color: #999900 }"); + ui->prune->setChecked(true); } else { ui->freeSpace->setStyleSheet(""); } diff --git a/src/qt/intro.h b/src/qt/intro.h index c3b26808d4..aca7e71642 100644 --- a/src/qt/intro.h +++ b/src/qt/intro.h @@ -39,6 +39,7 @@ public: /** * Determine data directory. Let the user choose if the current one doesn't exist. + * Let the user configure additional preferences such as pruning. * * @returns true if a data directory was selected, false if the user cancelled the selection * dialog. @@ -46,7 +47,7 @@ public: * @note do NOT call global GetDataDir() before calling this function, this * will cause the wrong path to be cached. */ - static bool pickDataDirectory(interfaces::Node& node); + static bool showIfNeeded(interfaces::Node& node, bool& did_show_intro, bool& prune); Q_SIGNALS: void requestCheck(); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index f3974b1c85..d047a82475 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -92,11 +92,7 @@ void OptionsModel::Init(bool resetSettings) settings.setValue("bPrune", false); if (!settings.contains("nPruneSize")) settings.setValue("nPruneSize", 2); - // Convert prune size from GB to MiB: - const uint64_t nPruneSizeMiB = (settings.value("nPruneSize").toInt() * GB_BYTES) >> 20; - if (!m_node.softSetArg("-prune", settings.value("bPrune").toBool() ? std::to_string(nPruneSizeMiB) : "0")) { - addOverriddenOption("-prune"); - } + SetPrune(settings.value("bPrune").toBool()); if (!settings.contains("nDatabaseCache")) settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); @@ -240,6 +236,22 @@ static const QString GetDefaultProxyAddress() return QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST).arg(DEFAULT_GUI_PROXY_PORT); } +void OptionsModel::SetPrune(bool prune, bool force) +{ + QSettings settings; + settings.setValue("bPrune", prune); + // Convert prune size from GB to MiB: + const uint64_t nPruneSizeMiB = (settings.value("nPruneSize").toInt() * GB_BYTES) >> 20; + std::string prune_val = prune ? std::to_string(nPruneSizeMiB) : "0"; + if (force) { + m_node.forceSetArg("-prune", prune_val); + return; + } + if (!m_node.softSetArg("-prune", prune_val)) { + addOverriddenOption("-prune"); + } +} + // read QSettings values and return them QVariant OptionsModel::data(const QModelIndex & index, int role) const { diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 1af3a72b92..b1231b7c7d 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -77,6 +77,9 @@ public: bool getCoinControlFeatures() const { return fCoinControlFeatures; } const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; } + /* Explicit setters */ + void SetPrune(bool prune, bool force = false); + /* Restart flag helper */ void setRestartRequired(bool fRequired); bool isRestartRequired() const; |