Skip to content

Commit 2642dee

Browse files
author
MacroFake
committed
Merge bitcoin/bitcoin#15936: interfaces: Expose settings.json methods to GUI
f9fdcec settings: Add resetSettings() method (Ryan Ofsky) 77fabff init: Remove Shutdown() node.args reset (Ryan Ofsky) 0e55bc6 settings: Add update/getPersistent/isIgnored methods (Ryan Ofsky) Pull request description: Add `interfaces::Node` `updateSetting`, `forceSetting`, `resetSettings`, `isSettingIgnored`, and `getPersistentSetting` methods so GUI is able to manipulate `settings.json` file and use and modify node settings. (Originally this PR also contained GUI changes to unify bitcoin-qt and bitcoind persistent settings and call these methods, but the GUI commits have been dropped from this PR and moved to /pull/602) ACKs for top commit: vasild: ACK f9fdcec hebasto: re-ACK f9fdcec, only a function renamed since my recent [review](bitcoin/bitcoin#15936 (review)). Tree-SHA512: 4cac853ee29be96d2ff38404165b9dfb7c622b2a9c99a15979596f3484ffde0da3d9c9c372677dff5119ca7cffa6383d81037fd9889a29cc9285882a8dc0c268
2 parents 48eec32 + f9fdcec commit 2642dee

File tree

8 files changed

+123
-17
lines changed

8 files changed

+123
-17
lines changed

src/init.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,6 @@ void Shutdown(NodeContext& node)
319319
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
320320
}
321321

322-
node.args = nullptr;
323322
LogPrintf("%s: done\n", __func__);
324323
}
325324

src/interfaces/node.h

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
#ifndef BITCOIN_INTERFACES_NODE_H
66
#define BITCOIN_INTERFACES_NODE_H
77

8-
#include <consensus/amount.h>
9-
#include <net.h> // For NodeId
10-
#include <net_types.h> // For banmap_t
11-
#include <netaddress.h> // For Network
12-
#include <netbase.h> // For ConnectionDirection
8+
#include <consensus/amount.h> // For CAmount
9+
#include <net.h> // For NodeId
10+
#include <net_types.h> // For banmap_t
11+
#include <netaddress.h> // For Network
12+
#include <netbase.h> // For ConnectionDirection
1313
#include <support/allocators/secure.h> // For SecureString
14+
#include <util/settings.h> // For util::SettingsValue
1415
#include <util/translation.h>
1516

1617
#include <functional>
@@ -97,6 +98,24 @@ class Node
9798
//! Return whether shutdown was requested.
9899
virtual bool shutdownRequested() = 0;
99100

101+
//! Return whether a particular setting in <datadir>/settings.json is or
102+
//! would be ignored because it is also specified in the command line.
103+
virtual bool isSettingIgnored(const std::string& name) = 0;
104+
105+
//! Return setting value from <datadir>/settings.json or bitcoin.conf.
106+
virtual util::SettingsValue getPersistentSetting(const std::string& name) = 0;
107+
108+
//! Update a setting in <datadir>/settings.json.
109+
virtual void updateRwSetting(const std::string& name, const util::SettingsValue& value) = 0;
110+
111+
//! Force a setting value to be applied, overriding any other configuration
112+
//! source, but not being persisted.
113+
virtual void forceSetting(const std::string& name, const util::SettingsValue& value) = 0;
114+
115+
//! Clear all settings in <datadir>/settings.json and store a backup of
116+
//! previous settings in <datadir>/settings.json.bak.
117+
virtual void resetSettings() = 0;
118+
100119
//! Map port.
101120
virtual void mapPort(bool use_upnp, bool use_natpmp) = 0;
102121

src/node/interfaces.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,46 @@ class NodeImpl : public Node
112112
}
113113
}
114114
bool shutdownRequested() override { return ShutdownRequested(); }
115+
bool isSettingIgnored(const std::string& name) override
116+
{
117+
bool ignored = false;
118+
gArgs.LockSettings([&](util::Settings& settings) {
119+
if (auto* options = util::FindKey(settings.command_line_options, name)) {
120+
ignored = !options->empty();
121+
}
122+
});
123+
return ignored;
124+
}
125+
util::SettingsValue getPersistentSetting(const std::string& name) override { return gArgs.GetPersistentSetting(name); }
126+
void updateRwSetting(const std::string& name, const util::SettingsValue& value) override
127+
{
128+
gArgs.LockSettings([&](util::Settings& settings) {
129+
if (value.isNull()) {
130+
settings.rw_settings.erase(name);
131+
} else {
132+
settings.rw_settings[name] = value;
133+
}
134+
});
135+
gArgs.WriteSettingsFile();
136+
}
137+
void forceSetting(const std::string& name, const util::SettingsValue& value) override
138+
{
139+
gArgs.LockSettings([&](util::Settings& settings) {
140+
if (value.isNull()) {
141+
settings.forced_settings.erase(name);
142+
} else {
143+
settings.forced_settings[name] = value;
144+
}
145+
});
146+
}
147+
void resetSettings() override
148+
{
149+
gArgs.WriteSettingsFile(/*errors=*/nullptr, /*backup=*/true);
150+
gArgs.LockSettings([&](util::Settings& settings) {
151+
settings.rw_settings.clear();
152+
});
153+
gArgs.WriteSettingsFile();
154+
}
115155
void mapPort(bool use_upnp, bool use_natpmp) override { StartMapPort(use_upnp, use_natpmp); }
116156
bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); }
117157
size_t getNodeCount(ConnectionDirection flags) override

src/test/settings_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ BOOST_AUTO_TEST_CASE(ReadWrite)
105105
//! Check settings struct contents against expected json strings.
106106
static void CheckValues(const util::Settings& settings, const std::string& single_val, const std::string& list_val)
107107
{
108-
util::SettingsValue single_value = GetSetting(settings, "section", "name", false, false);
108+
util::SettingsValue single_value = GetSetting(settings, "section", "name", false, false, false);
109109
util::SettingsValue list_value(util::SettingsValue::VARR);
110110
for (const auto& item : GetSettingsList(settings, "section", "name", false)) {
111111
list_value.push_back(item);
@@ -141,9 +141,9 @@ BOOST_AUTO_TEST_CASE(NullOverride)
141141
{
142142
util::Settings settings;
143143
settings.command_line_options["name"].push_back("value");
144-
BOOST_CHECK_EQUAL(R"("value")", GetSetting(settings, "section", "name", false, false).write().c_str());
144+
BOOST_CHECK_EQUAL(R"("value")", GetSetting(settings, "section", "name", false, false, false).write().c_str());
145145
settings.forced_settings["name"] = {};
146-
BOOST_CHECK_EQUAL(R"(null)", GetSetting(settings, "section", "name", false, false).write().c_str());
146+
BOOST_CHECK_EQUAL(R"(null)", GetSetting(settings, "section", "name", false, false, false).write().c_str());
147147
}
148148

149149
// Test different ways settings can be merged, and verify results. This test can
@@ -224,7 +224,7 @@ BOOST_FIXTURE_TEST_CASE(Merge, MergeTestingSetup)
224224
}
225225

226226
desc += " || ";
227-
desc += GetSetting(settings, network, name, ignore_default_section_config, /* get_chain_name= */ false).write();
227+
desc += GetSetting(settings, network, name, ignore_default_section_config, /*ignore_nonpersistent=*/false, /*get_chain_name=*/false).write();
228228
desc += " |";
229229
for (const auto& s : GetSettingsList(settings, network, name, ignore_default_section_config)) {
230230
desc += " ";

src/util/settings.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ SettingsValue GetSetting(const Settings& settings,
127127
const std::string& section,
128128
const std::string& name,
129129
bool ignore_default_section_config,
130+
bool ignore_nonpersistent,
130131
bool get_chain_name)
131132
{
132133
SettingsValue result;
@@ -162,6 +163,9 @@ SettingsValue GetSetting(const Settings& settings,
162163
return;
163164
}
164165

166+
// Ignore nonpersistent settings if requested.
167+
if (ignore_nonpersistent && (source == Source::COMMAND_LINE || source == Source::FORCED)) return;
168+
165169
// Skip negated command line settings.
166170
if (skip_negated_command_line && span.last_negated()) return;
167171

src/util/settings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,18 @@ bool WriteSettings(const fs::path& path,
5555
//! @param ignore_default_section_config - ignore values in the default section
5656
//! of the config file (part before any
5757
//! [section] keywords)
58+
//! @param ignore_nonpersistent - ignore non-persistent settings values (forced
59+
//! settings values and values specified on the
60+
//! command line). Only return settings in the
61+
//! read-only config and read-write settings
62+
//! files.
5863
//! @param get_chain_name - enable special backwards compatible behavior
5964
//! for GetChainName
6065
SettingsValue GetSetting(const Settings& settings,
6166
const std::string& section,
6267
const std::string& name,
6368
bool ignore_default_section_config,
69+
bool ignore_nonpersistent,
6470
bool get_chain_name);
6571

6672
//! Get combined setting value similar to GetSetting(), except if setting was

src/util/system.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -530,12 +530,15 @@ bool ArgsManager::InitSettings(std::string& error)
530530
return true;
531531
}
532532

533-
bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp) const
533+
bool ArgsManager::GetSettingsPath(fs::path* filepath, bool temp, bool backup) const
534534
{
535535
fs::path settings = GetPathArg("-settings", fs::path{BITCOIN_SETTINGS_FILENAME});
536536
if (settings.empty()) {
537537
return false;
538538
}
539+
if (backup) {
540+
settings += ".bak";
541+
}
539542
if (filepath) {
540543
*filepath = fsbridge::AbsPathJoin(GetDataDirNet(), temp ? settings + ".tmp" : settings);
541544
}
@@ -576,10 +579,10 @@ bool ArgsManager::ReadSettingsFile(std::vector<std::string>* errors)
576579
return true;
577580
}
578581

579-
bool ArgsManager::WriteSettingsFile(std::vector<std::string>* errors) const
582+
bool ArgsManager::WriteSettingsFile(std::vector<std::string>* errors, bool backup) const
580583
{
581584
fs::path path, path_tmp;
582-
if (!GetSettingsPath(&path, /* temp= */ false) || !GetSettingsPath(&path_tmp, /* temp= */ true)) {
585+
if (!GetSettingsPath(&path, /*temp=*/false, backup) || !GetSettingsPath(&path_tmp, /*temp=*/true, backup)) {
583586
throw std::logic_error("Attempt to write settings file when dynamic settings are disabled.");
584587
}
585588

@@ -596,6 +599,13 @@ bool ArgsManager::WriteSettingsFile(std::vector<std::string>* errors) const
596599
return true;
597600
}
598601

602+
util::SettingsValue ArgsManager::GetPersistentSetting(const std::string& name) const
603+
{
604+
LOCK(cs_args);
605+
return util::GetSetting(m_settings, m_network, name, !UseDefaultSection("-" + name),
606+
/*ignore_nonpersistent=*/true, /*get_chain_name=*/false);
607+
}
608+
599609
bool ArgsManager::IsArgNegated(const std::string& strArg) const
600610
{
601611
return GetSetting(strArg).isFalse();
@@ -604,18 +614,33 @@ bool ArgsManager::IsArgNegated(const std::string& strArg) const
604614
std::string ArgsManager::GetArg(const std::string& strArg, const std::string& strDefault) const
605615
{
606616
const util::SettingsValue value = GetSetting(strArg);
617+
return SettingToString(value, strDefault);
618+
}
619+
620+
std::string SettingToString(const util::SettingsValue& value, const std::string& strDefault)
621+
{
607622
return value.isNull() ? strDefault : value.isFalse() ? "0" : value.isTrue() ? "1" : value.isNum() ? value.getValStr() : value.get_str();
608623
}
609624

610625
int64_t ArgsManager::GetIntArg(const std::string& strArg, int64_t nDefault) const
611626
{
612627
const util::SettingsValue value = GetSetting(strArg);
628+
return SettingToInt(value, nDefault);
629+
}
630+
631+
int64_t SettingToInt(const util::SettingsValue& value, int64_t nDefault)
632+
{
613633
return value.isNull() ? nDefault : value.isFalse() ? 0 : value.isTrue() ? 1 : value.isNum() ? value.getInt<int64_t>() : LocaleIndependentAtoi<int64_t>(value.get_str());
614634
}
615635

616636
bool ArgsManager::GetBoolArg(const std::string& strArg, bool fDefault) const
617637
{
618638
const util::SettingsValue value = GetSetting(strArg);
639+
return SettingToBool(value, fDefault);
640+
}
641+
642+
bool SettingToBool(const util::SettingsValue& value, bool fDefault)
643+
{
619644
return value.isNull() ? fDefault : value.isBool() ? value.get_bool() : InterpretBool(value.get_str());
620645
}
621646

@@ -1006,6 +1031,7 @@ std::string ArgsManager::GetChainName() const
10061031
LOCK(cs_args);
10071032
util::SettingsValue value = util::GetSetting(m_settings, /* section= */ "", SettingName(arg),
10081033
/* ignore_default_section_config= */ false,
1034+
/*ignore_nonpersistent=*/false,
10091035
/* get_chain_name= */ true);
10101036
return value.isNull() ? false : value.isBool() ? value.get_bool() : InterpretBool(value.get_str());
10111037
};
@@ -1038,7 +1064,8 @@ util::SettingsValue ArgsManager::GetSetting(const std::string& arg) const
10381064
{
10391065
LOCK(cs_args);
10401066
return util::GetSetting(
1041-
m_settings, m_network, SettingName(arg), !UseDefaultSection(arg), /* get_chain_name= */ false);
1067+
m_settings, m_network, SettingName(arg), !UseDefaultSection(arg),
1068+
/*ignore_nonpersistent=*/false, /*get_chain_name=*/false);
10421069
}
10431070

10441071
std::vector<util::SettingsValue> ArgsManager::GetSettingsList(const std::string& arg) const

src/util/system.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ struct SectionInfo
160160
int m_line;
161161
};
162162

163+
std::string SettingToString(const util::SettingsValue&, const std::string&);
164+
int64_t SettingToInt(const util::SettingsValue&, int64_t);
165+
bool SettingToBool(const util::SettingsValue&, bool);
166+
163167
class ArgsManager
164168
{
165169
public:
@@ -436,17 +440,24 @@ class ArgsManager
436440
* Get settings file path, or return false if read-write settings were
437441
* disabled with -nosettings.
438442
*/
439-
bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false) const;
443+
bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const;
440444

441445
/**
442446
* Read settings file. Push errors to vector, or log them if null.
443447
*/
444448
bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
445449

446450
/**
447-
* Write settings file. Push errors to vector, or log them if null.
451+
* Write settings file or backup settings file. Push errors to vector, or
452+
* log them if null.
453+
*/
454+
bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const;
455+
456+
/**
457+
* Get current setting from config file or read/write settings file,
458+
* ignoring nonpersistent command line or forced settings values.
448459
*/
449-
bool WriteSettingsFile(std::vector<std::string>* errors = nullptr) const;
460+
util::SettingsValue GetPersistentSetting(const std::string& name) const;
450461

451462
/**
452463
* Access settings with lock held.

0 commit comments

Comments
 (0)