Skip to content

Commit

Permalink
- in order to stop populating userpass over and over again, populate …
Browse files Browse the repository at this point in the history
…once and reuse

- in order to eliminate discrepancies between char array sizes, use sizeof() in max_string_length of datum_config_options

- introduce a warning in case a config option is truncated

- where userpass was reused for a filepath, create a separate variable

- reduce user and pass to 128 bytes

- exit during config upon parsing error, makes more sense to me
  • Loading branch information
jesterhodl committed Dec 15, 2024
1 parent 96d3b1f commit 90e6b02
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 38 deletions.
6 changes: 0 additions & 6 deletions src/datum_blocktemplates.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ T_DATUM_TEMPLATE_DATA *datum_gbt_parser(json_t *gbt) {

void *datum_gateway_fallback_notifier(void *args) {
CURL *tcurl = NULL;
char userpass[1024];
char req[512];
char p1[72];
p1[0] = 0;
Expand All @@ -345,8 +344,6 @@ void *datum_gateway_fallback_notifier(void *args) {
}
DLOG_DEBUG("Fallback notifier thread ready.");

snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);

while(1) {
snprintf(req, sizeof(req), "{\"jsonrpc\":\"1.0\",\"id\":\"%"PRIu64"\",\"method\":\"getbestblockhash\",\"params\":[]}", current_time_millis());
gbbh = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, req);
Expand Down Expand Up @@ -383,7 +380,6 @@ void *datum_gateway_template_thread(void *args) {
uint64_t i = 0;
char gbt_req[1024];
int j;
char userpass[1024];
T_DATUM_TEMPLATE_DATA *t;
bool was_notified = false;
int wnc = 0;
Expand Down Expand Up @@ -411,8 +407,6 @@ void *datum_gateway_template_thread(void *args) {
char p1[72];
p1[0] = 0;

snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);

while(1) {
i++;

Expand Down
40 changes: 26 additions & 14 deletions src/datum_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,19 @@
#include "datum_sockets.h"

global_config_t datum_config;
// since we null-terminate the user and password, we'll have enough for the semicolon and NUL
char userpass[sizeof(datum_config.bitcoind_rpcuser) + sizeof(datum_config.bitcoind_rpcpassword)];

const char *datum_conf_var_type_text[] = { "N/A", "boolean", "integer", "string", "string_array" };

const T_DATUM_CONFIG_ITEM datum_config_options[] = {
// Bitcoind configs
{ .var_type = DATUM_CONF_STRING, .category = "bitcoind", .name = "rpcuser", .description = "RPC username for communication with local bitcoind.",
.required = true, .ptr = datum_config.bitcoind_rpcuser, .max_string_len = 128 },
.required = true, .ptr = datum_config.bitcoind_rpcuser, .max_string_len = sizeof(datum_config.bitcoind_rpcuser) },
{ .var_type = DATUM_CONF_STRING, .category = "bitcoind", .name = "rpcpassword", .description = "RPC password for communication with local bitcoind.",
.required = true, .ptr = datum_config.bitcoind_rpcpassword, .max_string_len = 128 },
.required = true, .ptr = datum_config.bitcoind_rpcpassword, .max_string_len = sizeof(datum_config.bitcoind_rpcpassword) },
{ .var_type = DATUM_CONF_STRING, .category = "bitcoind", .name = "rpcurl", .description = "RPC URL for communication with local bitcoind. (GBT Template Source)",
.required = true, .ptr = datum_config.bitcoind_rpcurl, .max_string_len = 128 },
.required = true, .ptr = datum_config.bitcoind_rpcurl, .max_string_len = sizeof(datum_config.bitcoind_rpcurl) },
{ .var_type = DATUM_CONF_INT, .category = "bitcoind", .name = "work_update_seconds", .description = "How many seconds between normal work updates? (5-120, 40 suggested)",
.required = false, .ptr = &datum_config.bitcoind_work_update_seconds, .default_int = 40 },
{ .var_type = DATUM_CONF_BOOL, .category = "bitcoind", .name = "notify_fallback", .description = "Fall back to less efficient methods for new block notifications. Can disable if you use blocknotify.",
Expand Down Expand Up @@ -93,23 +95,23 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {

// mining settings
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "pool_address", .description = "Bitcoin address used for mining rewards.",
.required = true, .ptr = datum_config.mining_pool_address, .max_string_len = 128 },
.required = true, .ptr = datum_config.mining_pool_address, .max_string_len = sizeof(datum_config.mining_pool_address) },
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "coinbase_tag_primary", .description = "Text to have in the primary coinbase tag when not using pool (overridden by DATUM Pool)",
.required = false, .ptr = datum_config.mining_coinbase_tag_primary, .default_string[0] = "DATUM Gateway", .max_string_len = 64 },
.required = false, .ptr = datum_config.mining_coinbase_tag_primary, .default_string[0] = "DATUM Gateway", .max_string_len = sizeof(datum_config.mining_coinbase_tag_primary) },
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "coinbase_tag_secondary", .description = "Text to have in the secondary coinbase tag (Short name/identifier)",
.required = false, .ptr = datum_config.mining_coinbase_tag_secondary, .default_string[0] = "DATUM User", .max_string_len = 64 },
.required = false, .ptr = datum_config.mining_coinbase_tag_secondary, .default_string[0] = "DATUM User", .max_string_len = sizeof(datum_config.mining_coinbase_tag_secondary) },
{ .var_type = DATUM_CONF_INT, .category = "mining", .name = "coinbase_unique_id", .description = "A unique ID between 1 and 65535. This is appended to the coinbase. Make unique per instance of datum with the same coinbase tags.",
.required = false, .ptr = &datum_config.coinbase_unique_id, .default_int = 4242 },
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "save_submitblocks_dir", .description = "Directory to save all submitted blocks to as submitblock JSON files",
.required = false, .ptr = datum_config.mining_save_submitblocks_dir, .default_string[0] = "", .max_string_len = 256 },
.required = false, .ptr = datum_config.mining_save_submitblocks_dir, .default_string[0] = "", .max_string_len = sizeof(datum_config.mining_save_submitblocks_dir) },

// API/dashboard
{ .var_type = DATUM_CONF_INT, .category = "api", .name = "listen_port", .description = "Port to listen for API/dashboard requests (0=disabled)",
.required = false, .ptr = &datum_config.api_listen_port, .default_int = 0 },

// extra block submissions list
{ .var_type = DATUM_CONF_STRING_ARRAY, .category = "extra_block_submissions", .name = "urls", .description = "Array of bitcoind RPC URLs to submit our blocks to directly. Include auth info: http://user:pass@IP",
.required = false, .ptr = datum_config.extra_block_submissions_urls[0], .max_string_len = 512 },
.required = false, .ptr = datum_config.extra_block_submissions_urls[0], .max_string_len = sizeof(datum_config.extra_block_submissions_urls[0]) },

// logger
{ .var_type = DATUM_CONF_BOOL, .category = "logger", .name = "log_to_console", .description = "Enable logging of messages to the console",
Expand All @@ -119,7 +121,7 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
{ .var_type = DATUM_CONF_BOOL, .category = "logger", .name = "log_to_file", .description = "Enable logging of messages to a file",
.required = false, .ptr = &datum_config.clog_to_file, .default_bool = false },
{ .var_type = DATUM_CONF_STRING, .category = "logger", .name = "log_file", .description = "Path to file to write log messages, when enabled",
.required = false, .ptr = datum_config.clog_file, .default_string[0] = "", .max_string_len = 1023 },
.required = false, .ptr = datum_config.clog_file, .default_string[0] = "", .max_string_len = sizeof(datum_config.clog_file) },
{ .var_type = DATUM_CONF_BOOL, .category = "logger", .name = "log_rotate_daily", .description = "Rotate the message log file at midnight",
.required = false, .ptr = &datum_config.clog_rotate_daily, .default_bool = true },
{ .var_type = DATUM_CONF_BOOL, .category = "logger", .name = "log_calling_function", .description = "Log the name of the calling function when logging",
Expand All @@ -131,11 +133,11 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {

// datum options
{ .var_type = DATUM_CONF_STRING, .category = "datum", .name = "pool_host", .description = "Remote DATUM server host/ip to use for decentralized pooled mining (set to \"\" to disable pooled mining)",
.required = false, .ptr = datum_config.datum_pool_host, .default_string[0] = "datum-beta1.mine.ocean.xyz", .max_string_len = 1023 },
.required = false, .ptr = datum_config.datum_pool_host, .default_string[0] = "datum-beta1.mine.ocean.xyz", .max_string_len = sizeof(datum_config.datum_pool_host) },
{ .var_type = DATUM_CONF_INT, .category = "datum", .name = "pool_port", .description = "Remote DATUM server port",
.required = false, .ptr = &datum_config.datum_pool_port, .default_int = 28915 },
{ .var_type = DATUM_CONF_STRING, .category = "datum", .name = "pool_pubkey", .description = "Public key of the DATUM server for initiating encrypted connection. Get from secure location, or set to empty to auto-fetch.",
.required = false, .ptr = datum_config.datum_pool_pubkey, .default_string[0] = "f21f2f0ef0aa1970468f22bad9bb7f4535146f8e4a8f646bebc93da3d89b1406f40d032f09a417d94dc068055df654937922d2c89522e3e8f6f0e649de473003", .max_string_len = 1023 },
.required = false, .ptr = datum_config.datum_pool_pubkey, .default_string[0] = "f21f2f0ef0aa1970468f22bad9bb7f4535146f8e4a8f646bebc93da3d89b1406f40d032f09a417d94dc068055df654937922d2c89522e3e8f6f0e649de473003", .max_string_len = sizeof(datum_config.datum_pool_pubkey) },
{ .var_type = DATUM_CONF_BOOL, .category = "datum", .name = "pool_pass_workers", .description = "Pass stratum miner usernames as sub-worker names to the pool (pool_username.miner's username)",
.required = false, .ptr = &datum_config.datum_pool_pass_workers, .default_bool = true },
{ .var_type = DATUM_CONF_BOOL, .category = "datum", .name = "pool_pass_full_users", .description = "Pass stratum miner usernames as raw usernames to the pool (use if putting multiple payout addresses on miners behind this gateway)",
Expand Down Expand Up @@ -221,8 +223,11 @@ int datum_config_parse_value(const T_DATUM_CONFIG_ITEM *c, json_t *item) {
return 1;
}
if (!json_is_string(item)) return -1;
strncpy((char *)c->ptr, json_string_value(item), c->max_string_len-1);
((char *)c->ptr)[c->max_string_len-1] = 0;
// check for overflow
int written = snprintf((char *)c->ptr, c->max_string_len, "%s", json_string_value(item));
if (written >= c->max_string_len) {
return -2;
}
return 1;
}

Expand Down Expand Up @@ -286,15 +291,22 @@ int datum_read_config(const char *conffile) {

// item might be valid
j = datum_config_parse_value(&datum_config_options[i], item);
if (j != 1) {
if (j == -1) {
DLOG_ERROR("Could not parse configuration option %s.%s. Type should be %s", datum_config_options[i].category, datum_config_options[i].name, (datum_config_options[i].var_type<DATUM_CONF_TYPES)?datum_conf_var_type_text[datum_config_options[i].var_type]:"UNKNOWN");
return -1;
} else if (j == -2) {
DLOG_ERROR("Configuration option %s.%s exceeds maximum length of %d", datum_config_options[i].category, datum_config_options[i].name, datum_config_options[i].max_string_len);
return -1;
}
}

if (config) {
json_decref(config);
}

// populate userpass for further reuse
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);

// pass configuration options to the logger
datum_logger_config(datum_config.clog_to_file, datum_config.clog_to_console, datum_config.clog_level_console, datum_config.clog_level_file, datum_config.clog_calling_function, datum_config.clog_to_stderr, datum_config.clog_rotate_daily, datum_config.clog_file);

Expand Down
5 changes: 3 additions & 2 deletions src/datum_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ typedef struct {

// Globally accessable config options
typedef struct {
char bitcoind_rpcuser[256];
char bitcoind_rpcpassword[256];
char bitcoind_rpcuser[128];
char bitcoind_rpcpassword[128];
char bitcoind_rpcurl[256];
int bitcoind_work_update_seconds;
bool bitcoind_notify_fallback;
Expand Down Expand Up @@ -126,6 +126,7 @@ typedef struct {
} global_config_t;

extern global_config_t datum_config;
extern char userpass[sizeof(datum_config.bitcoind_rpcuser) + sizeof(datum_config.bitcoind_rpcpassword)];

int datum_read_config(const char *conffile);
void datum_gateway_help(void);
Expand Down
25 changes: 14 additions & 11 deletions src/datum_stratum.c
Original file line number Diff line number Diff line change
Expand Up @@ -2071,7 +2071,6 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t
size_t i;
json_t *r;
CURL *tcurl;
char userpass[1024];
int ret = 0;
bool free_submitblock_req = false;
char *s = NULL;
Expand Down Expand Up @@ -2139,16 +2138,22 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t
// for added security. The thread above should already be submitting this block anyway.
if (datum_config.mining_save_submitblocks_dir[0] != 0) {
// save the block submission to a file named by the block's hash
FILE *f;
snprintf(userpass, sizeof(userpass), "%s/datum_submitblock_%s.json", datum_config.mining_save_submitblocks_dir, block_hash_hex);
f = fopen(userpass, "w");
if (!f) {
DLOG_ERROR("Could not open %s for writing submitblock record to disk: %s!", userpass, strerror(errno));
char submitblockpath[384];
int n = snprintf(submitblockpath, sizeof(submitblockpath), "%s/datum_submitblock_%s.json", datum_config.mining_save_submitblocks_dir, block_hash_hex);

if (n >= sizeof(submitblockpath)) {
DLOG_ERROR("Overflow in construction of submitblock path!");
} else {
if (!fwrite(submitblock_req, ptr-submitblock_req, 1, f)) {
DLOG_ERROR("Could not write to %s when writing submitblock record to disk: %s!", userpass, strerror(errno));
FILE *f;
f = fopen(submitblockpath, "w");
if (!f) {
DLOG_ERROR("Could not open %s for writing submitblock record to disk: %s!", submitblockpath, strerror(errno));
} else {
if (!fwrite(submitblock_req, ptr-submitblock_req, 1, f)) {
DLOG_ERROR("Could not write to %s when writing submitblock record to disk: %s!", submitblockpath, strerror(errno));
}
fclose(f);
}
fclose(f);
}
}

Expand All @@ -2161,8 +2166,6 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t
return 0;
}

snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);

// make the call!
r = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, submitblock_req);
curl_easy_cleanup(tcurl);
Expand Down
5 changes: 0 additions & 5 deletions src/datum_submitblock.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,8 @@ char submitblock_hash[256] = { 0 };
void preciousblock(CURL *curl, char *blockhash) {
json_t *json;
char rpc_data[384];
char userpass[1024];

// TODO: Move these types of things to the conf file
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);
snprintf(rpc_data, sizeof(rpc_data), "{\"method\":\"preciousblock\",\"params\":[\"%s\"],\"id\":1}", blockhash);
json = json_rpc_call(curl, datum_config.bitcoind_rpcurl, userpass, rpc_data);
if (!json) return;
Expand All @@ -65,13 +63,10 @@ void preciousblock(CURL *curl, char *blockhash) {
}

void datum_submitblock_doit(CURL *tcurl, char *url, const char *submitblock_req, const char *block_hash_hex) {
char userpass[1024];
json_t *r;
char *s = NULL;
// TODO: Move these types of things to the conf file
if (!url) {
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);

r = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, submitblock_req);
} else {
r = json_rpc_call(tcurl, url, NULL, submitblock_req);
Expand Down

0 comments on commit 90e6b02

Please sign in to comment.