mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Util helper func simplification. (#203)
This commit is contained in:
361
src/conf.cpp
361
src/conf.cpp
@@ -32,11 +32,9 @@ namespace conf
|
||||
// 2. Read and load the contract config into memory
|
||||
// 3. Validate the loaded config values
|
||||
|
||||
contract_config cfg = {};
|
||||
if (validate_contract_dir_paths() == -1 ||
|
||||
read_config(cfg) == -1 ||
|
||||
validate_config(cfg) == -1 ||
|
||||
populate_runtime_config(cfg) == -1)
|
||||
validate_config(cfg) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -55,7 +53,8 @@ namespace conf
|
||||
return -1;
|
||||
|
||||
crypto::generate_signing_keys(cfg.node.public_key, cfg.node.private_key);
|
||||
binpair_to_hex(cfg);
|
||||
cfg.node.public_key_hex = util::to_hex(cfg.node.public_key);
|
||||
cfg.node.private_key_hex = util::to_hex(cfg.node.private_key);
|
||||
|
||||
if (write_config(cfg) != 0)
|
||||
return -1;
|
||||
@@ -93,8 +92,10 @@ 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.node.public_key, cfg.node.private_key);
|
||||
binpair_to_hex(cfg);
|
||||
cfg.node.public_key_hex = util::to_hex(cfg.node.public_key);
|
||||
cfg.node.private_key_hex = util::to_hex(cfg.node.private_key);
|
||||
|
||||
cfg.hp_version = util::HP_VERSION;
|
||||
|
||||
@@ -119,14 +120,8 @@ namespace conf
|
||||
cfg.user.port = 8080;
|
||||
cfg.user.idle_timeout = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
cfg.log.loglevel_type = conf::LOG_SEVERITY::DEBUG;
|
||||
cfg.log.loglevel = "dbg";
|
||||
#else
|
||||
cfg.log.loglevel_type = conf::LOG_SEVERITY::WARN;
|
||||
cfg.log.loglevel = "inf";
|
||||
#endif
|
||||
|
||||
cfg.log.loggers.emplace("console");
|
||||
cfg.log.loggers.emplace("file");
|
||||
|
||||
@@ -240,126 +235,171 @@ namespace conf
|
||||
return -1;
|
||||
}
|
||||
|
||||
const jsoncons::json &node = d["node"];
|
||||
cfg.node.pub_key_hex = node["public_key"].as<std::string>();
|
||||
cfg.node.private_key_hex = node["private_key"].as<std::string>();
|
||||
if (node["role"] == ROLE_OBSERVER)
|
||||
cfg.node.role = ROLE::OBSERVER;
|
||||
else if (node["role"] == ROLE_VALIDATOR)
|
||||
cfg.node.role = ROLE::VALIDATOR;
|
||||
else
|
||||
// node
|
||||
{
|
||||
std::cerr << "Invalid mode. 'observer' or 'validator' expected.\n";
|
||||
return -1;
|
||||
}
|
||||
const jsoncons::json &node = d["node"];
|
||||
cfg.node.public_key_hex = node["public_key"].as<std::string>();
|
||||
cfg.node.private_key_hex = node["private_key"].as<std::string>();
|
||||
|
||||
const jsoncons::json &contract = d["contract"];
|
||||
cfg.contract.id = contract["id"].as<std::string>();
|
||||
cfg.contract.version = contract["version"].as<std::string>();
|
||||
if (cfg.contract.id.empty())
|
||||
{
|
||||
std::cerr << "Contract id not specified.\n";
|
||||
return -1;
|
||||
}
|
||||
else if (cfg.contract.version.empty())
|
||||
{
|
||||
std::cerr << "Contract version not specified.\n";
|
||||
return -1;
|
||||
}
|
||||
cfg.contract.unl.clear();
|
||||
for (auto &nodepk : contract["unl"].array_range())
|
||||
{
|
||||
// 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<unsigned char *>(bin_pubkey.data()),
|
||||
bin_pubkey.length(),
|
||||
nodepk.as<std::string_view>()) != 0)
|
||||
// Convert the hex keys to binary.
|
||||
cfg.node.public_key = util::to_bin(cfg.node.public_key_hex);
|
||||
if (cfg.node.public_key.empty())
|
||||
{
|
||||
std::cerr << "Error decoding unl list.\n";
|
||||
return -1;
|
||||
}
|
||||
cfg.contract.unl.emplace(bin_pubkey);
|
||||
}
|
||||
cfg.contract.bin_path = contract["bin_path"].as<std::string>();
|
||||
cfg.contract.bin_args = contract["bin_args"].as<std::string>();
|
||||
cfg.contract.roundtime = contract["roundtime"].as<uint16_t>();
|
||||
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;
|
||||
|
||||
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<std::string>();
|
||||
cfg.contract.appbill.bin_args = contract["appbill"]["bin_args"].as<std::string>();
|
||||
|
||||
const jsoncons::json &mesh = d["mesh"];
|
||||
cfg.mesh.port = mesh["port"].as<uint16_t>();
|
||||
// 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<std::string> splitted_peers;
|
||||
cfg.mesh.known_peers.clear();
|
||||
for (auto &v : mesh["known_peers"].array_range())
|
||||
{
|
||||
const char *ipport_concat = v.as<const char *>();
|
||||
// Split the address:port text into two
|
||||
util::split_string(splitted_peers, ipport_concat, ":");
|
||||
|
||||
// Push the peer address and the port to peers set
|
||||
if (splitted_peers.size() != 2)
|
||||
{
|
||||
std::cerr << "Invalid peer: " << ipport_concat << "\n";
|
||||
std::cerr << "Error decoding hex public key.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
peer_properties peer;
|
||||
peer.ip_port.host_address = splitted_peers.front();
|
||||
peer.ip_port.port = std::stoi(splitted_peers.back());
|
||||
cfg.node.private_key = util::to_bin(cfg.node.private_key_hex);
|
||||
if (cfg.node.private_key.empty())
|
||||
{
|
||||
std::cerr << "Error decoding hex private key.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
cfg.mesh.known_peers.push_back(peer);
|
||||
splitted_peers.clear();
|
||||
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;
|
||||
}
|
||||
startup_mode = cfg.node.role;
|
||||
}
|
||||
cfg.mesh.msg_forwarding = mesh["msg_forwarding"].as<bool>();
|
||||
cfg.mesh.max_connections = mesh["max_connections"].as<uint16_t>();
|
||||
cfg.mesh.max_known_connections = mesh["max_known_connections"].as<uint16_t>();
|
||||
// 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)
|
||||
|
||||
// contract
|
||||
{
|
||||
std::cerr << "Invalid configuration values: mesh max_known_connections count should not exceed mesh max_connections." << '\n';
|
||||
return -1;
|
||||
const jsoncons::json &contract = d["contract"];
|
||||
cfg.contract.id = contract["id"].as<std::string>();
|
||||
cfg.contract.version = contract["version"].as<std::string>();
|
||||
if (cfg.contract.id.empty())
|
||||
{
|
||||
std::cerr << "Contract id not specified.\n";
|
||||
return -1;
|
||||
}
|
||||
else if (cfg.contract.version.empty())
|
||||
{
|
||||
std::cerr << "Contract version not specified.\n";
|
||||
return -1;
|
||||
}
|
||||
cfg.contract.unl.clear();
|
||||
for (auto &nodepk : contract["unl"].array_range())
|
||||
{
|
||||
// Convert the public key hex of each node to binary and store it.
|
||||
const std::string bin_pubkey = util::to_bin(nodepk.as<std::string_view>());
|
||||
if (bin_pubkey.empty())
|
||||
{
|
||||
std::cerr << "Error decoding unl list.\n";
|
||||
return -1;
|
||||
}
|
||||
cfg.contract.unl.emplace(bin_pubkey);
|
||||
}
|
||||
cfg.contract.bin_path = contract["bin_path"].as<std::string>();
|
||||
cfg.contract.bin_args = contract["bin_args"].as<std::string>();
|
||||
cfg.contract.roundtime = contract["roundtime"].as<uint16_t>();
|
||||
|
||||
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;
|
||||
|
||||
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<std::string>();
|
||||
cfg.contract.appbill.bin_args = contract["appbill"]["bin_args"].as<std::string>();
|
||||
|
||||
// Populate runtime contract execution args.
|
||||
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.contract.appbill.bin_args.empty())
|
||||
util::split_string(cfg.contract.appbill.runtime_args, cfg.contract.appbill.bin_args, " ");
|
||||
|
||||
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.contract.bin_path.data()};
|
||||
// cfg.contract.runtime_binexec_args.insert(cfg.contract.runtime_binexec_args.begin(), std::begin(dockerargs), std::end(dockerargs));
|
||||
}
|
||||
cfg.mesh.max_bytes_per_msg = mesh["max_bytes_per_msg"].as<uint64_t>();
|
||||
cfg.mesh.max_bytes_per_min = mesh["max_bytes_per_min"].as<uint64_t>();
|
||||
cfg.mesh.max_bad_msgs_per_min = mesh["max_bad_msgs_per_min"].as<uint64_t>();
|
||||
cfg.mesh.max_bad_msgsigs_per_min = mesh["max_bad_msgsigs_per_min"].as<uint64_t>();
|
||||
cfg.mesh.max_dup_msgs_per_min = mesh["max_dup_msgs_per_min"].as<uint64_t>();
|
||||
cfg.mesh.idle_timeout = mesh["idle_timeout"].as<uint16_t>();
|
||||
cfg.mesh.peer_discovery.interval = mesh["peer_discovery"]["interval"].as<uint16_t>();
|
||||
cfg.mesh.peer_discovery.enabled = mesh["peer_discovery"]["enabled"].as<bool>();
|
||||
|
||||
|
||||
const jsoncons::json &user = d["user"];
|
||||
cfg.user.port = user["port"].as<uint16_t>();
|
||||
cfg.user.max_connections = user["max_connections"].as<unsigned int>();
|
||||
cfg.user.max_bytes_per_msg = user["max_bytes_per_msg"].as<uint64_t>();
|
||||
cfg.user.max_bytes_per_min = user["max_bytes_per_min"].as<uint64_t>();
|
||||
cfg.user.max_bad_msgs_per_min = user["max_bad_msgs_per_min"].as<uint64_t>();
|
||||
cfg.user.idle_timeout = user["idle_timeout"].as<uint16_t>();
|
||||
// mesh
|
||||
{
|
||||
const jsoncons::json &mesh = d["mesh"];
|
||||
cfg.mesh.port = mesh["port"].as<uint16_t>();
|
||||
// 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<std::string> splitted_peers;
|
||||
cfg.mesh.known_peers.clear();
|
||||
for (auto &v : mesh["known_peers"].array_range())
|
||||
{
|
||||
const char *ipport_concat = v.as<const char *>();
|
||||
// Split the address:port text into two
|
||||
util::split_string(splitted_peers, ipport_concat, ":");
|
||||
|
||||
const jsoncons::json &log = d["log"];
|
||||
cfg.log.loglevel = log["loglevel"].as<std::string>();
|
||||
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<std::string>());
|
||||
// Push the peer address and the port to peers set
|
||||
if (splitted_peers.size() != 2)
|
||||
{
|
||||
std::cerr << "Invalid peer: " << ipport_concat << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
peer_properties peer;
|
||||
peer.ip_port.host_address = splitted_peers.front();
|
||||
peer.ip_port.port = std::stoi(splitted_peers.back());
|
||||
|
||||
cfg.mesh.known_peers.push_back(peer);
|
||||
splitted_peers.clear();
|
||||
}
|
||||
cfg.mesh.msg_forwarding = mesh["msg_forwarding"].as<bool>();
|
||||
cfg.mesh.max_connections = mesh["max_connections"].as<uint16_t>();
|
||||
cfg.mesh.max_known_connections = mesh["max_known_connections"].as<uint16_t>();
|
||||
// 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)
|
||||
{
|
||||
std::cerr << "Invalid configuration values: mesh max_known_connections count should not exceed mesh max_connections." << '\n';
|
||||
return -1;
|
||||
}
|
||||
cfg.mesh.max_bytes_per_msg = mesh["max_bytes_per_msg"].as<uint64_t>();
|
||||
cfg.mesh.max_bytes_per_min = mesh["max_bytes_per_min"].as<uint64_t>();
|
||||
cfg.mesh.max_bad_msgs_per_min = mesh["max_bad_msgs_per_min"].as<uint64_t>();
|
||||
cfg.mesh.max_bad_msgsigs_per_min = mesh["max_bad_msgsigs_per_min"].as<uint64_t>();
|
||||
cfg.mesh.max_dup_msgs_per_min = mesh["max_dup_msgs_per_min"].as<uint64_t>();
|
||||
cfg.mesh.idle_timeout = mesh["idle_timeout"].as<uint16_t>();
|
||||
cfg.mesh.peer_discovery.interval = mesh["peer_discovery"]["interval"].as<uint16_t>();
|
||||
cfg.mesh.peer_discovery.enabled = mesh["peer_discovery"]["enabled"].as<bool>();
|
||||
}
|
||||
|
||||
// user
|
||||
{
|
||||
const jsoncons::json &user = d["user"];
|
||||
cfg.user.port = user["port"].as<uint16_t>();
|
||||
cfg.user.max_connections = user["max_connections"].as<unsigned int>();
|
||||
cfg.user.max_bytes_per_msg = user["max_bytes_per_msg"].as<uint64_t>();
|
||||
cfg.user.max_bytes_per_min = user["max_bytes_per_min"].as<uint64_t>();
|
||||
cfg.user.max_bad_msgs_per_min = user["max_bad_msgs_per_min"].as<uint64_t>();
|
||||
cfg.user.idle_timeout = user["idle_timeout"].as<uint16_t>();
|
||||
}
|
||||
|
||||
// log
|
||||
{
|
||||
const jsoncons::json &log = d["log"];
|
||||
cfg.log.loglevel = log["loglevel"].as<std::string>();
|
||||
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<std::string>());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -377,7 +417,7 @@ namespace conf
|
||||
|
||||
// Node configs.
|
||||
jsoncons::ojson node_config;
|
||||
node_config.insert_or_assign("public_key", cfg.node.pub_key_hex);
|
||||
node_config.insert_or_assign("public_key", cfg.node.public_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);
|
||||
@@ -390,13 +430,7 @@ namespace conf
|
||||
jsoncons::ojson unl(jsoncons::json_array_arg);
|
||||
for (const auto &nodepk : cfg.contract.unl)
|
||||
{
|
||||
std::string hex_pubkey;
|
||||
util::bin2hex(
|
||||
hex_pubkey,
|
||||
reinterpret_cast<const unsigned char *>(nodepk.data()),
|
||||
nodepk.length());
|
||||
|
||||
unl.push_back(hex_pubkey);
|
||||
unl.push_back(util::to_hex(nodepk));
|
||||
}
|
||||
contract.insert_or_assign("unl", unl);
|
||||
contract.insert_or_assign("bin_path", cfg.contract.bin_path);
|
||||
@@ -481,73 +515,6 @@ namespace conf
|
||||
return 0;
|
||||
}
|
||||
|
||||
int populate_runtime_config(contract_config &parsed_cfg)
|
||||
{
|
||||
cfg = parsed_cfg;
|
||||
startup_mode = cfg.node.role;
|
||||
|
||||
// Convert the hex keys to binary.
|
||||
|
||||
cfg.node.public_key.resize(crypto::PFXD_PUBKEY_BYTES);
|
||||
if (util::hex2bin(
|
||||
reinterpret_cast<unsigned char *>(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.node.private_key.resize(crypto::PFXD_SECKEY_BYTES);
|
||||
if (util::hex2bin(
|
||||
reinterpret_cast<unsigned char *>(cfg.node.private_key.data()),
|
||||
cfg.node.private_key.length(),
|
||||
cfg.node.private_key_hex) != 0)
|
||||
{
|
||||
std::cerr << "Error decoding hex private key.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Populate runtime contract execution args.
|
||||
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.contract.appbill.bin_args.empty())
|
||||
util::split_string(cfg.contract.appbill.runtime_args, cfg.contract.appbill.bin_args, " ");
|
||||
|
||||
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.contract.bin_path.data()};
|
||||
// cfg.contract.runtime_binexec_args.insert(cfg.contract.runtime_binexec_args.begin(), std::begin(dockerargs), std::end(dockerargs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode current binary keys in 'cfg' and populate the it with hex keys.
|
||||
*
|
||||
* @return Always returns 0.
|
||||
*/
|
||||
int binpair_to_hex(contract_config &cfg)
|
||||
{
|
||||
util::bin2hex(
|
||||
cfg.node.pub_key_hex,
|
||||
reinterpret_cast<const unsigned char *>(cfg.node.public_key.data()),
|
||||
cfg.node.public_key.length());
|
||||
|
||||
util::bin2hex(
|
||||
cfg.node.private_key_hex,
|
||||
reinterpret_cast<const unsigned char *>(cfg.node.private_key.data()),
|
||||
cfg.node.private_key.length());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the 'cfg' struct for invalid values.
|
||||
*
|
||||
@@ -557,7 +524,7 @@ namespace conf
|
||||
{
|
||||
// Check for non-empty signing keys.
|
||||
// We also check for key pair validity as well in the below code.
|
||||
if (cfg.node.pub_key_hex.empty() || cfg.node.private_key_hex.empty())
|
||||
if (cfg.node.public_key_hex.empty() || cfg.node.private_key_hex.empty())
|
||||
{
|
||||
std::cerr << "Signing keys missing. Run with 'rekey' to generate new keys.\n";
|
||||
return -1;
|
||||
@@ -602,8 +569,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.node.private_key_hex);
|
||||
if (crypto::verify_hex(msg, sighex, cfg.node.pub_key_hex) != 0)
|
||||
const std::string sig = crypto::sign(msg, cfg.node.private_key);
|
||||
if (crypto::verify(msg, sig, cfg.node.public_key) != 0)
|
||||
{
|
||||
std::cerr << "Invalid signing keys. Run with 'rekey' to generate new keys.\n";
|
||||
return -1;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace conf
|
||||
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 public_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.
|
||||
};
|
||||
@@ -185,14 +185,10 @@ namespace conf
|
||||
|
||||
int write_config(const contract_config &cfg);
|
||||
|
||||
int populate_runtime_config(contract_config &parsed_cfg);
|
||||
|
||||
int validate_config(const contract_config &cfg);
|
||||
|
||||
int validate_contract_dir_paths();
|
||||
|
||||
int binpair_to_hex(contract_config &cfg);
|
||||
|
||||
void change_role(const ROLE role);
|
||||
|
||||
LOG_SEVERITY get_loglevel_type(std::string_view severity);
|
||||
|
||||
@@ -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.node.public_key) ? "self" : util::get_hex(cp.pubkey, 1, 5)) << "]"
|
||||
<< " [from:" << ((cp.pubkey == conf::cfg.node.public_key) ? "self" : util::to_hex(cp.pubkey).substr(2, 10)) << "]"
|
||||
<< "(" << std::to_string(cp.recv_timestamp > cp.sent_timestamp ? cp.recv_timestamp - cp.sent_timestamp : 0) << "ms)";
|
||||
|
||||
if (keep_candidate)
|
||||
|
||||
@@ -28,10 +28,10 @@ namespace crypto
|
||||
// Generate key pair using libsodium default algorithm.
|
||||
// Currently using ed25519. So append prefix byte to represent that.
|
||||
|
||||
pubkey.resize(PFXD_PUBKEY_BYTES);
|
||||
pubkey.resize(crypto_sign_ed25519_PUBLICKEYBYTES + 1);
|
||||
pubkey[0] = KEYPFX_ed25519;
|
||||
|
||||
seckey.resize(PFXD_SECKEY_BYTES);
|
||||
seckey.resize(crypto_sign_ed25519_SECRETKEYBYTES + 1);
|
||||
seckey[0] = KEYPFX_ed25519;
|
||||
|
||||
crypto_sign_ed25519_keypair(
|
||||
@@ -62,33 +62,6 @@ namespace crypto
|
||||
return sig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hex signature string for a message.
|
||||
*
|
||||
* @param msg Message bytes to sign.
|
||||
* @param private_key_hex hex private key string.
|
||||
* @return hex signature string.
|
||||
*/
|
||||
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 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(
|
||||
sig,
|
||||
NULL,
|
||||
reinterpret_cast<const unsigned char *>(msg.data()),
|
||||
msg.length(),
|
||||
private_key + 1); // +1 to skip prefix byte.
|
||||
|
||||
std::string sighex;
|
||||
util::bin2hex(sighex, sig, crypto_sign_ed25519_BYTES);
|
||||
return sighex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the given signature bytes for the message.
|
||||
*
|
||||
@@ -106,31 +79,6 @@ namespace crypto
|
||||
reinterpret_cast<const unsigned char *>(pubkey.data() + 1)); // +1 to skip prefix byte.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the given hex signature for the message.
|
||||
*
|
||||
* @param msg hex message string.
|
||||
* @param sighex hex signature string.
|
||||
* @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)
|
||||
{
|
||||
//Decode hex string and verify the signature using libsodium.
|
||||
|
||||
unsigned char decoded_pubkey[PFXD_PUBKEY_BYTES];
|
||||
util::hex2bin(decoded_pubkey, PFXD_PUBKEY_BYTES, pubkeyhex);
|
||||
|
||||
unsigned char decoded_sig[crypto_sign_ed25519_BYTES];
|
||||
util::hex2bin(decoded_sig, crypto_sign_ed25519_BYTES, sighex);
|
||||
|
||||
return crypto_sign_ed25519_verify_detached(
|
||||
decoded_sig,
|
||||
reinterpret_cast<const unsigned char *>(msg.data()),
|
||||
msg.length(),
|
||||
decoded_pubkey + 1); // +1 to skip prefix byte.
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate random bytes of specified length.
|
||||
*/
|
||||
@@ -237,12 +185,7 @@ namespace crypto
|
||||
uuid[6] = (uuid[8] & 0x0F) | 0x40;
|
||||
uuid[8] = (uuid[8] & 0xBF) | 0x80;
|
||||
|
||||
std::string hex;
|
||||
util::bin2hex(
|
||||
hex,
|
||||
reinterpret_cast<const unsigned char *>(rand_bytes.data()),
|
||||
rand_bytes.length());
|
||||
|
||||
const std::string hex = util::to_hex(rand_bytes);
|
||||
return hex.substr(0, 8) + "-" + hex.substr(8, 4) + "-" + hex.substr(12, 4) + "-" + hex.substr(16, 4) + "-" + hex.substr(20);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,6 @@ namespace crypto
|
||||
|
||||
// Prefix byte to append to ed25519 keys.
|
||||
static unsigned char KEYPFX_ed25519 = 0xED;
|
||||
// Prefixed public key bytes.
|
||||
static size_t PFXD_PUBKEY_BYTES = crypto_sign_ed25519_PUBLICKEYBYTES + 1;
|
||||
// Prefixed private key bytes.
|
||||
static size_t PFXD_SECKEY_BYTES = crypto_sign_ed25519_SECRETKEYBYTES + 1;
|
||||
|
||||
int init();
|
||||
|
||||
@@ -23,12 +19,8 @@ namespace crypto
|
||||
|
||||
std::string sign(std::string_view msg, std::string_view seckey);
|
||||
|
||||
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);
|
||||
|
||||
int verify_hex(std::string_view msg, std::string_view sighex, std::string_view pubkeyhex);
|
||||
|
||||
void random_bytes(std::string &result, const size_t len);
|
||||
|
||||
std::string get_hash(std::string_view data);
|
||||
|
||||
@@ -359,10 +359,7 @@ namespace ledger
|
||||
const std::string lcl_hash = crypto::get_hash(ledger_str_buf);
|
||||
|
||||
// Get hex from binary hash.
|
||||
std::string lcl_hash_hex;
|
||||
util::bin2hex(lcl_hash_hex,
|
||||
reinterpret_cast<const unsigned char *>(lcl_hash.data()),
|
||||
lcl_hash.size());
|
||||
const std::string lcl_hash_hex = util::to_hex(lcl_hash);
|
||||
|
||||
// Acquire lock so history request serving does not access the ledger while consensus is updating the ledger.
|
||||
std::scoped_lock<std::mutex> ledger_lock(ctx.ledger_mutex);
|
||||
@@ -829,10 +826,7 @@ namespace ledger
|
||||
const std::string binary_block_hash = crypto::get_hash(block_buffer.data(), block_buffer.size());
|
||||
|
||||
// Get hex from binary hash.
|
||||
std::string block_hash;
|
||||
util::bin2hex(block_hash,
|
||||
reinterpret_cast<const unsigned char *>(binary_block_hash.data()),
|
||||
binary_block_hash.size());
|
||||
const std::string block_hash = util::to_hex(binary_block_hash);
|
||||
|
||||
return block_hash == supplied_hash;
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ int main(int argc, char **argv)
|
||||
|
||||
LOG_INFO << "Hot Pocket " << util::HP_VERSION;
|
||||
LOG_INFO << "Role: " << (conf::cfg.node.role == conf::ROLE::OBSERVER ? "Observer" : "Validator");
|
||||
LOG_INFO << "Public key: " << conf::cfg.node.pub_key_hex;
|
||||
LOG_INFO << "Public key: " << conf::cfg.node.public_key_hex;
|
||||
LOG_INFO << "Contract: " << conf::cfg.contract.id << " (" << conf::cfg.contract.version << ")";
|
||||
|
||||
if (ledger::init() == -1 ||
|
||||
|
||||
@@ -78,18 +78,11 @@ namespace msg::controlmsg::json
|
||||
if (!d.contains(field_name) || !d[field_name].is_array())
|
||||
return;
|
||||
|
||||
for (const auto &v : d[field_name].array_range())
|
||||
for (const auto &pkhex : d[field_name].array_range())
|
||||
{
|
||||
std::string_view hex_pubkey = v.as<std::string_view>();
|
||||
std::string bin_pubkey;
|
||||
bin_pubkey.resize(crypto::PFXD_PUBKEY_BYTES);
|
||||
if (util::hex2bin(
|
||||
reinterpret_cast<unsigned char *>(bin_pubkey.data()),
|
||||
bin_pubkey.length(),
|
||||
hex_pubkey) != -1)
|
||||
{
|
||||
const std::string bin_pubkey = util::to_bin(pkhex.as<std::string_view>());
|
||||
if (!bin_pubkey.empty())
|
||||
vec.emplace(bin_pubkey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,7 @@ namespace msg::usrmsg::json
|
||||
{
|
||||
std::string challenge_bytes;
|
||||
crypto::random_bytes(challenge_bytes, msg::usrmsg::CHALLENGE_LEN);
|
||||
util::bin2hex(challenge,
|
||||
reinterpret_cast<const unsigned char *>(challenge_bytes.data()),
|
||||
msg::usrmsg::CHALLENGE_LEN);
|
||||
challenge = util::to_hex(challenge_bytes);
|
||||
|
||||
// Construct the challenge msg json.
|
||||
// We do not use jsoncons library here in favour of performance because this is a simple json message.
|
||||
@@ -94,7 +92,7 @@ namespace msg::usrmsg::json
|
||||
{
|
||||
// Generate signature of challenge + contract id + contract version.
|
||||
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);
|
||||
const std::string sig_hex = util::to_hex(crypto::sign(content, conf::cfg.node.private_key));
|
||||
|
||||
// Since we know the rough size of the challenge message we reserve adequate amount for the holder.
|
||||
msg.reserve(1024);
|
||||
@@ -109,7 +107,7 @@ namespace msg::usrmsg::json
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_PUBKEY;
|
||||
msg += SEP_COLON;
|
||||
msg += conf::cfg.node.pub_key_hex;
|
||||
msg += conf::cfg.node.public_key_hex;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_UNL;
|
||||
msg += "\":[";
|
||||
@@ -169,9 +167,6 @@ namespace msg::usrmsg::json
|
||||
*/
|
||||
void create_contract_input_status(std::vector<uint8_t> &msg, std::string_view status, std::string_view reason, std::string_view input_sig)
|
||||
{
|
||||
std::string sighex;
|
||||
util::bin2hex(sighex, reinterpret_cast<const unsigned char *>(input_sig.data()), input_sig.length());
|
||||
|
||||
msg.reserve(256);
|
||||
msg += "{\"";
|
||||
msg += msg::usrmsg::FLD_TYPE;
|
||||
@@ -188,7 +183,7 @@ namespace msg::usrmsg::json
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::usrmsg::FLD_INPUT_SIG;
|
||||
msg += SEP_COLON;
|
||||
msg += sighex;
|
||||
msg += util::to_hex(input_sig);
|
||||
msg += "\"}";
|
||||
}
|
||||
|
||||
@@ -404,20 +399,12 @@ namespace msg::usrmsg::json
|
||||
// Verify the challenge signature. We do this last due to signature verification cost.
|
||||
|
||||
std::string_view pubkey_hex = d[msg::usrmsg::FLD_PUBKEY].as<std::string_view>();
|
||||
std::string pubkey_bytes;
|
||||
pubkey_bytes.resize(crypto::PFXD_PUBKEY_BYTES);
|
||||
util::hex2bin(reinterpret_cast<unsigned char *>(pubkey_bytes.data()),
|
||||
pubkey_bytes.size(),
|
||||
pubkey_hex);
|
||||
const std::string pubkey_bytes = util::to_bin(pubkey_hex);
|
||||
|
||||
std::string_view sig_hex = d[msg::usrmsg::FLD_SIG].as<std::string_view>();
|
||||
std::string sig_bytes;
|
||||
sig_bytes.resize(sig_hex.size() / 2);
|
||||
util::hex2bin(reinterpret_cast<unsigned char *>(sig_bytes.data()),
|
||||
sig_bytes.size(),
|
||||
sig_hex);
|
||||
const std::string sig_bytes = util::to_bin(sig_hex);
|
||||
|
||||
if (crypto::verify(original_challenge, sig_bytes, pubkey_bytes) != 0)
|
||||
if (pubkey_bytes.empty() || sig_bytes.empty() || crypto::verify(original_challenge, sig_bytes, pubkey_bytes) != 0)
|
||||
{
|
||||
LOG_DEBUG << "User challenge response signature verification failed.";
|
||||
return -1;
|
||||
@@ -537,9 +524,7 @@ namespace msg::usrmsg::json
|
||||
|
||||
// Extract the hex signature and convert to binary.
|
||||
const std::string_view sig_hex = d[msg::usrmsg::FLD_SIG].as<std::string_view>();
|
||||
extracted_sig.resize(crypto_sign_ed25519_BYTES);
|
||||
util::hex2bin(reinterpret_cast<unsigned char *>(extracted_sig.data()), extracted_sig.length(), sig_hex);
|
||||
|
||||
extracted_sig = util::to_bin(sig_hex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,7 @@ namespace p2p
|
||||
}
|
||||
|
||||
// Converting the binary pub key into hexadecimal string.
|
||||
std::string pubkeyhex;
|
||||
util::bin2hex(pubkeyhex, reinterpret_cast<const unsigned char *>(challenge_resp.pubkey.data()), challenge_resp.pubkey.length());
|
||||
std::string pubkeyhex = util::to_hex(challenge_resp.pubkey);
|
||||
|
||||
const int res = challenge_resp.pubkey.compare(conf::cfg.node.public_key);
|
||||
|
||||
|
||||
16
src/sc.cpp
16
src/sc.cpp
@@ -258,7 +258,7 @@ namespace sc
|
||||
|
||||
std::ostringstream os;
|
||||
os << "{\"version\":\"" << util::HP_VERSION
|
||||
<< "\",\"pubkey\":\"" << conf::cfg.node.pub_key_hex
|
||||
<< "\",\"pubkey\":\"" << conf::cfg.node.public_key_hex
|
||||
<< "\",\"ts\":" << ctx.args.time
|
||||
<< ",\"readonly\":" << (ctx.args.readonly ? "true" : "false");
|
||||
|
||||
@@ -437,11 +437,7 @@ namespace sc
|
||||
{
|
||||
if (npl_msg.lcl == ctx.args.lcl)
|
||||
{
|
||||
std::string pubkeyhex;
|
||||
util::bin2hex(
|
||||
pubkeyhex,
|
||||
reinterpret_cast<const unsigned char *>(npl_msg.pubkey.data()),
|
||||
npl_msg.pubkey.length());
|
||||
const std::string pubkeyhex = util::to_hex(npl_msg.pubkey);
|
||||
|
||||
// Writing the public key to the contract's fd (Skip first byte for key type prefix).
|
||||
if (write(writefd, pubkeyhex.data(), pubkeyhex.size()) == -1)
|
||||
@@ -541,16 +537,10 @@ namespace sc
|
||||
|
||||
// Get the hex pubkey.
|
||||
const std::string &pubkey = itr->first; // Pubkey in binary format.
|
||||
std::string pubkeyhex;
|
||||
util::bin2hex(
|
||||
pubkeyhex,
|
||||
reinterpret_cast<const unsigned char *>(pubkey.data()) + 1, // Skip key type prefix.
|
||||
pubkey.length() - 1);
|
||||
|
||||
const std::vector<util::buffer_view> &user_inputs = user_bufmap.find(pubkey)->second.inputs;
|
||||
|
||||
// Write hex pubkey as key and output fd as first element of array.
|
||||
os << "\"" << pubkeyhex << "\":["
|
||||
os << "\"" << util::to_hex(pubkey) << "\":["
|
||||
<< itr->second.scfd;
|
||||
|
||||
// Write input offsets into the same array.
|
||||
|
||||
@@ -101,13 +101,7 @@ namespace state_serve
|
||||
}
|
||||
|
||||
// Session id is in binary format. Converting to hex before printing.
|
||||
std::string session_id_hex;
|
||||
util::bin2hex(
|
||||
session_id_hex,
|
||||
reinterpret_cast<const unsigned char *>(session_id.data()),
|
||||
session_id.length());
|
||||
|
||||
LOG_DEBUG << "Serving state request from [" << session_id_hex.substr(2, 10) << "]";
|
||||
LOG_DEBUG << "Serving state request from [" << util::to_hex(session_id).substr(2, 10) << "]";
|
||||
|
||||
const msg::fbuf::p2pmsg::Content *content = msg::fbuf::p2pmsg::GetContent(request.data());
|
||||
|
||||
|
||||
24
src/unl.cpp
24
src/unl.cpp
@@ -163,13 +163,7 @@ namespace unl
|
||||
os << ","; // Trailing comma separator for previous element.
|
||||
|
||||
// Convert binary pubkey into hex.
|
||||
std::string pubkeyhex;
|
||||
util::bin2hex(
|
||||
pubkeyhex,
|
||||
reinterpret_cast<const unsigned char *>(pk->data()),
|
||||
pk->length());
|
||||
|
||||
os << "\"" << pubkeyhex << "\"";
|
||||
os << "\"" << util::to_hex(*pk) << "\"";
|
||||
}
|
||||
os << "]";
|
||||
json_list = os.str();
|
||||
@@ -208,7 +202,7 @@ namespace unl
|
||||
sync_ctx.target_unl = target_unl_hash;
|
||||
sync_ctx.target_requested_on = 0;
|
||||
sync_ctx.request_submissions = 0;
|
||||
LOG_INFO << "unl sync: Syncing for target:" << hash_bin2hex(sync_ctx.target_unl).substr(0, 10) << " (current:" << hash_bin2hex(get_hash()).substr(0, 10) << ")";
|
||||
LOG_INFO << "unl sync: Syncing for target:" << util::to_hex(sync_ctx.target_unl).substr(0, 10) << " (current:" << util::to_hex(get_hash()).substr(0, 10) << ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +227,7 @@ namespace unl
|
||||
std::string target_pubkey;
|
||||
p2p::send_message_to_random_peer(fbuf, target_pubkey);
|
||||
|
||||
LOG_DEBUG << "UNL list requested from [" << target_pubkey.substr(0, 10) << "]. Required unl hash:" << hash_bin2hex(sync_ctx.target_unl).substr(0, 10);
|
||||
LOG_DEBUG << "UNL list requested from [" << target_pubkey.substr(0, 10) << "]. Required unl hash:" << util::to_hex(sync_ctx.target_unl).substr(0, 10);
|
||||
sync_ctx.target_requested_on = time_now;
|
||||
sync_ctx.request_submissions++;
|
||||
}
|
||||
@@ -278,16 +272,6 @@ namespace unl
|
||||
LOG_INFO << "unl sync: Worker stopped.";
|
||||
}
|
||||
|
||||
std::string hash_bin2hex(std::string_view hash)
|
||||
{
|
||||
// Get hex from binary hash.
|
||||
std::string unl_hash_hex;
|
||||
util::bin2hex(unl_hash_hex,
|
||||
reinterpret_cast<const unsigned char *>(hash.data()),
|
||||
hash.size());
|
||||
return unl_hash_hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process any unl sync requests received.
|
||||
* @return Returns 0 if no requests were processed and returns 1 if atleast one request is served.
|
||||
@@ -355,7 +339,7 @@ namespace unl
|
||||
{
|
||||
if (unl.requester_unl == sync_ctx.target_unl && verify_and_replace(unl.unl_list) != -1)
|
||||
{
|
||||
LOG_INFO << "unl sync: Sync complete. New unl:" << hash_bin2hex(sync_ctx.target_unl).substr(0, 10);
|
||||
LOG_INFO << "unl sync: Sync complete. New unl:" << util::to_hex(sync_ctx.target_unl).substr(0, 10);
|
||||
sync_ctx.clear_target();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ namespace unl
|
||||
void set_sync_target(std::string_view target_unl_hash);
|
||||
void send_unl_sync_request();
|
||||
void unl_syncer_loop();
|
||||
std::string hash_bin2hex(std::string_view hash);
|
||||
int verify_and_replace(const std::set<std::string> &new_list);
|
||||
int check_unl_sync_requests();
|
||||
int check_unl_sync_responses();
|
||||
|
||||
@@ -238,14 +238,8 @@ namespace usr
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Decode hex pubkey and get binary pubkey. We are only going to keep
|
||||
// the binary pubkey due to reduced memory footprint.
|
||||
std::string pubkey;
|
||||
pubkey.resize(pubkey_hex.length() / 2);
|
||||
util::hex2bin(
|
||||
reinterpret_cast<unsigned char *>(pubkey.data()),
|
||||
pubkey.length(),
|
||||
pubkey_hex);
|
||||
// Decode hex pubkey and get binary pubkey.
|
||||
const std::string pubkey = util::to_bin(pubkey_hex);
|
||||
|
||||
// Acquire user list lock.
|
||||
std::scoped_lock<std::mutex> lock(ctx.users_mutex);
|
||||
@@ -371,8 +365,7 @@ namespace usr
|
||||
char option[] = "--check";
|
||||
execv_args[len - 4] = option;
|
||||
// add the hex encoded public key as the last parameter
|
||||
std::string hexpubkey;
|
||||
util::bin2hex(hexpubkey, reinterpret_cast<const unsigned char *>(pubkey.data()), pubkey.size());
|
||||
std::string hexpubkey = util::to_hex(pubkey);
|
||||
std::string inputsize = std::to_string(input_len);
|
||||
execv_args[len - 3] = hexpubkey.data();
|
||||
execv_args[len - 2] = inputsize.data();
|
||||
|
||||
@@ -19,58 +19,22 @@ namespace util
|
||||
return encoded_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes provided bytes to hex string.
|
||||
*
|
||||
* @param encoded_string String reference to assign the hex encoded output.
|
||||
* @param bin Bytes to encode.
|
||||
* @param bin_len Bytes length.
|
||||
* @return Always returns 0.
|
||||
*/
|
||||
int bin2hex(std::string &encoded_string, const unsigned char *bin, const size_t bin_len)
|
||||
const std::string to_bin(const std::string_view hex)
|
||||
{
|
||||
// Allocate the target string.
|
||||
encoded_string.resize(bin_len * 2);
|
||||
std::string bin;
|
||||
bin.resize(hex.size() / 2);
|
||||
|
||||
// Get encoded string.
|
||||
sodium_bin2hex(
|
||||
encoded_string.data(),
|
||||
encoded_string.length() + 1, // + 1 because sodium writes ending '\0' character as well.
|
||||
bin,
|
||||
bin_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes provided hex string into bytes.
|
||||
*
|
||||
* @param decodedbuf Buffer to assign decoded bytes.
|
||||
* @param decodedbuf_len Decoded buffer size.
|
||||
* @param hex_str hex string to decode.
|
||||
*/
|
||||
int hex2bin(unsigned char *decodedbuf, const size_t decodedbuf_len, std::string_view hex_str)
|
||||
{
|
||||
const char *hex_end;
|
||||
size_t bin_len;
|
||||
if (sodium_hex2bin(
|
||||
decodedbuf, decodedbuf_len,
|
||||
hex_str.data(),
|
||||
hex_str.length(),
|
||||
reinterpret_cast<unsigned char *>(bin.data()), bin.size(),
|
||||
hex.data(), hex.size(),
|
||||
"", &bin_len, &hex_end))
|
||||
{
|
||||
return -1;
|
||||
return ""; // Empty indicates error.
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string get_hex(std::string_view bin, const off_t skip, const size_t take)
|
||||
{
|
||||
std::string hex;
|
||||
const size_t len = (take ? take : (bin.size() - skip));
|
||||
bin2hex(hex, reinterpret_cast<unsigned char *>(const_cast<char *>(bin.data() + skip)), len);
|
||||
return hex;
|
||||
return bin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +92,7 @@ namespace util
|
||||
}
|
||||
|
||||
// Provide a safe std::string overload for realpath
|
||||
std::string realpath(const std::string &path)
|
||||
const std::string realpath(const std::string &path)
|
||||
{
|
||||
std::array<char, PATH_MAX> buffer;
|
||||
::realpath(path.c_str(), buffer.data());
|
||||
|
||||
@@ -40,11 +40,7 @@ namespace util
|
||||
|
||||
const std::string to_hex(const std::string_view bin);
|
||||
|
||||
int bin2hex(std::string &encoded_string, const unsigned char *bin, const size_t bin_len);
|
||||
|
||||
int hex2bin(unsigned char *decoded, const size_t decoded_len, std::string_view hex_str);
|
||||
|
||||
std::string get_hex(std::string_view bin, const off_t skip = 0, const size_t take = 0);
|
||||
const std::string to_bin(const std::string_view hex);
|
||||
|
||||
uint64_t get_epoch_milliseconds();
|
||||
|
||||
@@ -52,7 +48,7 @@ namespace util
|
||||
|
||||
int version_compare(const std::string &x, const std::string &y);
|
||||
|
||||
std::string realpath(const std::string &path);
|
||||
const std::string realpath(const std::string &path);
|
||||
|
||||
void mask_signal();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user