Skip to content

Commit

Permalink
ATTEMPT CONFIG OVERRIDES
Browse files Browse the repository at this point in the history
  • Loading branch information
pwojcikdev committed Jan 17, 2024
1 parent 445deef commit dc004fd
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 55 deletions.
49 changes: 38 additions & 11 deletions nano/lib/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@

#include <sstream>

std::vector<std::string> nano::config_overrides (std::vector<config_key_value_pair> const & key_value_pairs_a)
nano::config_overrides_t nano::make_config_overrides (const nano::cli_config_overrides_t & config_overrides)
{
std::vector<std::string> overrides;
auto format (boost::format ("%1%=%2%"));
auto format_add_escaped_quotes (boost::format ("%1%=\"%2%\""));
for (auto pair : key_value_pairs_a)
nano::config_overrides_t overrides;

for (auto const & pair : config_overrides)
{
auto start = pair.value.find ('[');
auto & [pair_key, pair_value] = pair;

auto start = pair_value.find ('[');

std::string value;
auto is_array = (start != std::string::npos);
if (is_array)
{
// Trim off the square brackets [] of the array
auto end = pair.value.find (']');
auto array_values = pair.value.substr (start + 1, end - start - 1);
auto end = pair_value.find (']');
auto array_values = pair_value.substr (start + 1, end - start - 1);

// Split the string by comma
std::vector<std::string> split_elements;
Expand All @@ -47,14 +48,40 @@ std::vector<std::string> nano::config_overrides (std::vector<config_key_value_pa
}
else
{
value = pair.value;
value = pair_value;
}

// Ensure the value is always surrounded by quotes
bool already_escaped = value.find ('\"') != std::string::npos;
if (!already_escaped)
{
value = "\"" + value + "\"";
}
auto already_escaped = value.find ('\"') != std::string::npos;
overrides.push_back (((!already_escaped ? format_add_escaped_quotes : format) % pair.key % value).str ());

overrides[pair_key] = value;
}

return overrides;
}

std::stringstream nano::config_overrides_to_toml (nano::config_overrides_t const & config_overrides)
{
std::stringstream config_overrides_stream;
for (auto const & entry : config_overrides)
{
auto [key, value] = entry;

auto format (boost::format ("%1%=%2%"));
auto format_add_escaped_quotes (boost::format ("%1%=\"%2%\""));

bool already_escaped = value.find ('\"') != std::string::npos;
auto key_value_pair = ((!already_escaped ? format_add_escaped_quotes : format) % key % value).str ();

config_overrides_stream << key_value_pair << std::endl;
}
config_overrides_stream << std::endl;
}

std::istream & nano::operator>> (std::istream & is, nano::config_key_value_pair & into)
{
char ch;
Expand Down
16 changes: 12 additions & 4 deletions nano/lib/cli.hpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
#pragma once

#include <nano/lib/config.hpp>

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

namespace nano
{
class config_key_value_pair
struct config_key_value_pair
{
public:
std::string key;
std::string value;
};
std::istream & operator>> (std::istream & is, nano::config_key_value_pair & into);

std::vector<std::string> config_overrides (std::vector<config_key_value_pair> const & key_value_pairs_a);
/// Type used by boost::program_options to store config key/value pairs
using cli_config_overrides_t = std::vector<config_key_value_pair>;

std::istream & operator>> (std::istream & is, nano::config_key_value_pair & into);
/// Convert a vector of key/value pairs from boost::program_options to a vector of strings in a toml compatible format
nano::config_overrides_t make_config_overrides (nano::cli_config_overrides_t const & raw_config_overrides);

/// Convert a vector of key/value pairs to a toml string suitable for parsing by nano::tomlconfig
std::stringstream config_overrides_to_toml (nano::config_overrides_t const & config_overrides);
}
14 changes: 5 additions & 9 deletions nano/lib/config.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <nano/lib/blocks.hpp>
#include <nano/lib/cli.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/logging.hpp>

Expand Down Expand Up @@ -377,19 +378,13 @@ std::string_view nano::to_string (nano::networks network)
return "n/a";
}

nano::tomlconfig nano::load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides)
nano::tomlconfig nano::load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const nano::config_overrides_t & config_overrides)
{
std::stringstream config_overrides_stream;
for (auto const & entry : config_overrides)
{
config_overrides_stream << entry << std::endl;
}
config_overrides_stream << std::endl;

auto try_load_toml = [&config_overrides_stream] (auto toml_config_path) -> std::optional<nano::tomlconfig> {
auto try_load_toml = [&config_overrides] (auto toml_config_path) -> std::optional<nano::tomlconfig> {
// Make sure we don't create an empty toml file if it doesn't exist. Running without a toml file is the default.
if (std::filesystem::exists (toml_config_path))
{
auto config_overrides_stream = nano::config_overrides_to_toml (config_overrides);
nano::tomlconfig toml;
auto error = toml.read (config_overrides_stream, toml_config_path);
if (error)
Expand All @@ -414,6 +409,7 @@ nano::tomlconfig nano::load_toml_file (const std::filesystem::path & config_file
}

// If no config was found, return an empty config with overrides applied
auto config_overrides_stream = nano::config_overrides_to_toml (config_overrides);
nano::tomlconfig toml;
auto error = toml.read (config_overrides_stream);
if (error)
Expand Down
7 changes: 5 additions & 2 deletions nano/lib/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <array>
#include <chrono>
#include <filesystem>
#include <map>
#include <optional>
#include <string>

Expand Down Expand Up @@ -80,6 +81,8 @@ inline bool is_tsan_build ()

namespace nano
{
using config_overrides_t = std::map<std::string, std::string>; // <config_key, config_value>

uint8_t get_major_node_version ();
uint8_t get_minor_node_version ();
uint8_t get_patch_node_version ();
Expand Down Expand Up @@ -413,10 +416,10 @@ void force_nano_dev_network ();
* Attempt to read a configuration file from current working directory, or if not found, the nano root directory.
* Returns empty tomlconfig if nothing is found.
*/
nano::tomlconfig load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides);
nano::tomlconfig load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const nano::config_overrides_t & config_overrides);

template <typename T>
T load_config_file (T fallback, const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides)
T load_config_file (T fallback, const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const nano::config_overrides_t & config_overrides)
{
auto toml = load_toml_file (config_filename, data_path, config_overrides);

Expand Down
16 changes: 15 additions & 1 deletion nano/lib/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,21 @@ std::map<nano::log_config::logger_id_t, nano::log::level> nano::log_config::defa
* config loading
*/

nano::log_config nano::load_log_config (nano::log_config fallback, const std::filesystem::path & data_path, const std::vector<std::string> & config_overrides)
/*
* Config prioritization hierarchy:
* 1. Command line options
* 2. Environment variables
* 3. Config file (current working directory)
* 4. Config file (nano::working_path ())
* 5. Defaults
*/

namespace
{

}

nano::log_config nano::load_log_config (nano::log_config fallback, std::filesystem::path data_path, nano::config_overrides_t config_overrides)
{
const std::string config_filename = "config-log.toml";
try
Expand Down
3 changes: 2 additions & 1 deletion nano/lib/logging.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <nano/lib/config.hpp>
#include <nano/lib/logging_enums.hpp>
#include <nano/lib/tomlconfig.hpp>

Expand Down Expand Up @@ -59,7 +60,7 @@ class log_config final
};

/// @throws std::runtime_error if the log config file is malformed
nano::log_config load_log_config (nano::log_config fallback, std::filesystem::path const & data_path = {}, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
nano::log_config load_log_config (nano::log_config fallback, std::filesystem::path data_path = {}, nano::config_overrides_t config_overrides = {});
}

namespace nano
Expand Down
11 changes: 3 additions & 8 deletions nano/lib/rpcconfig.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <nano/boost/asio/ip/address_v6.hpp>
#include <nano/lib/cli.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/rpcconfig.hpp>
#include <nano/lib/tomlconfig.hpp>
Expand Down Expand Up @@ -111,20 +112,14 @@ nano::rpc_process_config::rpc_process_config (nano::network_constants & network_

namespace nano
{
nano::error read_rpc_config_toml (std::filesystem::path const & data_path_a, nano::rpc_config & config_a, std::vector<std::string> const & config_overrides)
nano::error read_rpc_config_toml (std::filesystem::path data_path_a, nano::rpc_config & config_a, nano::config_overrides_t config_overrides)
{
nano::error error;
auto toml_config_path = nano::get_rpc_toml_config_path (data_path_a);

// Parse and deserialize
nano::tomlconfig toml;

std::stringstream config_overrides_stream;
for (auto const & entry : config_overrides)
{
config_overrides_stream << entry << std::endl;
}
config_overrides_stream << std::endl;
std::stringstream config_overrides_stream = nano::config_overrides_to_toml (config_overrides);

// Make sure we don't create an empty toml file if it doesn't exist. Running without a toml file is the default.
if (!error)
Expand Down
2 changes: 1 addition & 1 deletion nano/lib/rpcconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class rpc_config final
std::shared_ptr<nano::tls_config> tls_config;
};

nano::error read_rpc_config_toml (std::filesystem::path const & data_path_a, nano::rpc_config & config_a, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
nano::error read_rpc_config_toml (std::filesystem::path data_path_a, nano::rpc_config & config_a, nano::config_overrides_t config_overrides = {});

std::string get_default_rpc_filepath ();
}
4 changes: 2 additions & 2 deletions nano/nano_node/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1126,11 +1126,11 @@ int main (int argc, char * const * argv)
nano::work_pool work{ network_params.network, std::numeric_limits<unsigned>::max () };
auto path1 (nano::unique_path ());
auto path2 (nano::unique_path ());
std::vector<std::string> config_overrides;
nano::config_overrides_t config_overrides;
auto config (vm.find ("config"));
if (config != vm.end ())
{
config_overrides = nano::config_overrides (config->second.as<std::vector<nano::config_key_value_pair>> ());
config_overrides = nano::make_config_overrides (config->second.as<nano::cli_config_overrides_t> ());
}
nano::daemon_config daemon_config{ data_path, network_params };
auto error = nano::read_node_config_toml (data_path, daemon_config, config_overrides);
Expand Down
10 changes: 5 additions & 5 deletions nano/node/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ std::error_code nano::update_flags (nano::node_flags & flags_a, boost::program_o
auto config (vm.find ("config"));
if (config != vm.end ())
{
flags_a.config_overrides = nano::config_overrides (config->second.as<std::vector<nano::config_key_value_pair>> ());
flags_a.config_overrides = nano::make_config_overrides (config->second.as<nano::cli_config_overrides_t> ());
}
auto rpcconfig (vm.find ("rpcconfig"));
if (rpcconfig != vm.end ())
{
flags_a.rpc_config_overrides = nano::config_overrides (rpcconfig->second.as<std::vector<nano::config_key_value_pair>> ());
flags_a.rpc_config_overrides = nano::make_config_overrides (rpcconfig->second.as<nano::cli_config_overrides_t> ());
}
return ec;
}
Expand Down Expand Up @@ -455,7 +455,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map
{
auto data_path = vm.count ("data_path") ? std::filesystem::path (vm["data_path"].as<std::string> ()) : nano::working_path ();
auto node_flags = nano::inactive_node_flag_defaults ();
node_flags.config_overrides.push_back ("node.rocksdb.enable=false");
node_flags.config_overrides["node.rocksdb.enable"] = "false";
nano::update_flags (node_flags, vm);
nano::inactive_node node (data_path, node_flags);
auto error (false);
Expand Down Expand Up @@ -1332,10 +1332,10 @@ bool is_using_rocksdb (std::filesystem::path const & data_path, boost::program_o

// Config overriding
auto config_arg (vm.find ("config"));
std::vector<std::string> config_overrides;
nano::config_overrides_t config_overrides;
if (config_arg != vm.end ())
{
config_overrides = nano::config_overrides (config_arg->second.as<std::vector<nano::config_key_value_pair>> ());
config_overrides = nano::make_config_overrides (config_arg->second.as<nano::cli_config_overrides_t> ());
}

// config override...
Expand Down
11 changes: 3 additions & 8 deletions nano/node/daemonconfig.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <nano/lib/cli.hpp>
#include <nano/lib/config.hpp>
#include <nano/lib/jsonconfig.hpp>
#include <nano/lib/tomlconfig.hpp>
Expand Down Expand Up @@ -59,21 +60,15 @@ nano::error nano::daemon_config::deserialize_toml (nano::tomlconfig & toml)
return toml.get_error ();
}

nano::error nano::read_node_config_toml (std::filesystem::path const & data_path_a, nano::daemon_config & config_a, std::vector<std::string> const & config_overrides)
nano::error nano::read_node_config_toml (std::filesystem::path data_path_a, nano::daemon_config & config_a, nano::config_overrides_t config_overrides)
{
nano::error error;
auto toml_config_path = nano::get_node_toml_config_path (data_path_a);
auto toml_qt_config_path = nano::get_qtwallet_toml_config_path (data_path_a);

// Parse and deserialize
nano::tomlconfig toml;

std::stringstream config_overrides_stream;
for (auto const & entry : config_overrides)
{
config_overrides_stream << entry << std::endl;
}
config_overrides_stream << std::endl;
std::stringstream config_overrides_stream = nano::config_overrides_to_toml (config_overrides);

// Make sure we don't create an empty toml file if it doesn't exist. Running without a toml file is the default.
if (!error)
Expand Down
2 changes: 1 addition & 1 deletion nano/node/daemonconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ class daemon_config
std::filesystem::path data_path;
};

nano::error read_node_config_toml (std::filesystem::path const &, nano::daemon_config & config_a, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
nano::error read_node_config_toml (std::filesystem::path data_path, nano::daemon_config & config_a, nano::config_overrides_t config_overrides = {});
}
5 changes: 3 additions & 2 deletions nano/node/nodeconfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ class node_config
class node_flags final
{
public:
std::vector<std::string> config_overrides;
std::vector<std::string> rpc_config_overrides;
nano::config_overrides_t config_overrides;
nano::config_overrides_t rpc_config_overrides;

bool disable_add_initial_peers{ false }; // For testing only
bool disable_backup{ false };
bool disable_lazy_bootstrap{ false };
Expand Down

0 comments on commit dc004fd

Please sign in to comment.