Bitcoin Core  24.99.0
P2P Digital Currency
optionsmodel.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2022 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)
7 #endif
8 
9 #include <qt/optionsmodel.h>
10 
11 #include <qt/bitcoinunits.h>
12 #include <qt/guiconstants.h>
13 #include <qt/guiutil.h>
14 
15 #include <interfaces/node.h>
16 #include <mapport.h>
17 #include <net.h>
18 #include <netbase.h>
19 #include <txdb.h> // for -dbcache defaults
20 #include <util/string.h>
21 #include <validation.h> // For DEFAULT_SCRIPTCHECK_THREADS
22 #include <wallet/wallet.h> // For DEFAULT_SPEND_ZEROCONF_CHANGE
23 
24 #include <QDebug>
25 #include <QLatin1Char>
26 #include <QSettings>
27 #include <QStringList>
28 #include <QVariant>
29 
30 #include <univalue.h>
31 
32 const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1";
33 
34 static QString GetDefaultProxyAddress();
35 
37 static const char* SettingName(OptionsModel::OptionID option)
38 {
39  switch (option) {
40  case OptionsModel::DatabaseCache: return "dbcache";
41  case OptionsModel::ThreadsScriptVerif: return "par";
42  case OptionsModel::SpendZeroConfChange: return "spendzeroconfchange";
43  case OptionsModel::ExternalSignerPath: return "signer";
44  case OptionsModel::MapPortUPnP: return "upnp";
45  case OptionsModel::MapPortNatpmp: return "natpmp";
46  case OptionsModel::Listen: return "listen";
47  case OptionsModel::Server: return "server";
48  case OptionsModel::PruneSize: return "prune";
49  case OptionsModel::Prune: return "prune";
50  case OptionsModel::ProxyIP: return "proxy";
51  case OptionsModel::ProxyPort: return "proxy";
52  case OptionsModel::ProxyUse: return "proxy";
53  case OptionsModel::ProxyIPTor: return "onion";
54  case OptionsModel::ProxyPortTor: return "onion";
55  case OptionsModel::ProxyUseTor: return "onion";
56  case OptionsModel::Language: return "lang";
57  default: throw std::logic_error(strprintf("GUI option %i has no corresponding node setting.", option));
58  }
59 }
60 
63 {
64  if (value.isNum() &&
65  (option == OptionsModel::DatabaseCache ||
67  option == OptionsModel::Prune ||
68  option == OptionsModel::PruneSize)) {
69  // Write certain old settings as strings, even though they are numbers,
70  // because Bitcoin 22.x releases try to read these specific settings as
71  // strings in addOverriddenOption() calls at startup, triggering
72  // uncaught exceptions in UniValue::get_str(). These errors were fixed
73  // in later releases by https://github.com/bitcoin/bitcoin/pull/24498.
74  // If new numeric settings are added, they can be written as numbers
75  // instead of strings, because bitcoin 22.x will not try to read these.
76  node.updateRwSetting(SettingName(option), value.getValStr());
77  } else {
78  node.updateRwSetting(SettingName(option), value);
79  }
80 }
81 
83 static util::SettingsValue PruneSetting(bool prune_enabled, int prune_size_gb)
84 {
85  assert(!prune_enabled || prune_size_gb >= 1); // PruneSizeGB and ParsePruneSizeGB never return less
86  return prune_enabled ? PruneGBtoMiB(prune_size_gb) : 0;
87 }
88 
90 static bool PruneEnabled(const util::SettingsValue& prune_setting)
91 {
92  // -prune=1 setting is manual pruning mode, so disabled for purposes of the gui
93  return SettingToInt(prune_setting, 0) > 1;
94 }
95 
98 static int PruneSizeGB(const util::SettingsValue& prune_setting)
99 {
100  int value = SettingToInt(prune_setting, 0);
101  return value > 1 ? PruneMiBtoGB(value) : DEFAULT_PRUNE_TARGET_GB;
102 }
103 
107 static int ParsePruneSizeGB(const QVariant& prune_size)
108 {
109  return std::max(1, prune_size.toInt());
110 }
111 
112 struct ProxySetting {
113  bool is_set;
114  QString ip;
115  QString port;
116 };
117 static ProxySetting ParseProxyString(const std::string& proxy);
118 static std::string ProxyString(bool is_set, QString ip, QString port);
119 
121  QAbstractListModel(parent), m_node{node}
122 {
123 }
124 
125 void OptionsModel::addOverriddenOption(const std::string &option)
126 {
127  strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(gArgs.GetArg(option, "")) + " ";
128 }
129 
130 // Writes all missing QSettings with their default values
132 {
133  // 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;
141  language = QString::fromStdString(SettingToString(node().getPersistentSetting("lang"), ""));
142 
143  checkAndMigrate();
144 
145  QSettings settings;
146 
147  // Ensure restart flag is unset on client startup
148  setRestartRequired(false);
149 
150  // These are Qt-only settings:
151 
152  // Window
153  if (!settings.contains("fHideTrayIcon")) {
154  settings.setValue("fHideTrayIcon", false);
155  }
156  m_show_tray_icon = !settings.value("fHideTrayIcon").toBool();
158 
159  if (!settings.contains("fMinimizeToTray"))
160  settings.setValue("fMinimizeToTray", false);
161  fMinimizeToTray = settings.value("fMinimizeToTray").toBool() && m_show_tray_icon;
162 
163  if (!settings.contains("fMinimizeOnClose"))
164  settings.setValue("fMinimizeOnClose", false);
165  fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool();
166 
167  // Display
168  if (!settings.contains("DisplayBitcoinUnit")) {
169  settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(BitcoinUnit::BTC));
170  }
171  QVariant unit = settings.value("DisplayBitcoinUnit");
172  if (unit.canConvert<BitcoinUnit>()) {
173  m_display_bitcoin_unit = unit.value<BitcoinUnit>();
174  } else {
176  settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(m_display_bitcoin_unit));
177  }
178 
179  if (!settings.contains("strThirdPartyTxUrls"))
180  settings.setValue("strThirdPartyTxUrls", "");
181  strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();
182 
183  if (!settings.contains("fCoinControlFeatures"))
184  settings.setValue("fCoinControlFeatures", false);
185  fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();
186 
187  if (!settings.contains("enable_psbt_controls")) {
188  settings.setValue("enable_psbt_controls", false);
189  }
190  m_enable_psbt_controls = settings.value("enable_psbt_controls", false).toBool();
191 
192  // These are shared with the core or have a command-line parameter
193  // and we want command-line parameters to overwrite the GUI settings.
196  std::string setting = SettingName(option);
197  if (node().isSettingIgnored(setting)) addOverriddenOption("-" + setting);
198  try {
199  getOption(option);
200  } catch (const std::exception& e) {
201  // This handles exceptions thrown by univalue that can happen if
202  // settings in settings.json don't have the expected types.
203  error.original = strprintf("Could not read setting \"%s\", %s.", setting, e.what());
204  error.translated = tr("Could not read setting \"%1\", %2.").arg(QString::fromStdString(setting), e.what()).toStdString();
205  return false;
206  }
207  }
208 
209  // If setting doesn't exist create it with defaults.
210 
211  // Main
212  if (!settings.contains("strDataDir"))
213  settings.setValue("strDataDir", GUIUtil::getDefaultDataDirectory());
214 
215  // Wallet
216 #ifdef ENABLE_WALLET
217  if (!settings.contains("SubFeeFromAmount")) {
218  settings.setValue("SubFeeFromAmount", false);
219  }
220  m_sub_fee_from_amount = settings.value("SubFeeFromAmount", false).toBool();
221 #endif
222 
223  // Display
224  if (!settings.contains("UseEmbeddedMonospacedFont")) {
225  settings.setValue("UseEmbeddedMonospacedFont", "true");
226  }
227  m_use_embedded_monospaced_font = settings.value("UseEmbeddedMonospacedFont").toBool();
229 
230  return true;
231 }
232 
236 static void CopySettings(QSettings& dst, const QSettings& src)
237 {
238  for (const QString& key : src.allKeys()) {
239  dst.setValue(key, src.value(key));
240  }
241 }
242 
244 static void BackupSettings(const fs::path& filename, const QSettings& src)
245 {
246  qInfo() << "Backing up GUI settings to" << GUIUtil::PathToQString(filename);
247  QSettings dst(GUIUtil::PathToQString(filename), QSettings::IniFormat);
248  dst.clear();
249  CopySettings(dst, src);
250 }
251 
253 {
254  // Backup and reset settings.json
255  node().resetSettings();
256 
257  QSettings settings;
258 
259  // Backup old settings to chain-specific datadir for troubleshooting
260  BackupSettings(gArgs.GetDataDirNet() / "guisettings.ini.bak", settings);
261 
262  // Save the strDataDir setting
263  QString dataDir = GUIUtil::getDefaultDataDirectory();
264  dataDir = settings.value("strDataDir", dataDir).toString();
265 
266  // Remove all entries from our QSettings object
267  settings.clear();
268 
269  // Set strDataDir
270  settings.setValue("strDataDir", dataDir);
271 
272  // Set that this was reset
273  settings.setValue("fReset", true);
274 
275  // default setting for OptionsModel::StartAtStartup - disabled
278 }
279 
280 int OptionsModel::rowCount(const QModelIndex & parent) const
281 {
282  return OptionIDRowCount;
283 }
284 
285 static ProxySetting ParseProxyString(const QString& proxy)
286 {
287  static const ProxySetting default_val = {false, DEFAULT_GUI_PROXY_HOST, QString("%1").arg(DEFAULT_GUI_PROXY_PORT)};
288  // Handle the case that the setting is not set at all
289  if (proxy.isEmpty()) {
290  return default_val;
291  }
292  // contains IP at index 0 and port at index 1
293  QStringList ip_port = GUIUtil::SplitSkipEmptyParts(proxy, ":");
294  if (ip_port.size() == 2) {
295  return {true, ip_port.at(0), ip_port.at(1)};
296  } else { // Invalid: return default
297  return default_val;
298  }
299 }
300 
301 static ProxySetting ParseProxyString(const std::string& proxy)
302 {
303  return ParseProxyString(QString::fromStdString(proxy));
304 }
305 
306 static std::string ProxyString(bool is_set, QString ip, QString port)
307 {
308  return is_set ? QString(ip + ":" + port).toStdString() : "";
309 }
310 
311 static QString GetDefaultProxyAddress()
312 {
313  return QString("%1:%2").arg(DEFAULT_GUI_PROXY_HOST).arg(DEFAULT_GUI_PROXY_PORT);
314 }
315 
316 void OptionsModel::SetPruneTargetGB(int prune_target_gb)
317 {
318  const util::SettingsValue cur_value = node().getPersistentSetting("prune");
319  const util::SettingsValue new_value = PruneSetting(prune_target_gb > 0, prune_target_gb);
320 
321  m_prune_size_gb = prune_target_gb;
322 
323  // Force setting to take effect. It is still safe to change the value at
324  // this point because this function is only called after the intro screen is
325  // shown, before the node starts.
326  node().forceSetting("prune", new_value);
327 
328  // Update settings.json if value configured in intro screen is different
329  // from saved value. Avoid writing settings.json if bitcoin.conf value
330  // doesn't need to be overridden.
331  if (PruneEnabled(cur_value) != PruneEnabled(new_value) ||
332  PruneSizeGB(cur_value) != PruneSizeGB(new_value)) {
333  // Call UpdateRwSetting() instead of setOption() to avoid setting
334  // RestartRequired flag
335  UpdateRwSetting(node(), Prune, new_value);
336  }
337 }
338 
339 // read QSettings values and return them
340 QVariant OptionsModel::data(const QModelIndex & index, int role) const
341 {
342  if(role == Qt::EditRole)
343  {
344  return getOption(OptionID(index.row()));
345  }
346  return QVariant();
347 }
348 
349 // write QSettings values
350 bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role)
351 {
352  bool successful = true; /* set to false on parse error */
353  if(role == Qt::EditRole)
354  {
355  successful = setOption(OptionID(index.row()), value);
356  }
357 
358  Q_EMIT dataChanged(index, index);
359 
360  return successful;
361 }
362 
363 QVariant OptionsModel::getOption(OptionID option) const
364 {
365  auto setting = [&]{ return node().getPersistentSetting(SettingName(option)); };
366 
367  QSettings settings;
368  switch (option) {
369  case StartAtStartup:
371  case ShowTrayIcon:
372  return m_show_tray_icon;
373  case MinimizeToTray:
374  return fMinimizeToTray;
375  case MapPortUPnP:
376 #ifdef USE_UPNP
377  return SettingToBool(setting(), DEFAULT_UPNP);
378 #else
379  return false;
380 #endif // USE_UPNP
381  case MapPortNatpmp:
382 #ifdef USE_NATPMP
383  return SettingToBool(setting(), DEFAULT_NATPMP);
384 #else
385  return false;
386 #endif // USE_NATPMP
387  case MinimizeOnClose:
388  return fMinimizeOnClose;
389 
390  // default proxy
391  case ProxyUse:
392  return ParseProxyString(SettingToString(setting(), "")).is_set;
393  case ProxyIP:
394  return m_proxy_ip;
395  case ProxyPort:
396  return m_proxy_port;
397 
398  // separate Tor proxy
399  case ProxyUseTor:
400  return ParseProxyString(SettingToString(setting(), "")).is_set;
401  case ProxyIPTor:
402  return m_onion_ip;
403  case ProxyPortTor:
404  return m_onion_port;
405 
406 #ifdef ENABLE_WALLET
407  case SpendZeroConfChange:
409  case ExternalSignerPath:
410  return QString::fromStdString(SettingToString(setting(), ""));
411  case SubFeeFromAmount:
412  return m_sub_fee_from_amount;
413 #endif
414  case DisplayUnit:
415  return QVariant::fromValue(m_display_bitcoin_unit);
416  case ThirdPartyTxUrls:
417  return strThirdPartyTxUrls;
418  case Language:
419  return QString::fromStdString(SettingToString(setting(), ""));
422  case CoinControlFeatures:
423  return fCoinControlFeatures;
424  case EnablePSBTControls:
425  return settings.value("enable_psbt_controls");
426  case Prune:
427  return PruneEnabled(setting());
428  case PruneSize:
429  return m_prune_size_gb;
430  case DatabaseCache:
431  return qlonglong(SettingToInt(setting(), nDefaultDbCache));
432  case ThreadsScriptVerif:
433  return qlonglong(SettingToInt(setting(), DEFAULT_SCRIPTCHECK_THREADS));
434  case Listen:
435  return SettingToBool(setting(), DEFAULT_LISTEN);
436  case Server:
437  return SettingToBool(setting(), false);
438  default:
439  return QVariant();
440  }
441 }
442 
443 bool OptionsModel::setOption(OptionID option, const QVariant& value)
444 {
445  auto changed = [&] { return value.isValid() && value != getOption(option); };
446  auto update = [&](const util::SettingsValue& value) { return UpdateRwSetting(node(), option, value); };
447 
448  bool successful = true; /* set to false on parse error */
449  QSettings settings;
450 
451  switch (option) {
452  case StartAtStartup:
453  successful = GUIUtil::SetStartOnSystemStartup(value.toBool());
454  break;
455  case ShowTrayIcon:
456  m_show_tray_icon = value.toBool();
457  settings.setValue("fHideTrayIcon", !m_show_tray_icon);
459  break;
460  case MinimizeToTray:
461  fMinimizeToTray = value.toBool();
462  settings.setValue("fMinimizeToTray", fMinimizeToTray);
463  break;
464  case MapPortUPnP: // core option - can be changed on-the-fly
465  if (changed()) {
466  update(value.toBool());
467  node().mapPort(value.toBool(), getOption(MapPortNatpmp).toBool());
468  }
469  break;
470  case MapPortNatpmp: // core option - can be changed on-the-fly
471  if (changed()) {
472  update(value.toBool());
473  node().mapPort(getOption(MapPortUPnP).toBool(), value.toBool());
474  }
475  break;
476  case MinimizeOnClose:
477  fMinimizeOnClose = value.toBool();
478  settings.setValue("fMinimizeOnClose", fMinimizeOnClose);
479  break;
480 
481  // default proxy
482  case ProxyUse:
483  if (changed()) {
484  update(ProxyString(value.toBool(), m_proxy_ip, m_proxy_port));
485  setRestartRequired(true);
486  }
487  break;
488  case ProxyIP:
489  if (changed()) {
490  m_proxy_ip = value.toString();
491  if (getOption(ProxyUse).toBool()) {
492  update(ProxyString(true, m_proxy_ip, m_proxy_port));
493  setRestartRequired(true);
494  }
495  }
496  break;
497  case ProxyPort:
498  if (changed()) {
499  m_proxy_port = value.toString();
500  if (getOption(ProxyUse).toBool()) {
501  update(ProxyString(true, m_proxy_ip, m_proxy_port));
502  setRestartRequired(true);
503  }
504  }
505  break;
506 
507  // separate Tor proxy
508  case ProxyUseTor:
509  if (changed()) {
510  update(ProxyString(value.toBool(), m_onion_ip, m_onion_port));
511  setRestartRequired(true);
512  }
513  break;
514  case ProxyIPTor:
515  if (changed()) {
516  m_onion_ip = value.toString();
517  if (getOption(ProxyUseTor).toBool()) {
518  update(ProxyString(true, m_onion_ip, m_onion_port));
519  setRestartRequired(true);
520  }
521  }
522  break;
523  case ProxyPortTor:
524  if (changed()) {
525  m_onion_port = value.toString();
526  if (getOption(ProxyUseTor).toBool()) {
527  update(ProxyString(true, m_onion_ip, m_onion_port));
528  setRestartRequired(true);
529  }
530  }
531  break;
532 
533 #ifdef ENABLE_WALLET
534  case SpendZeroConfChange:
535  if (changed()) {
536  update(value.toBool());
537  setRestartRequired(true);
538  }
539  break;
540  case ExternalSignerPath:
541  if (changed()) {
542  update(value.toString().toStdString());
543  setRestartRequired(true);
544  }
545  break;
546  case SubFeeFromAmount:
547  m_sub_fee_from_amount = value.toBool();
548  settings.setValue("SubFeeFromAmount", m_sub_fee_from_amount);
549  break;
550 #endif
551  case DisplayUnit:
552  setDisplayUnit(value);
553  break;
554  case ThirdPartyTxUrls:
555  if (strThirdPartyTxUrls != value.toString()) {
556  strThirdPartyTxUrls = value.toString();
557  settings.setValue("strThirdPartyTxUrls", strThirdPartyTxUrls);
558  setRestartRequired(true);
559  }
560  break;
561  case Language:
562  if (changed()) {
563  update(value.toString().toStdString());
564  setRestartRequired(true);
565  }
566  break;
568  m_use_embedded_monospaced_font = value.toBool();
569  settings.setValue("UseEmbeddedMonospacedFont", m_use_embedded_monospaced_font);
571  break;
572  case CoinControlFeatures:
573  fCoinControlFeatures = value.toBool();
574  settings.setValue("fCoinControlFeatures", fCoinControlFeatures);
576  break;
577  case EnablePSBTControls:
578  m_enable_psbt_controls = value.toBool();
579  settings.setValue("enable_psbt_controls", m_enable_psbt_controls);
580  break;
581  case Prune:
582  if (changed()) {
583  update(PruneSetting(value.toBool(), m_prune_size_gb));
584  setRestartRequired(true);
585  }
586  break;
587  case PruneSize:
588  if (changed()) {
590  if (getOption(Prune).toBool()) {
591  update(PruneSetting(true, m_prune_size_gb));
592  setRestartRequired(true);
593  }
594  }
595  break;
596  case DatabaseCache:
597  if (changed()) {
598  update(static_cast<int64_t>(value.toLongLong()));
599  setRestartRequired(true);
600  }
601  break;
602  case ThreadsScriptVerif:
603  if (changed()) {
604  update(static_cast<int64_t>(value.toLongLong()));
605  setRestartRequired(true);
606  }
607  break;
608  case Listen:
609  case Server:
610  if (changed()) {
611  update(value.toBool());
612  setRestartRequired(true);
613  }
614  break;
615  default:
616  break;
617  }
618 
619  return successful;
620 }
621 
622 void OptionsModel::setDisplayUnit(const QVariant& new_unit)
623 {
624  if (new_unit.isNull() || new_unit.value<BitcoinUnit>() == m_display_bitcoin_unit) return;
625  m_display_bitcoin_unit = new_unit.value<BitcoinUnit>();
626  QSettings settings;
627  settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(m_display_bitcoin_unit));
629 }
630 
632 {
633  QSettings settings;
634  return settings.setValue("fRestartRequired", fRequired);
635 }
636 
638 {
639  QSettings settings;
640  return settings.value("fRestartRequired", false).toBool();
641 }
642 
644 {
645  // Migration of default values
646  // Check if the QSettings container was already loaded with this client version
647  QSettings settings;
648  static const char strSettingsVersionKey[] = "nSettingsVersion";
649  int settingsVersion = settings.contains(strSettingsVersionKey) ? settings.value(strSettingsVersionKey).toInt() : 0;
650  if (settingsVersion < CLIENT_VERSION)
651  {
652  // -dbcache was bumped from 100 to 300 in 0.13
653  // see https://github.com/bitcoin/bitcoin/pull/8273
654  // force people to upgrade to the new value if they are using 100MB
655  if (settingsVersion < 130000 && settings.contains("nDatabaseCache") && settings.value("nDatabaseCache").toLongLong() == 100)
656  settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache);
657 
658  settings.setValue(strSettingsVersionKey, CLIENT_VERSION);
659  }
660 
661  // Overwrite the 'addrProxy' setting in case it has been set to an illegal
662  // default value (see issue #12623; PR #12650).
663  if (settings.contains("addrProxy") && settings.value("addrProxy").toString().endsWith("%2")) {
664  settings.setValue("addrProxy", GetDefaultProxyAddress());
665  }
666 
667  // Overwrite the 'addrSeparateProxyTor' setting in case it has been set to an illegal
668  // default value (see issue #12623; PR #12650).
669  if (settings.contains("addrSeparateProxyTor") && settings.value("addrSeparateProxyTor").toString().endsWith("%2")) {
670  settings.setValue("addrSeparateProxyTor", GetDefaultProxyAddress());
671  }
672 
673  // Migrate and delete legacy GUI settings that have now moved to <datadir>/settings.json.
674  auto migrate_setting = [&](OptionID option, const QString& qt_name) {
675  if (!settings.contains(qt_name)) return;
676  QVariant value = settings.value(qt_name);
677  if (node().getPersistentSetting(SettingName(option)).isNull()) {
678  if (option == ProxyIP) {
679  ProxySetting parsed = ParseProxyString(value.toString());
680  setOption(ProxyIP, parsed.ip);
681  setOption(ProxyPort, parsed.port);
682  } else if (option == ProxyIPTor) {
683  ProxySetting parsed = ParseProxyString(value.toString());
684  setOption(ProxyIPTor, parsed.ip);
685  setOption(ProxyPortTor, parsed.port);
686  } else {
687  setOption(option, value);
688  }
689  }
690  settings.remove(qt_name);
691  };
692 
693  migrate_setting(DatabaseCache, "nDatabaseCache");
694  migrate_setting(ThreadsScriptVerif, "nThreadsScriptVerif");
695 #ifdef ENABLE_WALLET
696  migrate_setting(SpendZeroConfChange, "bSpendZeroConfChange");
697  migrate_setting(ExternalSignerPath, "external_signer_path");
698 #endif
699  migrate_setting(MapPortUPnP, "fUseUPnP");
700  migrate_setting(MapPortNatpmp, "fUseNatpmp");
701  migrate_setting(Listen, "fListen");
702  migrate_setting(Server, "server");
703  migrate_setting(PruneSize, "nPruneSize");
704  migrate_setting(Prune, "bPrune");
705  migrate_setting(ProxyIP, "addrProxy");
706  migrate_setting(ProxyUse, "fUseProxy");
707  migrate_setting(ProxyIPTor, "addrSeparateProxyTor");
708  migrate_setting(ProxyUseTor, "fUseSeparateProxyTor");
709  migrate_setting(Language, "language");
710 
711  // In case migrating QSettings caused any settings value to change, rerun
712  // parameter interaction code to update other settings. This is particularly
713  // important for the -listen setting, which should cause -listenonion, -upnp,
714  // and other settings to default to false if it was set to false.
715  // (https://github.com/bitcoin-core/gui/issues/567).
717 }
node::NodeContext m_node
Definition: bitcoin-gui.cpp:37
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: system.h:295
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:591
Unit
Bitcoin units.
Definition: bitcoinunits.h:42
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QString m_onion_ip
Definition: optionsmodel.h:130
BitcoinUnit m_display_bitcoin_unit
Definition: optionsmodel.h:117
QString strOverriddenByCommandLine
Definition: optionsmodel.h:134
bool m_use_embedded_monospaced_font
Definition: optionsmodel.h:119
bool isRestartRequired() const
QString m_proxy_port
Definition: optionsmodel.h:129
bool fCoinControlFeatures
Definition: optionsmodel.h:120
int m_prune_size_gb
In-memory settings for display.
Definition: optionsmodel.h:127
QString m_proxy_ip
Definition: optionsmodel.h:128
void coinControlFeaturesChanged(bool)
QString strThirdPartyTxUrls
Definition: optionsmodel.h:118
int rowCount(const QModelIndex &parent=QModelIndex()) const override
bool m_sub_fee_from_amount
Definition: optionsmodel.h:121
@ UseEmbeddedMonospacedFont
Definition: optionsmodel.h:63
void displayUnitChanged(BitcoinUnit unit)
void SetPruneTargetGB(int prune_target_gb)
bool Init(bilingual_str &error)
QVariant getOption(OptionID option) const
void showTrayIconChanged(bool)
OptionsModel(interfaces::Node &node, QObject *parent=nullptr)
bool fMinimizeToTray
Definition: optionsmodel.h:114
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
bool setOption(OptionID option, const QVariant &value)
QString m_onion_port
Definition: optionsmodel.h:131
bool m_enable_psbt_controls
Definition: optionsmodel.h:122
void setDisplayUnit(const QVariant &new_unit)
Updates current unit in memory, settings and emits displayUnitChanged(new_unit) signal.
interfaces::Node & node() const
Definition: optionsmodel.h:108
void checkAndMigrate()
QString language
Definition: optionsmodel.h:116
void addOverriddenOption(const std::string &option)
void useEmbeddedMonospacedFontChanged(bool)
bool fMinimizeOnClose
Definition: optionsmodel.h:115
void setRestartRequired(bool fRequired)
bool m_show_tray_icon
Definition: optionsmodel.h:113
bool isNull() const
Definition: univalue.h:75
const std::string & getValStr() const
Definition: univalue.h:64
bool isNum() const
Definition: univalue.h:80
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:31
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:70
virtual void resetSettings()=0
Clear all settings in <datadir>/settings.json and store a backup of previous settings in <datadir>/se...
virtual void initParameterInteraction()=0
Init parameter interaction.
virtual void forceSetting(const std::string &name, const util::SettingsValue &value)=0
Force a setting value to be applied, overriding any other configuration source, but not being persist...
virtual void mapPort(bool use_upnp, bool use_natpmp)=0
Map port.
virtual util::SettingsValue getPersistentSetting(const std::string &name)=0
Return setting value from <datadir>/settings.json or bitcoin.conf.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
static CService ip(uint32_t i)
static constexpr int DEFAULT_PRUNE_TARGET_GB
Definition: guiconstants.h:60
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:288
bool SetStartOnSystemStartup(bool fAutoStart)
Definition: guiutil.cpp:648
QString PathToQString(const fs::path &path)
Convert OS specific boost path to QString through UTF-8.
Definition: guiutil.cpp:666
bool GetStartOnSystemStartup()
Definition: guiutil.cpp:647
QStringList SplitSkipEmptyParts(const QString &string, const SeparatorType &separator)
Splits the string into substrings wherever separator occurs, and returns the list of those strings.
Definition: guiutil.h:363
Definition: init.h:25
static const bool DEFAULT_SPEND_ZEROCONF_CHANGE
Default for -spendzeroconfchange.
Definition: wallet.h:100
static const bool DEFAULT_LISTEN
-listen default
Definition: net.h:75
static void CopySettings(QSettings &dst, const QSettings &src)
Helper function to copy contents from one QSettings to another.
static int ParsePruneSizeGB(const QVariant &prune_size)
Parse pruning size value provided by user in GUI or loaded from QSettings (windows registry key or qt...
static const char * SettingName(OptionsModel::OptionID option)
Map GUI option ID to node setting name.
static util::SettingsValue PruneSetting(bool prune_enabled, int prune_size_gb)
Convert enabled/size values to bitcoin -prune setting.
static ProxySetting ParseProxyString(const std::string &proxy)
static QString GetDefaultProxyAddress()
static int PruneSizeGB(const util::SettingsValue &prune_setting)
Get pruning size value to show in GUI from bitcoin -prune setting.
static std::string ProxyString(bool is_set, QString ip, QString port)
static void UpdateRwSetting(interfaces::Node &node, OptionsModel::OptionID option, const util::SettingsValue &value)
Call node.updateRwSetting() with Bitcoin 22.x workaround.
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 bool PruneEnabled(const util::SettingsValue &prune_setting)
Get pruning enabled value to show in GUI from bitcoin -prune setting.
static int PruneMiBtoGB(int64_t mib)
Convert configured prune target MiB to displayed GB.
Definition: optionsmodel.h:27
static int64_t PruneGBtoMiB(int gb)
Convert displayed prune target GB to configured MiB.
Definition: optionsmodel.h:32
static constexpr uint16_t DEFAULT_GUI_PROXY_PORT
Definition: optionsmodel.h:22
Bilingual messages:
Definition: translation.h:18
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
static const int64_t nDefaultDbCache
-dbcache default (MiB)
Definition: txdb.h:30
std::optional< std::string > SettingToString(const util::SettingsValue &value)
Definition: system.cpp:602
ArgsManager gArgs
Definition: system.cpp:73
std::optional< int64_t > SettingToInt(const util::SettingsValue &value)
Definition: system.cpp:627
std::optional< bool > SettingToBool(const util::SettingsValue &value)
Definition: system.cpp:652
assert(!tx.IsCoinBase())
static const int DEFAULT_SCRIPTCHECK_THREADS
-par default (number of script-checking threads, 0 = auto)
Definition: validation.h:66