Skip to content

Commit 7ded45d

Browse files
committed
Migrate -listen and -server settings from QSettings to settings.json
This commit also removes the `node.args = nullptr` assignment in the Shutdown() function. Clearing node.args there never made sense because it made the Shutdown() function not idempotent, making it fragile and causing issues like bitcoin/bitcoin#23186. Removing that assignment is necessary in this commit to avoid a segfault in OptionTests during the new node().initParameterInteraction() call added here. AppTests calls Shutdown() which sets node.args to null, and OptionTests runs after AppTests and needs node.args not to be null.
1 parent b2c8fc3 commit 7ded45d

File tree

2 files changed

+21
-38
lines changed

2 files changed

+21
-38
lines changed

src/qt/optionsmodel.cpp

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ static const char* SettingName(OptionsModel::OptionID option)
4343
case OptionsModel::ExternalSignerPath: return "signer";
4444
case OptionsModel::MapPortUPnP: return "upnp";
4545
case OptionsModel::MapPortNatpmp: return "natpmp";
46+
case OptionsModel::Listen: return "listen";
47+
case OptionsModel::Server: return "server";
4648
default: throw std::logic_error(strprintf("GUI option %i has no corresponding node setting.", option));
4749
}
4850
}
@@ -131,7 +133,7 @@ bool OptionsModel::Init(bilingual_str& error)
131133
// These are shared with the core or have a command-line parameter
132134
// and we want command-line parameters to overwrite the GUI settings.
133135
for (OptionID option : {DatabaseCache, ThreadsScriptVerif, SpendZeroConfChange, ExternalSignerPath, MapPortUPnP,
134-
MapPortNatpmp}) {
136+
MapPortNatpmp, Listen, Server}) {
135137
std::string setting = SettingName(option);
136138
if (node().isSettingIgnored(setting)) addOverriddenOption("-" + setting);
137139
try {
@@ -167,37 +169,6 @@ bool OptionsModel::Init(bilingual_str& error)
167169
#endif
168170

169171
// Network
170-
if (!settings.contains("fListen"))
171-
settings.setValue("fListen", DEFAULT_LISTEN);
172-
const bool listen{settings.value("fListen").toBool()};
173-
if (!gArgs.SoftSetBoolArg("-listen", listen)) {
174-
addOverriddenOption("-listen");
175-
} else if (!listen) {
176-
// We successfully set -listen=0, thus mimic the logic from InitParameterInteraction():
177-
// "parameter interaction: -listen=0 -> setting -listenonion=0".
178-
//
179-
// Both -listen and -listenonion default to true.
180-
//
181-
// The call order is:
182-
//
183-
// InitParameterInteraction()
184-
// would set -listenonion=0 if it sees -listen=0, but for bitcoin-qt with
185-
// fListen=false -listen is 1 at this point
186-
//
187-
// OptionsModel::Init()
188-
// (this method) can flip -listen from 1 to 0 if fListen=false
189-
//
190-
// AppInitParameterInteraction()
191-
// raises an error if -listen=0 and -listenonion=1
192-
gArgs.SoftSetBoolArg("-listenonion", false);
193-
}
194-
195-
if (!settings.contains("server")) {
196-
settings.setValue("server", false);
197-
}
198-
if (!gArgs.SoftSetBoolArg("-server", settings.value("server").toBool())) {
199-
addOverriddenOption("-server");
200-
}
201172

202173
if (!settings.contains("fUseProxy"))
203174
settings.setValue("fUseProxy", false);
@@ -438,9 +409,9 @@ QVariant OptionsModel::getOption(OptionID option) const
438409
case ThreadsScriptVerif:
439410
return qlonglong(SettingToInt(setting(), DEFAULT_SCRIPTCHECK_THREADS));
440411
case Listen:
441-
return settings.value("fListen");
412+
return SettingToBool(setting(), DEFAULT_LISTEN);
442413
case Server:
443-
return settings.value("server");
414+
return SettingToBool(setting(), false);
444415
default:
445416
return QVariant();
446417
}
@@ -609,14 +580,14 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
609580
}
610581
break;
611582
case Listen:
612-
if (settings.value("fListen") != value) {
613-
settings.setValue("fListen", value);
583+
if (changed()) {
584+
update(value.toBool());
614585
setRestartRequired(true);
615586
}
616587
break;
617588
case Server:
618-
if (settings.value("server") != value) {
619-
settings.setValue("server", value);
589+
if (changed()) {
590+
update(value.toBool());
620591
setRestartRequired(true);
621592
}
622593
break;
@@ -696,4 +667,13 @@ void OptionsModel::checkAndMigrate()
696667
#endif
697668
migrate_setting(MapPortUPnP, "fUseUPnP");
698669
migrate_setting(MapPortNatpmp, "fUseNatpmp");
670+
migrate_setting(Listen, "fListen");
671+
migrate_setting(Server, "server");
672+
673+
// In case migrating QSettings caused any settings value to change, rerun
674+
// parameter interaction code to update other settings. This is particularly
675+
// important for the -listen setting, which should cause -listenonion, -upnp,
676+
// and other settings to default to false if it was set to false.
677+
// (https://github.com/bitcoin-core/gui/issues/567).
678+
node().initParameterInteraction();
699679
}

src/qt/test/optiontests.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ void OptionTests::migrateSettings()
3636
settings.setValue("nDatabaseCache", 600);
3737
settings.setValue("nThreadsScriptVerif", 12);
3838
settings.setValue("fUseUPnP", false);
39+
settings.setValue("fListen", false);
3940

4041
settings.sync();
4142

@@ -45,10 +46,12 @@ void OptionTests::migrateSettings()
4546
QVERIFY(!settings.contains("nDatabaseCache"));
4647
QVERIFY(!settings.contains("nThreadsScriptVerif"));
4748
QVERIFY(!settings.contains("fUseUPnP"));
49+
QVERIFY(!settings.contains("fListen"));
4850

4951
std::ifstream file(gArgs.GetDataDirNet() / "settings.json");
5052
QCOMPARE(std::string(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()).c_str(), "{\n"
5153
" \"dbcache\": \"600\",\n"
54+
" \"listen\": false,\n"
5255
" \"par\": \"12\"\n"
5356
"}\n");
5457
}

0 commit comments

Comments
 (0)