Skip to content

Commit f7464d8

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 29e371d commit f7464d8

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
@@ -42,6 +42,8 @@ const char* SettingName(OptionsModel::OptionID option)
4242
case OptionsModel::ExternalSignerPath: return "signer";
4343
case OptionsModel::MapPortUPnP: return "upnp";
4444
case OptionsModel::MapPortNatpmp: return "natpmp";
45+
case OptionsModel::Listen: return "listen";
46+
case OptionsModel::Server: return "server";
4547
default: throw std::logic_error(strprintf("GUI option %i has no corresponding node setting.", option));
4648
};
4749
}
@@ -126,7 +128,7 @@ bool OptionsModel::Init(bilingual_str& error)
126128
// These are shared with the core or have a command-line parameter
127129
// and we want command-line parameters to overwrite the GUI settings.
128130
for (OptionID option : {DatabaseCache, ThreadsScriptVerif, SpendZeroConfChange, ExternalSignerPath, MapPortUPnP,
129-
MapPortNatpmp}) {
131+
MapPortNatpmp, Listen, Server}) {
130132
std::string setting = SettingName(option);
131133
if (node().isSettingIgnored(setting)) addOverriddenOption("-" + setting);
132134
try {
@@ -162,37 +164,6 @@ bool OptionsModel::Init(bilingual_str& error)
162164
#endif
163165

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

197168
if (!settings.contains("fUseProxy"))
198169
settings.setValue("fUseProxy", false);
@@ -433,9 +404,9 @@ QVariant OptionsModel::getOption(OptionID option) const
433404
case ThreadsScriptVerif:
434405
return qlonglong(SettingToInt(setting(), DEFAULT_SCRIPTCHECK_THREADS));
435406
case Listen:
436-
return settings.value("fListen");
407+
return SettingToBool(setting(), DEFAULT_LISTEN);
437408
case Server:
438-
return settings.value("server");
409+
return SettingToBool(setting(), false);
439410
default:
440411
return QVariant();
441412
}
@@ -604,14 +575,14 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
604575
}
605576
break;
606577
case Listen:
607-
if (settings.value("fListen") != value) {
608-
settings.setValue("fListen", value);
578+
if (changed()) {
579+
update(value.toBool());
609580
setRestartRequired(true);
610581
}
611582
break;
612583
case Server:
613-
if (settings.value("server") != value) {
614-
settings.setValue("server", value);
584+
if (changed()) {
585+
update(value.toBool());
615586
setRestartRequired(true);
616587
}
617588
break;
@@ -691,4 +662,13 @@ void OptionsModel::checkAndMigrate()
691662
#endif
692663
migrate_setting(MapPortUPnP, "fUseUPnP");
693664
migrate_setting(MapPortNatpmp, "fUseNatpmp");
665+
migrate_setting(Listen, "fListen");
666+
migrate_setting(Server, "server");
667+
668+
// In case migrating QSettings caused any settings value to change, rerun
669+
// parameter interaction code to update other settings. This is particularly
670+
// important for the -listen setting, which should cause -listenonion, -upnp,
671+
// and other settings to default to false if it was set to false.
672+
// (https://github.com/bitcoin-core/gui/issues/567).
673+
node().initParameterInteraction();
694674
}

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)