@@ -45,6 +45,8 @@ static const char* SettingName(OptionsModel::OptionID option)
4545 case OptionsModel::MapPortNatpmp: return " natpmp" ;
4646 case OptionsModel::Listen: return " listen" ;
4747 case OptionsModel::Server: return " server" ;
48+ case OptionsModel::PruneSize: return " prune" ;
49+ case OptionsModel::Prune: return " prune" ;
4850 case OptionsModel::ProxyIP: return " proxy" ;
4951 case OptionsModel::ProxyPort: return " proxy" ;
5052 case OptionsModel::ProxyUse: return " proxy" ;
@@ -60,7 +62,9 @@ static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID optio
6062{
6163 if (value.isNum () &&
6264 (option == OptionsModel::DatabaseCache ||
63- option == OptionsModel::ThreadsScriptVerif)) {
65+ option == OptionsModel::ThreadsScriptVerif ||
66+ option == OptionsModel::Prune ||
67+ option == OptionsModel::PruneSize)) {
6468 // Write certain old settings as strings, even though they are numbers,
6569 // because Bitcoin 22.x releases try to read these specific settings as
6670 // strings in addOverriddenOption() calls at startup, triggering
@@ -74,6 +78,36 @@ static void UpdateRwSetting(interfaces::Node& node, OptionsModel::OptionID optio
7478 }
7579}
7680
81+ // ! Convert enabled/size values to bitcoin -prune setting.
82+ static util::SettingsValue PruneSetting (bool prune_enabled, int prune_size_gb)
83+ {
84+ assert (!prune_enabled || prune_size_gb >= 1 ); // PruneSizeGB and ParsePruneSizeGB never return less
85+ return prune_enabled ? PruneGBtoMiB (prune_size_gb) : 0 ;
86+ }
87+
88+ // ! Get pruning enabled value to show in GUI from bitcoin -prune setting.
89+ static bool PruneEnabled (const util::SettingsValue& prune_setting)
90+ {
91+ // -prune=1 setting is manual pruning mode, so disabled for purposes of the gui
92+ return SettingToInt (prune_setting, 0 ) > 1 ;
93+ }
94+
95+ // ! Get pruning size value to show in GUI from bitcoin -prune setting. If
96+ // ! pruning is not enabled, just show default recommended pruning size (2GB).
97+ static int PruneSizeGB (const util::SettingsValue& prune_setting)
98+ {
99+ int value = SettingToInt (prune_setting, 0 );
100+ return value > 1 ? PruneMiBtoGB (value) : DEFAULT_PRUNE_TARGET_GB;
101+ }
102+
103+ // ! Parse pruning size value provided by user in GUI or loaded from QSettings
104+ // ! (windows registry key or qt .conf file). Smallest value that the GUI can
105+ // ! display is 1 GB, so round up if anything less is parsed.
106+ static int ParsePruneSizeGB (const QVariant& prune_size)
107+ {
108+ return std::max (1 , prune_size.toInt ());
109+ }
110+
77111struct ProxySetting {
78112 bool is_set;
79113 QString ip;
@@ -96,6 +130,7 @@ void OptionsModel::addOverriddenOption(const std::string &option)
96130bool OptionsModel::Init (bilingual_str& error)
97131{
98132 // Initialize display settings from stored settings.
133+ m_prune_size_gb = PruneSizeGB (node ().getPersistentSetting (" prune" ));
99134 ProxySetting proxy = ParseProxyString (SettingToString (node ().getPersistentSetting (" proxy" ), GetDefaultProxyAddress ().toStdString ()));
100135 m_proxy_ip = proxy.ip ;
101136 m_proxy_port = proxy.port ;
@@ -155,7 +190,7 @@ bool OptionsModel::Init(bilingual_str& error)
155190 // These are shared with the core or have a command-line parameter
156191 // and we want command-line parameters to overwrite the GUI settings.
157192 for (OptionID option : {DatabaseCache, ThreadsScriptVerif, SpendZeroConfChange, ExternalSignerPath, MapPortUPnP,
158- MapPortNatpmp, Listen, Server, ProxyUse, ProxyUseTor}) {
193+ MapPortNatpmp, Listen, Server, Prune, ProxyUse, ProxyUseTor}) {
159194 std::string setting = SettingName (option);
160195 if (node ().isSettingIgnored (setting)) addOverriddenOption (" -" + setting);
161196 try {
@@ -175,11 +210,6 @@ bool OptionsModel::Init(bilingual_str& error)
175210 // by command-line and show this in the UI.
176211
177212 // Main
178- if (!settings.contains (" bPrune" ))
179- settings.setValue (" bPrune" , false );
180- if (!settings.contains (" nPruneSize" ))
181- settings.setValue (" nPruneSize" , DEFAULT_PRUNE_TARGET_GB);
182- SetPruneEnabled (settings.value (" bPrune" ).toBool ());
183213 if (!settings.contains (" strDataDir" ))
184214 settings.setValue (" strDataDir" , GUIUtil::getDefaultDataDirectory ());
185215
@@ -288,29 +318,27 @@ static const QString GetDefaultProxyAddress()
288318 return QString (" %1:%2" ).arg (DEFAULT_GUI_PROXY_HOST).arg (DEFAULT_GUI_PROXY_PORT);
289319}
290320
291- void OptionsModel::SetPruneEnabled ( bool prune, bool force )
321+ void OptionsModel::SetPruneTargetGB ( int prune_target_gb )
292322{
293- QSettings settings;
294- settings.setValue (" bPrune" , prune);
295- const int64_t prune_target_mib = PruneGBtoMiB (settings.value (" nPruneSize" ).toInt ());
296- std::string prune_val = prune ? ToString (prune_target_mib) : " 0" ;
297- if (force) {
298- gArgs .ForceSetArg (" -prune" , prune_val);
299- return ;
300- }
301- if (!gArgs .SoftSetArg (" -prune" , prune_val)) {
302- addOverriddenOption (" -prune" );
303- }
304- }
305-
306- void OptionsModel::SetPruneTargetGB (int prune_target_gb, bool force)
307- {
308- const bool prune = prune_target_gb > 0 ;
309- if (prune) {
310- QSettings settings;
311- settings.setValue (" nPruneSize" , prune_target_gb);
323+ const util::SettingsValue cur_value = node ().getPersistentSetting (" prune" );
324+ const util::SettingsValue new_value = PruneSetting (prune_target_gb > 0 , prune_target_gb);
325+
326+ m_prune_size_gb = prune_target_gb;
327+
328+ // Force setting to take effect. It is still safe to change the value at
329+ // this point because this function is only called after the intro screen is
330+ // shown, before the node starts.
331+ node ().forceSetting (" prune" , new_value);
332+
333+ // Update settings.json if value configured in intro screen is different
334+ // from saved value. Avoid writing settings.json if bitcoin.conf value
335+ // doesn't need to be overridden.
336+ if (PruneEnabled (cur_value) != PruneEnabled (new_value) ||
337+ PruneSizeGB (cur_value) != PruneSizeGB (new_value)) {
338+ // Call UpdateRwSetting() instead of setOption() to avoid setting
339+ // RestartRequired flag
340+ UpdateRwSetting (node (), Prune, new_value);
312341 }
313- SetPruneEnabled (prune, force);
314342}
315343
316344// read QSettings values and return them
@@ -401,9 +429,9 @@ QVariant OptionsModel::getOption(OptionID option) const
401429 case EnablePSBTControls:
402430 return settings.value (" enable_psbt_controls" );
403431 case Prune:
404- return settings. value ( " bPrune " );
432+ return PruneEnabled ( setting () );
405433 case PruneSize:
406- return settings. value ( " nPruneSize " ) ;
434+ return m_prune_size_gb ;
407435 case DatabaseCache:
408436 return qlonglong (SettingToInt (setting (), nDefaultDbCache));
409437 case ThreadsScriptVerif:
@@ -556,15 +584,18 @@ bool OptionsModel::setOption(OptionID option, const QVariant& value)
556584 settings.setValue (" enable_psbt_controls" , m_enable_psbt_controls);
557585 break ;
558586 case Prune:
559- if (settings. value ( " bPrune " ) != value ) {
560- settings. setValue ( " bPrune " , value );
587+ if (changed () ) {
588+ update ( PruneSetting (value. toBool (), m_prune_size_gb) );
561589 setRestartRequired (true );
562590 }
563591 break ;
564592 case PruneSize:
565- if (settings.value (" nPruneSize" ) != value) {
566- settings.setValue (" nPruneSize" , value);
567- setRestartRequired (true );
593+ if (changed ()) {
594+ m_prune_size_gb = ParsePruneSizeGB (value);
595+ if (getOption (Prune).toBool ()) {
596+ update (PruneSetting (true , m_prune_size_gb));
597+ setRestartRequired (true );
598+ }
568599 }
569600 break ;
570601 case DatabaseCache:
@@ -674,6 +705,8 @@ void OptionsModel::checkAndMigrate()
674705 migrate_setting (MapPortNatpmp, " fUseNatpmp" );
675706 migrate_setting (Listen, " fListen" );
676707 migrate_setting (Server, " server" );
708+ migrate_setting (PruneSize, " nPruneSize" );
709+ migrate_setting (Prune, " bPrune" );
677710 migrate_setting (ProxyIP, " addrProxy" );
678711 migrate_setting (ProxyUse, " fUseProxy" );
679712 migrate_setting (ProxyIPTor, " addrSeparateProxyTor" );
0 commit comments