Skip to content

Commit f35cb70

Browse files
committed
- in order to stop populating userpass over and over again, populate 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
1 parent 96d3b1f commit f35cb70

File tree

6 files changed

+66
-38
lines changed

6 files changed

+66
-38
lines changed

src/datum_blocktemplates.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,6 @@ T_DATUM_TEMPLATE_DATA *datum_gbt_parser(json_t *gbt) {
331331

332332
void *datum_gateway_fallback_notifier(void *args) {
333333
CURL *tcurl = NULL;
334-
char userpass[1024];
335334
char req[512];
336335
char p1[72];
337336
p1[0] = 0;
@@ -345,8 +344,6 @@ void *datum_gateway_fallback_notifier(void *args) {
345344
}
346345
DLOG_DEBUG("Fallback notifier thread ready.");
347346

348-
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);
349-
350347
while(1) {
351348
snprintf(req, sizeof(req), "{\"jsonrpc\":\"1.0\",\"id\":\"%"PRIu64"\",\"method\":\"getbestblockhash\",\"params\":[]}", current_time_millis());
352349
gbbh = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, req);
@@ -383,7 +380,6 @@ void *datum_gateway_template_thread(void *args) {
383380
uint64_t i = 0;
384381
char gbt_req[1024];
385382
int j;
386-
char userpass[1024];
387383
T_DATUM_TEMPLATE_DATA *t;
388384
bool was_notified = false;
389385
int wnc = 0;
@@ -411,8 +407,6 @@ void *datum_gateway_template_thread(void *args) {
411407
char p1[72];
412408
p1[0] = 0;
413409

414-
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);
415-
416410
while(1) {
417411
i++;
418412

src/datum_conf.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,19 @@
4747
#include "datum_sockets.h"
4848

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

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

5355
const T_DATUM_CONFIG_ITEM datum_config_options[] = {
5456
// Bitcoind configs
5557
{ .var_type = DATUM_CONF_STRING, .category = "bitcoind", .name = "rpcuser", .description = "RPC username for communication with local bitcoind.",
56-
.required = true, .ptr = datum_config.bitcoind_rpcuser, .max_string_len = 128 },
58+
.required = true, .ptr = datum_config.bitcoind_rpcuser, .max_string_len = sizeof(datum_config.bitcoind_rpcuser) },
5759
{ .var_type = DATUM_CONF_STRING, .category = "bitcoind", .name = "rpcpassword", .description = "RPC password for communication with local bitcoind.",
58-
.required = true, .ptr = datum_config.bitcoind_rpcpassword, .max_string_len = 128 },
60+
.required = true, .ptr = datum_config.bitcoind_rpcpassword, .max_string_len = sizeof(datum_config.bitcoind_rpcpassword) },
5961
{ .var_type = DATUM_CONF_STRING, .category = "bitcoind", .name = "rpcurl", .description = "RPC URL for communication with local bitcoind. (GBT Template Source)",
60-
.required = true, .ptr = datum_config.bitcoind_rpcurl, .max_string_len = 128 },
62+
.required = true, .ptr = datum_config.bitcoind_rpcurl, .max_string_len = sizeof(datum_config.bitcoind_rpcurl) },
6163
{ .var_type = DATUM_CONF_INT, .category = "bitcoind", .name = "work_update_seconds", .description = "How many seconds between normal work updates? (5-120, 40 suggested)",
6264
.required = false, .ptr = &datum_config.bitcoind_work_update_seconds, .default_int = 40 },
6365
{ .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.",
@@ -93,23 +95,23 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
9395

9496
// mining settings
9597
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "pool_address", .description = "Bitcoin address used for mining rewards.",
96-
.required = true, .ptr = datum_config.mining_pool_address, .max_string_len = 128 },
98+
.required = true, .ptr = datum_config.mining_pool_address, .max_string_len = sizeof(datum_config.mining_pool_address) },
9799
{ .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)",
98-
.required = false, .ptr = datum_config.mining_coinbase_tag_primary, .default_string[0] = "DATUM Gateway", .max_string_len = 64 },
100+
.required = false, .ptr = datum_config.mining_coinbase_tag_primary, .default_string[0] = "DATUM Gateway", .max_string_len = sizeof(datum_config.mining_coinbase_tag_primary) },
99101
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "coinbase_tag_secondary", .description = "Text to have in the secondary coinbase tag (Short name/identifier)",
100-
.required = false, .ptr = datum_config.mining_coinbase_tag_secondary, .default_string[0] = "DATUM User", .max_string_len = 64 },
102+
.required = false, .ptr = datum_config.mining_coinbase_tag_secondary, .default_string[0] = "DATUM User", .max_string_len = sizeof(datum_config.mining_coinbase_tag_secondary) },
101103
{ .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.",
102104
.required = false, .ptr = &datum_config.coinbase_unique_id, .default_int = 4242 },
103105
{ .var_type = DATUM_CONF_STRING, .category = "mining", .name = "save_submitblocks_dir", .description = "Directory to save all submitted blocks to as submitblock JSON files",
104-
.required = false, .ptr = datum_config.mining_save_submitblocks_dir, .default_string[0] = "", .max_string_len = 256 },
106+
.required = false, .ptr = datum_config.mining_save_submitblocks_dir, .default_string[0] = "", .max_string_len = sizeof(datum_config.mining_save_submitblocks_dir) },
105107

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

110112
// extra block submissions list
111113
{ .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",
112-
.required = false, .ptr = datum_config.extra_block_submissions_urls[0], .max_string_len = 512 },
114+
.required = false, .ptr = datum_config.extra_block_submissions_urls[0], .max_string_len = sizeof(datum_config.extra_block_submissions_urls[0]) },
113115

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

132134
// datum options
133135
{ .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)",
134-
.required = false, .ptr = datum_config.datum_pool_host, .default_string[0] = "datum-beta1.mine.ocean.xyz", .max_string_len = 1023 },
136+
.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) },
135137
{ .var_type = DATUM_CONF_INT, .category = "datum", .name = "pool_port", .description = "Remote DATUM server port",
136138
.required = false, .ptr = &datum_config.datum_pool_port, .default_int = 28915 },
137139
{ .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.",
138-
.required = false, .ptr = datum_config.datum_pool_pubkey, .default_string[0] = "f21f2f0ef0aa1970468f22bad9bb7f4535146f8e4a8f646bebc93da3d89b1406f40d032f09a417d94dc068055df654937922d2c89522e3e8f6f0e649de473003", .max_string_len = 1023 },
140+
.required = false, .ptr = datum_config.datum_pool_pubkey, .default_string[0] = "f21f2f0ef0aa1970468f22bad9bb7f4535146f8e4a8f646bebc93da3d89b1406f40d032f09a417d94dc068055df654937922d2c89522e3e8f6f0e649de473003", .max_string_len = sizeof(datum_config.datum_pool_pubkey) },
139141
{ .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)",
140142
.required = false, .ptr = &datum_config.datum_pool_pass_workers, .default_bool = true },
141143
{ .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)",
@@ -221,8 +223,11 @@ int datum_config_parse_value(const T_DATUM_CONFIG_ITEM *c, json_t *item) {
221223
return 1;
222224
}
223225
if (!json_is_string(item)) return -1;
224-
strncpy((char *)c->ptr, json_string_value(item), c->max_string_len-1);
225-
((char *)c->ptr)[c->max_string_len-1] = 0;
226+
// check for overflow
227+
int written = snprintf((char *)c->ptr, c->max_string_len, "%s", json_string_value(item));
228+
if (written >= c->max_string_len) {
229+
return -2;
230+
}
226231
return 1;
227232
}
228233

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

287292
// item might be valid
288293
j = datum_config_parse_value(&datum_config_options[i], item);
289-
if (j != 1) {
294+
if (j == -1) {
290295
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");
296+
return -1;
297+
} else if (j == -2) {
298+
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);
299+
return -1;
291300
}
292301
}
293302

294303
if (config) {
295304
json_decref(config);
296305
}
297306

307+
// populate userpass for further reuse
308+
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);
309+
298310
// pass configuration options to the logger
299311
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);
300312

src/datum_conf.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ typedef struct {
6767

6868
// Globally accessable config options
6969
typedef struct {
70-
char bitcoind_rpcuser[256];
71-
char bitcoind_rpcpassword[256];
70+
char bitcoind_rpcuser[128];
71+
char bitcoind_rpcpassword[128];
7272
char bitcoind_rpcurl[256];
7373
int bitcoind_work_update_seconds;
7474
bool bitcoind_notify_fallback;
@@ -126,6 +126,7 @@ typedef struct {
126126
} global_config_t;
127127

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

130131
int datum_read_config(const char *conffile);
131132
void datum_gateway_help(void);

src/datum_stratum.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,7 +2071,6 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t
20712071
size_t i;
20722072
json_t *r;
20732073
CURL *tcurl;
2074-
char userpass[1024];
20752074
int ret = 0;
20762075
bool free_submitblock_req = false;
20772076
char *s = NULL;
@@ -2139,16 +2138,22 @@ int assembleBlockAndSubmit(uint8_t *block_header, uint8_t *coinbase_txn, size_t
21392138
// for added security. The thread above should already be submitting this block anyway.
21402139
if (datum_config.mining_save_submitblocks_dir[0] != 0) {
21412140
// save the block submission to a file named by the block's hash
2142-
FILE *f;
2143-
snprintf(userpass, sizeof(userpass), "%s/datum_submitblock_%s.json", datum_config.mining_save_submitblocks_dir, block_hash_hex);
2144-
f = fopen(userpass, "w");
2145-
if (!f) {
2146-
DLOG_ERROR("Could not open %s for writing submitblock record to disk: %s!", userpass, strerror(errno));
2141+
char submitblockpath[384];
2142+
int n = snprintf(submitblockpath, sizeof(submitblockpath), "%s/datum_submitblock_%s.json", datum_config.mining_save_submitblocks_dir, block_hash_hex);
2143+
2144+
if (n >= sizeof(submitblockpath)) {
2145+
DLOG_ERROR("Overflow in construction of submitblock path!");
21472146
} else {
2148-
if (!fwrite(submitblock_req, ptr-submitblock_req, 1, f)) {
2149-
DLOG_ERROR("Could not write to %s when writing submitblock record to disk: %s!", userpass, strerror(errno));
2147+
FILE *f;
2148+
f = fopen(submitblockpath, "w");
2149+
if (!f) {
2150+
DLOG_ERROR("Could not open %s for writing submitblock record to disk: %s!", submitblockpath, strerror(errno));
2151+
} else {
2152+
if (!fwrite(submitblock_req, ptr-submitblock_req, 1, f)) {
2153+
DLOG_ERROR("Could not write to %s when writing submitblock record to disk: %s!", submitblockpath, strerror(errno));
2154+
}
2155+
fclose(f);
21502156
}
2151-
fclose(f);
21522157
}
21532158
}
21542159

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

2164-
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);
2165-
21662169
// make the call!
21672170
r = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, submitblock_req);
21682171
curl_easy_cleanup(tcurl);

src/datum_submitblock.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,8 @@ char submitblock_hash[256] = { 0 };
5252
void preciousblock(CURL *curl, char *blockhash) {
5353
json_t *json;
5454
char rpc_data[384];
55-
char userpass[1024];
5655

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

6765
void datum_submitblock_doit(CURL *tcurl, char *url, const char *submitblock_req, const char *block_hash_hex) {
68-
char userpass[1024];
6966
json_t *r;
7067
char *s = NULL;
7168
// TODO: Move these types of things to the conf file
7269
if (!url) {
73-
snprintf(userpass, sizeof(userpass), "%s:%s", datum_config.bitcoind_rpcuser, datum_config.bitcoind_rpcpassword);
74-
7570
r = json_rpc_call(tcurl, datum_config.bitcoind_rpcurl, userpass, submitblock_req);
7671
} else {
7772
r = json_rpc_call(tcurl, url, NULL, submitblock_req);

src/dg.log

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2024-12-15 19:00:08.570 [ datum_logger_thread] DEBUG: Logging thread started! (Approximately 32 MB of RAM allocated for up to 116507 entries per cycle)
2+
2024-12-15 19:00:08.570 [ main] INFO: Waiting on DATUM server... 15
3+
2024-12-15 19:00:08.570 [ datum_coinbaser_thread] DEBUG: Coinbaser thread active
4+
2024-12-15 19:00:08.570 [ datum_api_thread] INFO: API listening on port 13335
5+
2024-12-15 19:00:08.573 [ datum_protocol_send_hello] DEBUG: Signing handshake 317 bytes
6+
2024-12-15 19:00:08.573 [ datum_protocol_send_hello] DEBUG: Sending handshake init (429 bytes)
7+
2024-12-15 19:00:08.862 [ datum_protocol_handshake_response] DEBUG: Handshake response received.
8+
2024-12-15 19:00:08.862 [ datum_protocol_handshake_response] INFO: DATUM Server MOTD: DATUM Prime - v0.2 - "They aint gonna sink this battleship, no way"
9+
2024-12-15 19:00:08.863 [ datum_protocol_client_configure] DEBUG: client configuration cmd received from DATUM server
10+
2024-12-15 19:00:08.863 [ datum_protocol_client_configure] DEBUG: DATUM Pool Payout Scriptsig: (len 23) a914413b5901fe4e591c95405fd446b5b002da575bf087
11+
2024-12-15 19:00:08.863 [ datum_protocol_client_configure] DEBUG: DATUM Pool Coinbase Tag: "< OCEAN.XYZ >"
12+
2024-12-15 19:00:08.863 [ datum_protocol_client_configure] DEBUG: DATUM Pool Prime ID: 5d969e58
13+
2024-12-15 19:00:08.863 [ datum_protocol_client_configure] DEBUG: DATUM Pool Min Diff: 131072
14+
2024-12-15 19:00:09.570 [ main] DEBUG: Starting template fetcher thread
15+
2024-12-15 19:00:09.570 [ main] DEBUG: Starting Stratum v1 server
16+
2024-12-15 19:00:09.571 [ datum_stratum_v1_socket_server] DEBUG: Stratum V1 server startup
17+
2024-12-15 19:00:09.571 [ datum_template_init] DEBUG: Allocated 555 MB of RAM for template memory
18+
2024-12-15 19:00:09.571 [ datum_gateway_template_thread] DEBUG: Starting fallback block notifier
19+
2024-12-15 19:00:09.571 [ datum_gateway_template_thread] DEBUG: Template fetcher thread ready.
20+
2024-12-15 19:00:09.571 [ datum_stratum_v1_socket_server] DEBUG: Starting submitblock thread
21+
2024-12-15 19:00:09.571 [ datum_stratum_v1_socket_server] DEBUG: Waiting for our first job before starting listening server...
22+
2024-12-15 19:00:09.571 [ datum_gateway_fallback_notifier] DEBUG: Fallback notifier thread ready.
23+
2024-12-15 19:00:09.571 [ datum_submitblock_thread] DEBUG: Submitblock thread active

0 commit comments

Comments
 (0)