Bitcoin ABC 0.32.12
P2P Digital Currency
optionsmodel.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2016 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#if defined(HAVE_CONFIG_H)
6#include <config/bitcoin-config.h>
7#endif
8
9#include <qt/optionsmodel.h>
10
11#include <clientversion.h>
12#include <common/args.h>
13#include <interfaces/node.h>
14#include <mapport.h>
15#include <net.h>
16#include <netbase.h>
17#include <node/caches.h>
18#include <qt/bitcoinunits.h>
19#include <qt/guiconstants.h>
20#include <qt/guiutil.h>
21#include <util/string.h>
22#include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
23
24#include <QDebug> // needed by qInfo()
25#ifdef ENABLE_BIP70
26#include <QNetworkProxy>
27#endif
28#include <QSettings>
29#include <QStringList>
30
31using util::ToString;
32
33const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1";
34
35static QString GetDefaultProxyAddress();
36
37OptionsModel::OptionsModel(QObject *parent, bool resetSettings)
38 : QAbstractListModel(parent) {
39 Init(resetSettings);
40}
41
42void OptionsModel::addOverriddenOption(const std::string &option) {
44 QString::fromStdString(option) + "=" +
45 QString::fromStdString(gArgs.GetArg(option, "")) + " ";
46}
47
48// Writes all missing QSettings with their default values
49void OptionsModel::Init(bool resetSettings) {
50 if (resetSettings) {
51 Reset();
52 }
53
55
56 QSettings settings;
57
58 // Ensure restart flag is unset on client startup
59 setRestartRequired(false);
60
61 // These are Qt-only settings:
62
63 // Window
64 if (!settings.contains("fHideTrayIcon")) {
65 settings.setValue("fHideTrayIcon", false);
66 }
67 fHideTrayIcon = settings.value("fHideTrayIcon").toBool();
69
70 if (!settings.contains("fMinimizeToTray")) {
71 settings.setValue("fMinimizeToTray", false);
72 }
74 settings.value("fMinimizeToTray").toBool() && !fHideTrayIcon;
75
76 if (!settings.contains("fMinimizeOnClose")) {
77 settings.setValue("fMinimizeOnClose", false);
78 }
79 fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool();
80
81 // Display
82 if (!settings.contains("nDisplayUnit")) {
83 settings.setValue("nDisplayUnit", BitcoinUnits::base);
84 }
85 nDisplayUnit = settings.value("nDisplayUnit").toInt();
86
87 if (!settings.contains("strThirdPartyTxUrls")) {
88 settings.setValue("strThirdPartyTxUrls", "");
89 }
90 strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();
91
92 if (!settings.contains("fCoinControlFeatures")) {
93 settings.setValue("fCoinControlFeatures", false);
94 }
96 settings.value("fCoinControlFeatures", false).toBool();
97
98 // These are shared with the core or have a command-line parameter
99 // and we want command-line parameters to overwrite the GUI settings.
100 //
101 // If setting doesn't exist create it with defaults.
102 //
103 // If gArgs.SoftSetArg() or gArgs.SoftSetBoolArg() return false we were
104 // overridden
105 // by command-line and show this in the UI.
106
107 // Main
108 if (!settings.contains("bPrune")) {
109 settings.setValue("bPrune", false);
110 }
111 if (!settings.contains("nPruneSize")) {
112 settings.setValue("nPruneSize", DEFAULT_PRUNE_TARGET_GB);
113 }
114 SetPruneEnabled(settings.value("bPrune").toBool());
115
116 if (!settings.contains("nDatabaseCache")) {
117 settings.setValue("nDatabaseCache", (qint64)DEFAULT_DB_CACHE >> 20);
118 }
119 if (!gArgs.SoftSetArg(
120 "-dbcache",
121 settings.value("nDatabaseCache").toString().toStdString())) {
122 addOverriddenOption("-dbcache");
123 }
124
125 if (!settings.contains("nThreadsScriptVerif")) {
126 settings.setValue("nThreadsScriptVerif", DEFAULT_SCRIPTCHECK_THREADS);
127 }
128 if (!gArgs.SoftSetArg(
129 "-par",
130 settings.value("nThreadsScriptVerif").toString().toStdString())) {
131 addOverriddenOption("-par");
132 }
133
134 if (!settings.contains("strDataDir")) {
135 settings.setValue("strDataDir", GUIUtil::getDefaultDataDirectory());
136 }
137
138// Wallet
139#ifdef ENABLE_WALLET
140 if (!settings.contains("bSpendZeroConfChange")) {
141 settings.setValue("bSpendZeroConfChange", true);
142 }
144 "-spendzeroconfchange",
145 settings.value("bSpendZeroConfChange").toBool())) {
146 addOverriddenOption("-spendzeroconfchange");
147 }
148#endif
149
150 // Network
151 if (!settings.contains("fUseUPnP")) {
152 settings.setValue("fUseUPnP", DEFAULT_UPNP);
153 }
154 if (!gArgs.SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool())) {
155 addOverriddenOption("-upnp");
156 }
157
158 if (!settings.contains("fUseNatpmp")) {
159 settings.setValue("fUseNatpmp", DEFAULT_NATPMP);
160 }
161 if (!gArgs.SoftSetBoolArg("-natpmp",
162 settings.value("fUseNatpmp").toBool())) {
163 addOverriddenOption("-natpmp");
164 }
165
166 if (!settings.contains("fListen")) {
167 settings.setValue("fListen", DEFAULT_LISTEN);
168 }
169 if (!gArgs.SoftSetBoolArg("-listen", settings.value("fListen").toBool())) {
170 addOverriddenOption("-listen");
171 }
172
173 if (!settings.contains("fUseProxy")) {
174 settings.setValue("fUseProxy", false);
175 }
176 if (!settings.contains("addrProxy")) {
177 settings.setValue("addrProxy", GetDefaultProxyAddress());
178 }
179 // Only try to set -proxy, if user has enabled fUseProxy
180 if (settings.value("fUseProxy").toBool() &&
182 "-proxy", settings.value("addrProxy").toString().toStdString())) {
183 addOverriddenOption("-proxy");
184 } else if (!settings.value("fUseProxy").toBool() &&
185 !gArgs.GetArg("-proxy", "").empty()) {
186 addOverriddenOption("-proxy");
187 }
188
189 if (!settings.contains("fUseSeparateProxyTor")) {
190 settings.setValue("fUseSeparateProxyTor", false);
191 }
192 if (!settings.contains("addrSeparateProxyTor")) {
193 settings.setValue("addrSeparateProxyTor", GetDefaultProxyAddress());
194 }
195 // Only try to set -onion, if user has enabled fUseSeparateProxyTor
196 if (settings.value("fUseSeparateProxyTor").toBool() &&
198 "-onion",
199 settings.value("addrSeparateProxyTor").toString().toStdString())) {
200 addOverriddenOption("-onion");
201 } else if (!settings.value("fUseSeparateProxyTor").toBool() &&
202 !gArgs.GetArg("-onion", "").empty()) {
203 addOverriddenOption("-onion");
204 }
205
206 // Display
207 if (!settings.contains("language")) {
208 settings.setValue("language", "");
209 }
210 if (!gArgs.SoftSetArg(
211 "-lang", settings.value("language").toString().toStdString())) {
212 addOverriddenOption("-lang");
213 }
214
215 language = settings.value("language").toString();
216}
217
222static void CopySettings(QSettings &dst, const QSettings &src) {
223 for (const QString &key : src.allKeys()) {
224 dst.setValue(key, src.value(key));
225 }
226}
227
229static void BackupSettings(const fs::path &filename, const QSettings &src) {
230 qInfo() << "Backing up GUI settings to"
231 << GUIUtil::boostPathToQString(filename);
232 QSettings dst(GUIUtil::boostPathToQString(filename), QSettings::IniFormat);
233 dst.clear();
234 CopySettings(dst, src);
235}
236
238 QSettings settings;
239
240 // Backup old settings to chain-specific datadir for troubleshooting
241 BackupSettings(gArgs.GetDataDirNet() / "guisettings.ini.bak", settings);
242
243 // Save the strDataDir setting
244 QString dataDir = GUIUtil::getDefaultDataDirectory();
245 dataDir = settings.value("strDataDir", dataDir).toString();
246
247 // Remove all entries from our QSettings object
248 settings.clear();
249
250 // Set strDataDir
251 settings.setValue("strDataDir", dataDir);
252
253 // Set that this was reset
254 settings.setValue("fReset", true);
255
256 // default setting for OptionsModel::StartAtStartup - disabled
259 }
260}
261
262int OptionsModel::rowCount(const QModelIndex &parent) const {
263 return OptionIDRowCount;
264}
265
267 bool is_set;
268 QString ip;
269 QString port;
270};
271
272static ProxySetting GetProxySetting(QSettings &settings, const QString &name) {
273 static const ProxySetting default_val = {
275 QString("%1").arg(DEFAULT_GUI_PROXY_PORT)};
276 // Handle the case that the setting is not set at all
277 if (!settings.contains(name)) {
278 return default_val;
279 }
280 // contains IP at index 0 and port at index 1
281 QStringList ip_port =
282 GUIUtil::splitSkipEmptyParts(settings.value(name).toString(), ":");
283 if (ip_port.size() == 2) {
284 return {true, ip_port.at(0), ip_port.at(1)};
285 } else { // Invalid: return default
286 return default_val;
287 }
288}
289
290static void SetProxySetting(QSettings &settings, const QString &name,
291 const ProxySetting &ip_port) {
292 settings.setValue(name, ip_port.ip + ":" + ip_port.port);
293}
294
295static QString GetDefaultProxyAddress() {
296 return QString("%1:%2")
299}
300
301void OptionsModel::SetPruneEnabled(bool prune, bool force) {
302 QSettings settings;
303 settings.setValue("bPrune", prune);
304 const int64_t prune_target_mib =
305 PruneGBtoMiB(settings.value("nPruneSize").toInt());
306 std::string prune_val = prune ? ToString(prune_target_mib) : "0";
307 if (force) {
308 gArgs.ForceSetArg("-prune", prune_val);
309 return;
310 }
311 if (!gArgs.SoftSetArg("-prune", prune_val)) {
312 addOverriddenOption("-prune");
313 }
314}
315
316void OptionsModel::SetPruneTargetGB(int prune_target_gb, bool force) {
317 const bool prune = prune_target_gb > 0;
318 if (prune) {
319 QSettings settings;
320 settings.setValue("nPruneSize", prune_target_gb);
321 }
322 SetPruneEnabled(prune, force);
323}
324
325// read QSettings values and return them
326QVariant OptionsModel::data(const QModelIndex &index, int role) const {
327 if (role == Qt::EditRole) {
328 QSettings settings;
329 switch (index.row()) {
330 case StartAtStartup:
332 case HideTrayIcon:
333 return fHideTrayIcon;
334 case MinimizeToTray:
335 return fMinimizeToTray;
336 case MapPortUPnP:
337#ifdef USE_UPNP
338 return settings.value("fUseUPnP");
339#else
340 return false;
341#endif // USE_UPNP
342 case MapPortNatpmp:
343#ifdef USE_NATPMP
344 return settings.value("fUseNatpmp");
345#else
346 return false;
347#endif // USE_NATPMP
348 case MinimizeOnClose:
349 return fMinimizeOnClose;
350
351 // default proxy
352 case ProxyUse:
353 return settings.value("fUseProxy", false);
354 case ProxyIP:
355 return GetProxySetting(settings, "addrProxy").ip;
356 case ProxyPort:
357 return GetProxySetting(settings, "addrProxy").port;
358
359 // separate Tor proxy
360 case ProxyUseTor:
361 return settings.value("fUseSeparateProxyTor", false);
362 case ProxyIPTor:
363 return GetProxySetting(settings, "addrSeparateProxyTor").ip;
364 case ProxyPortTor:
365 return GetProxySetting(settings, "addrSeparateProxyTor").port;
366
367#ifdef ENABLE_WALLET
369 return settings.value("bSpendZeroConfChange");
370#endif
371 case DisplayUnit:
372 return nDisplayUnit;
373 case ThirdPartyTxUrls:
374 return strThirdPartyTxUrls;
375 case Language:
376 return settings.value("language");
379 case Prune:
380 return settings.value("bPrune");
381 case PruneSize:
382 return settings.value("nPruneSize");
383 case DatabaseCache:
384 return settings.value("nDatabaseCache");
386 return settings.value("nThreadsScriptVerif");
387 case Listen:
388 return settings.value("fListen");
389 default:
390 return QVariant();
391 }
392 }
393 return QVariant();
394}
395
396// write QSettings values
397bool OptionsModel::setData(const QModelIndex &index, const QVariant &value,
398 int role) {
399 bool successful = true; /* set to false on parse error */
400 if (role == Qt::EditRole) {
401 QSettings settings;
402 switch (index.row()) {
403 case StartAtStartup:
404 successful = GUIUtil::SetStartOnSystemStartup(value.toBool());
405 break;
406 case HideTrayIcon:
407 fHideTrayIcon = value.toBool();
408 settings.setValue("fHideTrayIcon", fHideTrayIcon);
410 break;
411 case MinimizeToTray:
412 fMinimizeToTray = value.toBool();
413 settings.setValue("fMinimizeToTray", fMinimizeToTray);
414 break;
415 case MapPortUPnP: // core option - can be changed on-the-fly
416 settings.setValue("fUseUPnP", value.toBool());
417 break;
418 case MapPortNatpmp: // core option - can be changed on-the-fly
419 settings.setValue("fUseNatpmp", value.toBool());
420 break;
421 case MinimizeOnClose:
422 fMinimizeOnClose = value.toBool();
423 settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
424 break;
425
426 // default proxy
427 case ProxyUse:
428 if (settings.value("fUseProxy") != value) {
429 settings.setValue("fUseProxy", value.toBool());
430 setRestartRequired(true);
431 }
432 break;
433 case ProxyIP: {
434 auto ip_port = GetProxySetting(settings, "addrProxy");
435 if (!ip_port.is_set || ip_port.ip != value.toString()) {
436 ip_port.ip = value.toString();
437 SetProxySetting(settings, "addrProxy", ip_port);
438 setRestartRequired(true);
439 }
440 } break;
441 case ProxyPort: {
442 auto ip_port = GetProxySetting(settings, "addrProxy");
443 if (!ip_port.is_set || ip_port.port != value.toString()) {
444 ip_port.port = value.toString();
445 SetProxySetting(settings, "addrProxy", ip_port);
446 setRestartRequired(true);
447 }
448 } break;
449
450 // separate Tor proxy
451 case ProxyUseTor:
452 if (settings.value("fUseSeparateProxyTor") != value) {
453 settings.setValue("fUseSeparateProxyTor", value.toBool());
454 setRestartRequired(true);
455 }
456 break;
457 case ProxyIPTor: {
458 auto ip_port =
459 GetProxySetting(settings, "addrSeparateProxyTor");
460 if (!ip_port.is_set || ip_port.ip != value.toString()) {
461 ip_port.ip = value.toString();
462 SetProxySetting(settings, "addrSeparateProxyTor", ip_port);
463 setRestartRequired(true);
464 }
465 } break;
466 case ProxyPortTor: {
467 auto ip_port =
468 GetProxySetting(settings, "addrSeparateProxyTor");
469 if (!ip_port.is_set || ip_port.port != value.toString()) {
470 ip_port.port = value.toString();
471 SetProxySetting(settings, "addrSeparateProxyTor", ip_port);
472 setRestartRequired(true);
473 }
474 } break;
475
476#ifdef ENABLE_WALLET
478 if (settings.value("bSpendZeroConfChange") != value) {
479 settings.setValue("bSpendZeroConfChange", value);
480 setRestartRequired(true);
481 }
482 break;
483#endif
484 case DisplayUnit:
485 setDisplayUnit(value);
486 break;
487 case ThirdPartyTxUrls:
488 if (strThirdPartyTxUrls != value.toString()) {
489 strThirdPartyTxUrls = value.toString();
490 settings.setValue("strThirdPartyTxUrls",
492 setRestartRequired(true);
493 }
494 break;
495 case Language:
496 if (settings.value("language") != value) {
497 settings.setValue("language", value);
498 setRestartRequired(true);
499 }
500 break;
502 fCoinControlFeatures = value.toBool();
503 settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
505 break;
506 case Prune:
507 if (settings.value("bPrune") != value) {
508 settings.setValue("bPrune", value);
509 setRestartRequired(true);
510 }
511 break;
512 case PruneSize:
513 if (settings.value("nPruneSize") != value) {
514 settings.setValue("nPruneSize", value);
515 setRestartRequired(true);
516 }
517 break;
518 case DatabaseCache:
519 if (settings.value("nDatabaseCache") != value) {
520 settings.setValue("nDatabaseCache", value);
521 setRestartRequired(true);
522 }
523 break;
525 if (settings.value("nThreadsScriptVerif") != value) {
526 settings.setValue("nThreadsScriptVerif", value);
527 setRestartRequired(true);
528 }
529 break;
530 case Listen:
531 if (settings.value("fListen") != value) {
532 settings.setValue("fListen", value);
533 setRestartRequired(true);
534 }
535 break;
536 default:
537 break;
538 }
539 }
540
541 Q_EMIT dataChanged(index, index);
542
543 return successful;
544}
545
548void OptionsModel::setDisplayUnit(const QVariant &value) {
549 if (!value.isNull()) {
550 QSettings settings;
551 nDisplayUnit = value.toInt();
552 settings.setValue("nDisplayUnit", nDisplayUnit);
554 }
555}
556
557#ifdef ENABLE_BIP70
558bool OptionsModel::getProxySettings(QNetworkProxy &proxy) const {
559 // Directly query current base proxy, because
560 // GUI settings can be overridden with -proxy.
561 Proxy curProxy;
562 if (node().getProxy(NET_IPV4, curProxy)) {
563 proxy.setType(QNetworkProxy::Socks5Proxy);
564 proxy.setHostName(
565 QString::fromStdString(curProxy.proxy.ToStringAddr()));
566 proxy.setPort(curProxy.proxy.GetPort());
567
568 return true;
569 } else {
570 proxy.setType(QNetworkProxy::NoProxy);
571 }
572
573 return false;
574}
575#endif
576
578 QSettings settings;
579 return settings.setValue("fRestartRequired", fRequired);
580}
581
583 QSettings settings;
584 return settings.value("fRestartRequired", false).toBool();
585}
586
588 // Migration of default values
589 // Check if the QSettings container was already loaded with this client
590 // version
591 QSettings settings;
592 static const char strSettingsVersionKey[] = "nSettingsVersion";
593 int settingsVersion = settings.contains(strSettingsVersionKey)
594 ? settings.value(strSettingsVersionKey).toInt()
595 : 0;
596 if (settingsVersion < CLIENT_VERSION) {
597 // -dbcache was bumped from 100 to 300 in 0.13
598 // see https://github.com/bitcoin/bitcoin/pull/8273
599 // force people to upgrade to the new value if they are using 100MB
600 if (settingsVersion < 130000 && settings.contains("nDatabaseCache") &&
601 settings.value("nDatabaseCache").toLongLong() == 100) {
602 settings.setValue("nDatabaseCache", (qint64)DEFAULT_DB_CACHE >> 20);
603 }
604
605 settings.setValue(strSettingsVersionKey, CLIENT_VERSION);
606 }
607
608 // Overwrite the 'addrProxy' setting in case it has been set to an illegal
609 // default value (see issue #12623; PR #12650).
610 if (settings.contains("addrProxy") &&
611 settings.value("addrProxy").toString().endsWith("%2")) {
612 settings.setValue("addrProxy", GetDefaultProxyAddress());
613 }
614
615 // Overwrite the 'addrSeparateProxyTor' setting in case it has been set to
616 // an illegal default value (see issue #12623; PR #12650).
617 if (settings.contains("addrSeparateProxyTor") &&
618 settings.value("addrSeparateProxyTor").toString().endsWith("%2")) {
619 settings.setValue("addrSeparateProxyTor", GetDefaultProxyAddress());
620 }
621}
ArgsManager gArgs
Definition: args.cpp:39
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: args.cpp:565
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: args.h:239
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: args.cpp:547
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: args.cpp:462
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: args.cpp:557
std::string ToStringAddr() const
Definition: netaddress.cpp:630
uint16_t GetPort() const
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QString strOverriddenByCommandLine
Definition: optionsmodel.h:133
bool getProxySettings(QNetworkProxy &proxy) const
bool isRestartRequired() const
void Init(bool resetSettings=false)
bool fCoinControlFeatures
Definition: optionsmodel.h:131
interfaces::Node & node() const
Definition: optionsmodel.h:113
void setDisplayUnit(const QVariant &value)
Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal.
void coinControlFeaturesChanged(bool)
QString strThirdPartyTxUrls
Definition: optionsmodel.h:130
OptionsModel(QObject *parent=nullptr, bool resetSettings=false)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void SetPruneTargetGB(int prune_target_gb, bool force=false)
void SetPruneEnabled(bool prune, bool force=false)
void displayUnitChanged(int unit)
bool fHideTrayIcon
Definition: optionsmodel.h:125
bool fMinimizeToTray
Definition: optionsmodel.h:126
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
void checkAndMigrate()
QString language
Definition: optionsmodel.h:128
void addOverriddenOption(const std::string &option)
bool fMinimizeOnClose
Definition: optionsmodel.h:127
void setRestartRequired(bool fRequired)
void hideTrayIconChanged(bool)
Definition: netbase.h:67
CService proxy
Definition: netbase.h:77
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:38
static constexpr int DEFAULT_PRUNE_TARGET_GB
Definition: guiconstants.h:56
static constexpr bool DEFAULT_NATPMP
Definition: mapport.h:10
static constexpr bool DEFAULT_UPNP
Definition: mapport.h:8
QString getDefaultDataDirectory()
Determine default data directory for operating system.
Definition: guiutil.cpp:295
QString boostPathToQString(const fs::path &path)
Convert OS specific boost path to QString through UTF-8.
Definition: guiutil.cpp:791
bool SetStartOnSystemStartup(bool fAutoStart)
Definition: guiutil.cpp:776
bool GetStartOnSystemStartup()
Definition: guiutil.cpp:773
QStringList splitSkipEmptyParts(const QString &s, const QString &separator)
Definition: guiutil.cpp:451
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:150
static const bool DEFAULT_LISTEN
-listen default
Definition: net.h:89
@ NET_IPV4
IPv4.
Definition: netaddress.h:43
static constexpr size_t DEFAULT_DB_CACHE
-dbcache default (bytes)
Definition: caches.h:18
static void CopySettings(QSettings &dst, const QSettings &src)
Helper function to copy contents from one QSettings to another.
static QString GetDefaultProxyAddress()
static ProxySetting GetProxySetting(QSettings &settings, const QString &name)
static void SetProxySetting(QSettings &settings, const QString &name, const ProxySetting &ip_port)
static void BackupSettings(const fs::path &filename, const QSettings &src)
Back up a QSettings to an ini-formatted file.
const char * DEFAULT_GUI_PROXY_HOST
static int64_t PruneGBtoMiB(int gb)
Convert displayed prune target GB to configured MiB.
Definition: optionsmodel.h:38
static constexpr uint16_t DEFAULT_GUI_PROXY_PORT
Definition: optionsmodel.h:24
const char * name
Definition: rest.cpp:47
static std::string ToString(const CService &ip)
Definition: db.h:36
static const int DEFAULT_SCRIPTCHECK_THREADS
-par default (number of script-checking threads, 0 = auto)
Definition: validation.h:91