Skip to content

Commit

Permalink
Update to config generation branch based on merge comments
Browse files Browse the repository at this point in the history
Signed-off-by: Yiannis Karavas <[email protected]>
  • Loading branch information
ykaravas authored and Yiannis Karavas committed Jul 7, 2022
1 parent 21a8d69 commit 6249f1d
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 111 deletions.
4 changes: 2 additions & 2 deletions config/tools/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
project(config_gen)

include_directories(../../src ../../config/tools ../../3rdparty/secp256k1/include)
include_directories(../../src ../../3rdparty/secp256k1/include)

add_library(config_generator config_generator.cpp)

add_executable(generate_config generate_configd.cpp)
add_executable(generate_config generate_config.cpp)

target_link_libraries(generate_config config_generator
util
Expand Down
134 changes: 72 additions & 62 deletions config/tools/config_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,32 @@

#include "config_generator.hpp"

#include "util/common/config.hpp"
#include "util/common/keys.hpp"
#include "util/common/variant_overloaded.hpp"
#include "util/network/tcp_listener.hpp"

#include <algorithm>
#include <cassert>
#include <filesystem>
#include <functional>
#include <random>
#include <set>

// NORMAL CONFIGS

// Integer that determines if this is 2PC or Atomizer. 1 means 2PC
static constexpr auto two_phase_mode = "2pc";
// Number of shards to be created
static constexpr auto shard_count_key = "shard_count";
// Number of sentinels to be created
static constexpr auto sentinel_count_key = "sentinel_count";
// Number of coordinators to be created
static constexpr auto coordinator_count_key = "coordinator_count";
// Number of archivers to be created
static constexpr auto archiver_count_key = "archiver_count";
// Number of atomizers to be created
static constexpr auto atomizer_count_key = "atomizer_count";
// Number of watchtowers to be created
static constexpr auto watchtower_count_key = "watchtower_count";
using namespace cbdc::config;

// Using the following values from src/common/config.hpp:

// "cbdc::config::two_phase_mode" : Name of value in config template file that
// is an integer which determines if this is 2PC or Atomizer. 1 means 2PC
// "cbdc::config::shard_count_key" : Number of shards to be created
// "cbdc::config::sentinel_count_key" : Number of sentinels to be created
// "cbdc::config::coordinator_count_key" : Number of coordinators to be created
// "cbdc::config::archiver_count_key" : Number of archivers to be created
// "cbdc::config::atomizer_count_key" : Number of atomizers to be created
// "cbdc::config::watchtower_count_key" : Number of watchtowers to be created

// Prefix of interest that denotes parameters in the file that are used
// here to help generate the config file but will not be present in the
// final product
Expand Down Expand Up @@ -69,9 +69,41 @@ std::set<std::string> log_levels
namespace cbdc::generate_config {

config_generator::config_generator(std::string& _template_config_file,
const size_t _start_port)
const size_t _start_port,
std::string _build_dir)
: m_template_config_file(_template_config_file),
m_current_port(_start_port) {
// Get Project root dir and build dir
std::filesystem::path build_dir = std::filesystem::current_path();
if(_build_dir.at(_build_dir.size() - 1) == '/') {
_build_dir.erase(_build_dir.end() - 1);
}
// This config generator class assumes project root is "opencbdc-tx"
while(build_dir.has_parent_path()) {
if(build_dir.filename() == "opencbdc-tx") {
m_project_root_dir = build_dir;
std::string delimiter = "/";
std::string tmp_str = _build_dir;
size_t pos = 0;
std::string token;
while((pos = tmp_str.find("/")) != std::string::npos) {
token = tmp_str.substr(0, pos);
build_dir = build_dir.append(token);
tmp_str.erase(0, pos + delimiter.length());
}
token = tmp_str.substr(0, pos);
build_dir = build_dir.append(token);
tmp_str.erase(0, pos + delimiter.length());
m_build_dir = build_dir;
std::cout << "Build directory determined to be "
<< m_build_dir.string() << std::endl;
std::cout << "Project Root directory determined to be "
<< m_project_root_dir.string() << std::endl;
break;
} else {
build_dir = build_dir.parent_path();
}
}
template_file_is_valid = true;
if(!std::filesystem::exists(m_template_config_file)) {
template_file_is_valid = false;
Expand Down Expand Up @@ -335,7 +367,7 @@ namespace cbdc::generate_config {
[[nodiscard]] auto config_generator::get_param_from_template_file(
const std::string option,
std::map<std::string, std::string>& config_map)
-> std::variant<size_t, double, std::string> {
-> std::variant<std::string, size_t, double> {
auto it = config_map.find(option);
if(it != config_map.end()) {
value_t parsed_val = parse_value(it->second, false);
Expand All @@ -346,10 +378,7 @@ namespace cbdc::generate_config {
} else if(std::holds_alternative<std::string>(parsed_val)) {
return std::get<std::string>(parsed_val);
} else {
std::string error_msg
= "Warning: Unrecognized type for param, " + option + ".";
std::cout << error_msg << std::endl;
return error_msg;
__builtin_unreachable();
}
} else {
std::string error_msg
Expand All @@ -376,13 +405,12 @@ namespace cbdc::generate_config {

void config_generator::set_log_level(const std::string key,
std::string& log_level) {
if(find_value(key, log_level) == false) {
find_value(tmpl_universal_override_log_level, log_level);
}
if(log_levels.find(log_level) == log_levels.end()) {
log_level = "DEBUG";
std::cout << "Warning: Log level not recognized. Setting to DEBUG"
<< std::endl;
} else if(find_value(key, log_level) == false) {
find_value(tmpl_universal_override_log_level, log_level);
}
}

Expand Down Expand Up @@ -642,27 +670,16 @@ namespace cbdc::generate_config {
outFile.close();
}

// This method assumes project root is "opencbdc-tx" and build dir is
// "build"
[[nodiscard]] auto
config_generator::copy_to_build_dir(const std::string filename) -> bool {
std::filesystem::path cwd = std::filesystem::current_path();
cwd.append(filename);
std::filesystem::path build_dir = std::filesystem::current_path();
while(build_dir.has_parent_path()) {
if(build_dir.filename() == "opencbdc-tx") {
build_dir = build_dir.append("build");
break;
} else {
build_dir = build_dir.parent_path();
}
}
if(std::filesystem::exists(filename)) {
const auto copyOptions
= std::filesystem::copy_options::overwrite_existing;
// Copy and remove file if we are not in build currently
if(std::filesystem::current_path().filename() != "build") {
std::filesystem::copy(cwd, build_dir, copyOptions);
if(std::filesystem::current_path() != m_build_dir) {
std::filesystem::copy(cwd, m_build_dir, copyOptions);
std::filesystem::remove(cwd);
}
return true;
Expand All @@ -671,24 +688,11 @@ namespace cbdc::generate_config {
}
}

// This method assumes project root is "opencbdc-tx" and build dir is
// "build"
void config_generator::copy_templates_to_build_dir() {
std::filesystem::path config_dir = std::filesystem::current_path();
std::filesystem::path build_dir = std::filesystem::current_path();
while(config_dir.has_parent_path()) {
if(config_dir.filename() == "opencbdc-tx") {
config_dir = config_dir.append("config");
config_dir = config_dir.append("tools");
build_dir = build_dir.append("build");
build_dir = build_dir.append("config");
build_dir = build_dir.append("tools");
break;
} else {
config_dir = config_dir.parent_path();
build_dir = build_dir.parent_path();
}
}
std::filesystem::path config_dir = m_project_root_dir;
config_dir.append("config").append("tools");
std::filesystem::path build_config_dir = m_build_dir;
build_config_dir.append("config").append("tools");
for(auto const& dir_entry :
std::filesystem::directory_iterator{config_dir}) {
std::string filename = dir_entry.path().filename();
Expand All @@ -697,7 +701,11 @@ namespace cbdc::generate_config {
if(tmp_str == match_str) {
const auto copyOptions
= std::filesystem::copy_options::overwrite_existing;
std::filesystem::copy(dir_entry, build_dir, copyOptions);
std::filesystem::copy(dir_entry,
build_config_dir,
copyOptions);
std::cout << "Copying " << dir_entry.path().string() << " to "
<< build_config_dir.string() << std::endl;
}
}
}
Expand Down Expand Up @@ -728,8 +736,13 @@ namespace cbdc::generate_config {
std::string output_filename = "tmp.cfg";

if(!template_file_is_valid) {
std::filesystem::path temp_build_dir = m_build_dir;
temp_build_dir.append("config").append("tools");
return_msg += "File provided, " + m_template_config_file
+ ", does not exist. Aborting operation. \n";
+ ", did not exist but has likely been copied to "
+ temp_build_dir.string()
+ ". Aborting operation. Please rerun with proper "
"template location \n";
return return_msg;
}
std::map<std::string, std::string> config_map;
Expand Down Expand Up @@ -757,8 +770,7 @@ namespace cbdc::generate_config {
config_map_it->first,
std::get<std::string>(parsed_val));
} else {
return_msg += "Warning: Unrecognized type for param, "
+ config_map_it->first + ". \n";
__builtin_unreachable();
}
}
}
Expand Down Expand Up @@ -794,8 +806,7 @@ namespace cbdc::generate_config {
return_msg
+= "Warning: Two-phase mode requires at least one "
"configured shard. Fix configuration template "
"and "
"rerun.\n";
"and rerun.\n";
return return_msg;
} else {
create_2pc_component(shard_count_key,
Expand Down Expand Up @@ -853,8 +864,7 @@ namespace cbdc::generate_config {
return_msg
+= "Warning: Sentinels require at least one "
"configured shard. Fix configuration template "
"and "
"rerun. \n";
"and rerun. \n";
return return_msg;
} else {
create_atomizer_component(
Expand Down
10 changes: 8 additions & 2 deletions config/tools/config_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "util/common/config.hpp"
#include "util/common/random_source.hpp"

#include <filesystem>
#include <random>
#include <secp256k1.h>

Expand Down Expand Up @@ -45,7 +46,8 @@ namespace cbdc::generate_config {
/// \param _start_port Port to begin using and incrementing from for generated
/// configuration file's endpoints
config_generator(std::string& _template_config_file,
size_t _start_port);
size_t _start_port,
std::string _build_dir);

~config_generator() = default;

Expand All @@ -64,6 +66,10 @@ namespace cbdc::generate_config {
std::string& m_template_config_file;
// Incrementing port to use in config file for all ports
unsigned short m_current_port;
// Build directory
std::filesystem::path m_build_dir;
// Project root directory
std::filesystem::path m_project_root_dir;
// Map with shard ranges (shard_id, (start range, end_range)
std::vector<ShardInfo> shard_info;
std::default_random_engine generator;
Expand Down Expand Up @@ -115,7 +121,7 @@ namespace cbdc::generate_config {
[[nodiscard]] auto get_param_from_template_file(
std::string option,
std::map<std::string, std::string>& config_map)
-> std::variant<size_t, double, std::string>;
-> std::variant<std::string, size_t, double>;
void set_param_to_config_file(std::string key, std::string value);
void set_param_to_config_file(std::string key, size_t value);
void set_param_to_config_file(std::string key, double value);
Expand Down
69 changes: 69 additions & 0 deletions config/tools/generate_config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) 2022 MIT Digital Currency Initiative,
// Federal Reserve Bank of Boston
// MITRE Corporation
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "config_generator.hpp"

#include <iostream>
#include <random>

auto main(int argc, char** argv) -> int {
auto args = cbdc::config::get_args(argc, argv);

std::mt19937 rng;
static const auto m_random_source
= std::make_unique<cbdc::random_source>(cbdc::config::random_source);

std::string build_dir = "build";
size_t max_param_num = 4;
size_t min_param_num = 3;
if(args.size() == 2 && (args[1] == "-h" || args[1] == "--help")) {
std::cout << "Usage: " << args[0]
<< " <config template file> <starting port number to "
"increment from> <build directory name, using '/' as "
"separator. (defaults to 'build')>"
<< std::endl;
return 0;
} else if(args.size() < min_param_num) {
std::cerr << "Usage: " << args[0]
<< " <config template file> <starting port number to "
"increment from> <build directory name, using '/' as "
"separator. (defaults to 'build')>"
<< std::endl;
return 0;
} else if(args.size() == min_param_num) {
std::cout << "No build directory name specified as third. Using "
"default name of 'build'"
<< std::endl;
} else if(args.size() == max_param_num) {
build_dir = args[max_param_num - 1];
} else if(args.size() > max_param_num) {
std::cerr << "Too many parameters input. Usage: " << args[0]
<< " <config template file> <starting port number to "
"increment from> <build directory name, using '/' as "
"separator. (defaults to 'build')>"
<< std::endl;
return 0;
}

auto port_is_valid = std::isdigit(*args[2].c_str());
if(!port_is_valid) {
std::cerr << "Port number provided, " << args[2]
<< ", is not a valid number. Exiting..." << std::endl;
return 0;
}
size_t port_num = static_cast<size_t>(std::stoull(args[2]));
if(port_num > MAX_PORT_NUM) {
std::cerr << "Port number provided, " << args[2]
<< ", is too large. Exiting..." << std::endl;
return 0;
}
cbdc::generate_config::config_generator new_config_gen(args[1],
port_num,
build_dir);
auto cfg_or_err = new_config_gen.generate_configuration_file();
std::cout << cfg_or_err << std::endl;
return 0;
}
Loading

0 comments on commit 6249f1d

Please sign in to comment.