Skip to content

Commit 9d3127b

Browse files
committed
Add settings.json prune-prev, proxy-prev, onion-prev settings
This provides a way for the GUI settings dialog box to retain previous pruning and proxy settings when they are disabled, as requested by vasild: bitcoin#15936 (review) bitcoin#15936 (comment) bitcoin#15936 (comment) Importantly, while this PR changes the settings.json format, it changes it in a fully backwards compatible way, so previous versious of bitcoind and bitcoin-qt will correctly interpret prune, proxy, and onion settins written by new versions of bitcoin-qt.
1 parent 80d1598 commit 9d3127b

File tree

2 files changed

+77
-66
lines changed

2 files changed

+77
-66
lines changed

src/qt/optionsmodel.cpp

+75-55
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static const char* SettingName(OptionsModel::OptionID option)
5959
}
6060

6161
/** Call node.updateRwSetting() with Bitcoin 22.x workaround. */
62-
static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID option, const util::SettingsValue& value)
62+
static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID option, const std::string& suffix, const util::SettingsValue& value)
6363
{
6464
if (value.isNum() &&
6565
(option == OptionsModel::DatabaseCache ||
@@ -73,9 +73,9 @@ static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID optio
7373
// in later releases by https://github.com/bitcoin/bitcoin/pull/24498.
7474
// If new numeric settings are added, they can be written as numbers
7575
// instead of strings, because bitcoin 22.x will not try to read these.
76-
node.updateRwSetting(SettingName(option), value.getValStr());
76+
node.updateRwSetting(SettingName(option) + suffix, value.getValStr());
7777
} else {
78-
node.updateRwSetting(SettingName(option), value);
78+
node.updateRwSetting(SettingName(option) + suffix, value);
7979
}
8080
}
8181

@@ -131,13 +131,6 @@ void OptionsModel::addOverriddenOption(const std::string &option)
131131
bool OptionsModel::Init(bilingual_str& error)
132132
{
133133
// Initialize display settings from stored settings.
134-
m_prune_size_gb = PruneSizeGB(node().getPersistentSetting("prune"));
135-
ProxySetting proxy = ParseProxyString(SettingToString(node().getPersistentSetting("proxy"), GetDefaultProxyAddress().toStdString()));
136-
m_proxy_ip = proxy.ip;
137-
m_proxy_port = proxy.port;
138-
ProxySetting onion = ParseProxyString(SettingToString(node().getPersistentSetting("onion"), GetDefaultProxyAddress().toStdString()));
139-
m_onion_ip = onion.ip;
140-
m_onion_port = onion.port;
141134
language = QString::fromStdString(SettingToString(node().getPersistentSetting("lang"), ""));
142135

143136
checkAndMigrate();
@@ -318,8 +311,6 @@ void OptionsModel::SetPruneTargetGB(int prune_target_gb)
318311
const util::SettingsValue cur_value = node().getPersistentSetting("prune");
319312
const util::SettingsValue new_value = PruneSetting(prune_target_gb > 0, prune_target_gb);
320313

321-
m_prune_size_gb = prune_target_gb;
322-
323314
// Force setting to take effect. It is still safe to change the value at
324315
// this point because this function is only called after the intro screen is
325316
// shown, before the node starts.
@@ -332,7 +323,12 @@ void OptionsModel::SetPruneTargetGB(int prune_target_gb)
332323
PruneSizeGB(cur_value) != PruneSizeGB(new_value)) {
333324
// Call UpdateRwSetting() instead of setOption() to avoid setting
334325
// RestartRequired flag
335-
UpdateRwSetting(node(), Prune, new_value);
326+
UpdateRwSetting(node(), Prune, "", new_value);
327+
}
328+
329+
// Keep previous pruning size, if pruning was disabled.
330+
if (PruneEnabled(cur_value)) {
331+
UpdateRwSetting(node(), Prune, "-prev", PruneEnabled(new_value) ? util::SettingsValue{} : cur_value);
336332
}
337333
}
338334

@@ -360,9 +356,9 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
360356
return successful;
361357
}
362358

363-
QVariant OptionsModel::getOption(OptionID option) const
359+
QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) const
364360
{
365-
auto setting = [&]{ return node().getPersistentSetting(SettingName(option)); };
361+
auto setting = [&]{ return node().getPersistentSetting(SettingName(option) + suffix); };
366362

367363
QSettings settings;
368364
switch (option) {
@@ -389,19 +385,30 @@ QVariant OptionsModel::getOption(OptionID option) const
389385

390386
// default proxy
391387
case ProxyUse:
388+
case ProxyUseTor:
392389
return ParseProxyString(SettingToString(setting(), "")).is_set;
393390
case ProxyIP:
394-
return m_proxy_ip;
391+
case ProxyIPTor: {
392+
ProxySetting proxy = ParseProxyString(SettingToString(setting(), ""));
393+
if (proxy.is_set) {
394+
return proxy.ip;
395+
} else if (suffix.empty()) {
396+
return getOption(option, "-prev");
397+
} else {
398+
return ParseProxyString(GetDefaultProxyAddress().toStdString()).ip;
399+
}
400+
}
395401
case ProxyPort:
396-
return m_proxy_port;
397-
398-
// separate Tor proxy
399-
case ProxyUseTor:
400-
return ParseProxyString(SettingToString(setting(), "")).is_set;
401-
case ProxyIPTor:
402-
return m_onion_ip;
403-
case ProxyPortTor:
404-
return m_onion_port;
402+
case ProxyPortTor: {
403+
ProxySetting proxy = ParseProxyString(SettingToString(setting(), ""));
404+
if (proxy.is_set) {
405+
return proxy.port;
406+
} else if (suffix.empty()) {
407+
return getOption(option, "-prev");
408+
} else {
409+
return ParseProxyString(GetDefaultProxyAddress().toStdString()).port;
410+
}
411+
}
405412

406413
#ifdef ENABLE_WALLET
407414
case SpendZeroConfChange:
@@ -426,7 +433,9 @@ QVariant OptionsModel::getOption(OptionID option) const
426433
case Prune:
427434
return PruneEnabled(setting());
428435
case PruneSize:
429-
return m_prune_size_gb;
436+
return PruneEnabled(setting()) ? PruneSizeGB(setting()) :
437+
suffix.empty() ? getOption(option, "-prev") :
438+
DEFAULT_PRUNE_TARGET_GB;
430439
case DatabaseCache:
431440
return qlonglong(SettingToInt(setting(), nDefaultDbCache));
432441
case ThreadsScriptVerif:
@@ -440,10 +449,10 @@ QVariant OptionsModel::getOption(OptionID option) const
440449
}
441450
}
442451

443-
bool OptionsModel::setOption(OptionID option, const QVariant& value)
452+
bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::string& suffix)
444453
{
445-
auto changed = [&] { return value.isValid() && value != getOption(option); };
446-
auto update = [&](const util::SettingsValue& value) { return UpdateRwSetting(node(), option, value); };
454+
auto changed = [&] { return value.isValid() && value != getOption(option, suffix); };
455+
auto update = [&](const util::SettingsValue& value) { return UpdateRwSetting(node(), option, suffix, value); };
447456

448457
bool successful = true; /* set to false on parse error */
449458
QSettings settings;
@@ -481,52 +490,60 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
481490
// default proxy
482491
case ProxyUse:
483492
if (changed()) {
484-
update(ProxyString(value.toBool(), m_proxy_ip, m_proxy_port));
485-
setRestartRequired(true);
493+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
494+
update(ProxyString(value.toBool(), getOption(ProxyIP).toString(), getOption(ProxyPort).toString()));
495+
if (suffix.empty() && value.toBool()) UpdateRwSetting(node(), option, "-prev", {});
496+
if (suffix.empty()) setRestartRequired(true);
486497
}
487498
break;
488499
case ProxyIP:
489500
if (changed()) {
490-
m_proxy_ip = value.toString();
491-
if (getOption(ProxyUse).toBool()) {
492-
update(ProxyString(true, m_proxy_ip, m_proxy_port));
493-
setRestartRequired(true);
501+
if (suffix.empty() && !getOption(ProxyUse).toBool()) {
502+
setOption(option, value, "-prev");
503+
} else {
504+
update(ProxyString(true, value.toString(), getOption(ProxyPort).toString()));
494505
}
506+
if (suffix.empty() && getOption(ProxyUse).toBool()) setRestartRequired(true);
495507
}
496508
break;
497509
case ProxyPort:
498510
if (changed()) {
499-
m_proxy_port = value.toString();
500-
if (getOption(ProxyUse).toBool()) {
501-
update(ProxyString(true, m_proxy_ip, m_proxy_port));
502-
setRestartRequired(true);
511+
if (suffix.empty() && !getOption(ProxyUse).toBool()) {
512+
setOption(option, value, "-prev");
513+
} else {
514+
update(ProxyString(true, getOption(ProxyIP).toString(), value.toString()));
503515
}
516+
if (suffix.empty() && getOption(ProxyUse).toBool()) setRestartRequired(true);
504517
}
505518
break;
506519

507520
// separate Tor proxy
508521
case ProxyUseTor:
509522
if (changed()) {
510-
update(ProxyString(value.toBool(), m_onion_ip, m_onion_port));
511-
setRestartRequired(true);
523+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
524+
update(ProxyString(value.toBool(), getOption(ProxyIPTor).toString(), getOption(ProxyPortTor).toString()));
525+
if (suffix.empty() && value.toBool()) UpdateRwSetting(node(), option, "-prev", {});
526+
if (suffix.empty()) setRestartRequired(true);
512527
}
513528
break;
514529
case ProxyIPTor:
515530
if (changed()) {
516-
m_onion_ip = value.toString();
517-
if (getOption(ProxyUseTor).toBool()) {
518-
update(ProxyString(true, m_onion_ip, m_onion_port));
519-
setRestartRequired(true);
531+
if (suffix.empty() && !getOption(ProxyUseTor).toBool()) {
532+
setOption(option, value, "-prev");
533+
} else {
534+
update(ProxyString(true, value.toString(), getOption(ProxyPortTor).toString()));
520535
}
536+
if (suffix.empty() && getOption(ProxyUseTor).toBool()) setRestartRequired(true);
521537
}
522538
break;
523539
case ProxyPortTor:
524540
if (changed()) {
525-
m_onion_port = value.toString();
526-
if (getOption(ProxyUseTor).toBool()) {
527-
update(ProxyString(true, m_onion_ip, m_onion_port));
528-
setRestartRequired(true);
541+
if (suffix.empty() && !getOption(ProxyUseTor).toBool()) {
542+
setOption(option, value, "-prev");
543+
} else {
544+
update(ProxyString(true, getOption(ProxyIPTor).toString(), value.toString()));
529545
}
546+
if (suffix.empty() && getOption(ProxyUseTor).toBool()) setRestartRequired(true);
530547
}
531548
break;
532549

@@ -580,17 +597,20 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
580597
break;
581598
case Prune:
582599
if (changed()) {
583-
update(PruneSetting(value.toBool(), m_prune_size_gb));
584-
setRestartRequired(true);
600+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
601+
update(PruneSetting(value.toBool(), getOption(PruneSize).toInt()));
602+
if (suffix.empty() && value.toBool()) UpdateRwSetting(node(), option, "-prev", {});
603+
if (suffix.empty()) setRestartRequired(true);
585604
}
586605
break;
587606
case PruneSize:
588607
if (changed()) {
589-
m_prune_size_gb = ParsePruneSizeGB(value);
590-
if (getOption(Prune).toBool()) {
591-
update(PruneSetting(true, m_prune_size_gb));
592-
setRestartRequired(true);
608+
if (suffix.empty() && !getOption(Prune).toBool()) {
609+
setOption(option, value, "-prev");
610+
} else {
611+
update(PruneSetting(true, ParsePruneSizeGB(value)));
593612
}
613+
if (suffix.empty() && getOption(Prune).toBool()) setRestartRequired(true);
594614
}
595615
break;
596616
case DatabaseCache:

src/qt/optionsmodel.h

+2-11
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ class OptionsModel : public QAbstractListModel
8181
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
8282
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
8383
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;
84-
QVariant getOption(OptionID option) const;
85-
bool setOption(OptionID option, const QVariant& value);
84+
QVariant getOption(OptionID option, const std::string& suffix="") const;
85+
bool setOption(OptionID option, const QVariant& value, const std::string& suffix="");
8686
/** Updates current unit in memory, settings and emits displayUnitChanged(new_unit) signal */
8787
void setDisplayUnit(const QVariant& new_unit);
8888

@@ -121,15 +121,6 @@ class OptionsModel : public QAbstractListModel
121121
bool m_sub_fee_from_amount;
122122
bool m_enable_psbt_controls;
123123

124-
//! In-memory settings for display. These are stored persistently by the
125-
//! bitcoin node but it's also nice to store them in memory to prevent them
126-
//! getting cleared when enable/disable toggles are used in the GUI.
127-
int m_prune_size_gb;
128-
QString m_proxy_ip;
129-
QString m_proxy_port;
130-
QString m_onion_ip;
131-
QString m_onion_port;
132-
133124
/* settings that were overridden by command-line */
134125
QString strOverriddenByCommandLine;
135126

0 commit comments

Comments
 (0)