From e835e18d18f705466ee8995c50780bfb2f8c7f5b Mon Sep 17 00:00:00 2001 From: Savinda Senevirathne Date: Wed, 23 Dec 2020 18:52:58 +0530 Subject: [PATCH] New config file structure. (#201) --- src/conf.cpp | 426 ++++++++++++++------------- src/conf.hpp | 142 +++++---- src/consensus.cpp | 38 +-- src/crypto.cpp | 18 +- src/crypto.hpp | 4 +- src/hpfs/hpfs.cpp | 4 +- src/hplog.cpp | 10 +- src/ledger.cpp | 8 +- src/main.cpp | 8 +- src/msg/fbuf/ledger_helpers.cpp | 4 +- src/msg/fbuf/p2pmsg_helpers.cpp | 10 +- src/msg/json/usrmsg_json.cpp | 10 +- src/p2p/p2p.cpp | 32 +- src/p2p/peer_comm_server.cpp | 16 +- src/p2p/peer_session_handler.cpp | 6 +- src/sc.cpp | 20 +- src/state/state_common.hpp | 2 +- src/unl.cpp | 12 +- src/usr/user_session_handler.cpp | 4 +- src/usr/usr.cpp | 18 +- test/local-cluster/cluster-create.sh | 36 ++- test/vm-cluster/cluster.sh | 15 +- 22 files changed, 450 insertions(+), 393 deletions(-) diff --git a/src/conf.cpp b/src/conf.cpp index f0f57af3..7441f8cd 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -13,10 +13,10 @@ namespace conf contract_config cfg; // Stores the initial startup mode of the node. - OPERATING_MODE startup_mode; + ROLE startup_mode; - const static char *MODE_OBSERVER = "observer"; - const static char *MODE_PROPOSER = "proposer"; + const static char *ROLE_OBSERVER = "observer"; + const static char *ROLE_VALIDATOR = "validator"; const static char *PUBLIC = "public"; const static char *PRIVATE = "private"; @@ -54,7 +54,7 @@ namespace conf if (read_config(cfg) != 0) return -1; - crypto::generate_signing_keys(cfg.pubkey, cfg.seckey); + crypto::generate_signing_keys(cfg.node.public_key, cfg.node.private_key); binpair_to_hex(cfg); if (write_config(cfg) != 0) @@ -93,42 +93,42 @@ namespace conf //We populate the in-memory struct with default settings and then save it to the file. contract_config cfg = {}; - crypto::generate_signing_keys(cfg.pubkey, cfg.seckey); + crypto::generate_signing_keys(cfg.node.public_key, cfg.node.private_key); binpair_to_hex(cfg); - cfg.hpversion = util::HP_VERSION; - cfg.contractversion = "1.0"; - cfg.contractid = crypto::generate_uuid(); + cfg.hp_version = util::HP_VERSION; + cfg.node.role = ROLE::VALIDATOR; + cfg.node.full_history = false; + + cfg.contract.id = crypto::generate_uuid(); + cfg.contract.version = "1.0"; //Add self pubkey to the unl. - cfg.unl.emplace(cfg.pubkey); + cfg.contract.unl.emplace(cfg.node.public_key); + cfg.contract.bin_path = ""; + cfg.contract.roundtime = 1000; + cfg.contract.is_consensus_public = false; + cfg.contract.is_npl_public = false; - cfg.operating_mode = OPERATING_MODE::PROPOSER; - cfg.peerport = 22860; - cfg.roundtime = 1000; - cfg.pubport = 8080; - cfg.peerdiscoverytime = 30000; - cfg.pubidletimeout = 0; - cfg.peeridletimeout = 120; + cfg.mesh.port = 22860; + cfg.mesh.msg_forwarding = false; + cfg.mesh.idle_timeout = 120; + cfg.mesh.peer_discovery.enabled = false; + cfg.mesh.peer_discovery.interval = 30000; - cfg.is_consensus_public = false; - cfg.is_npl_public = false; - - cfg.msgforwarding = false; - cfg.dynamicpeerdiscovery = false; - cfg.fullhistory = false; + cfg.user.port = 8080; + cfg.user.idle_timeout = 0; #ifndef NDEBUG - cfg.loglevel_type = conf::LOG_SEVERITY::DEBUG; - cfg.loglevel = "dbg"; + cfg.log.loglevel_type = conf::LOG_SEVERITY::DEBUG; + cfg.log.loglevel = "dbg"; #else - cfg.loglevel_type = conf::LOG_SEVERITY::WARN; - cfg.loglevel = "inf"; + cfg.log.loglevel_type = conf::LOG_SEVERITY::WARN; + cfg.log.loglevel = "inf"; #endif - cfg.loggers.emplace("console"); - cfg.loggers.emplace("file"); - cfg.binary = ""; + cfg.log.loggers.emplace("console"); + cfg.log.loggers.emplace("file"); //Save the default settings into the config file. if (write_config(cfg) != 0) @@ -188,7 +188,7 @@ namespace conf if (read_config(cfg) == -1) return -1; - cfg.unl = updated_unl; + cfg.contract.unl = updated_unl; if (write_config(cfg) == -1) return -1; @@ -218,20 +218,20 @@ namespace conf ifs.close(); // Check whether the hp version is specified. - cfg.hpversion = d["hpversion"].as(); - if (cfg.hpversion.empty()) + cfg.hp_version = d["hp_version"].as(); + if (cfg.hp_version.empty()) { std::cerr << "Contract config HP version missing.\n"; return -1; } // Check whether this config complies with the min version requirement. - int verresult = util::version_compare(cfg.hpversion, std::string(util::MIN_CONFIG_VERSION)); + int verresult = util::version_compare(cfg.hp_version, std::string(util::MIN_CONFIG_VERSION)); if (verresult == -1) { std::cerr << "Config version too old. Minimum " << util::MIN_CONFIG_VERSION << " required. " - << cfg.hpversion << " found.\n"; + << cfg.hp_version << " found.\n"; return -1; } else if (verresult == -2) @@ -240,42 +240,74 @@ namespace conf return -1; } - cfg.contractid = d["contractid"].as(); - cfg.contractversion = d["contractversion"].as(); - if (cfg.contractid.empty()) + const jsoncons::json &node = d["node"]; + cfg.node.pub_key_hex = node["public_key"].as(); + cfg.node.private_key_hex = node["private_key"].as(); + if (node["role"] == ROLE_OBSERVER) + cfg.node.role = ROLE::OBSERVER; + else if (node["role"] == ROLE_VALIDATOR) + cfg.node.role = ROLE::VALIDATOR; + else + { + std::cerr << "Invalid mode. 'observer' or 'validator' expected.\n"; + return -1; + } + + const jsoncons::json &contract = d["contract"]; + cfg.contract.id = contract["id"].as(); + cfg.contract.version = contract["version"].as(); + if (cfg.contract.id.empty()) { std::cerr << "Contract id not specified.\n"; return -1; } - else if (cfg.contractversion.empty()) + else if (cfg.contract.version.empty()) { std::cerr << "Contract version not specified.\n"; return -1; } - - if (d["mode"] == MODE_OBSERVER) - cfg.operating_mode = OPERATING_MODE::OBSERVER; - else if (d["mode"] == MODE_PROPOSER) - cfg.operating_mode = OPERATING_MODE::PROPOSER; - else + cfg.contract.unl.clear(); + for (auto &nodepk : contract["unl"].array_range()) { - std::cerr << "Invalid mode. 'observer' or 'proposer' expected.\n"; + // Convert the public key hex of each node to binary and store it. + std::string bin_pubkey; + bin_pubkey.resize(crypto::PFXD_PUBKEY_BYTES); + if (util::hex2bin( + reinterpret_cast(bin_pubkey.data()), + bin_pubkey.length(), + nodepk.as()) != 0) + { + std::cerr << "Error decoding unl list.\n"; + return -1; + } + cfg.contract.unl.emplace(bin_pubkey); + } + cfg.contract.bin_path = contract["bin_path"].as(); + cfg.contract.bin_args = contract["bin_args"].as(); + cfg.contract.roundtime = contract["roundtime"].as(); + if (contract["consensus"] != PUBLIC && contract["consensus"] != PRIVATE) + { + std::cerr << "Invalid consensus flag configured. Valid values: public|private\n"; return -1; } + cfg.contract.is_consensus_public = contract["consensus"] == PUBLIC; - cfg.pubkeyhex = d["pubkeyhex"].as(); - cfg.seckeyhex = d["seckeyhex"].as(); - - cfg.binary = d["binary"].as(); - cfg.binargs = d["binargs"].as(); - cfg.appbill = d["appbill"].as(); - cfg.appbillargs = d["appbillargs"].as(); + if (contract["npl"] != PUBLIC && contract["npl"] != PRIVATE) + { + std::cerr << "Invalid npl flag configured. Valid values: public|private\n"; + return -1; + } + cfg.contract.is_npl_public = contract["npl"] == PUBLIC; + cfg.contract.appbill.mode = contract["appbill"]["mode"].as(); + cfg.contract.appbill.bin_args = contract["appbill"]["bin_args"].as(); + const jsoncons::json &mesh = d["mesh"]; + cfg.mesh.port = mesh["port"].as(); // Storing peers in unordered map keyed by the concatenated address:port and also saving address and port // seperately to retrieve easily when handling peer connections. std::vector splitted_peers; - cfg.peers.clear(); - for (auto &v : d["peers"].array_range()) + cfg.mesh.known_peers.clear(); + for (auto &v : mesh["known_peers"].array_range()) { const char *ipport_concat = v.as(); // Split the address:port text into two @@ -292,78 +324,42 @@ namespace conf peer.ip_port.host_address = splitted_peers.front(); peer.ip_port.port = std::stoi(splitted_peers.back()); - cfg.peers.push_back(peer); + cfg.mesh.known_peers.push_back(peer); splitted_peers.clear(); } - - cfg.unl.clear(); - for (auto &nodepk : d["unl"].array_range()) + cfg.mesh.msg_forwarding = mesh["msg_forwarding"].as(); + cfg.mesh.max_connections = mesh["max_connections"].as(); + cfg.mesh.max_known_connections = mesh["max_known_connections"].as(); + // If max_connections is greater than max_known_connections then show error and stop execution. + if (cfg.mesh.max_known_connections > cfg.mesh.max_connections) { - // Convert the public key hex of each node to binary and store it. - std::string bin_pubkey; - bin_pubkey.resize(crypto::PFXD_PUBKEY_BYTES); - if (util::hex2bin( - reinterpret_cast(bin_pubkey.data()), - bin_pubkey.length(), - nodepk.as()) != 0) - { - std::cerr << "Error decoding unl list.\n"; - return -1; - } - cfg.unl.emplace(bin_pubkey); - } - - cfg.peerport = d["peerport"].as(); - cfg.pubport = d["pubport"].as(); - cfg.roundtime = d["roundtime"].as(); - cfg.peerdiscoverytime = d["peerdiscoverytime"].as(); - - cfg.peeridletimeout = d["peeridletimeout"].as(); - cfg.pubidletimeout = d["pubidletimeout"].as(); - - cfg.pubmaxsize = d["pubmaxsize"].as(); - cfg.pubmaxcpm = d["pubmaxcpm"].as(); - cfg.pubmaxbadmpm = d["pubmaxbadmpm"].as(); - cfg.pubmaxcons = d["pubmaxcons"].as(); - - cfg.peermaxsize = d["peermaxsize"].as(); - cfg.peermaxcpm = d["peermaxcpm"].as(); - cfg.peermaxdupmpm = d["peermaxdupmpm"].as(); - cfg.peermaxbadmpm = d["peermaxbadmpm"].as(); - cfg.peermaxbadsigpm = d["peermaxbadsigpm"].as(); - cfg.peermaxcons = d["peermaxcons"].as(); - cfg.peermaxknowncons = d["peermaxknowncons"].as(); - - if (d["consensus"] != PUBLIC && d["consensus"] != PRIVATE) - { - std::cerr << "Invalid consensus flag configured. Valid values: public|private\n"; + std::cerr << "Invalid configuration values: mesh max_known_connections count should not exceed mesh max_connections." << '\n'; return -1; } - cfg.is_consensus_public = d["consensus"] == PUBLIC; + cfg.mesh.max_bytes_per_msg = mesh["max_bytes_per_msg"].as(); + cfg.mesh.max_bytes_per_min = mesh["max_bytes_per_min"].as(); + cfg.mesh.max_bad_msgs_per_min = mesh["max_bad_msgs_per_min"].as(); + cfg.mesh.max_bad_msgsigs_per_min = mesh["max_bad_msgsigs_per_min"].as(); + cfg.mesh.max_dup_msgs_per_min = mesh["max_dup_msgs_per_min"].as(); + cfg.mesh.idle_timeout = mesh["idle_timeout"].as(); + cfg.mesh.peer_discovery.interval = mesh["peer_discovery"]["interval"].as(); + cfg.mesh.peer_discovery.enabled = mesh["peer_discovery"]["enabled"].as(); - if (d["npl"] != PUBLIC && d["npl"] != PRIVATE) - { - std::cerr << "Invalid npl flag configured. Valid values: public|private\n"; - return -1; - } - cfg.is_npl_public = d["npl"] == PUBLIC; + + const jsoncons::json &user = d["user"]; + cfg.user.port = user["port"].as(); + cfg.user.max_connections = user["max_connections"].as(); + cfg.user.max_bytes_per_msg = user["max_bytes_per_msg"].as(); + cfg.user.max_bytes_per_min = user["max_bytes_per_min"].as(); + cfg.user.max_bad_msgs_per_min = user["max_bad_msgs_per_min"].as(); + cfg.user.idle_timeout = user["idle_timeout"].as(); - // If peermaxknowcons is greater than peermaxcons then show error and stop execution. - if (cfg.peermaxknowncons > cfg.peermaxcons) - { - std::cerr << "Invalid configuration values: peermaxknowncons count should not exceed peermaxcons." << '\n'; - return -1; - } - - cfg.msgforwarding = d["msgforwarding"].as(); - cfg.dynamicpeerdiscovery = d["dynamicpeerdiscovery"].as(); - // cfg.fullhistory = d["fullhistory"].as(); - - cfg.loglevel = d["loglevel"].as(); - cfg.loglevel_type = get_loglevel_type(cfg.loglevel); - cfg.loggers.clear(); - for (auto &v : d["loggers"].array_range()) - cfg.loggers.emplace(v.as()); + const jsoncons::json &log = d["log"]; + cfg.log.loglevel = log["loglevel"].as(); + cfg.log.loglevel_type = get_loglevel_type(cfg.log.loglevel); + cfg.log.loggers.clear(); + for (auto &v : log["loggers"].array_range()) + cfg.log.loggers.emplace(v.as()); return 0; } @@ -377,28 +373,22 @@ namespace conf // Popualte json document with 'cfg' values. // ojson is used instead of json to preserve insertion order. jsoncons::ojson d; - d.insert_or_assign("hpversion", cfg.hpversion); - d.insert_or_assign("contractid", cfg.contractid); - d.insert_or_assign("contractversion", cfg.contractversion); - d.insert_or_assign("mode", cfg.operating_mode == OPERATING_MODE::OBSERVER ? MODE_OBSERVER : MODE_PROPOSER); + d.insert_or_assign("hp_version", cfg.hp_version); - d.insert_or_assign("pubkeyhex", cfg.pubkeyhex); - d.insert_or_assign("seckeyhex", cfg.seckeyhex); - d.insert_or_assign("binary", cfg.binary); - d.insert_or_assign("binargs", cfg.binargs); - d.insert_or_assign("appbill", cfg.appbill); - d.insert_or_assign("appbillargs", cfg.appbillargs); - - jsoncons::ojson peers(jsoncons::json_array_arg); - for (const auto &peer : cfg.peers) - { - const std::string concat_str = std::string(peer.ip_port.host_address).append(":").append(std::to_string(peer.ip_port.port)); - peers.push_back(concat_str); - } - d.insert_or_assign("peers", peers); + // Node configs. + jsoncons::ojson node_config; + node_config.insert_or_assign("public_key", cfg.node.pub_key_hex); + node_config.insert_or_assign("private_key", cfg.node.private_key_hex); + node_config.insert_or_assign("role", cfg.node.role == ROLE::OBSERVER ? ROLE_OBSERVER : ROLE_VALIDATOR); + // node_config.insert_or_assign("full_history", cfg.node.full_history); + d.insert_or_assign("node", node_config); + // Contract configs. + jsoncons::ojson contract; + contract.insert_or_assign("id", cfg.contract.id); + contract.insert_or_assign("version", cfg.contract.version); jsoncons::ojson unl(jsoncons::json_array_arg); - for (const auto &nodepk : cfg.unl) + for (const auto &nodepk : cfg.contract.unl) { std::string hex_pubkey; util::bin2hex( @@ -408,47 +398,71 @@ namespace conf unl.push_back(hex_pubkey); } - d.insert_or_assign("unl", unl); + contract.insert_or_assign("unl", unl); + contract.insert_or_assign("bin_path", cfg.contract.bin_path); + contract.insert_or_assign("bin_args", cfg.contract.bin_args); + contract.insert_or_assign("roundtime", cfg.contract.roundtime); + contract.insert_or_assign("consensus", cfg.contract.is_consensus_public ? PUBLIC : PRIVATE); + contract.insert_or_assign("npl", cfg.contract.is_npl_public ? PUBLIC : PRIVATE); - d.insert_or_assign("peerport", cfg.peerport); - d.insert_or_assign("pubport", cfg.pubport); - d.insert_or_assign("roundtime", cfg.roundtime); - d.insert_or_assign("peerdiscoverytime", cfg.peerdiscoverytime); + jsoncons::ojson appbill; + appbill.insert_or_assign("mode", cfg.contract.appbill.mode); + appbill.insert_or_assign("bin_args", cfg.contract.appbill.bin_args); - d.insert_or_assign("peeridletimeout", cfg.peeridletimeout); - d.insert_or_assign("pubidletimeout", cfg.pubidletimeout); + contract.insert_or_assign("appbill", appbill); + d.insert_or_assign("contract", contract); - d.insert_or_assign("pubmaxsize", cfg.pubmaxsize); - d.insert_or_assign("pubmaxcpm", cfg.pubmaxcpm); - d.insert_or_assign("pubmaxbadmpm", cfg.pubmaxbadmpm); - d.insert_or_assign("pubmaxcons", cfg.pubmaxcons); + // Mesh configs. + jsoncons::ojson mesh_config; + mesh_config.insert_or_assign("port", cfg.mesh.port); - d.insert_or_assign("peermaxsize", cfg.peermaxsize); - d.insert_or_assign("peermaxcpm", cfg.peermaxcpm); - d.insert_or_assign("peermaxdupmpm", cfg.peermaxdupmpm); - d.insert_or_assign("peermaxbadmpm", cfg.peermaxbadmpm); - d.insert_or_assign("peermaxbadsigpm", cfg.peermaxbadsigpm); - d.insert_or_assign("peermaxcons", cfg.peermaxcons); - d.insert_or_assign("peermaxknowncons", cfg.peermaxknowncons); + jsoncons::ojson peers(jsoncons::json_array_arg); + for (const auto &peer : cfg.mesh.known_peers) + { + const std::string concat_str = std::string(peer.ip_port.host_address).append(":").append(std::to_string(peer.ip_port.port)); + peers.push_back(concat_str); + } + mesh_config.insert_or_assign("known_peers", peers); + mesh_config.insert_or_assign("msg_forwarding", cfg.mesh.msg_forwarding); + mesh_config.insert_or_assign("max_connections", cfg.mesh.max_connections); + mesh_config.insert_or_assign("max_known_connections", cfg.mesh.max_known_connections); + mesh_config.insert_or_assign("max_bytes_per_msg", cfg.mesh.max_bytes_per_msg); + mesh_config.insert_or_assign("max_bytes_per_min", cfg.mesh.max_bytes_per_min); + mesh_config.insert_or_assign("max_bad_msgs_per_min", cfg.mesh.max_bad_msgs_per_min); + mesh_config.insert_or_assign("max_bad_msgsigs_per_min", cfg.mesh.max_bad_msgsigs_per_min); + mesh_config.insert_or_assign("max_dup_msgs_per_min", cfg.mesh.max_dup_msgs_per_min); + mesh_config.insert_or_assign("idle_timeout", cfg.mesh.idle_timeout); - d.insert_or_assign("consensus", cfg.is_consensus_public ? PUBLIC : PRIVATE); - d.insert_or_assign("npl", cfg.is_npl_public ? PUBLIC : PRIVATE); + jsoncons::ojson peer_discovery_config; + peer_discovery_config.insert_or_assign("enabled", cfg.mesh.peer_discovery.enabled); + peer_discovery_config.insert_or_assign("interval", cfg.mesh.peer_discovery.interval); - d.insert_or_assign("msgforwarding", cfg.msgforwarding); - d.insert_or_assign("dynamicpeerdiscovery", cfg.dynamicpeerdiscovery); - // d.insert_or_assign("fullhistory", cfg.fullhistory); + mesh_config.insert_or_assign("peer_discovery", peer_discovery_config); + d.insert_or_assign("mesh", mesh_config); - d.insert_or_assign("loglevel", cfg.loglevel); + // User configs. + jsoncons::ojson user_config; + user_config.insert_or_assign("port", cfg.user.port); + user_config.insert_or_assign("idle_timeout", cfg.user.idle_timeout); + user_config.insert_or_assign("max_bytes_per_msg", cfg.user.max_bytes_per_msg); + user_config.insert_or_assign("max_bytes_per_min", cfg.user.max_bytes_per_min); + user_config.insert_or_assign("max_bad_msgs_per_min", cfg.user.max_bad_msgs_per_min); + user_config.insert_or_assign("max_connections", cfg.user.max_connections); + d.insert_or_assign("user", user_config); + + // Log configs. + jsoncons::ojson log_config; + log_config.insert_or_assign("loglevel", cfg.log.loglevel); jsoncons::ojson loggers(jsoncons::json_array_arg); - for (std::string_view logger : cfg.loggers) + for (std::string_view logger : cfg.log.loggers) { loggers.push_back(logger); } - d.insert_or_assign("loggers", loggers); + log_config.insert_or_assign("loggers", loggers); + d.insert_or_assign("log", log_config); // Write the json doc to file. - std::ofstream ofs(ctx.config_file); try { @@ -470,46 +484,46 @@ namespace conf int populate_runtime_config(contract_config &parsed_cfg) { cfg = parsed_cfg; - startup_mode = cfg.operating_mode; + startup_mode = cfg.node.role; // Convert the hex keys to binary. - cfg.pubkey.resize(crypto::PFXD_PUBKEY_BYTES); + cfg.node.public_key.resize(crypto::PFXD_PUBKEY_BYTES); if (util::hex2bin( - reinterpret_cast(cfg.pubkey.data()), - cfg.pubkey.length(), - cfg.pubkeyhex) != 0) + reinterpret_cast(cfg.node.public_key.data()), + cfg.node.public_key.length(), + cfg.node.pub_key_hex) != 0) { std::cerr << "Error decoding hex public key.\n"; return -1; } - cfg.seckey.resize(crypto::PFXD_SECKEY_BYTES); + cfg.node.private_key.resize(crypto::PFXD_SECKEY_BYTES); if (util::hex2bin( - reinterpret_cast(cfg.seckey.data()), - cfg.seckey.length(), - cfg.seckeyhex) != 0) + reinterpret_cast(cfg.node.private_key.data()), + cfg.node.private_key.length(), + cfg.node.private_key_hex) != 0) { - std::cerr << "Error decoding hex secret key.\n"; + std::cerr << "Error decoding hex private key.\n"; return -1; } // Populate runtime contract execution args. - if (!cfg.binargs.empty()) - util::split_string(cfg.runtime_binexec_args, cfg.binargs, " "); - cfg.runtime_binexec_args.insert(cfg.runtime_binexec_args.begin(), (cfg.binary[0] == '/' ? cfg.binary : util::realpath(ctx.contract_dir + "/bin/" + cfg.binary))); + if (!cfg.contract.bin_args.empty()) + util::split_string(cfg.contract.runtime_binexec_args, cfg.contract.bin_args, " "); + cfg.contract.runtime_binexec_args.insert(cfg.contract.runtime_binexec_args.begin(), (cfg.contract.bin_path[0] == '/' ? cfg.contract.bin_path : util::realpath(ctx.contract_dir + "/bin/" + cfg.contract.bin_path))); // Populate runtime app bill args. - if (!cfg.appbillargs.empty()) - util::split_string(cfg.runtime_appbill_args, cfg.appbillargs, " "); + if (!cfg.contract.appbill.bin_args.empty()) + util::split_string(cfg.contract.appbill.runtime_args, cfg.contract.appbill.bin_args, " "); - cfg.runtime_appbill_args.insert(cfg.runtime_appbill_args.begin(), (cfg.appbill[0] == '/' ? cfg.appbill : util::realpath(ctx.contract_dir + "/bin/" + cfg.appbill))); + cfg.contract.appbill.runtime_args.insert(cfg.contract.appbill.runtime_args.begin(), (cfg.contract.appbill.mode[0] == '/' ? cfg.contract.appbill.mode : util::realpath(ctx.contract_dir + "/bin/" + cfg.contract.appbill.mode))); // Uncomment for docker-based execution. // std::string volumearg; // volumearg.append("type=bind,source=").append(ctx.state_dir).append(",target=/state"); - // const char *dockerargs[] = {"/usr/bin/docker", "run", "--rm", "-i", "--mount", volumearg.data(), cfg.binary.data()}; - // cfg.runtime_binexec_args.insert(cfg.runtime_binexec_args.begin(), std::begin(dockerargs), std::end(dockerargs)); + // const char *dockerargs[] = {"/usr/bin/docker", "run", "--rm", "-i", "--mount", volumearg.data(), cfg.contract.bin_path.data()}; + // cfg.contract.runtime_binexec_args.insert(cfg.contract.runtime_binexec_args.begin(), std::begin(dockerargs), std::end(dockerargs)); return 0; } @@ -522,14 +536,14 @@ namespace conf int binpair_to_hex(contract_config &cfg) { util::bin2hex( - cfg.pubkeyhex, - reinterpret_cast(cfg.pubkey.data()), - cfg.pubkey.length()); + cfg.node.pub_key_hex, + reinterpret_cast(cfg.node.public_key.data()), + cfg.node.public_key.length()); util::bin2hex( - cfg.seckeyhex, - reinterpret_cast(cfg.seckey.data()), - cfg.seckey.length()); + cfg.node.private_key_hex, + reinterpret_cast(cfg.node.private_key.data()), + cfg.node.private_key.length()); return 0; } @@ -543,7 +557,7 @@ namespace conf { // Check for non-empty signing keys. // We also check for key pair validity as well in the below code. - if (cfg.pubkeyhex.empty() || cfg.seckeyhex.empty()) + if (cfg.node.pub_key_hex.empty() || cfg.node.private_key_hex.empty()) { std::cerr << "Signing keys missing. Run with 'rekey' to generate new keys.\n"; return -1; @@ -553,12 +567,14 @@ namespace conf bool fields_missing = false; - fields_missing |= cfg.binary.empty() && std::cerr << "Missing cfg field: binary\n"; - fields_missing |= cfg.peerport == 0 && std::cerr << "Missing cfg field: peerport\n"; - fields_missing |= cfg.roundtime == 0 && std::cerr << "Missing cfg field: roundtime\n"; - fields_missing |= cfg.pubport == 0 && std::cerr << "Missing cfg field: pubport\n"; - fields_missing |= cfg.loglevel.empty() && std::cerr << "Missing cfg field: loglevel\n"; - fields_missing |= cfg.loggers.empty() && std::cerr << "Missing cfg field: loggers\n"; + fields_missing |= cfg.contract.bin_path.empty() && std::cerr << "Missing cfg field: bin_path\n"; + fields_missing |= cfg.contract.roundtime == 0 && std::cerr << "Missing cfg field: roundtime\n"; + fields_missing |= cfg.contract.unl.empty() && std::cerr << "Missing cfg field: unl. Unl list cannot be empty.\n"; + fields_missing |= cfg.contract.id.empty() && std::cerr << "Missing cfg field: contract id.\n"; + fields_missing |= cfg.mesh.port == 0 && std::cerr << "Missing cfg field: mesh port\n"; + fields_missing |= cfg.user.port == 0 && std::cerr << "Missing cfg field: user port\n"; + fields_missing |= cfg.log.loglevel.empty() && std::cerr << "Missing cfg field: loglevel\n"; + fields_missing |= cfg.log.loggers.empty() && std::cerr << "Missing cfg field: loggers\n"; if (fields_missing) { @@ -568,14 +584,14 @@ namespace conf // Log settings const std::unordered_set valid_loglevels({"dbg", "inf", "wrn", "err"}); - if (valid_loglevels.count(cfg.loglevel) != 1) + if (valid_loglevels.count(cfg.log.loglevel) != 1) { std::cerr << "Invalid loglevel configured. Valid values: dbg|inf|wrn|err\n"; return -1; } const std::unordered_set valid_loggers({"console", "file"}); - for (const std::string &logger : cfg.loggers) + for (const std::string &logger : cfg.log.loggers) { if (valid_loggers.count(logger) != 1) { @@ -586,8 +602,8 @@ namespace conf //Sign and verify a sample message to ensure we have a matching signing key pair. const std::string msg = "hotpocket"; - const std::string sighex = crypto::sign_hex(msg, cfg.seckeyhex); - if (crypto::verify_hex(msg, sighex, cfg.pubkeyhex) != 0) + const std::string sighex = crypto::sign_hex(msg, cfg.node.private_key_hex); + if (crypto::verify_hex(msg, sighex, cfg.node.pub_key_hex) != 0) { std::cerr << "Invalid signing keys. Run with 'rekey' to generate new keys.\n"; return -1; @@ -640,18 +656,18 @@ namespace conf return 0; } - void change_operating_mode(const OPERATING_MODE mode) + void change_role(const ROLE role) { // Do not allow to change the mode if the node was started as an observer. - if (startup_mode == OPERATING_MODE::OBSERVER || cfg.operating_mode == mode) + if (startup_mode == ROLE::OBSERVER || cfg.node.role == role) return; - cfg.operating_mode = mode; + cfg.node.role = role; - if (mode == OPERATING_MODE::OBSERVER) + if (role == ROLE::OBSERVER) LOG_INFO << "Switched to OBSERVER mode."; else - LOG_INFO << "Switched back to PROPOSER mode."; + LOG_INFO << "Switched back to VALIDATOR mode."; } /** diff --git a/src/conf.hpp b/src/conf.hpp index ed1de697..46b005c5 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -36,11 +36,11 @@ namespace conf uint64_t timestamp = 0; }; - // The operating mode of the contract node. - enum OPERATING_MODE + // The role of the contract node. + enum ROLE { OBSERVER = 0, // Observer mode. Only emits NUPs. Does not participate in voting. - PROPOSER = 1 // Consensus participant mode. + VALIDATOR = 1 // Consensus participant mode. }; // Log severity levels used in Hot Pocket. @@ -52,6 +52,82 @@ namespace conf ERROR }; + struct log_config + { + std::string loglevel; // Log severity level (debug, info, warn, error) + LOG_SEVERITY loglevel_type; // Log severity level enum (debug, info, warn, error) + std::unordered_set loggers; // List of enabled loggers (console, file) + }; + + struct node_config + { + // Config elements which are initialized in memory (these are not directly loaded from the config file) + std::string public_key; // Contract public key bytes + std::string private_key; // Contract private key bytes + ROLE role = ROLE::OBSERVER; // Configured startup role of the contract (Observer/validator). + bool is_unl = false; // Indicate whether we are a unl node or not. + + std::string pub_key_hex; // Contract hex public key + std::string private_key_hex; // Contract hex private key + bool full_history = false; // Whether full history mode is on/off. + }; + + struct appbill_config + { + std::string mode; // Binary to execute for appbill. + std::string bin_args; // Any arguments to supply to appbill binary by default. + + // Config element which are initialized in memory (This is not directly loaded from the config file) + std::vector runtime_args; // Appbill execution args used during runtime. + }; + struct contract_params + { + std::string id; // Contract guid. + std::string version; // Contract version string. + std::set unl; // Unique node list (list of binary public keys) + std::string bin_path; // Full path to the contract binary + std::string bin_args; // CLI arguments to pass to the contract binary + uint16_t roundtime = 0; // Consensus round time in ms + bool is_consensus_public = false; // If true, consensus are broadcasted to non-unl nodes as well. + bool is_npl_public = false; // If true, npl messages are broadcasted to non-unl nodes as well. + appbill_config appbill; + + // Config element which are initialized in memory (This is not directly loaded from the config file) + std::vector runtime_binexec_args; // Contract binary execution args used during runtime. + }; + + struct user_config + { + uint16_t port = 0; // Listening port for public user connections + uint16_t idle_timeout = 0; // Idle connection timeout for user connections in seconds. + uint64_t max_bytes_per_msg = 0; // User message max size in bytes + uint64_t max_bytes_per_min = 0; // User message rate (characters(bytes) per minute) + uint64_t max_bad_msgs_per_min = 0; // User bad messages per minute + uint16_t max_connections = 0; // Max inbound user connections + }; + + struct peer_discovery_config + { + bool enabled = false; // Whether dynamic peer discovery is on/off. + uint16_t interval = 0; // Time interval in ms to find for peers dynamicpeerdiscovery should be on for this + }; + + struct mesh_config + { + uint16_t port = 0; // Listening port for peer connections + std::vector known_peers; // Vector of peers with ip_port, timestamp, capacity + bool msg_forwarding = false; // Whether peer message forwarding is on/off. + uint16_t max_connections = 0; // Max peer connections + uint16_t max_known_connections = 0; // Max known peer connections + uint64_t max_bytes_per_msg = 0; // Peer message max size in bytes + uint64_t max_bytes_per_min = 0; // Peer message rate (characters(bytes) per minute) + uint64_t max_bad_msgs_per_min = 0; // Peer bad messages per minute + uint64_t max_bad_msgsigs_per_min = 0; // Peer bad signatures per minute + uint64_t max_dup_msgs_per_min = 0; // Peer max duplicate messages per minute + uint16_t idle_timeout = 0; // Idle connection timeout for peer connections in seconds. + peer_discovery_config peer_discovery; // Peer discovery configs. + }; + // Holds contextual information about the currently loaded contract. struct contract_ctx { @@ -69,64 +145,20 @@ namespace conf std::string log_dir; // Contract log dir full path std::string config_dir; // Contract config dir full path std::string config_file; // Full path to the contract config file - std::string tls_key_file; // Full path to the tls secret key file + std::string tls_key_file; // Full path to the tls private key file std::string tls_cert_file; // Full path to the tls certificate }; // Holds all the contract config values. struct contract_config { - // Config elements which are initialized in memory (these are not directly loaded from the config file) - std::string pubkey; // Contract public key bytes - std::string seckey; // Contract secret key bytes - std::vector runtime_binexec_args; // Contract binary execution args used during runtime. - std::vector runtime_appbill_args; // Appbill execution args used during runtime. - bool is_unl = false; // Indicate whether we are a unl node or not. - // Config elements which are loaded from the config file. - std::string hpversion; // Version of Hot Pocket that generated the config. - std::string contractid; // Contract guid. - std::string contractversion; // Contract version string. - OPERATING_MODE operating_mode = OPERATING_MODE::OBSERVER; // Configured startup operating mode of the contract (Observer/Proposer). - std::string pubkeyhex; // Contract hex public key - std::string seckeyhex; // Contract hex secret key - std::string binary; // Full path to the contract binary - std::string binargs; // CLI arguments to pass to the contract binary - std::string appbill; // binary to execute for appbill - std::string appbillargs; // any arguments to supply to appbill binary by default - std::vector peers; // Vector of peers with ip_port, timestamp, capacity - std::set unl; // Unique node list (list of binary public keys) - uint16_t peerport = 0; // Listening port for peer connections - uint16_t roundtime = 0; // Consensus round time in ms - uint16_t pubport = 0; // Listening port for public user connections - uint16_t peerdiscoverytime = 0; // Time interval in ms to find for peers dynamicpeerdiscovery should be on for this - - uint16_t peeridletimeout = 0; // Idle connection timeout for peer connections in seconds. - uint16_t pubidletimeout = 0; // Idle connection timeout for user connections in seconds. - - uint64_t pubmaxsize = 0; // User message max size in bytes - uint64_t pubmaxcpm = 0; // User message rate (characters(bytes) per minute) - uint64_t pubmaxbadmpm = 0; // User bad messages per minute - uint16_t pubmaxcons = 0; // Max inbound user connections - - uint64_t peermaxsize = 0; // Peer message max size in bytes - uint64_t peermaxcpm = 0; // Peer message rate (characters(bytes) per minute) - uint64_t peermaxdupmpm = 0; // Peer max duplicate messages per minute - uint64_t peermaxbadmpm = 0; // Peer bad messages per minute - uint64_t peermaxbadsigpm = 0; // Peer bad signatures per minute - uint16_t peermaxcons = 0; // Max peer connections - uint16_t peermaxknowncons = 0; // Max known peer connections - - bool is_consensus_public = false; // If true, consensus are broadcasted to non-unl nodes as well. - bool is_npl_public = false; // If true, npl messages are broadcasted to non-unl nodes as well. - - bool msgforwarding = false; // Whether peer message forwarding is on/off. - bool dynamicpeerdiscovery = false; // Whether dynamic peer discovery is on/off. - bool fullhistory = false; // Whether full history mode is on/off. - - std::string loglevel; // Log severity level (debug, info, warn, error) - LOG_SEVERITY loglevel_type; // Log severity level enum (debug, info, warn, error) - std::unordered_set loggers; // List of enabled loggers (console, file) + std::string hp_version; // Version of Hot Pocket that generated the config. + node_config node; + contract_params contract; + mesh_config mesh; + user_config user; + log_config log; }; // Global contract context struct exposed to the application. @@ -161,7 +193,7 @@ namespace conf int binpair_to_hex(contract_config &cfg); - void change_operating_mode(const OPERATING_MODE mode); + void change_role(const ROLE role); LOG_SEVERITY get_loglevel_type(std::string_view severity); } // namespace conf diff --git a/src/consensus.cpp b/src/consensus.cpp index 3615b957..cef563a5 100644 --- a/src/consensus.cpp +++ b/src/consensus.cpp @@ -33,8 +33,8 @@ namespace consensus int init() { // We allocate 1/4 of roundtime for each stage (0, 1, 2, 3). - ctx.stage_time = conf::cfg.roundtime / 4; - ctx.stage_reset_wait_threshold = conf::cfg.roundtime / 10; + ctx.stage_time = conf::cfg.contract.roundtime / 4; + ctx.stage_reset_wait_threshold = conf::cfg.contract.roundtime / 10; // Starting consensus processing thread. ctx.consensus_thread = std::thread(run_consensus); @@ -106,7 +106,7 @@ namespace consensus // arived ones and expired ones. revise_candidate_proposals(); - // If possible, switch back to proposer mode before stage processing. (if we were syncing before) + // If possible, switch back to validator mode before stage processing. (if we were syncing before) check_sync_completion(); // Get current lcl and state. @@ -181,7 +181,7 @@ namespace consensus // State lcl sync if we are out-of-sync with majority lcl. if (is_lcl_desync) { - conf::change_operating_mode(conf::OPERATING_MODE::OBSERVER); + conf::change_role(conf::ROLE::OBSERVER); ledger::set_sync_target(majority_lcl); } @@ -193,7 +193,7 @@ namespace consensus // Start state sync if we are out-of-sync with majority state. if (is_state_desync) { - conf::change_operating_mode(conf::OPERATING_MODE::OBSERVER); + conf::change_role(conf::ROLE::OBSERVER); state_sync::set_target(majority_state); } @@ -204,14 +204,14 @@ namespace consensus // Start unl sync if we are out-of-sync with majority unl. if (is_unl_desync) { - conf::change_operating_mode(conf::OPERATING_MODE::OBSERVER); + conf::change_role(conf::ROLE::OBSERVER); unl::set_sync_target(majority_unl); } // Proceed further only if both lcl and state are in sync with majority. if (!is_lcl_desync && !is_state_desync && !is_unl_desync) { - conf::change_operating_mode(conf::OPERATING_MODE::PROPOSER); + conf::change_role(conf::ROLE::VALIDATOR); return 0; } @@ -229,8 +229,8 @@ namespace consensus */ void check_sync_completion() { - if (conf::cfg.operating_mode == conf::OPERATING_MODE::OBSERVER && !state_sync::ctx.is_syncing && !ledger::sync_ctx.is_syncing) - conf::change_operating_mode(conf::OPERATING_MODE::PROPOSER); + if (conf::cfg.node.role == conf::ROLE::OBSERVER && !state_sync::ctx.is_syncing && !ledger::sync_ctx.is_syncing) + conf::change_role(conf::ROLE::VALIDATOR); } /** @@ -265,7 +265,7 @@ namespace consensus const int8_t stage_diff = ctx.stage - cp.stage; // only consider recent proposals and proposals from previous stage and current stage. - const bool keep_candidate = (time_diff < (conf::cfg.roundtime * 4)) && (stage_diff == -3 || stage_diff <= 1); + const bool keep_candidate = (time_diff < (conf::cfg.contract.roundtime * 4)) && (stage_diff == -3 || stage_diff <= 1); LOG_DEBUG << (keep_candidate ? "Prop--->" : "Erased") << " [s" << std::to_string(cp.stage) << "] u/i:" << cp.users.size() @@ -273,7 +273,7 @@ namespace consensus << " ts:" << std::to_string(cp.time) << " lcl:" << cp.lcl.substr(0, 15) << " state:" << cp.state - << " [from:" << ((cp.pubkey == conf::cfg.pubkey) ? "self" : util::get_hex(cp.pubkey, 1, 5)) << "]" + << " [from:" << ((cp.pubkey == conf::cfg.node.public_key) ? "self" : util::get_hex(cp.pubkey, 1, 5)) << "]" << "(" << std::to_string(cp.recv_timestamp > cp.sent_timestamp ? cp.recv_timestamp - cp.sent_timestamp : 0) << "ms)"; if (keep_candidate) @@ -300,11 +300,11 @@ namespace consensus if (ctx.stage == 0) { // This gets the start time of current round window. Stage 0 must start in the window after that. - const uint64_t previous_round_start = (((uint64_t)(now / conf::cfg.roundtime)) * conf::cfg.roundtime); + const uint64_t previous_round_start = (((uint64_t)(now / conf::cfg.contract.roundtime)) * conf::cfg.contract.roundtime); // Stage 0 must start in the next round window. // (This makes sure stage 3 gets whichever the remaining time in the round after stages 0,1,2) - ctx.round_start_time = previous_round_start + conf::cfg.roundtime; + ctx.round_start_time = previous_round_start + conf::cfg.contract.roundtime; const uint64_t to_wait = ctx.round_start_time - now; LOG_DEBUG << "Waiting " << to_wait << "ms for next round stage 0."; @@ -371,18 +371,18 @@ namespace consensus } /** - * Broadcasts the given proposal to all connected peers if in PROPOSER mode. Does not send in OBSERVER mode. + * Broadcasts the given proposal to all connected peers if in VALIDATOR mode. Does not send in OBSERVER mode. * @return 0 on success. -1 if no peers to broadcast. */ void broadcast_proposal(const p2p::proposal &p) { // In observer mode, we do not send out proposals. - if (conf::cfg.operating_mode == conf::OPERATING_MODE::OBSERVER || !conf::cfg.is_unl) // If we are a non-unl node, do not broadcast proposals. + if (conf::cfg.node.role == conf::ROLE::OBSERVER || !conf::cfg.node.is_unl) // If we are a non-unl node, do not broadcast proposals. return; flatbuffers::FlatBufferBuilder fbuf(1024); p2pmsg::create_msg_from_proposal(fbuf, p); - p2p::broadcast_message(fbuf, true, false, !conf::cfg.is_consensus_public); + p2p::broadcast_message(fbuf, true, false, !conf::cfg.contract.is_consensus_public); LOG_DEBUG << "Proposed u/i:" << p.users.size() << "/" << p.input_hashes.size() @@ -581,7 +581,7 @@ namespace consensus { // Vote for times. // Everyone votes on the discreet time, as long as it's not in the future and within 2 round times. - if (time_now > cp.time && (time_now - cp.time) <= (conf::cfg.roundtime * 2)) + if (time_now > cp.time && (time_now - cp.time) <= (conf::cfg.contract.roundtime * 2)) increment(votes.time, cp.time); // Vote for round nonce. @@ -822,7 +822,7 @@ namespace consensus std::unordered_map raw_inputs; // Add raw_inputs to the proposal if full history mode is on. - if (conf::cfg.fullhistory) + if (conf::cfg.node.full_history) { for (const auto &hash : cons_prop.input_hashes) { @@ -907,7 +907,7 @@ namespace consensus hashes.push_back(hash); hashes.push_back(new_state.to_string_view()); ctx.user_outputs_hashtree.populate(hashes); - ctx.user_outputs_our_sig = crypto::sign(ctx.user_outputs_hashtree.root_hash(), conf::cfg.seckey); + ctx.user_outputs_our_sig = crypto::sign(ctx.user_outputs_hashtree.root_hash(), conf::cfg.node.private_key); } // Prepare the consensus candidate unl changeset that we have accumulated so far. (We receive them as control inputs) diff --git a/src/crypto.cpp b/src/crypto.cpp index 21a4dc08..00e30d7a 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -43,10 +43,10 @@ namespace crypto * Returns the signature bytes for a message. * * @param msg Message bytes to sign. - * @param seckey Secret key bytes. + * @param private_key Private key bytes. * @return Signature bytes. */ - std::string sign(std::string_view msg, std::string_view seckey) + std::string sign(std::string_view msg, std::string_view private_key) { //Generate the signature using libsodium. @@ -57,7 +57,7 @@ namespace crypto NULL, reinterpret_cast(msg.data()), msg.length(), - reinterpret_cast(seckey.data() + 1)); // +1 to skip the prefix byte. + reinterpret_cast(private_key.data() + 1)); // +1 to skip the prefix byte. return sig; } @@ -66,15 +66,15 @@ namespace crypto * Returns the hex signature string for a message. * * @param msg Message bytes to sign. - * @param seckeyhex hex secret key string. + * @param private_key_hex hex private key string. * @return hex signature string. */ - std::string sign_hex(std::string_view msg, std::string_view seckeyhex) + std::string sign_hex(std::string_view msg, std::string_view private_key_hex) { //Decode hex string and generate the signature using libsodium. - unsigned char seckey[PFXD_SECKEY_BYTES]; - util::hex2bin(seckey, PFXD_SECKEY_BYTES, seckeyhex); + unsigned char private_key[PFXD_SECKEY_BYTES]; + util::hex2bin(private_key, PFXD_SECKEY_BYTES, private_key_hex); unsigned char sig[crypto_sign_ed25519_BYTES]; crypto_sign_ed25519_detached( @@ -82,7 +82,7 @@ namespace crypto NULL, reinterpret_cast(msg.data()), msg.length(), - seckey + 1); // +1 to skip prefix byte. + private_key + 1); // +1 to skip prefix byte. std::string sighex; util::bin2hex(sighex, sig, crypto_sign_ed25519_BYTES); @@ -111,7 +111,7 @@ namespace crypto * * @param msg hex message string. * @param sighex hex signature string. - * @param pubkeyhex hex secret key. + * @param pubkeyhex hex public key. * @return 0 for successful verification. -1 for failure. */ int verify_hex(std::string_view msg, std::string_view sighex, std::string_view pubkeyhex) diff --git a/src/crypto.hpp b/src/crypto.hpp index 95745aa9..2bc3d6d8 100644 --- a/src/crypto.hpp +++ b/src/crypto.hpp @@ -14,7 +14,7 @@ namespace crypto static unsigned char KEYPFX_ed25519 = 0xED; // Prefixed public key bytes. static size_t PFXD_PUBKEY_BYTES = crypto_sign_ed25519_PUBLICKEYBYTES + 1; - // Prefixed secret key bytes. + // Prefixed private key bytes. static size_t PFXD_SECKEY_BYTES = crypto_sign_ed25519_SECRETKEYBYTES + 1; int init(); @@ -23,7 +23,7 @@ namespace crypto std::string sign(std::string_view msg, std::string_view seckey); - std::string sign_hex(std::string_view msg, std::string_view seckeyhex); + std::string sign_hex(std::string_view msg, std::string_view private_key_hex); int verify(std::string_view msg, std::string_view sig, std::string_view pubkey); diff --git a/src/hpfs/hpfs.cpp b/src/hpfs/hpfs.cpp index 2bdb5d40..693d6f56 100644 --- a/src/hpfs/hpfs.cpp +++ b/src/hpfs/hpfs.cpp @@ -41,7 +41,7 @@ namespace hpfs // hpfs process. util::fork_detach(); - const char *active_hpfs_trace_arg = (conf::cfg.loglevel_type == conf::LOG_SEVERITY::DEBUG ? HPFS_TRACE_ARG_DEBUG : HPFS_TRACE_ARG_ERROR); + const char *active_hpfs_trace_arg = (conf::cfg.log.loglevel_type == conf::LOG_SEVERITY::DEBUG ? HPFS_TRACE_ARG_DEBUG : HPFS_TRACE_ARG_ERROR); // Fill process args. char *execv_args[] = { @@ -141,7 +141,7 @@ namespace hpfs .append("/") .append(std::to_string(self_pid)); - const char *active_hpfs_trace_arg = (conf::cfg.loglevel_type == conf::LOG_SEVERITY::DEBUG ? HPFS_TRACE_ARG_DEBUG : HPFS_TRACE_ARG_ERROR); + const char *active_hpfs_trace_arg = (conf::cfg.log.loglevel_type == conf::LOG_SEVERITY::DEBUG ? HPFS_TRACE_ARG_DEBUG : HPFS_TRACE_ARG_ERROR); // Fill process args. char *execv_args[] = { diff --git a/src/hplog.cpp b/src/hplog.cpp index 3571a05c..dd7f7644 100644 --- a/src/hplog.cpp +++ b/src/hplog.cpp @@ -64,11 +64,11 @@ namespace hplog { plog::Severity level; - if (conf::cfg.loglevel_type == conf::LOG_SEVERITY::DEBUG) + if (conf::cfg.log.loglevel_type == conf::LOG_SEVERITY::DEBUG) level = plog::Severity::debug; - else if (conf::cfg.loglevel_type == conf::LOG_SEVERITY::INFO) + else if (conf::cfg.log.loglevel_type == conf::LOG_SEVERITY::INFO) level = plog::Severity::info; - else if (conf::cfg.loglevel_type == conf::LOG_SEVERITY::WARN) + else if (conf::cfg.log.loglevel_type == conf::LOG_SEVERITY::WARN) level = plog::Severity::warning; else level = plog::Severity::error; @@ -80,12 +80,12 @@ namespace hplog plog::Logger<0> &logger = plog::init(level); // Take decision to append logger for file / console or both. - if (conf::cfg.loggers.count("console") == 1) + if (conf::cfg.log.loggers.count("console") == 1) { logger.addAppender(&consoleAppender); } - if (conf::cfg.loggers.count("file") == 1) + if (conf::cfg.log.loggers.count("file") == 1) { logger.addAppender(&fileAppender); } diff --git a/src/ledger.cpp b/src/ledger.cpp index b9803f47..a5d62f6a 100644 --- a/src/ledger.cpp +++ b/src/ledger.cpp @@ -31,7 +31,7 @@ namespace ledger */ int init() { - REQUEST_RESUBMIT_TIMEOUT = conf::cfg.roundtime; + REQUEST_RESUBMIT_TIMEOUT = conf::cfg.contract.roundtime; // Filename list of the history folder. std::list sorted_folder_entries = util::fetch_dir_entries(conf::ctx.hist_dir); @@ -221,7 +221,7 @@ namespace ledger // Before first request, if full history mode is not enabled check the target lcl seq no to see whether // it's too far ahead. That means no one probably has our lcl in their ledgers. So we should clear our // entire ledger history before requesting from peers. - if (sync_ctx.target_requested_on == 0 && !conf::cfg.fullhistory && sync_ctx.target_lcl_seq_no > (ctx.get_seq_no() + MAX_LEDGER_SEQUENCE)) + if (sync_ctx.target_requested_on == 0 && !conf::cfg.node.full_history && sync_ctx.target_lcl_seq_no > (ctx.get_seq_no() + MAX_LEDGER_SEQUENCE)) { LOG_INFO << "lcl sync: Target " << sync_ctx.target_lcl.substr(0, 15) << " is too far ahead. Clearing our history."; clear_ledger(); @@ -378,7 +378,7 @@ namespace ledger ctx.cache.emplace(seq_no, std::move(file_name)); // Write full history to the full history directory if full history mode is on. - if (conf::cfg.fullhistory) + if (conf::cfg.node.full_history) { builder.Clear(); msg::fbuf::ledger::create_full_history_block_from_raw_input_map(builder, raw_inputs); @@ -400,7 +400,7 @@ namespace ledger void remove_old_ledgers(const uint64_t led_seq_no) { // Remove old ledgers if full history mode is not enabled. - if (!conf::cfg.fullhistory) + if (!conf::cfg.node.full_history) { std::map::iterator itr; diff --git a/src/main.cpp b/src/main.cpp index 5857f920..818bb288 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -196,10 +196,10 @@ int main(int argc, char **argv) hplog::init(); LOG_INFO << "Hot Pocket " << util::HP_VERSION; - LOG_INFO << "Operating mode: " - << (conf::cfg.operating_mode == conf::OPERATING_MODE::OBSERVER ? "Observer" : "Proposer"); - LOG_INFO << "Public key: " << conf::cfg.pubkeyhex.substr(2); // Public key without 'ed' prefix. - LOG_INFO << "Contract: " << conf::cfg.contractid << " (" << conf::cfg.contractversion << ")"; + LOG_INFO << "Role: " + << (conf::cfg.node.role == conf::ROLE::OBSERVER ? "Observer" : "Validator"); + LOG_INFO << "Public key: " << conf::cfg.node.pub_key_hex.substr(2); // Public key without 'ed' prefix. + LOG_INFO << "Contract: " << conf::cfg.contract.id << " (" << conf::cfg.contract.version << ")"; if (ledger::init() == -1 || unl::init() == -1 || diff --git a/src/msg/fbuf/ledger_helpers.cpp b/src/msg/fbuf/ledger_helpers.cpp index a88acd4d..8fd7d97c 100644 --- a/src/msg/fbuf/ledger_helpers.cpp +++ b/src/msg/fbuf/ledger_helpers.cpp @@ -21,7 +21,7 @@ namespace msg::fbuf::ledger flatbuffers::Offset ledger = ledger::CreateLedgerBlock( builder, - sv_to_flatbuff_str(builder, conf::cfg.hpversion), + sv_to_flatbuff_str(builder, conf::cfg.hp_version), seq_no, p.time, sv_to_flatbuff_bytes(builder, p.lcl), @@ -71,7 +71,7 @@ namespace msg::fbuf::ledger flatbuffers::Offset fullhistory = ledger::CreateFullHistoryBlock( builder, - sv_to_flatbuff_str(builder, conf::cfg.hpversion), + sv_to_flatbuff_str(builder, conf::cfg.hp_version), builder.CreateVector(fbvec)); builder.Finish(fullhistory); // Finished building message content to get serialised content. diff --git a/src/msg/fbuf/p2pmsg_helpers.cpp b/src/msg/fbuf/p2pmsg_helpers.cpp index d34d5c4b..8af15342 100644 --- a/src/msg/fbuf/p2pmsg_helpers.cpp +++ b/src/msg/fbuf/p2pmsg_helpers.cpp @@ -76,7 +76,7 @@ namespace msg::fbuf::p2pmsg if (container_buf_size <= MAX_SIZE_FOR_TIME_CHECK) { const uint64_t time_now = util::get_epoch_milliseconds(); - if (container->timestamp() < (time_now - conf::cfg.roundtime * 4)) + if (container->timestamp() < (time_now - conf::cfg.contract.roundtime * 4)) { LOG_DEBUG << "Peer message is too old."; return -1; @@ -317,7 +317,7 @@ namespace msg::fbuf::p2pmsg const flatbuffers::Offset peer_challenge_msg = CreatePeer_Challenge_Message( builder, - sv_to_flatbuff_str(builder, conf::cfg.contractid), + sv_to_flatbuff_str(builder, conf::cfg.contract.id), sv_to_flatbuff_str(builder, challenge)); const flatbuffers::Offset message = CreateContent(builder, Message_Peer_Challenge_Message, peer_challenge_msg.Union()); @@ -340,7 +340,7 @@ namespace msg::fbuf::p2pmsg CreatePeer_Challenge_Response_Message( builder, sv_to_flatbuff_str(builder, challenge), - sv_to_flatbuff_bytes(builder, crypto::sign(challenge, conf::cfg.seckey))); + sv_to_flatbuff_bytes(builder, crypto::sign(challenge, conf::cfg.node.private_key))); const flatbuffers::Offset message = CreateContent(builder, Message_Peer_Challenge_Response_Message, challenge_resp_msg.Union()); builder.Finish(message); // Finished building message content to get serialised content. @@ -788,8 +788,8 @@ namespace msg::fbuf::p2pmsg // Sign message content with this node's private key. std::string_view content_to_sign(reinterpret_cast(content_buf), content_size); - sig_offset = sv_to_flatbuff_bytes(container_builder, crypto::sign(content_to_sign, conf::cfg.seckey)); - pubkey_offset = sv_to_flatbuff_bytes(container_builder, conf::cfg.pubkey); + sig_offset = sv_to_flatbuff_bytes(container_builder, crypto::sign(content_to_sign, conf::cfg.node.private_key)); + pubkey_offset = sv_to_flatbuff_bytes(container_builder, conf::cfg.node.public_key); } if (!lcl.empty()) diff --git a/src/msg/json/usrmsg_json.cpp b/src/msg/json/usrmsg_json.cpp index c2a6bc6d..504606d1 100644 --- a/src/msg/json/usrmsg_json.cpp +++ b/src/msg/json/usrmsg_json.cpp @@ -64,11 +64,11 @@ namespace msg::usrmsg::json msg += SEP_COMMA; msg += msg::usrmsg::FLD_CONTRACT_ID; msg += SEP_COLON; - msg += conf::cfg.contractid; + msg += conf::cfg.contract.id; msg += SEP_COMMA; msg += msg::usrmsg::FLD_CONTRACT_VERSION; msg += SEP_COLON; - msg += conf::cfg.contractversion; + msg += conf::cfg.contract.version; msg += SEP_COMMA; msg += msg::usrmsg::FLD_CHALLENGE; msg += SEP_COLON; @@ -93,8 +93,8 @@ namespace msg::usrmsg::json void create_server_challenge_response(std::vector &msg, const std::string &original_challenge) { // Generate signature of challenge + contract id + contract version. - const std::string content = original_challenge + conf::cfg.contractid + conf::cfg.contractversion; - const std::string sig_hex = crypto::sign_hex(content, conf::cfg.seckeyhex); + const std::string content = original_challenge + conf::cfg.contract.id + conf::cfg.contract.version; + const std::string sig_hex = crypto::sign_hex(content, conf::cfg.node.private_key_hex); // Since we know the rough size of the challenge message we reserve adequate amount for the holder. msg.reserve(1024); @@ -109,7 +109,7 @@ namespace msg::usrmsg::json msg += SEP_COMMA; msg += msg::usrmsg::FLD_PUBKEY; msg += SEP_COLON; - msg += conf::cfg.pubkeyhex; + msg += conf::cfg.node.pub_key_hex; msg += SEP_COMMA; msg += msg::usrmsg::FLD_UNL; msg += "\":["; diff --git a/src/p2p/p2p.cpp b/src/p2p/p2p.cpp index d694724a..2fc6851a 100644 --- a/src/p2p/p2p.cpp +++ b/src/p2p/p2p.cpp @@ -24,11 +24,11 @@ namespace p2p */ int init() { - metric_thresholds[0] = conf::cfg.peermaxcpm; - metric_thresholds[1] = conf::cfg.peermaxdupmpm; - metric_thresholds[2] = conf::cfg.peermaxbadsigpm; - metric_thresholds[3] = conf::cfg.peermaxbadmpm; - metric_thresholds[4] = conf::cfg.peeridletimeout; + metric_thresholds[0] = conf::cfg.mesh.max_bytes_per_min; + metric_thresholds[1] = conf::cfg.mesh.max_dup_msgs_per_min; + metric_thresholds[2] = conf::cfg.mesh.max_bad_msgsigs_per_min; + metric_thresholds[3] = conf::cfg.mesh.max_bad_msgs_per_min; + metric_thresholds[4] = conf::cfg.mesh.idle_timeout; //Entry point for p2p which will start peer connections to other nodes if (start_peer_connections() == -1) @@ -49,11 +49,11 @@ namespace p2p int start_peer_connections() { - ctx.server.emplace(conf::cfg.peerport, metric_thresholds, conf::cfg.peermaxsize, conf::cfg.peers); + ctx.server.emplace(conf::cfg.mesh.port, metric_thresholds, conf::cfg.mesh.max_bytes_per_msg, conf::cfg.mesh.known_peers); if (ctx.server->start() == -1) return -1; - LOG_INFO << "Started listening for peer connections on " << std::to_string(conf::cfg.peerport); + LOG_INFO << "Started listening for peer connections on " << std::to_string(conf::cfg.mesh.port); return 0; } @@ -77,7 +77,7 @@ namespace p2p std::string pubkeyhex; util::bin2hex(pubkeyhex, reinterpret_cast(challenge_resp.pubkey.data()), challenge_resp.pubkey.length()); - const int res = challenge_resp.pubkey.compare(conf::cfg.pubkey); + const int res = challenge_resp.pubkey.compare(conf::cfg.node.public_key); // If pub key is greater than our id (< 0), then we should give priority to any existing inbound connection // from the same peer and drop the outbound connection. @@ -204,14 +204,14 @@ namespace p2p bool validate_for_peer_msg_forwarding(const peer_comm_session &session, const msg::fbuf::p2pmsg::Container *container, const msg::fbuf::p2pmsg::Message &content_message_type) { // Checking whether the message forwarding is enabled. - if (!conf::cfg.msgforwarding) + if (!conf::cfg.mesh.msg_forwarding) { return false; } const uint64_t time_now = util::get_epoch_milliseconds(); // Checking the time to live of the container. The time to live for forwarding is three times the round time. - if (container->timestamp() < (time_now - (conf::cfg.roundtime * 3))) + if (container->timestamp() < (time_now - (conf::cfg.contract.roundtime * 3))) { LOG_DEBUG << "Peer message is too old for forwarding."; return false; @@ -419,18 +419,18 @@ namespace p2p */ int16_t get_available_capacity() { - // If both peermaxcons and peermaxknowncons are configured calculate the capacity. - if (conf::cfg.peermaxcons != 0 && conf::cfg.peermaxknowncons != 0) + // If both max_connections and max_known_connections are configured calculate the capacity. + if (conf::cfg.mesh.max_connections != 0 && conf::cfg.mesh.max_known_connections != 0) { // If known peer max connection count is equal to the peer max connection count then return 0. // Otherwise peer max con count - know peer max con count - inbound peer cons. - if (conf::cfg.peermaxcons != conf::cfg.peermaxknowncons) - return conf::cfg.peermaxcons - conf::cfg.peermaxknowncons - ctx.peer_connections.size() + ctx.server->known_remote_count; + if (conf::cfg.mesh.max_connections != conf::cfg.mesh.max_known_connections) + return conf::cfg.mesh.max_connections - conf::cfg.mesh.max_known_connections - ctx.peer_connections.size() + ctx.server->known_remote_count; else return 0; } - else if (conf::cfg.peermaxcons != 0 && conf::cfg.peermaxknowncons == 0) - return conf::cfg.peermaxcons - ctx.peer_connections.size(); + else if (conf::cfg.mesh.max_connections != 0 && conf::cfg.mesh.max_known_connections == 0) + return conf::cfg.mesh.max_connections - ctx.peer_connections.size(); return -1; } diff --git a/src/p2p/peer_comm_server.cpp b/src/p2p/peer_comm_server.cpp index 98c22591..334584b2 100644 --- a/src/p2p/peer_comm_server.cpp +++ b/src/p2p/peer_comm_server.cpp @@ -75,25 +75,25 @@ namespace p2p { peer_managing_counter++; - // Send available peer capacity if peermaxcons is configured. - if (conf::cfg.peermaxcons != 0) + // Send available peer capacity if peer max connections is configured. + if (conf::cfg.mesh.max_connections != 0) p2p::send_available_capacity_announcement(p2p::get_available_capacity()); // Start peer list request loop if dynamic peer discovery is enabled. - if (conf::cfg.dynamicpeerdiscovery && known_remote_count > 0) + if (conf::cfg.mesh.peer_discovery.enabled && known_remote_count > 0) { // If max known peer connection cap is reached then periodically request peer list from random known peer. // Otherwise frequently request peer list from a random known peer. // Peer discovery time interval can be configured in the config. - if (conf::cfg.peermaxknowncons != 0 && known_remote_count == conf::cfg.peermaxknowncons) + if (conf::cfg.mesh.max_known_connections != 0 && known_remote_count == conf::cfg.mesh.max_known_connections) { - if (peer_managing_counter * 100 >= conf::cfg.peerdiscoverytime * 5) + if (peer_managing_counter * 100 >= conf::cfg.mesh.peer_discovery.interval * 5) { p2p::send_peer_list_request(); peer_managing_counter = 0; } } - else if (peer_managing_counter * 100 >= conf::cfg.peerdiscoverytime) + else if (peer_managing_counter * 100 >= conf::cfg.mesh.peer_discovery.interval) { p2p::send_peer_list_request(); peer_managing_counter = 0; @@ -135,11 +135,11 @@ namespace p2p break; // Break if known peer cap is reached. - if (conf::cfg.peermaxknowncons != 0 && known_remote_count == conf::cfg.peermaxknowncons) + if (conf::cfg.mesh.max_known_connections != 0 && known_remote_count == conf::cfg.mesh.max_known_connections) break; // Break if max peer connection cap is reached. - if (conf::cfg.peermaxcons != 0 && known_remote_count == conf::cfg.peermaxcons) + if (conf::cfg.mesh.max_connections != 0 && known_remote_count == conf::cfg.mesh.max_connections) break; // Continue if the peer has no free slots. diff --git a/src/p2p/peer_session_handler.cpp b/src/p2p/peer_session_handler.cpp index cb14fff3..b9560d6b 100644 --- a/src/p2p/peer_session_handler.cpp +++ b/src/p2p/peer_session_handler.cpp @@ -84,8 +84,8 @@ namespace p2p { // Npl messages and consensus proposals are forwarded only to unl nodes if relavent flags (npl and consensus) are set to private. // If consensus and npl flags are public, these messages are forward to all the connected nodes. - const bool unl_only = (!conf::cfg.is_npl_public && content_message_type == p2pmsg::Message_Npl_Message) || - (!conf::cfg.is_consensus_public && content_message_type == p2pmsg::Message_Proposal_Message); + const bool unl_only = (!conf::cfg.contract.is_npl_public && content_message_type == p2pmsg::Message_Npl_Message) || + (!conf::cfg.contract.is_consensus_public && content_message_type == p2pmsg::Message_Proposal_Message); if (session.need_consensus_msg_forwarding) { // Forward messages received by weakly connected nodes to other peers. @@ -103,7 +103,7 @@ namespace p2p const p2p::peer_challenge chall = p2pmsg::get_peer_challenge_from_msg(*content->message_as_Peer_Challenge_Message()); // Check whether contract ids match. - if (chall.contract_id != conf::cfg.contractid) + if (chall.contract_id != conf::cfg.contract.id) return -1; // Sending the challenge response to the sender. diff --git a/src/sc.cpp b/src/sc.cpp index 128de1e0..dfb982ef 100644 --- a/src/sc.cpp +++ b/src/sc.cpp @@ -112,22 +112,22 @@ namespace sc // Write the contract execution args from HotPocket to the stdin (0) of the contract process. write_contract_args(ctx, user_inputs_fd); - const bool using_appbill = !ctx.args.readonly && !conf::cfg.appbill.empty(); - int len = conf::cfg.runtime_binexec_args.size() + 1; + const bool using_appbill = !ctx.args.readonly && !conf::cfg.contract.appbill.mode.empty(); + int len = conf::cfg.contract.runtime_binexec_args.size() + 1; if (using_appbill) - len += conf::cfg.runtime_appbill_args.size(); + len += conf::cfg.contract.appbill.runtime_args.size(); // Fill process args. char *execv_args[len]; int j = 0; if (using_appbill) { - for (int i = 0; i < conf::cfg.runtime_appbill_args.size(); i++, j++) - execv_args[i] = conf::cfg.runtime_appbill_args[i].data(); + for (int i = 0; i < conf::cfg.contract.appbill.runtime_args.size(); i++, j++) + execv_args[i] = conf::cfg.contract.appbill.runtime_args[i].data(); } - for (int i = 0; i < conf::cfg.runtime_binexec_args.size(); i++, j++) - execv_args[j] = conf::cfg.runtime_binexec_args[i].data(); + for (int i = 0; i < conf::cfg.contract.runtime_binexec_args.size(); i++, j++) + execv_args[j] = conf::cfg.contract.runtime_binexec_args[i].data(); execv_args[len - 1] = NULL; chdir(ctx.args.state_dir.c_str()); @@ -258,7 +258,7 @@ namespace sc std::ostringstream os; os << "{\"version\":\"" << util::HP_VERSION - << "\",\"pubkey\":\"" << conf::cfg.pubkeyhex.substr(2) + << "\",\"pubkey\":\"" << conf::cfg.node.pub_key_hex.substr(2) << "\",\"ts\":" << ctx.args.time << ",\"readonly\":" << (ctx.args.readonly ? "true" : "false"); @@ -521,14 +521,14 @@ namespace sc void broadcast_npl_output(std::string_view output) { // In observer mode, we do not send out npl messages. - if (conf::cfg.operating_mode == conf::OPERATING_MODE::OBSERVER || !conf::cfg.is_unl) // If we are a non-unl node, do not broadcast npl messages. + if (conf::cfg.node.role == conf::ROLE::OBSERVER || !conf::cfg.node.is_unl) // If we are a non-unl node, do not broadcast npl messages. return; if (!output.empty()) { flatbuffers::FlatBufferBuilder fbuf(1024); msg::fbuf::p2pmsg::create_msg_from_npl_output(fbuf, output, ledger::ctx.get_lcl()); - p2p::broadcast_message(fbuf, true, false, !conf::cfg.is_npl_public); + p2p::broadcast_message(fbuf, true, false, !conf::cfg.contract.is_npl_public); } } diff --git a/src/state/state_common.hpp b/src/state/state_common.hpp index 11907b10..0bf5a151 100644 --- a/src/state/state_common.hpp +++ b/src/state/state_common.hpp @@ -11,7 +11,7 @@ namespace state_common inline uint16_t get_request_resubmit_timeout() { - return conf::cfg.roundtime; + return conf::cfg.contract.roundtime; } struct state_context diff --git a/src/unl.cpp b/src/unl.cpp index ceaa9a09..cc241240 100644 --- a/src/unl.cpp +++ b/src/unl.cpp @@ -31,17 +31,17 @@ namespace unl */ int init() { - if (conf::cfg.unl.empty()) + if (conf::cfg.contract.unl.empty()) return -1; std::unique_lock lock(unl_mutex); - list = conf::cfg.unl; + list = conf::cfg.contract.unl; // Update the own node's unl status. - conf::cfg.is_unl = (list.find(conf::cfg.pubkey) != list.end()); + conf::cfg.node.is_unl = (list.find(conf::cfg.node.public_key) != list.end()); update_json_list(); hash = calculate_hash(list); sync_ctx.unl_sync_thread = std::thread(unl_syncer_loop); - REQUEST_RESUBMIT_TIMEOUT = conf::cfg.roundtime; + REQUEST_RESUBMIT_TIMEOUT = conf::cfg.contract.roundtime; init_success = true; return 0; } @@ -115,7 +115,7 @@ namespace unl hash = calculate_hash(list); LOG_INFO << "UNL updated. Count:" << list.size(); // Update the own node's unl status. - conf::cfg.is_unl = (list.find(conf::cfg.pubkey) != list.end()); + conf::cfg.node.is_unl = (list.find(conf::cfg.node.public_key) != list.end()); } } @@ -145,7 +145,7 @@ namespace unl conf::persist_unl_update(list); hash = new_unl_hash; // Update the own node's unl status. - conf::cfg.is_unl = (list.find(conf::cfg.pubkey) != list.end()); + conf::cfg.node.is_unl = (list.find(conf::cfg.node.public_key) != list.end()); } // Update the is_unl flag of peer sessions. diff --git a/src/usr/user_session_handler.cpp b/src/usr/user_session_handler.cpp index e80ccc33..c5ac648a 100644 --- a/src/usr/user_session_handler.cpp +++ b/src/usr/user_session_handler.cpp @@ -18,7 +18,7 @@ namespace usr int handle_user_connect(usr::user_comm_session &session) { // Allow connection only if the maximum capacity is not reached. 0 means allowing unlimited connections. - if ((conf::cfg.pubmaxcons == 0) || (usr::ctx.users.size() < conf::cfg.pubmaxcons)) + if ((conf::cfg.user.max_connections == 0) || (usr::ctx.users.size() < conf::cfg.user.max_connections)) { corebill::add_to_whitelist(session.host_address); LOG_DEBUG << "User client connected " << session.display_name(); @@ -35,7 +35,7 @@ namespace usr } else { - LOG_DEBUG << "Dropping the user connection. Maximum user capacity reached. Session: " << session.display_name() << " (limit: " << conf::cfg.pubmaxcons << ")."; + LOG_DEBUG << "Dropping the user connection. Maximum user capacity reached. Session: " << session.display_name() << " (limit: " << conf::cfg.user.max_connections << ")."; return -1; } } diff --git a/src/usr/usr.cpp b/src/usr/usr.cpp index dedd7e6c..a510d284 100644 --- a/src/usr/usr.cpp +++ b/src/usr/usr.cpp @@ -33,11 +33,11 @@ namespace usr */ int init() { - metric_thresholds[0] = conf::cfg.pubmaxcpm; + metric_thresholds[0] = conf::cfg.user.max_bytes_per_min; metric_thresholds[1] = 0; // This metric doesn't apply to user context. metric_thresholds[2] = 0; // This metric doesn't apply to user context. - metric_thresholds[3] = conf::cfg.pubmaxbadmpm; - metric_thresholds[4] = conf::cfg.pubidletimeout; + metric_thresholds[3] = conf::cfg.user.max_bad_msgs_per_min; + metric_thresholds[4] = conf::cfg.user.idle_timeout; if (input_store.init() == -1) return -1; @@ -67,11 +67,11 @@ namespace usr */ int start_listening() { - ctx.server.emplace("User", conf::cfg.pubport, metric_thresholds, conf::cfg.pubmaxsize); + ctx.server.emplace("User", conf::cfg.user.port, metric_thresholds, conf::cfg.user.max_bytes_per_msg); if (ctx.server->start() == -1) return -1; - LOG_INFO << "Started listening for user connections on " << std::to_string(conf::cfg.pubport); + LOG_INFO << "Started listening for user connections on " << std::to_string(conf::cfg.user.port); return 0; } @@ -357,17 +357,17 @@ namespace usr bool verify_appbill_check(std::string_view pubkey, const size_t input_len) { // If appbill not enabled always green light the input. - if (conf::cfg.appbill.empty()) + if (conf::cfg.contract.appbill.mode.empty()) return true; // execute appbill in --check mode to verify this user can submit a packet/connection to the network // todo: this can be made more efficient, appbill --check can process 7 at a time // Fill appbill args - const int len = conf::cfg.runtime_appbill_args.size() + 4; + const int len = conf::cfg.contract.appbill.runtime_args.size() + 4; char *execv_args[len]; - for (int i = 0; i < conf::cfg.runtime_appbill_args.size(); i++) - execv_args[i] = conf::cfg.runtime_appbill_args[i].data(); + for (int i = 0; i < conf::cfg.contract.appbill.runtime_args.size(); i++) + execv_args[i] = conf::cfg.contract.appbill.runtime_args[i].data(); char option[] = "--check"; execv_args[len - 4] = option; // add the hex encoded public key as the last parameter diff --git a/test/local-cluster/cluster-create.sh b/test/local-cluster/cluster-create.sh index f2e23610..774c760c 100755 --- a/test/local-cluster/cluster-create.sh +++ b/test/local-cluster/cluster-create.sh @@ -76,24 +76,34 @@ do # Collect each node pubkey and peer ports for later processing. - pubkeys[i]=$(node -p "require('./tmp.json').pubkeyhex") + pubkeys[i]=$(node -p "require('./tmp.json').node.public_key") # During hosting we use docker virtual dns instead of IP address. # So each node is reachable via 'node' name. peers[i]="node${n}:${peerport}" # Update contract config. + contract_json=$(node -p "JSON.stringify({...require('./tmp.json').contract, + id: '3c349abe-4d70-4f50-9fa6-018f1f2530ab', \ + bin_path: '$binary', \ + bin_args: '$binargs', \ + roundtime: $roundtime, \ + appbill: { \ + mode: '', \ + bin_args: '' \ + },}, null, 2)") + + mesh_json=$(node -p "JSON.stringify({...require('./tmp.json').mesh, port:${peerport}}, null, 2)") + user_json=$(node -p "JSON.stringify({...require('./tmp.json').user, port:${pubport}}, null, 2)") + node -p "JSON.stringify({...require('./tmp.json'), \ - contractid: '3c349abe-4d70-4f50-9fa6-018f1f2530ab', \ - binary: '$binary', \ - binargs: '$binargs', \ - appbill: '', \ - appbillargs: '', \ - peerport: ${peerport}, \ - pubport: ${pubport}, \ - roundtime: $roundtime, \ - loglevel: '$loglevel', \ - loggers:['console', 'file'] \ + contract: ${contract_json},\ + mesh: ${mesh_json},\ + user: ${user_json}, \ + log: {\ + loglevel: '$loglevel', \ + loggers:['console', 'file'] \ + }\ }, null, 2)" > hp.cfg rm tmp.json @@ -151,7 +161,9 @@ do pushd ./node$n/cfg > /dev/null 2>&1 mv hp.cfg tmp.json # nodejs needs file extension to be .json - node -p "JSON.stringify({...require('./tmp.json'),peers:${mypeers},unl:${myunl}}, null, 2)" > hp.cfg + contract_json=$(node -p "JSON.stringify({...require('./tmp.json').contract, unl:${myunl}}, null, 2)") + mesh_json=$(node -p "JSON.stringify({...require('./tmp.json').mesh, known_peers:${mypeers}}, null, 2)") + node -p "JSON.stringify({...require('./tmp.json'), contract:${contract_json}, mesh:${mesh_json}}, null, 2)" > hp.cfg rm tmp.json popd > /dev/null 2>&1 done diff --git a/test/vm-cluster/cluster.sh b/test/vm-cluster/cluster.sh index 1fe79496..11210b13 100755 --- a/test/vm-cluster/cluster.sh +++ b/test/vm-cluster/cluster.sh @@ -38,7 +38,7 @@ fi contconfig=$(jq -r ".contracts[] | select(.name == \"${CONTRACT}\") | .config" $conf) if [ "$contconfig" = "" ]; then # Apply default config. - contconfig="{'pubport': 8080, peerport: 22860, 'roundtime': 2000, 'loglevel': 'dbg', loggers:['console','file']}" + contconfig="{user: {'port': 8080 }, mesh:{ 'port': 22860}, 'contract': {'roundtime': 2000 }, 'log':{'loglevel': 'dbg', 'loggers':['console','file']}}" fi vmpass=$(jq -r '.vmpass' $conf) @@ -248,7 +248,7 @@ if [ $mode = "lcl" ]; then fi if [ $mode = "pubkey" ]; then - command="cat $contdir/cfg/hp.cfg | grep pubkeyhex | cut -d '\"' -f4" + command="cat $contdir/cfg/hp.cfg | grep public_key | cut -d '\"' -f4" if [ $nodeid = -1 ]; then for (( i=0; i<$vmcount; i++ )) do @@ -308,14 +308,14 @@ fi # Update downloaded hp.cfg files from all nodes to be part of the same UNL cluster. # Locally update values of download hp.cfg files. -peerport=$(echo $contconfig | jq -r ".peerport") +peerport=$(echo $contconfig | jq -r ".mesh.port") for (( i=0; i<$vmcount; i++ )) do vmaddr=${vmaddrs[i]} let n=$i+1 # Collect each node's pub key and peer address. - pubkeys[i]=$(jq -r ".pubkeyhex" ./cfg/node$n.cfg) + pubkeys[i]=$(jq -r ".node.public_key" ./cfg/node$n.cfg) peers[i]="$vmaddr:$peerport" done @@ -364,11 +364,8 @@ do # Merge json contents to produce final contract config. echo "$(cat ./cfg/node$n.cfg)" \ - '{"contractid":"3c349abe-4d70-4f50-9fa6-018f1f2530ab"}' \ - '{"binary":"/usr/bin/node"}' \ - '{"binargs":"'$basedir'/hpfiles/nodejs_contract/echo_contract.js"}' \ - '{"peers":'${mypeers}'}' \ - '{"unl":'${myunl}'}' \ + '{"contract": {"id": "3c349abe-4d70-4f50-9fa6-018f1f2530ab", "bin_path": "/usr/bin/node", "bin_args": "'$basedir'/hpfiles/nodejs_contract/echo_contract.js", "unl": '${myunl}'}}'\ + '{"mesh": {"known_peers": '${mypeers}'}}'\ $contconfig \ | jq --slurp 'reduce .[] as $item ({}; . * $item)' > ./cfg/node$n-merged.cfg done