Skip to content

Commit c2051b3

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/bitcoin#15936 (review) bitcoin/bitcoin#15936 (comment) bitcoin/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 8377408 commit c2051b3

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.updateSetting() with Bitcoin 22.x workaround. */
62-
static void UpdateSetting(interfaces::Node& node, OptionsModel::OptionID option, const util::SettingsValue& value)
62+
static void UpdateSetting(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 UpdateSetting(interfaces::Node& node, OptionsModel::OptionID option,
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.updateSetting(SettingName(option), value.getValStr());
76+
node.updateSetting(SettingName(option) + suffix, value.getValStr());
7777
} else {
78-
node.updateSetting(SettingName(option), value);
78+
node.updateSetting(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();
@@ -317,8 +310,6 @@ void OptionsModel::SetPruneTargetGB(int prune_target_gb)
317310
const util::SettingsValue cur_value = node().getPersistentSetting("prune");
318311
const util::SettingsValue new_value = PruneSetting(prune_target_gb > 0, prune_target_gb);
319312

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

@@ -359,9 +355,9 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
359355
return successful;
360356
}
361357

362-
QVariant OptionsModel::getOption(OptionID option) const
358+
QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) const
363359
{
364-
auto setting = [&]{ return node().getPersistentSetting(SettingName(option)); };
360+
auto setting = [&]{ return node().getPersistentSetting(SettingName(option) + suffix); };
365361

366362
QSettings settings;
367363
switch (option) {
@@ -388,19 +384,30 @@ QVariant OptionsModel::getOption(OptionID option) const
388384

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

405412
#ifdef ENABLE_WALLET
406413
case SpendZeroConfChange:
@@ -425,7 +432,9 @@ QVariant OptionsModel::getOption(OptionID option) const
425432
case Prune:
426433
return PruneEnabled(setting());
427434
case PruneSize:
428-
return m_prune_size_gb;
435+
return PruneEnabled(setting()) ? PruneSizeGB(setting()) :
436+
suffix.empty() ? getOption(option, "-prev") :
437+
DEFAULT_PRUNE_TARGET_GB;
429438
case DatabaseCache:
430439
return qlonglong(SettingToInt(setting(), nDefaultDbCache));
431440
case ThreadsScriptVerif:
@@ -439,10 +448,10 @@ QVariant OptionsModel::getOption(OptionID option) const
439448
}
440449
}
441450

442-
bool OptionsModel::setOption(OptionID option, const QVariant& value)
451+
bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::string& suffix)
443452
{
444-
auto changed = [&] { return value.isValid() && value != getOption(option); };
445-
auto update = [&](const util::SettingsValue& value) { return UpdateSetting(node(), option, value); };
453+
auto changed = [&] { return value.isValid() && value != getOption(option, suffix); };
454+
auto update = [&](const util::SettingsValue& value) { return UpdateSetting(node(), option, suffix, value); };
446455

447456
bool successful = true; /* set to false on parse error */
448457
QSettings settings;
@@ -480,51 +489,59 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
480489
// default proxy
481490
case ProxyUse:
482491
if (changed()) {
483-
update(ProxyString(value.toBool(), m_proxy_ip, m_proxy_port));
484-
setRestartRequired(true);
492+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
493+
update(ProxyString(value.toBool(), getOption(ProxyIP).toString(), getOption(ProxyPort).toString()));
494+
if (suffix.empty() && value.toBool()) setOption(option, false, "-prev");
495+
if (suffix.empty()) setRestartRequired(true);
485496
}
486497
break;
487498
case ProxyIP:
488499
if (changed()) {
489-
m_proxy_ip = value.toString();
490-
if (getOption(ProxyUse).toBool()) {
491-
update(ProxyString(true, m_proxy_ip, m_proxy_port));
492-
setRestartRequired(true);
500+
if (!suffix.empty() || getOption(ProxyUse).toBool()) {
501+
update(ProxyString(true, value.toString(), getOption(ProxyPort).toString()));
502+
if (suffix.empty()) setRestartRequired(true);
503+
} else {
504+
setOption(option, value, "-prev");
493505
}
494506
}
495507
break;
496508
case ProxyPort:
497509
if (changed()) {
498-
m_proxy_port = value.toString();
499-
if (getOption(ProxyUse).toBool()) {
500-
update(ProxyString(true, m_proxy_ip, m_proxy_port));
501-
setRestartRequired(true);
510+
if (!suffix.empty() || getOption(ProxyUse).toBool()) {
511+
update(ProxyString(true, getOption(ProxyIP).toString(), value.toString()));
512+
if (suffix.empty()) setRestartRequired(true);
513+
} else {
514+
setOption(option, value, "-prev");
502515
}
503516
}
504517
break;
505518

506519
// separate Tor proxy
507520
case ProxyUseTor:
508521
if (changed()) {
509-
update(ProxyString(value.toBool(), m_onion_ip, m_onion_port));
510-
setRestartRequired(true);
522+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
523+
update(ProxyString(value.toBool(), getOption(ProxyIPTor).toString(), getOption(ProxyPortTor).toString()));
524+
if (suffix.empty() && value.toBool()) setOption(option, false, "-prev");
525+
if (suffix.empty()) setRestartRequired(true);
511526
}
512527
break;
513528
case ProxyIPTor:
514529
if (changed()) {
515-
m_onion_ip = value.toString();
516-
if (getOption(ProxyUseTor).toBool()) {
517-
update(ProxyString(true, m_onion_ip, m_onion_port));
518-
setRestartRequired(true);
530+
if (!suffix.empty() || getOption(ProxyUseTor).toBool()) {
531+
update(ProxyString(true, value.toString(), getOption(ProxyPortTor).toString()));
532+
if (suffix.empty()) setRestartRequired(true);
533+
} else {
534+
setOption(option, value, "-prev");
519535
}
520536
}
521537
break;
522538
case ProxyPortTor:
523539
if (changed()) {
524-
m_onion_port = value.toString();
525-
if (getOption(ProxyUseTor).toBool()) {
526-
update(ProxyString(true, m_onion_ip, m_onion_port));
527-
setRestartRequired(true);
540+
if (!suffix.empty() || getOption(ProxyUseTor).toBool()) {
541+
update(ProxyString(true, getOption(ProxyIPTor).toString(), value.toString()));
542+
if (suffix.empty()) setRestartRequired(true);
543+
} else {
544+
setOption(option, value, "-prev");
528545
}
529546
}
530547
break;
@@ -579,16 +596,19 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
579596
break;
580597
case Prune:
581598
if (changed()) {
582-
update(PruneSetting(value.toBool(), m_prune_size_gb));
583-
setRestartRequired(true);
599+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
600+
update(PruneSetting(value.toBool(), getOption(PruneSize).toInt()));
601+
if (suffix.empty() && value.toBool()) setOption(option, false, "-prev");
602+
if (suffix.empty()) setRestartRequired(true);
584603
}
585604
break;
586605
case PruneSize:
587606
if (changed()) {
588-
m_prune_size_gb = ParsePruneSizeGB(value);
589-
if (getOption(Prune).toBool()) {
590-
update(PruneSetting(true, m_prune_size_gb));
591-
setRestartRequired(true);
607+
if (!suffix.empty() || getOption(Prune).toBool()) {
608+
update(PruneSetting(true, ParsePruneSizeGB(value)));
609+
if (suffix.empty()) setRestartRequired(true);
610+
} else {
611+
setOption(option, value, "-prev");
592612
}
593613
}
594614
break;

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)