Skip to content

Commit 884f7cc

Browse files
committed
Merge #16714: gui: add prune to intro screen with smart default
9924bce [gui] intro: enable pruning by default unless disk is big (Sjors Provoost) c8de347 [gui] intro: add prune preference (Sjors Provoost) 1bbc49d [gui] intro: inform caller if intro was shown (Sjors Provoost) 1957103 [gui] add explicit prune setter (Sjors Provoost) 1bccf6a [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 9924bce ryanofsky: utACK 9924bce. 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
2 parents ca97d29 + 9924bce commit 884f7cc

File tree

9 files changed

+68
-9
lines changed

9 files changed

+68
-9
lines changed

src/interfaces/node.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class NodeImpl : public Node
6262
return gArgs.ParseParameters(argc, argv, error);
6363
}
6464
bool readConfigFiles(std::string& error) override { return gArgs.ReadConfigFiles(error, true); }
65+
void forceSetArg(const std::string& arg, const std::string& value) override { gArgs.ForceSetArg(arg, value); }
6566
bool softSetArg(const std::string& arg, const std::string& value) override { return gArgs.SoftSetArg(arg, value); }
6667
bool softSetBoolArg(const std::string& arg, bool value) override { return gArgs.SoftSetBoolArg(arg, value); }
6768
void selectParams(const std::string& network) override { SelectParams(network); }

src/interfaces/node.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class Node
4646
//! Set command line arguments.
4747
virtual bool parseParameters(int argc, const char* const argv[], std::string& error) = 0;
4848

49+
//! Set a command line argument
50+
virtual void forceSetArg(const std::string& arg, const std::string& value) = 0;
51+
4952
//! Set a command line argument if it doesn't already have a value
5053
virtual bool softSetArg(const std::string& arg, const std::string& value) = 0;
5154

src/qt/bitcoin.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,10 @@ void BitcoinApplication::parameterSetup()
282282
m_node.initParameterInteraction();
283283
}
284284

285+
void BitcoinApplication::SetPrune(bool prune, bool force) {
286+
optionsModel->SetPrune(prune, force);
287+
}
288+
285289
void BitcoinApplication::requestInitialize()
286290
{
287291
qDebug() << __func__ << ": Requesting initialize";
@@ -487,8 +491,10 @@ int GuiMain(int argc, char* argv[])
487491

488492
/// 5. Now that settings and translations are available, ask user for data directory
489493
// User language is set up: pick a data directory
490-
if (!Intro::pickDataDirectory(*node))
491-
return EXIT_SUCCESS;
494+
bool did_show_intro = false;
495+
bool prune = false; // Intro dialog prune check box
496+
// Gracefully exit if the user cancels
497+
if (!Intro::showIfNeeded(*node, did_show_intro, prune)) return EXIT_SUCCESS;
492498

493499
/// 6. Determine availability of data directory and parse bitcoin.conf
494500
/// - Do not call GetDataDir(true) before this step finishes
@@ -562,6 +568,11 @@ int GuiMain(int argc, char* argv[])
562568
// Load GUI settings from QSettings
563569
app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
564570

571+
if (did_show_intro) {
572+
// Store intro dialog settings other than datadir (network specific)
573+
app.SetPrune(prune, true);
574+
}
575+
565576
if (gArgs.GetBoolArg("-splash", DEFAULT_SPLASHSCREEN) && !gArgs.GetBoolArg("-min", false))
566577
app.createSplashScreen(networkStyle.data());
567578

src/qt/bitcoin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class BitcoinApplication: public QApplication
6767
void parameterSetup();
6868
/// Create options model
6969
void createOptionsModel(bool resetSettings);
70+
/// Update prune value
71+
void SetPrune(bool prune, bool force = false);
7072
/// Create main window
7173
void createWindow(const NetworkStyle *networkStyle);
7274
/// Create splash screen

src/qt/forms/intro.ui

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,16 @@
210210
</property>
211211
</widget>
212212
</item>
213+
<item>
214+
<widget class="QCheckBox" name="prune">
215+
<property name="toolTip">
216+
<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>
217+
</property>
218+
<property name="text">
219+
<string></string>
220+
</property>
221+
</widget>
222+
</item>
213223
<item>
214224
<widget class="QLabel" name="lblExplanation2">
215225
<property name="text">

src/qt/intro.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ Intro::Intro(QWidget *parent, uint64_t blockchain_size, uint64_t chain_state_siz
131131
ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(PACKAGE_NAME));
132132

133133
uint64_t pruneTarget = std::max<int64_t>(0, gArgs.GetArg("-prune", 0));
134+
if (pruneTarget > 1) { // -prune=1 means enabled, above that it's a size in MB
135+
ui->prune->setChecked(true);
136+
ui->prune->setEnabled(false);
137+
}
138+
ui->prune->setText(tr("Discard blocks after verification, except most recent %1 GB (prune)").arg(pruneTarget ? pruneTarget / 1000 : 2));
134139
requiredSpace = m_blockchain_size;
135140
QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time.");
136141
if (pruneTarget) {
@@ -180,8 +185,10 @@ void Intro::setDataDirectory(const QString &dataDir)
180185
}
181186
}
182187

183-
bool Intro::pickDataDirectory(interfaces::Node& node)
188+
bool Intro::showIfNeeded(interfaces::Node& node, bool& did_show_intro, bool& prune)
184189
{
190+
did_show_intro = false;
191+
185192
QSettings settings;
186193
/* If data directory provided on command line, no need to look at settings
187194
or show a picking dialog */
@@ -205,6 +212,7 @@ bool Intro::pickDataDirectory(interfaces::Node& node)
205212
Intro intro(0, node.getAssumedBlockchainSize(), node.getAssumedChainStateSize());
206213
intro.setDataDirectory(dataDir);
207214
intro.setWindowIcon(QIcon(":icons/bitcoin"));
215+
did_show_intro = true;
208216

209217
while(true)
210218
{
@@ -227,6 +235,9 @@ bool Intro::pickDataDirectory(interfaces::Node& node)
227235
}
228236
}
229237

238+
// Additional preferences:
239+
prune = intro.ui->prune->isChecked();
240+
230241
settings.setValue("strDataDir", dataDir);
231242
settings.setValue("fReset", false);
232243
}
@@ -263,6 +274,11 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable
263274
{
264275
freeString += " " + tr("(of %n GB needed)", "", requiredSpace);
265276
ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
277+
ui->prune->setChecked(true);
278+
} else if (bytesAvailable / GB_BYTES - requiredSpace < 10) {
279+
freeString += " " + tr("(%n GB needed for full chain)", "", requiredSpace);
280+
ui->freeSpace->setStyleSheet("QLabel { color: #999900 }");
281+
ui->prune->setChecked(true);
266282
} else {
267283
ui->freeSpace->setStyleSheet("");
268284
}

src/qt/intro.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@ class Intro : public QDialog
3939

4040
/**
4141
* Determine data directory. Let the user choose if the current one doesn't exist.
42+
* Let the user configure additional preferences such as pruning.
4243
*
4344
* @returns true if a data directory was selected, false if the user cancelled the selection
4445
* dialog.
4546
*
4647
* @note do NOT call global GetDataDir() before calling this function, this
4748
* will cause the wrong path to be cached.
4849
*/
49-
static bool pickDataDirectory(interfaces::Node& node);
50+
static bool showIfNeeded(interfaces::Node& node, bool& did_show_intro, bool& prune);
5051

5152
Q_SIGNALS:
5253
void requestCheck();

src/qt/optionsmodel.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,7 @@ void OptionsModel::Init(bool resetSettings)
9292
settings.setValue("bPrune", false);
9393
if (!settings.contains("nPruneSize"))
9494
settings.setValue("nPruneSize", 2);
95-
// Convert prune size from GB to MiB:
96-
const uint64_t nPruneSizeMiB = (settings.value("nPruneSize").toInt() * GB_BYTES) >> 20;
97-
if (!m_node.softSetArg("-prune", settings.value("bPrune").toBool() ? std::to_string(nPruneSizeMiB) : "0")) {
98-
addOverriddenOption("-prune");
99-
}
95+
SetPrune(settings.value("bPrune").toBool());
10096

10197
if (!settings.contains("nDatabaseCache"))
10298
settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
@@ -240,6 +236,22 @@ static const QString GetDefaultProxyAddress()
240236
return QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST).arg(DEFAULT_GUI_PROXY_PORT);
241237
}
242238

239+
void OptionsModel::SetPrune(bool prune, bool force)
240+
{
241+
QSettings settings;
242+
settings.setValue("bPrune", prune);
243+
// Convert prune size from GB to MiB:
244+
const uint64_t nPruneSizeMiB = (settings.value("nPruneSize").toInt() * GB_BYTES) >> 20;
245+
std::string prune_val = prune ? std::to_string(nPruneSizeMiB) : "0";
246+
if (force) {
247+
m_node.forceSetArg("-prune", prune_val);
248+
return;
249+
}
250+
if (!m_node.softSetArg("-prune", prune_val)) {
251+
addOverriddenOption("-prune");
252+
}
253+
}
254+
243255
// read QSettings values and return them
244256
QVariant OptionsModel::data(const QModelIndex & index, int role) const
245257
{

src/qt/optionsmodel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ class OptionsModel : public QAbstractListModel
7777
bool getCoinControlFeatures() const { return fCoinControlFeatures; }
7878
const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; }
7979

80+
/* Explicit setters */
81+
void SetPrune(bool prune, bool force = false);
82+
8083
/* Restart flag helper */
8184
void setRestartRequired(bool fRequired);
8285
bool isRestartRequired() const;

0 commit comments

Comments
 (0)