Skip to content

Commit 4e86ab5

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 fd3962d commit 4e86ab5

File tree

2 files changed

+73
-62
lines changed

2 files changed

+73
-62
lines changed

src/qt/optionsmodel.cpp

+71-51
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,6 @@ void OptionsModel::addOverriddenOption(const std::string &option)
109109
bool OptionsModel::Init(bilingual_str& error)
110110
{
111111
// Initialize display settings from stored settings.
112-
m_prune_size_gb = PruneSizeGB(node().getPersistentSetting("prune"));
113-
ProxySetting proxy = ParseProxyString(SettingToString(node().getPersistentSetting("proxy"), GetDefaultProxyAddress().toStdString()));
114-
m_proxy_ip = proxy.ip;
115-
m_proxy_port = proxy.port;
116-
ProxySetting onion = ParseProxyString(SettingToString(node().getPersistentSetting("onion"), GetDefaultProxyAddress().toStdString()));
117-
m_onion_ip = onion.ip;
118-
m_onion_port = onion.port;
119112
language = QString::fromStdString(SettingToString(node().getPersistentSetting("lang"), ""));
120113

121114
checkAndMigrate();
@@ -290,8 +283,6 @@ void OptionsModel::SetPruneTargetGB(int prune_target_gb)
290283
const util::SettingsValue cur_value = node().getPersistentSetting("prune");
291284
const util::SettingsValue new_value = PruneSetting(prune_target_gb > 0, prune_target_gb);
292285

293-
m_prune_size_gb = prune_target_gb;
294-
295286
// Force setting to take effect. It is still safe to change the value at
296287
// this point because this function is only called after the intro screen is
297288
// shown, before the node starts.
@@ -306,6 +297,11 @@ void OptionsModel::SetPruneTargetGB(int prune_target_gb)
306297
// RestartRequired flag
307298
node().updateSetting("prune", new_value);
308299
}
300+
301+
// Keep previous pruning size, if pruning was disabled.
302+
if (PruneEnabled(cur_value)) {
303+
node().updateSetting("prune-prev", PruneEnabled(new_value) ? util::SettingsValue{} : cur_value);
304+
}
309305
}
310306

311307
// read QSettings values and return them
@@ -332,9 +328,9 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
332328
return successful;
333329
}
334330

335-
QVariant OptionsModel::getOption(OptionID option) const
331+
QVariant OptionsModel::getOption(OptionID option, const std::string& suffix) const
336332
{
337-
auto setting = [&]{ return node().getPersistentSetting(SettingName(option)); };
333+
auto setting = [&]{ return node().getPersistentSetting(SettingName(option) + suffix); };
338334

339335
QSettings settings;
340336
switch (option) {
@@ -361,19 +357,30 @@ QVariant OptionsModel::getOption(OptionID option) const
361357

362358
// default proxy
363359
case ProxyUse:
360+
case ProxyUseTor:
364361
return ParseProxyString(SettingToString(setting(), "")).is_set;
365362
case ProxyIP:
366-
return m_proxy_ip;
363+
case ProxyIPTor: {
364+
ProxySetting proxy = ParseProxyString(SettingToString(setting(), ""));
365+
if (proxy.is_set) {
366+
return proxy.ip;
367+
} else if (suffix.empty()) {
368+
return getOption(option, "-prev");
369+
} else {
370+
return ParseProxyString(GetDefaultProxyAddress().toStdString()).ip;
371+
}
372+
}
367373
case ProxyPort:
368-
return m_proxy_port;
369-
370-
// separate Tor proxy
371-
case ProxyUseTor:
372-
return ParseProxyString(SettingToString(setting(), "")).is_set;
373-
case ProxyIPTor:
374-
return m_onion_ip;
375-
case ProxyPortTor:
376-
return m_onion_port;
374+
case ProxyPortTor: {
375+
ProxySetting proxy = ParseProxyString(SettingToString(setting(), ""));
376+
if (proxy.is_set) {
377+
return proxy.port;
378+
} else if (suffix.empty()) {
379+
return getOption(option, "-prev");
380+
} else {
381+
return ParseProxyString(GetDefaultProxyAddress().toStdString()).port;
382+
}
383+
}
377384

378385
#ifdef ENABLE_WALLET
379386
case SpendZeroConfChange:
@@ -398,7 +405,9 @@ QVariant OptionsModel::getOption(OptionID option) const
398405
case Prune:
399406
return PruneEnabled(setting());
400407
case PruneSize:
401-
return m_prune_size_gb;
408+
return PruneEnabled(setting()) ? PruneSizeGB(setting()) :
409+
suffix.empty() ? getOption(option, "-prev") :
410+
DEFAULT_PRUNE_TARGET_GB;
402411
case DatabaseCache:
403412
return qlonglong(SettingToInt(setting(), nDefaultDbCache));
404413
case ThreadsScriptVerif:
@@ -412,10 +421,10 @@ QVariant OptionsModel::getOption(OptionID option) const
412421
}
413422
}
414423

415-
bool OptionsModel::setOption(OptionID option, const QVariant& value)
424+
bool OptionsModel::setOption(OptionID option, const QVariant& value, const std::string& suffix)
416425
{
417-
auto changed = [&] { return value.isValid() && value != getOption(option); };
418-
auto update = [&](const util::SettingsValue& value) { return node().updateSetting(SettingName(option), value); };
426+
auto changed = [&] { return value.isValid() && value != getOption(option, suffix); };
427+
auto update = [&](const util::SettingsValue& value) { return node().updateSetting(SettingName(option) + suffix, value); };
419428

420429
bool successful = true; /* set to false on parse error */
421430
QSettings settings;
@@ -453,51 +462,59 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
453462
// default proxy
454463
case ProxyUse:
455464
if (changed()) {
456-
update(ProxyString(value.toBool(), m_proxy_ip, m_proxy_port));
457-
setRestartRequired(true);
465+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
466+
update(ProxyString(value.toBool(), getOption(ProxyIP).toString(), getOption(ProxyPort).toString()));
467+
if (suffix.empty() && value.toBool()) setOption(option, false, "-prev");
468+
if (suffix.empty()) setRestartRequired(true);
458469
}
459470
break;
460471
case ProxyIP:
461472
if (changed()) {
462-
m_proxy_ip = value.toString();
463-
if (getOption(ProxyUse).toBool()) {
464-
update(ProxyString(true, m_proxy_ip, m_proxy_port));
465-
setRestartRequired(true);
473+
if (!suffix.empty() || getOption(ProxyUse).toBool()) {
474+
update(ProxyString(true, value.toString(), getOption(ProxyPort).toString()));
475+
if (suffix.empty()) setRestartRequired(true);
476+
} else {
477+
setOption(option, value, "-prev");
466478
}
467479
}
468480
break;
469481
case ProxyPort:
470482
if (changed()) {
471-
m_proxy_port = value.toString();
472-
if (getOption(ProxyUse).toBool()) {
473-
update(ProxyString(true, m_proxy_ip, m_proxy_port));
474-
setRestartRequired(true);
483+
if (!suffix.empty() || getOption(ProxyUse).toBool()) {
484+
update(ProxyString(true, getOption(ProxyIP).toString(), value.toString()));
485+
if (suffix.empty()) setRestartRequired(true);
486+
} else {
487+
setOption(option, value, "-prev");
475488
}
476489
}
477490
break;
478491

479492
// separate Tor proxy
480493
case ProxyUseTor:
481494
if (changed()) {
482-
update(ProxyString(value.toBool(), m_onion_ip, m_onion_port));
483-
setRestartRequired(true);
495+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
496+
update(ProxyString(value.toBool(), getOption(ProxyIPTor).toString(), getOption(ProxyPortTor).toString()));
497+
if (suffix.empty() && value.toBool()) setOption(option, false, "-prev");
498+
if (suffix.empty()) setRestartRequired(true);
484499
}
485500
break;
486501
case ProxyIPTor:
487502
if (changed()) {
488-
m_onion_ip = value.toString();
489-
if (getOption(ProxyUseTor).toBool()) {
490-
update(ProxyString(true, m_onion_ip, m_onion_port));
491-
setRestartRequired(true);
503+
if (!suffix.empty() || getOption(ProxyUseTor).toBool()) {
504+
update(ProxyString(true, value.toString(), getOption(ProxyPortTor).toString()));
505+
if (suffix.empty()) setRestartRequired(true);
506+
} else {
507+
setOption(option, value, "-prev");
492508
}
493509
}
494510
break;
495511
case ProxyPortTor:
496512
if (changed()) {
497-
m_onion_port = value.toString();
498-
if (getOption(ProxyUseTor).toBool()) {
499-
update(ProxyString(true, m_onion_ip, m_onion_port));
500-
setRestartRequired(true);
513+
if (!suffix.empty() || getOption(ProxyUseTor).toBool()) {
514+
update(ProxyString(true, getOption(ProxyIPTor).toString(), value.toString()));
515+
if (suffix.empty()) setRestartRequired(true);
516+
} else {
517+
setOption(option, value, "-prev");
501518
}
502519
}
503520
break;
@@ -552,16 +569,19 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
552569
break;
553570
case Prune:
554571
if (changed()) {
555-
update(PruneSetting(value.toBool(), m_prune_size_gb));
556-
setRestartRequired(true);
572+
if (suffix.empty() && !value.toBool()) setOption(option, true, "-prev");
573+
update(PruneSetting(value.toBool(), getOption(PruneSize).toInt()));
574+
if (suffix.empty() && value.toBool()) setOption(option, false, "-prev");
575+
if (suffix.empty()) setRestartRequired(true);
557576
}
558577
break;
559578
case PruneSize:
560579
if (changed()) {
561-
m_prune_size_gb = ParsePruneSizeGB(value);
562-
if (getOption(Prune).toBool()) {
563-
update(PruneSetting(true, m_prune_size_gb));
564-
setRestartRequired(true);
580+
if (!suffix.empty() || getOption(Prune).toBool()) {
581+
update(PruneSetting(true, ParsePruneSizeGB(value)));
582+
if (suffix.empty()) setRestartRequired(true);
583+
} else {
584+
setOption(option, value, "-prev");
565585
}
566586
}
567587
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)