Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2011-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <bitcoin-build-config.h> // IWYU pragma: keep7#include <qt/optionsmodel.h>9#include <qt/bitcoinunits.h>10#include <qt/guiconstants.h>11#include <qt/guiutil.h>13#include <common/args.h>14#include <interfaces/node.h>15#include <mapport.h>16#include <net.h>17#include <netbase.h>18#include <node/caches.h>19#include <node/chainstatemanager_args.h>20#include <univalue.h>21#include <util/string.h>22#include <validation.h>23#include <wallet/wallet.h>25#include <QDebug>26#include <QLatin1Char>27#include <QSettings>28#include <QStringList>29#include <QVariant>31const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1";33static QString GetDefaultProxyAddress();35/** Map GUI option ID to node setting name. */36static const char* SettingName(OptionsModel::OptionID option)37{38switch (option) {39case OptionsModel::DatabaseCache: return "dbcache";40case OptionsModel::ThreadsScriptVerif: return "par";41case OptionsModel::SpendZeroConfChange: return "spendzeroconfchange";42case OptionsModel::ExternalSignerPath: return "signer";43case OptionsModel::MapPortNatpmp: return "natpmp";44case OptionsModel::Listen: return "listen";45case OptionsModel::Server: return "server";46case OptionsModel::PruneSize: return "prune";47case OptionsModel::Prune: return "prune";48case OptionsModel::ProxyIP: return "proxy";49case OptionsModel::ProxyPort: return "proxy";50case OptionsModel::ProxyUse: return "proxy";51case OptionsModel::ProxyIPTor: return "onion";52case OptionsModel::ProxyPortTor: return "onion";53case OptionsModel::ProxyUseTor: return "onion";54case OptionsModel::Language: return "lang";55default: throw std::logic_error(strprintf("GUI option %i has no corresponding node setting.", option));56}57}59/** Call node.updateRwSetting() with Bitcoin 22.x workaround. */60static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID option, const std::string& suffix, const common::SettingsValue& value)61{62if (value.isNum() &&63(option == OptionsModel::DatabaseCache ||64option == OptionsModel::ThreadsScriptVerif ||65option == OptionsModel::Prune ||66option == OptionsModel::PruneSize)) {67// Write certain old settings as strings, even though they are numbers,68// because Bitcoin 22.x releases try to read these specific settings as69// strings in addOverriddenOption() calls at startup, triggering70// uncaught exceptions in UniValue::get_str(). These errors were fixed71// in later releases by https://github.com/bitcoin/bitcoin/pull/24498.72// If new numeric settings are added, they can be written as numbers73// instead of strings, because bitcoin 22.x will not try to read these.74node.updateRwSetting(SettingName(option) + suffix, value.getValStr());75} else {76node.updateRwSetting(SettingName(option) + suffix, value);77}78}80//! Convert enabled/size values to bitcoin -prune setting.81static common::SettingsValue PruneSetting(bool prune_enabled, int prune_size_gb)82{83assert(!prune_enabled || prune_size_gb >= 1); // PruneSizeGB and ParsePruneSizeGB never return less84return prune_enabled ? PruneGBtoMiB(prune_size_gb) : 0;85}87//! Get pruning enabled value to show in GUI from bitcoin -prune setting.88static bool PruneEnabled(const common::SettingsValue& prune_setting)89{90// -prune=1 setting is manual pruning mode, so disabled for purposes of the gui91return SettingTo<int64_t>(prune_setting, 0) > 1;92}94//! Get pruning size value to show in GUI from bitcoin -prune setting. If95//! pruning is not enabled, just show default recommended pruning size (2GB).96static int PruneSizeGB(const common::SettingsValue& prune_setting)97{98int value = SettingTo<int64_t>(prune_setting, 0);99return value > 1 ? PruneMiBtoGB(value) : DEFAULT_PRUNE_TARGET_GB;100}102//! Parse pruning size value provided by user in GUI or loaded from QSettings103//! (windows registry key or qt .conf file). Smallest value that the GUI can104//! display is 1 GB, so round up if anything less is parsed.105static int ParsePruneSizeGB(const QVariant& prune_size)106{107return std::max(1, prune_size.toInt());108}110struct ProxySetting {111bool is_set;112QString ip;113QString port;114};115static ProxySetting ParseProxyString(const std::string& proxy);116static std::string ProxyString(bool is_set, QString ip, QString port);118static const QLatin1String fontchoice_str_embedded{"embedded"};119static const QLatin1String fontchoice_str_best_system{"best_system"};120static const QString fontchoice_str_custom_prefix{QStringLiteral("custom, ")};122QString OptionsModel::FontChoiceToString(const OptionsModel::FontChoice& f)123{124if (std::holds_alternative<FontChoiceAbstract>(f)) {125if (f == UseBestSystemFont) {126return fontchoice_str_best_system;127} else {128return fontchoice_str_embedded;129}130}131return fontchoice_str_custom_prefix + std::get<QFont>(f).toString();132}134OptionsModel::FontChoice OptionsModel::FontChoiceFromString(const QString& s)135{136if (s == fontchoice_str_best_system) {137return FontChoiceAbstract::BestSystemFont;138} else if (s == fontchoice_str_embedded) {139return FontChoiceAbstract::EmbeddedFont;140} else if (s.startsWith(fontchoice_str_custom_prefix)) {141QFont f;142f.fromString(s.mid(fontchoice_str_custom_prefix.size()));143return f;144} else {145return FontChoiceAbstract::EmbeddedFont; // default146}147}149OptionsModel::OptionsModel(interfaces::Node& node, QObject *parent) :150QAbstractListModel(parent), m_node{node}151{152}154void OptionsModel::addOverriddenOption(const std::string &option)155{156strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(gArgs.GetArg(option, "")) + " ";157}159// Writes all missing QSettings with their default values160bool OptionsModel::Init(bilingual_str& error)161{162// Initialize display settings from stored settings.163language = QString::fromStdString(SettingToString(node().getPersistentSetting("lang"), ""));165checkAndMigrate();167QSettings settings;169// Ensure restart flag is unset on client startup170setRestartRequired(false);172// These are Qt-only settings:174// Window175if (!settings.contains("fHideTrayIcon")) {176settings.setValue("fHideTrayIcon", false);177}178m_show_tray_icon = !settings.value("fHideTrayIcon").toBool();179Q_EMIT showTrayIconChanged(m_show_tray_icon);181if (!settings.contains("fMinimizeToTray"))182settings.setValue("fMinimizeToTray", false);183fMinimizeToTray = settings.value("fMinimizeToTray").toBool() && m_show_tray_icon;185if (!settings.contains("fMinimizeOnClose"))186settings.setValue("fMinimizeOnClose", false);187fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool();189// Display190if (!settings.contains("DisplayBitcoinUnit")) {191settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(BitcoinUnit::BTC));192}193QVariant unit = settings.value("DisplayBitcoinUnit");194if (unit.canConvert<BitcoinUnit>()) {195m_display_bitcoin_unit = unit.value<BitcoinUnit>();196} else {197m_display_bitcoin_unit = BitcoinUnit::BTC;198settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(m_display_bitcoin_unit));199}201if (!settings.contains("strThirdPartyTxUrls"))202settings.setValue("strThirdPartyTxUrls", "");203strThirdPartyTxUrls = settings.value("strThirdPartyTxUrls", "").toString();205if (!settings.contains("fCoinControlFeatures"))206settings.setValue("fCoinControlFeatures", false);207fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool();209if (!settings.contains("enable_psbt_controls")) {210settings.setValue("enable_psbt_controls", false);211}212m_enable_psbt_controls = settings.value("enable_psbt_controls", false).toBool();214// These are shared with the core or have a command-line parameter215// and we want command-line parameters to overwrite the GUI settings.216for (OptionID option : {DatabaseCache, ThreadsScriptVerif, SpendZeroConfChange, ExternalSignerPath,217MapPortNatpmp, Listen, Server, Prune, ProxyUse, ProxyUseTor, Language}) {218std::string setting = SettingName(option);219if (node().isSettingIgnored(setting)) addOverriddenOption("-" + setting);220try {221getOption(option);222} catch (const std::exception& e) {223// This handles exceptions thrown by univalue that can happen if224// settings in settings.json don't have the expected types.225error.original = strprintf("Could not read setting \"%s\", %s.", setting, e.what());226error.translated = tr("Could not read setting \"%1\", %2.").arg(QString::fromStdString(setting), e.what()).toStdString();227return false;228}229}231// If setting doesn't exist create it with defaults.233// Main234if (!settings.contains("strDataDir"))235settings.setValue("strDataDir", GUIUtil::getDefaultDataDirectory());237// Wallet238#ifdef ENABLE_WALLET239if (!settings.contains("SubFeeFromAmount")) {240settings.setValue("SubFeeFromAmount", false);241}242m_sub_fee_from_amount = settings.value("SubFeeFromAmount", false).toBool();243#endif245// Display246if (settings.contains("FontForMoney")) {247m_font_money = FontChoiceFromString(settings.value("FontForMoney").toString());248} else if (settings.contains("UseEmbeddedMonospacedFont")) {249if (settings.value("UseEmbeddedMonospacedFont").toBool()) {250m_font_money = FontChoiceAbstract::EmbeddedFont;
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.