Skip to content

Commit d7b0258

Browse files
committed
Merge #14708: Warn unrecognised sections in the config file
3fb09b9 Warn unrecognized sections in the config file (Akio Nakamura) Pull request description: This PR intends to resolve #14702. In the config file, sections are specified by square bracket pair "[]"$, or included in the option name itself which separated by a period"(.)". Typicaly, [testnet] is not a correct section name and specified options in that section are ignored but user cannot recognize what is happen. So, add some log-warning messages if unrecognized section names are present in the config file after checking section only args. note: Currentry, followings are out of scope of this PR. 1) Empty section name or option name can describe. e.g. [] , .a=b, =c 2) Multiple period characters can exist in the section name and option name. e.g. [c.d.e], [..], f.g.h.i=j, ..=k Tree-SHA512: 2cea02a0525feb40320613989a75cd7b7b1bd12158d5e6f3174ca77e6a25bb84425dd8812f62483df9fc482045c7b5402d69bc714430518b1847d055a2dc304b
2 parents 1649886 + 3fb09b9 commit d7b0258

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

src/init.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,15 @@ void InitParameterInteraction()
803803
// Warn if network-specific options (-addnode, -connect, etc) are
804804
// specified in default section of config file, but not overridden
805805
// on the command line or in this network's section of the config file.
806-
gArgs.WarnForSectionOnlyArgs();
806+
std::string network = gArgs.GetChainName();
807+
for (const auto& arg : gArgs.GetUnsuitableSectionOnlyArgs()) {
808+
InitWarning(strprintf(_("Config setting for %s only applied on %s network when in [%s] section."), arg, network, network));
809+
}
810+
811+
// Warn if unrecognized section name are present in the config file.
812+
for (const auto& section : gArgs.GetUnrecognizedSections()) {
813+
InitWarning(strprintf(_("Section [%s] is not recognized."), section));
814+
}
807815
}
808816

809817
static std::string ResolveErrMsg(const char * const optname, const std::string& strBind)

src/util/system.cpp

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,15 +371,17 @@ ArgsManager::ArgsManager() :
371371
// nothing to do
372372
}
373373

374-
void ArgsManager::WarnForSectionOnlyArgs()
374+
const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs() const
375375
{
376+
std::set<std::string> unsuitables;
377+
376378
LOCK(cs_args);
377379

378380
// if there's no section selected, don't worry
379-
if (m_network.empty()) return;
381+
if (m_network.empty()) return std::set<std::string> {};
380382

381383
// if it's okay to use the default section for this network, don't worry
382-
if (m_network == CBaseChainParams::MAIN) return;
384+
if (m_network == CBaseChainParams::MAIN) return std::set<std::string> {};
383385

384386
for (const auto& arg : m_network_only_args) {
385387
std::pair<bool, std::string> found_result;
@@ -397,8 +399,28 @@ void ArgsManager::WarnForSectionOnlyArgs()
397399
if (!found_result.first) continue;
398400

399401
// otherwise, issue a warning
400-
LogPrintf("Warning: Config setting for %s only applied on %s network when in [%s] section.\n", arg, m_network, m_network);
402+
unsuitables.insert(arg);
401403
}
404+
return unsuitables;
405+
}
406+
407+
408+
const std::set<std::string> ArgsManager::GetUnrecognizedSections() const
409+
{
410+
// Section names to be recognized in the config file.
411+
static const std::set<std::string> available_sections{
412+
CBaseChainParams::REGTEST,
413+
CBaseChainParams::TESTNET,
414+
CBaseChainParams::MAIN
415+
};
416+
std::set<std::string> diff;
417+
418+
LOCK(cs_args);
419+
std::set_difference(
420+
m_config_sections.begin(), m_config_sections.end(),
421+
available_sections.begin(), available_sections.end(),
422+
std::inserter(diff, diff.end()));
423+
return diff;
402424
}
403425

404426
void ArgsManager::SelectConfigNetwork(const std::string& network)
@@ -819,7 +841,7 @@ static std::string TrimString(const std::string& str, const std::string& pattern
819841
return str.substr(front, end - front + 1);
820842
}
821843

822-
static bool GetConfigOptions(std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>> &options)
844+
static bool GetConfigOptions(std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::set<std::string>& sections)
823845
{
824846
std::string str, prefix;
825847
std::string::size_type pos;
@@ -834,7 +856,9 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
834856
str = TrimString(str, pattern);
835857
if (!str.empty()) {
836858
if (*str.begin() == '[' && *str.rbegin() == ']') {
837-
prefix = str.substr(1, str.size() - 2) + '.';
859+
const std::string section = str.substr(1, str.size() - 2);
860+
sections.insert(section);
861+
prefix = section + '.';
838862
} else if (*str.begin() == '-') {
839863
error = strprintf("parse error on line %i: %s, options in configuration file must be specified without leading -", linenr, str);
840864
return false;
@@ -846,6 +870,9 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
846870
return false;
847871
}
848872
options.emplace_back(name, value);
873+
if ((pos = name.rfind('.')) != std::string::npos) {
874+
sections.insert(name.substr(0, pos));
875+
}
849876
} else {
850877
error = strprintf("parse error on line %i: %s", linenr, str);
851878
if (str.size() >= 2 && str.substr(0, 2) == "no") {
@@ -863,7 +890,8 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, std::string& error, boo
863890
{
864891
LOCK(cs_args);
865892
std::vector<std::pair<std::string, std::string>> options;
866-
if (!GetConfigOptions(stream, error, options)) {
893+
m_config_sections.clear();
894+
if (!GetConfigOptions(stream, error, options, m_config_sections)) {
867895
return false;
868896
}
869897
for (const std::pair<std::string, std::string>& option : options) {

src/util/system.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class ArgsManager
149149
std::string m_network GUARDED_BY(cs_args);
150150
std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
151151
std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
152+
std::set<std::string> m_config_sections GUARDED_BY(cs_args);
152153

153154
bool ReadConfigStream(std::istream& stream, std::string& error, bool ignore_invalid_keys = false);
154155

@@ -169,7 +170,12 @@ class ArgsManager
169170
* on the command line or in a network-specific section in the
170171
* config file.
171172
*/
172-
void WarnForSectionOnlyArgs();
173+
const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
174+
175+
/**
176+
* Log warnings for unrecognized section names in the config file.
177+
*/
178+
const std::set<std::string> GetUnrecognizedSections() const;
173179

174180
/**
175181
* Return a vector of strings of the given argument

test/functional/feature_config_args.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ def test_config_file_parser(self):
3333
conf.write('server=1\nrpcuser=someuser\nrpcpassword=some#pass')
3434
self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
3535

36+
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
37+
conf.write('testnot.datadir=1\n[testnet]\n')
38+
self.restart_node(0)
39+
self.nodes[0].stop_node(expected_stderr='Warning: Section [testnet] is not recognized.' + os.linesep + 'Warning: Section [testnot] is not recognized.')
40+
3641
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
3742
conf.write('') # clear
3843

0 commit comments

Comments
 (0)