Skip to content

Commit b89f2d0

Browse files
committed
Merge bitcoin#17453: gui: Fix intro dialog labels when the prune button is toggled
4f7127d gui: Make Intro consistent with prune checkbox (Hennadii Stepanov) 4824a7d gui: Add Intro::UpdateFreeSpaceLabel() (Hennadii Stepanov) daa3f3f refactor: Add Intro::UpdatePruneLabels() (Hennadii Stepanov) e4caa82 refactor: Replace static variable with data member (Hennadii Stepanov) 2bede28 util: Add PruneGBtoMiB() function (Hennadii Stepanov) e35e4b2 util: Add PruneMiBtoGB() function (Hennadii Stepanov) Pull request description: On master (a6f6333) and on 0.19.0.1 the intro dialog with prune enabled (checkbox "Discard blocks..." is checked) provides a user with wrong info about the required disk space: ![DeepinScreenshot_bitcoin-qt_20191208112228](https://user-images.githubusercontent.com/32963518/70387510-8daab400-19ae-11ea-9338-29add9c31118.png) Also the paragraph "If you have chosen to limit..." is missed. --- With this PR when prune checkbox is toggled, the related text labels and the amount of required space shown are updated (previously they were only updated when the data directory was updated): ![Screenshot from 2019-12-08 11-34-53](https://user-images.githubusercontent.com/32963518/70387542-eed28780-19ae-11ea-9565-49d8a64b2f33.png) --- This PR is an alternative to bitcoin#17035. **ryanofsky**'s [suggestion](bitcoin#17035 (comment)) also has been implemented. ACKs for top commit: emilengler: ACK 4f7127d Sjors: tACK 4f7127d ryanofsky: Code review ACK 4f7127d. It seems like there are a few visible changes here: jonasschnelli: utACK 4f7127d Tree-SHA512: fa0bbdcfafde97d7906cda066cbd4608b936a71cae1b4cda3ee3aa2eed3a9795f279f14c6b1b4997278e094db891c7d3bb695368ba0882347aa42165a86e5172
2 parents ef8e2ce + 4f7127d commit b89f2d0

File tree

4 files changed

+82
-48
lines changed

4 files changed

+82
-48
lines changed

src/qt/intro.cpp

+60-42
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <qt/guiconstants.h>
1414
#include <qt/guiutil.h>
15+
#include <qt/optionsmodel.h>
1516

1617
#include <interfaces/node.h>
1718
#include <util/system.h>
@@ -22,9 +23,6 @@
2223

2324
#include <cmath>
2425

25-
/* Total required space (in GB) depending on user choice (prune, not prune) */
26-
static uint64_t requiredSpace;
27-
2826
/* Check free space asynchronously to prevent hanging the UI thread.
2927
3028
Up to one request to check a path is in flight to this thread; when the check()
@@ -109,52 +107,49 @@ void FreespaceChecker::check()
109107
Q_EMIT reply(replyStatus, replyMessage, freeBytesAvailable);
110108
}
111109

110+
namespace {
111+
//! Return pruning size that will be used if automatic pruning is enabled.
112+
int GetPruneTargetGB()
113+
{
114+
int64_t prune_target_mib = gArgs.GetArg("-prune", 0);
115+
// >1 means automatic pruning is enabled by config, 1 means manual pruning, 0 means no pruning.
116+
return prune_target_mib > 1 ? PruneMiBtoGB(prune_target_mib) : DEFAULT_PRUNE_TARGET_GB;
117+
}
118+
} // namespace
112119

113-
Intro::Intro(QWidget *parent, uint64_t blockchain_size, uint64_t chain_state_size) :
120+
Intro::Intro(QWidget *parent, int64_t blockchain_size_gb, int64_t chain_state_size_gb) :
114121
QDialog(parent),
115122
ui(new Ui::Intro),
116123
thread(nullptr),
117124
signalled(false),
118-
m_blockchain_size(blockchain_size),
119-
m_chain_state_size(chain_state_size)
125+
m_blockchain_size_gb(blockchain_size_gb),
126+
m_chain_state_size_gb(chain_state_size_gb),
127+
m_prune_target_gb{GetPruneTargetGB()}
120128
{
121129
ui->setupUi(this);
122130
ui->welcomeLabel->setText(ui->welcomeLabel->text().arg(PACKAGE_NAME));
123131
ui->storageLabel->setText(ui->storageLabel->text().arg(PACKAGE_NAME));
124132

125133
ui->lblExplanation1->setText(ui->lblExplanation1->text()
126134
.arg(PACKAGE_NAME)
127-
.arg(m_blockchain_size)
135+
.arg(m_blockchain_size_gb)
128136
.arg(2009)
129137
.arg(tr("Bitcoin"))
130138
);
131139
ui->lblExplanation2->setText(ui->lblExplanation2->text().arg(PACKAGE_NAME));
132140

133-
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
141+
if (gArgs.GetArg("-prune", 0) > 1) { // -prune=1 means enabled, above that it's a size in MiB
135142
ui->prune->setChecked(true);
136143
ui->prune->setEnabled(false);
137144
}
138-
ui->prune->setText(tr("Discard blocks after verification, except most recent %1 GB (prune)").arg(pruneTarget ? pruneTarget / 1000 : DEFAULT_PRUNE_TARGET_GB));
139-
requiredSpace = m_blockchain_size;
140-
QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time.");
141-
if (pruneTarget) {
142-
uint64_t prunedGBs = std::ceil(pruneTarget * 1024 * 1024.0 / GB_BYTES);
143-
if (prunedGBs <= requiredSpace) {
144-
requiredSpace = prunedGBs;
145-
storageRequiresMsg = tr("Approximately %1 GB of data will be stored in this directory.");
146-
}
147-
ui->lblExplanation3->setVisible(true);
148-
} else {
149-
ui->lblExplanation3->setVisible(false);
150-
}
151-
requiredSpace += m_chain_state_size;
152-
ui->sizeWarningLabel->setText(
153-
tr("%1 will download and store a copy of the Bitcoin block chain.").arg(PACKAGE_NAME) + " " +
154-
storageRequiresMsg.arg(requiredSpace) + " " +
155-
tr("The wallet will also be stored in this directory.")
156-
);
157-
this->adjustSize();
145+
ui->prune->setText(tr("Discard blocks after verification, except most recent %1 GB (prune)").arg(m_prune_target_gb));
146+
UpdatePruneLabels(ui->prune->isChecked());
147+
148+
connect(ui->prune, &QCheckBox::toggled, [this](bool prune_checked) {
149+
UpdatePruneLabels(prune_checked);
150+
UpdateFreeSpaceLabel();
151+
});
152+
158153
startThread();
159154
}
160155

@@ -270,25 +265,31 @@ void Intro::setStatus(int status, const QString &message, quint64 bytesAvailable
270265
{
271266
ui->freeSpace->setText("");
272267
} else {
273-
QString freeString = tr("%n GB of free space available", "", bytesAvailable/GB_BYTES);
274-
if(bytesAvailable < requiredSpace * GB_BYTES)
275-
{
276-
freeString += " " + tr("(of %n GB needed)", "", requiredSpace);
277-
ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
278-
ui->prune->setChecked(true);
279-
} else if (bytesAvailable / GB_BYTES - requiredSpace < 10) {
280-
freeString += " " + tr("(%n GB needed for full chain)", "", requiredSpace);
281-
ui->freeSpace->setStyleSheet("QLabel { color: #999900 }");
282-
ui->prune->setChecked(true);
283-
} else {
284-
ui->freeSpace->setStyleSheet("");
268+
m_bytes_available = bytesAvailable;
269+
if (ui->prune->isEnabled()) {
270+
ui->prune->setChecked(m_bytes_available < (m_blockchain_size_gb + m_chain_state_size_gb + 10) * GB_BYTES);
285271
}
286-
ui->freeSpace->setText(freeString + ".");
272+
UpdateFreeSpaceLabel();
287273
}
288274
/* Don't allow confirm in ERROR state */
289275
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(status != FreespaceChecker::ST_ERROR);
290276
}
291277

278+
void Intro::UpdateFreeSpaceLabel()
279+
{
280+
QString freeString = tr("%n GB of free space available", "", m_bytes_available / GB_BYTES);
281+
if (m_bytes_available < m_required_space_gb * GB_BYTES) {
282+
freeString += " " + tr("(of %n GB needed)", "", m_required_space_gb);
283+
ui->freeSpace->setStyleSheet("QLabel { color: #800000 }");
284+
} else if (m_bytes_available / GB_BYTES - m_required_space_gb < 10) {
285+
freeString += " " + tr("(%n GB needed for full chain)", "", m_required_space_gb);
286+
ui->freeSpace->setStyleSheet("QLabel { color: #999900 }");
287+
} else {
288+
ui->freeSpace->setStyleSheet("");
289+
}
290+
ui->freeSpace->setText(freeString + ".");
291+
}
292+
292293
void Intro::on_dataDirectory_textChanged(const QString &dataDirStr)
293294
{
294295
/* Disable OK button until check result comes in */
@@ -349,3 +350,20 @@ QString Intro::getPathToCheck()
349350
mutex.unlock();
350351
return retval;
351352
}
353+
354+
void Intro::UpdatePruneLabels(bool prune_checked)
355+
{
356+
m_required_space_gb = m_blockchain_size_gb + m_chain_state_size_gb;
357+
QString storageRequiresMsg = tr("At least %1 GB of data will be stored in this directory, and it will grow over time.");
358+
if (prune_checked && m_prune_target_gb <= m_blockchain_size_gb) {
359+
m_required_space_gb = m_prune_target_gb + m_chain_state_size_gb;
360+
storageRequiresMsg = tr("Approximately %1 GB of data will be stored in this directory.");
361+
}
362+
ui->lblExplanation3->setVisible(prune_checked);
363+
ui->sizeWarningLabel->setText(
364+
tr("%1 will download and store a copy of the Bitcoin block chain.").arg(PACKAGE_NAME) + " " +
365+
storageRequiresMsg.arg(m_required_space_gb) + " " +
366+
tr("The wallet will also be stored in this directory.")
367+
);
368+
this->adjustSize();
369+
}

src/qt/intro.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Intro : public QDialog
3131

3232
public:
3333
explicit Intro(QWidget *parent = nullptr,
34-
uint64_t blockchain_size = 0, uint64_t chain_state_size = 0);
34+
int64_t blockchain_size_gb = 0, int64_t chain_state_size_gb = 0);
3535
~Intro();
3636

3737
QString getDataDirectory();
@@ -67,12 +67,18 @@ private Q_SLOTS:
6767
QMutex mutex;
6868
bool signalled;
6969
QString pathToCheck;
70-
uint64_t m_blockchain_size;
71-
uint64_t m_chain_state_size;
70+
const int64_t m_blockchain_size_gb;
71+
const int64_t m_chain_state_size_gb;
72+
//! Total required space (in GB) depending on user choice (prune or not prune).
73+
int64_t m_required_space_gb{0};
74+
uint64_t m_bytes_available{0};
75+
const int64_t m_prune_target_gb;
7276

7377
void startThread();
7478
void checkPath(const QString &dataDir);
7579
QString getPathToCheck();
80+
void UpdatePruneLabels(bool prune_checked);
81+
void UpdateFreeSpaceLabel();
7682

7783
friend class FreespaceChecker;
7884
};

src/qt/optionsmodel.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,8 @@ void OptionsModel::SetPruneEnabled(bool prune, bool force)
240240
{
241241
QSettings settings;
242242
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";
243+
const int64_t prune_target_mib = PruneGBtoMiB(settings.value("nPruneSize").toInt());
244+
std::string prune_val = prune ? std::to_string(prune_target_mib) : "0";
246245
if (force) {
247246
m_node.forceSetArg("-prune", prune_val);
248247
return;

src/qt/optionsmodel.h

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_QT_OPTIONSMODEL_H
77

88
#include <amount.h>
9+
#include <qt/guiconstants.h>
910

1011
#include <QAbstractListModel>
1112

@@ -16,6 +17,16 @@ class Node;
1617
extern const char *DEFAULT_GUI_PROXY_HOST;
1718
static constexpr unsigned short DEFAULT_GUI_PROXY_PORT = 9050;
1819

20+
/**
21+
* Convert configured prune target MiB to displayed GB. Round up to avoid underestimating max disk usage.
22+
*/
23+
static inline int PruneMiBtoGB(int64_t mib) { return (mib * 1024 * 1024 + GB_BYTES - 1) / GB_BYTES; }
24+
25+
/**
26+
* Convert displayed prune target GB to configured MiB. Round down so roundtrip GB -> MiB -> GB conversion is stable.
27+
*/
28+
static inline int64_t PruneGBtoMiB(int gb) { return gb * GB_BYTES / 1024 / 1024; }
29+
1930
/** Interface from Qt to configuration data structure for Bitcoin client.
2031
To Qt, the options are presented as a list with the different options
2132
laid out vertically.

0 commit comments

Comments
 (0)