Added support for params config file
This commit is contained in:
+32
-4
@@ -108,6 +108,7 @@ void p2pool_usage()
|
||||
"--full-validation Enables full share validation / increases CPU usage\n"
|
||||
"--onion-address Tell other peers to use this .onion address to connect to this node through TOR\n"
|
||||
"--no-clearnet-p2p Forces P2P server to listen on 127.0.0.1 and to not connect to clearnet IPs\n"
|
||||
"--params-file File name to load parameters from. It can't be used together with any other command line parameters\n"
|
||||
"--help Show this help message\n\n"
|
||||
"Example command line:\n\n"
|
||||
"%s --host 127.0.0.1 --rpc-port 18081 --zmq-port 18083 --wallet YOUR_WALLET_ADDRESS --stratum 0.0.0.0:%d --p2p 0.0.0.0:%d\n\n",
|
||||
@@ -222,10 +223,10 @@ int p2pool_test()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static p2pool::Params get_params(int argc, char* argv[]) noexcept
|
||||
static p2pool::Params get_params(int argc, const char* const argv[]) noexcept
|
||||
{
|
||||
try {
|
||||
std::vector<std::vector<std::string_view>> args;
|
||||
std::vector<std::vector<std::string>> args;
|
||||
args.reserve(argc);
|
||||
|
||||
// Group command-line parameters by the pattern "--name [data1 data2 ... data_n]"
|
||||
@@ -236,7 +237,7 @@ static p2pool::Params get_params(int argc, char* argv[]) noexcept
|
||||
if ((arg.size() > 2) && (arg[0] == '-') && (arg[1] == '-')) {
|
||||
// Store the parameter name without the "--" prefix
|
||||
arg.remove_prefix(2);
|
||||
args.emplace_back(std::vector<std::string_view>(1, std::move(arg)));
|
||||
args.emplace_back(std::vector<std::string>(1, std::string(arg)));
|
||||
}
|
||||
else if (!args.empty()) {
|
||||
args.back().emplace_back(std::move(arg));
|
||||
@@ -256,6 +257,22 @@ static p2pool::Params get_params(int argc, char* argv[]) noexcept
|
||||
abort();
|
||||
}
|
||||
|
||||
static p2pool::Params get_params(const std::string& params_file) noexcept
|
||||
{
|
||||
try {
|
||||
p2pool::Params params(p2pool::parse_config(params_file));
|
||||
|
||||
if (params.valid()) {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
catch (const std::exception&) {
|
||||
}
|
||||
|
||||
printf("Invalid or missing command line. Try \"p2pool --help\".\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc == 1) {
|
||||
@@ -263,6 +280,8 @@ int main(int argc, char* argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string params_file;
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "/help") || !strcmp(argv[i], "-h") || !strcmp(argv[i], "/h") || !strcmp(argv[i], "/?")) {
|
||||
p2pool_usage();
|
||||
@@ -277,6 +296,15 @@ int main(int argc, char* argv[])
|
||||
if (!strcmp(argv[i], "--test")) {
|
||||
return p2pool_test();
|
||||
}
|
||||
|
||||
if (!strcmp(argv[i], "--params-file") && (i + 1 < argc)) {
|
||||
params_file = argv[++i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!params_file.empty() && (argc != 3)) {
|
||||
fprintf(stderr, "--params-file can't be combined with other command line parameters\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG)
|
||||
@@ -292,7 +320,7 @@ int main(int argc, char* argv[])
|
||||
// Some P2Pool code will not work without libuv initialized, so the code above this line must be minimal
|
||||
uv_default_loop();
|
||||
|
||||
const p2pool::Params params = get_params(argc, argv);
|
||||
const p2pool::Params params = params_file.empty() ? get_params(argc, argv) : get_params(params_file);
|
||||
|
||||
if (!params.m_dataDir.empty()) {
|
||||
printf("Using \"%s\" for P2Pool files\n", params.m_dataDir.c_str());
|
||||
|
||||
+13
-13
@@ -30,7 +30,7 @@ namespace p2pool {
|
||||
static constexpr uint64_t MIN_STRATUM_BAN_TIME = UINT64_C(1);
|
||||
static constexpr uint64_t MAX_STRATUM_BAN_TIME = (UINT64_C(1) << 34) - 1;
|
||||
|
||||
Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
Params::Params(const std::vector<std::vector<std::string>>& args)
|
||||
{
|
||||
auto has1 = [](const auto& v) { return (v.size() > 1) && !v[1].empty();};
|
||||
auto has2 = [](const auto& v) { return (v.size() > 2) && !v[2].empty();};
|
||||
@@ -44,7 +44,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
bool ok = false;
|
||||
|
||||
if ((arg[0] == "host") && has1(arg)) {
|
||||
const char* address = arg[1].data();
|
||||
const char* address = arg[1].c_str();
|
||||
|
||||
if (m_hosts.empty()) {
|
||||
m_hosts.emplace_back();
|
||||
@@ -63,7 +63,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
m_hosts.emplace_back();
|
||||
}
|
||||
|
||||
m_hosts.back().m_rpcPort = static_cast<int32_t>(std::min(std::max(strtoul(arg[1].data(), nullptr, 10), 1UL), 65535UL));
|
||||
m_hosts.back().m_rpcPort = static_cast<int32_t>(std::min(std::max(strtoul(arg[1].c_str(), nullptr, 10), 1UL), 65535UL));
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
m_hosts.emplace_back();
|
||||
}
|
||||
|
||||
m_hosts.back().m_zmqPort = static_cast<int32_t>(std::min(std::max(strtoul(arg[1].data(), nullptr, 10), 1UL), 65535UL));
|
||||
m_hosts.back().m_zmqPort = static_cast<int32_t>(std::min(std::max(strtoul(arg[1].c_str(), nullptr, 10), 1UL), 65535UL));
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
}
|
||||
|
||||
if ((arg[0] == "wallet") && has1(arg)) {
|
||||
const char* s = arg[1].data();
|
||||
const char* s = arg[1].c_str();
|
||||
|
||||
if (!m_mainWallet.decode(s)) {
|
||||
LOGERR(1, "Wallet " << s << " failed to decode");
|
||||
@@ -92,7 +92,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
}
|
||||
|
||||
if ((arg[0] == "subaddress") && has1(arg)) {
|
||||
const char* s = arg[1].data();
|
||||
const char* s = arg[1].c_str();
|
||||
|
||||
if (!m_subaddress.decode(s)) {
|
||||
LOGERR(1, "Subaddress " << s << " failed to decode");
|
||||
@@ -107,7 +107,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
}
|
||||
|
||||
if ((arg[0] == "stratum-ban-time") && has1(arg)) {
|
||||
m_stratumBanTime = strtoull(arg[1].data(), nullptr, 10);
|
||||
m_stratumBanTime = strtoull(arg[1].c_str(), nullptr, 10);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
}
|
||||
|
||||
if ((arg[0] == "loglevel") && has1(arg)) {
|
||||
const int level = std::min(std::max<int>(static_cast<int>(strtol(arg[1].data(), nullptr, 10)), 0), log::MAX_GLOBAL_LOG_LEVEL);
|
||||
const int level = std::min(std::max<int>(static_cast<int>(strtol(arg[1].c_str(), nullptr, 10)), 0), log::MAX_GLOBAL_LOG_LEVEL);
|
||||
log::GLOBAL_LOG_LEVEL = level;
|
||||
ok = true;
|
||||
}
|
||||
@@ -170,17 +170,17 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
#endif
|
||||
|
||||
if (((arg[0] == "out-peers") || (arg[0] == "outpeers")) && has1(arg)) {
|
||||
m_maxOutgoingPeers = std::min(std::max(strtoul(arg[1].data(), nullptr, 10), 10UL), 450UL);
|
||||
m_maxOutgoingPeers = std::min(std::max(strtoul(arg[1].c_str(), nullptr, 10), 10UL), 450UL);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if (((arg[0] == "in-peers") || (arg[0] == "inpeers")) && has1(arg)) {
|
||||
m_maxIncomingPeers = std::min(std::max(strtoul(arg[1].data(), nullptr, 10), 10UL), 450UL);
|
||||
m_maxIncomingPeers = std::min(std::max(strtoul(arg[1].c_str(), nullptr, 10), 10UL), 450UL);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if ((arg[0] == "start-mining") && has1(arg)) {
|
||||
m_minerThreads = std::min(std::max(strtoul(arg[1].data(), nullptr, 10), 1UL), 64UL);
|
||||
m_minerThreads = std::min(std::max(strtoul(arg[1].c_str(), nullptr, 10), 1UL), 64UL);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
}
|
||||
|
||||
if ((arg[0] == "p2p-external-port") && has1(arg)) {
|
||||
m_p2pExternalPort = static_cast<int32_t>(std::min(std::max(strtoul(arg[1].data(), nullptr, 10), 1UL), 65535UL));
|
||||
m_p2pExternalPort = static_cast<int32_t>(std::min(std::max(strtoul(arg[1].c_str(), nullptr, 10), 1UL), 65535UL));
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ Params::Params(const std::vector<std::vector<std::string_view>>& args)
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
fprintf(stderr, "Unknown or invalid command line parameter \"%s\"\n\n", arg[0].data());
|
||||
fprintf(stderr, "Unknown or invalid command line parameter \"%s\"\n\n", arg[0].c_str());
|
||||
p2pool_usage();
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ struct Params
|
||||
FORCEINLINE Params() {}
|
||||
#endif
|
||||
|
||||
Params(const std::vector<std::vector<std::string_view>>& args);
|
||||
explicit Params(const std::vector<std::vector<std::string>>& args);
|
||||
|
||||
bool valid() const;
|
||||
|
||||
|
||||
+111
@@ -27,6 +27,7 @@ extern "C" {
|
||||
#include <map>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <fstream>
|
||||
|
||||
#if !defined(_WIN32) && defined(HAVE_SCHED)
|
||||
#include <sched.h>
|
||||
@@ -1033,4 +1034,114 @@ hash from_onion_v3(const std::string& address)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::string>> parse_config(const std::string& file_name)
|
||||
{
|
||||
std::ifstream f(file_name);
|
||||
|
||||
if (!f.is_open() || !f.good()) {
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::string>> args;
|
||||
|
||||
auto is_alpha = [](char c) { return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); };
|
||||
auto is_num = [](char c) { return ('0' <= c && c <= '9'); };
|
||||
|
||||
std::string s;
|
||||
|
||||
while (std::getline(f, s).good()) {
|
||||
if (s.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool quoted = false;
|
||||
|
||||
enum {
|
||||
BEFORE_NAME,
|
||||
COMMENT,
|
||||
NAME,
|
||||
AFTER_NAME,
|
||||
VALUE,
|
||||
VALUE_ESCAPE_CHAR,
|
||||
} state = BEFORE_NAME;
|
||||
|
||||
for (const char c : s) {
|
||||
switch (state) {
|
||||
case BEFORE_NAME:
|
||||
if (is_alpha(c)) {
|
||||
state = NAME;
|
||||
args.emplace_back(std::vector<std::string>(1, std::string(1, c)));
|
||||
}
|
||||
else if (c == '#') {
|
||||
state = COMMENT;
|
||||
}
|
||||
break;
|
||||
|
||||
case COMMENT:
|
||||
break;
|
||||
|
||||
case NAME:
|
||||
if (is_alpha(c) || is_num(c) || (c == '-')) {
|
||||
args.back()[0] += c;
|
||||
}
|
||||
else if (c == '#') {
|
||||
state = COMMENT;
|
||||
}
|
||||
else {
|
||||
state = AFTER_NAME;
|
||||
}
|
||||
break;
|
||||
|
||||
case AFTER_NAME:
|
||||
if (c == '#') {
|
||||
state = COMMENT;
|
||||
}
|
||||
else if ((c != '\t') && (c != ' ') && (c != '=')) {
|
||||
state = VALUE;
|
||||
quoted = (c == '"');
|
||||
if (quoted) {
|
||||
args.back().emplace_back(std::string());
|
||||
}
|
||||
else {
|
||||
args.back().emplace_back(std::string(1, c));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VALUE:
|
||||
if (quoted) {
|
||||
if (c == '"') {
|
||||
state = AFTER_NAME;
|
||||
}
|
||||
else if (c == '\\') {
|
||||
state = VALUE_ESCAPE_CHAR;
|
||||
}
|
||||
else {
|
||||
args.back().back() += c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c == ' ') {
|
||||
state = AFTER_NAME;
|
||||
}
|
||||
else if (c == '#') {
|
||||
state = COMMENT;
|
||||
}
|
||||
else {
|
||||
args.back().back() += c;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VALUE_ESCAPE_CHAR:
|
||||
args.back().back() += c;
|
||||
state = VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
@@ -441,6 +441,8 @@ static FORCEINLINE constexpr hash from_onion_v3_const(const char* address)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::string>> parse_config(const std::string& file_name);
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
void memory_tracking_start();
|
||||
|
||||
Reference in New Issue
Block a user