Qt/Options: Handle manual pruning cleanly

This commit is contained in:
Luke Dashjr 2023-08-03 20:34:08 +00:00
parent c72cb20934
commit 42e3bc0dd8
4 changed files with 68 additions and 28 deletions

View File

@ -143,22 +143,32 @@ Intro::Intro(QWidget *parent, int64_t blockchain_size_gb, int64_t chain_state_si
ui->pruneMiB->setRange(min_prune_target_MiB, std::numeric_limits<int>::max());
if (gArgs.IsArgSet("-prune")) {
m_prune_checkbox_is_default = false;
ui->prune->setChecked(gArgs.GetIntArg("-prune", 0) >= 1);
switch (gArgs.GetIntArg("-prune", 0)) {
case 0:
ui->prune->setChecked(false);
break;
case 1:
ui->prune->setTristate();
ui->prune->setCheckState(Qt::PartiallyChecked);
break;
default:
ui->prune->setChecked(true);
}
ui->prune->setEnabled(false);
}
ui->pruneMiB->setValue(m_prune_target_mib);
ui->pruneMiB->setToolTip(ui->prune->toolTip());
ui->lblPruneSuffix->setToolTip(ui->prune->toolTip());
UpdatePruneLabels(ui->prune->isChecked());
UpdatePruneLabels(ui->prune->checkState() == Qt::Checked);
connect(ui->prune, &QCheckBox::toggled, [this](bool prune_checked) {
connect(ui->prune, &QCheckBox::stateChanged, [this](int prune_state) {
m_prune_checkbox_is_default = false;
UpdatePruneLabels(prune_checked);
UpdatePruneLabels(prune_state == Qt::Checked);
UpdateFreeSpaceLabel();
});
connect(ui->pruneMiB, qOverload<int>(&QSpinBox::valueChanged), [this](int prune_MiB) {
m_prune_target_mib = prune_MiB;
UpdatePruneLabels(ui->prune->isChecked());
UpdatePruneLabels(ui->prune->checkState() == Qt::Checked);
UpdateFreeSpaceLabel();
});
@ -198,6 +208,8 @@ int64_t Intro::getPruneMiB() const
switch (ui->prune->checkState()) {
case Qt::Checked:
return m_prune_target_mib;
case Qt::PartiallyChecked:
return 1;
case Qt::Unchecked: default:
return 0;
}

View File

@ -302,7 +302,11 @@ void OptionsDialog::setMapper()
mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif);
mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
mapper->addMapping(ui->prune, OptionsModel::Prune);
if (model->data(model->index(OptionsModel::PruneTristate, 0), Qt::EditRole).value<Qt::CheckState>() == Qt::PartiallyChecked) {
ui->prune->setTristate();
}
mapper->addMapping(ui->prune, OptionsModel::PruneTristate);
mapper->addMapping(ui->pruneSizeMiB, OptionsModel::PruneSizeMiB);
/* Wallet */

View File

@ -55,7 +55,7 @@ static const char* SettingName(OptionsModel::OptionID option)
case OptionsModel::Listen: return "listen";
case OptionsModel::Server: return "server";
case OptionsModel::PruneSizeMiB: return "prune";
case OptionsModel::Prune: return "prune";
case OptionsModel::PruneTristate: return "prune";
case OptionsModel::ProxyIP: return "proxy";
case OptionsModel::ProxyPort: return "proxy";
case OptionsModel::ProxyUse: return "proxy";
@ -73,7 +73,7 @@ static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID optio
if (value.isNum() &&
(option == OptionsModel::DatabaseCache ||
option == OptionsModel::ThreadsScriptVerif ||
option == OptionsModel::Prune ||
option == OptionsModel::PruneTristate ||
option == OptionsModel::PruneSizeMiB)) {
// Write certain old settings as strings, even though they are numbers,
// because Bitcoin 22.x releases try to read these specific settings as
@ -89,10 +89,17 @@ static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID optio
}
//! Convert enabled/size values to bitcoin -prune setting.
static util::SettingsValue PruneSettingFromMiB(bool prune_enabled, int prune_size_mib)
static util::SettingsValue PruneSettingFromMiB(Qt::CheckState prune_enabled, int prune_size_mib)
{
assert(!prune_enabled || prune_size_mib >= 1); // PruneSizeMiB and ParsePruneSizeMiB never return less
return prune_enabled ? prune_size_mib : 0;
assert(prune_enabled != Qt::Checked || prune_size_mib >= 1); // PruneSizeMiB and ParsePruneSizeMiB never return less
switch (prune_enabled) {
case Qt::Unchecked:
return 0;
case Qt::PartiallyChecked:
return 1;
default:
return prune_size_mib;
}
}
//! Get pruning enabled value to show in GUI from bitcoin -prune setting.
@ -102,6 +109,19 @@ static bool PruneEnabled(const util::SettingsValue& prune_setting)
return SettingToInt(prune_setting, 0) > 1;
}
//! Get pruning enabled value to show in GUI from bitcoin -prune setting.
static Qt::CheckState PruneSettingAsTristate(const util::SettingsValue& prune_setting)
{
switch (SettingToInt(prune_setting, 0)) {
case 0:
return Qt::Unchecked;
case 1:
return Qt::PartiallyChecked;
default:
return Qt::Checked;
}
}
//! Get pruning size value to show in GUI from bitcoin -prune setting. If
//! pruning is not enabled, just show default recommended pruning size (2GB).
static int PruneSizeAsMiB(const util::SettingsValue& prune_setting)
@ -217,7 +237,7 @@ bool OptionsModel::Init(bilingual_str& error)
// These are shared with the core or have a command-line parameter
// and we want command-line parameters to overwrite the GUI settings.
for (OptionID option : {DatabaseCache, ThreadsScriptVerif, SpendZeroConfChange, ExternalSignerPath, MapPortUPnP,
MapPortNatpmp, Listen, Server, Prune, ProxyUse, ProxyUseTor, Language}) {
MapPortNatpmp, Listen, Server, PruneTristate, ProxyUse, ProxyUseTor, Language}) {
std::string setting = SettingName(option);
if (node().isSettingIgnored(setting)) addOverriddenOption("-" + setting);
try {
@ -371,7 +391,7 @@ static QString GetDefaultProxyAddress()
void OptionsModel::SetPruneTargetMiB(int prune_target_mib)
{
const util::SettingsValue cur_value = node().getPersistentSetting("prune");
const util::SettingsValue new_value = PruneSettingFromMiB(prune_target_mib > 0, prune_target_mib);
const util::SettingsValue new_value = prune_target_mib;
// Force setting to take effect. It is still safe to change the value at
// this point because this function is only called after the intro screen is
@ -381,16 +401,15 @@ void OptionsModel::SetPruneTargetMiB(int prune_target_mib)
// Update settings.json if value configured in intro screen is different
// from saved value. Avoid writing settings.json if bitcoin.conf value
// doesn't need to be overridden.
if (PruneEnabled(cur_value) != PruneEnabled(new_value) ||
PruneSizeAsMiB(cur_value) != PruneSizeAsMiB(new_value)) {
if (cur_value.write() != new_value.write()) {
// Call UpdateRwSetting() instead of setOption() to avoid setting
// RestartRequired flag
UpdateRwSetting(node(), Prune, "", new_value);
UpdateRwSetting(node(), PruneTristate, "", new_value);
}
// Keep previous pruning size, if pruning was disabled.
if (PruneEnabled(cur_value)) {
UpdateRwSetting(node(), Prune, "-prev", PruneEnabled(new_value) ? util::SettingsValue{} : cur_value);
UpdateRwSetting(node(), PruneTristate, "-prev", PruneEnabled(new_value) ? util::SettingsValue{} : cur_value);
}
}
@ -503,8 +522,8 @@ QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) con
return fCoinControlFeatures;
case EnablePSBTControls:
return settings.value("enable_psbt_controls");
case Prune:
return PruneEnabled(setting());
case PruneTristate:
return PruneSettingAsTristate(setting());
case PruneSizeMiB:
return PruneEnabled(setting()) ? PruneSizeAsMiB(setting()) :
suffix.empty() ? getOption(option, "-prev") :
@ -741,22 +760,24 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::
m_enable_psbt_controls = value.toBool();
settings.setValue("enable_psbt_controls", m_enable_psbt_controls);
break;
case Prune:
case PruneTristate:
if (changed()) {
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
update(PruneSettingFromMiB(value.toBool(), getOption(PruneSizeMiB).toInt()));
if (suffix.empty() && value.toBool()) UpdateRwSetting(node(), option, "-prev", {});
const bool is_autoprune = (value.value<Qt::CheckState>() == Qt::Checked);
if (suffix.empty() && !is_autoprune) setOption(option, true, "-prev");
update(PruneSettingFromMiB(value.value<Qt::CheckState>(), getOption(PruneSizeMiB).toInt()));
if (suffix.empty() && is_autoprune) UpdateRwSetting(node(), option, "-prev", {});
if (suffix.empty()) setRestartRequired(true);
}
break;
case PruneSizeMiB:
if (changed()) {
if (suffix.empty() && !getOption(Prune).toBool()) {
const bool is_autoprune = (Qt::Checked == getOption(PruneTristate).value<Qt::CheckState>());
if (suffix.empty() && !is_autoprune) {
setOption(option, value, "-prev");
} else {
update(PruneSettingFromMiB(true, value.toInt()));
update(PruneSettingFromMiB(Qt::Checked, value.toInt()));
}
if (suffix.empty() && getOption(Prune).toBool()) setRestartRequired(true);
if (suffix.empty() && is_autoprune) setRestartRequired(true);
}
break;
case DatabaseCache:
@ -878,6 +899,9 @@ void OptionsModel::checkAndMigrate()
const int64_t prune_size_gb = value.toInt();
const int prune_size_mib = std::max(prune_size_gb * GB_BYTES / MiB_BYTES, MIN_DISK_SPACE_FOR_BLOCK_FILES / MiB_BYTES);
setOption(option, prune_size_mib);
} else if (option == PruneTristate) {
// Stored as bool
setOption(option, value.toBool() ? Qt::Checked : Qt::Unchecked);
} else {
setOption(option, value);
}
@ -896,7 +920,7 @@ void OptionsModel::checkAndMigrate()
migrate_setting(Listen, "fListen");
migrate_setting(Server, "server");
migrate_setting(PruneSizeMiB, "nPruneSize");
migrate_setting(Prune, "bPrune");
migrate_setting(PruneTristate, "bPrune");
migrate_setting(ProxyIP, "addrProxy");
migrate_setting(ProxyUse, "fUseProxy");
migrate_setting(ProxyIPTor, "addrSeparateProxyTor");

View File

@ -59,7 +59,7 @@ public:
CoinControlFeatures, // bool
SubFeeFromAmount, // bool
ThreadsScriptVerif, // int
Prune, // bool
PruneTristate, // Qt::CheckState
PruneSizeMiB, // int
DatabaseCache, // int
ExternalSignerPath, // QString