4343#include <jansson.h>
4444
4545#include "datum_conf.h"
46+ #include "datum_jsonrpc.h"
4647#include "datum_utils.h"
4748#include "datum_sockets.h"
4849
@@ -52,10 +53,12 @@ const char *datum_conf_var_type_text[] = { "N/A", "boolean", "integer", "string"
5253
5354const T_DATUM_CONFIG_ITEM datum_config_options [] = {
5455 // Bitcoind configs
56+ { .var_type = DATUM_CONF_STRING , .category = "bitcoind" , .name = "rpccookiefile" , .description = "Path to file to read RPC cookie from, for communication with local bitcoind." ,
57+ .required = false, .ptr = datum_config .bitcoind_rpccookiefile , .default_string [0 ] = "" , .max_string_len = sizeof (datum_config .bitcoind_rpccookiefile ) },
5558 { .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 = sizeof (datum_config .bitcoind_rpcuser ) },
59+ .required = false , .ptr = datum_config .bitcoind_rpcuser , . default_string [ 0 ] = "" , .max_string_len = sizeof (datum_config .bitcoind_rpcuser ) },
5760 { .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 = sizeof (datum_config .bitcoind_rpcpassword ) },
61+ .required = false , .ptr = datum_config .bitcoind_rpcpassword , . default_string [ 0 ] = "" , .max_string_len = sizeof (datum_config .bitcoind_rpcpassword ) },
5962 { .var_type = DATUM_CONF_STRING , .category = "bitcoind" , .name = "rpcurl" , .description = "RPC URL for communication with local bitcoind. (GBT Template Source)" ,
6063 .required = true, .ptr = datum_config .bitcoind_rpcurl , .max_string_len = sizeof (datum_config .bitcoind_rpcurl ) },
6164 { .var_type = DATUM_CONF_INT , .category = "bitcoind" , .name = "work_update_seconds" , .description = "How many seconds between normal work updates? (5-120, 40 suggested)" ,
@@ -150,6 +153,21 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
150153
151154#define NUM_CONFIG_ITEMS (sizeof(datum_config_options) / sizeof(datum_config_options[0]))
152155
156+ const T_DATUM_CONFIG_ITEM * datum_config_get_option_info (const char * const category , const size_t category_len , const char * const name , const size_t name_len ) {
157+ for (size_t i = 0 ; i < NUM_CONFIG_ITEMS ; ++ i ) {
158+ if (strncmp (category , datum_config_options [i ].category , category_len )) continue ;
159+ if (datum_config_options [i ].category [category_len ]) continue ;
160+ if (strncmp (name , datum_config_options [i ].name , name_len )) continue ;
161+ if (datum_config_options [i ].name [name_len ]) continue ;
162+ return & datum_config_options [i ];
163+ }
164+ return NULL ;
165+ }
166+
167+ const T_DATUM_CONFIG_ITEM * datum_config_get_option_info2 (const char * const category , const char * const name ) {
168+ return datum_config_get_option_info (category , strlen (category ), name , strlen (name ));
169+ }
170+
153171json_t * load_json_from_file (const char * file_path ) {
154172 json_error_t error ;
155173 json_t * root = json_load_file (file_path , 0 , & error );
@@ -254,6 +272,11 @@ int datum_config_parse_value(const T_DATUM_CONFIG_ITEM *c, json_t *item) {
254272 return -1 ;
255273}
256274
275+ static void datum_config_opt_missing_error (const T_DATUM_CONFIG_ITEM * const opt ) {
276+ DLOG_ERROR ("Required configuration option (%s.%s) not found in config file:" , opt -> category , opt -> name );
277+ DLOG_ERROR ("--- Config description: \"%s\"" , opt -> description );
278+ }
279+
257280int datum_read_config (const char * conffile ) {
258281 json_t * config = NULL ;
259282 json_t * cat , * item ;
@@ -278,8 +301,7 @@ int datum_read_config(const char *conffile) {
278301 }
279302 if ((!item ) || json_is_null (item )) {
280303 if (datum_config_options [i ].required ) {
281- DLOG_ERROR ("Required configuration option (%s.%s) not found in config file:" , datum_config_options [i ].category , datum_config_options [i ].name );
282- DLOG_ERROR ("--- Config description: \"%s\"" , datum_config_options [i ].description );
304+ datum_config_opt_missing_error (& datum_config_options [i ]);
283305 return 0 ;
284306 } else {
285307 datum_config_set_default (& datum_config_options [i ]);
@@ -321,6 +343,24 @@ int datum_read_config(const char *conffile) {
321343 datum_config .bitcoind_work_update_seconds = 120 ;
322344 }
323345
346+ if (datum_config .bitcoind_rpcuser [0 ]) {
347+ if (!datum_config .bitcoind_rpcpassword [0 ]) {
348+ datum_config_opt_missing_error (datum_config_get_option_info2 ("bitcoind" , "rpcpassword" ));
349+ return 0 ;
350+ }
351+ snprintf (datum_config .bitcoind_rpcuserpass , sizeof (datum_config .bitcoind_rpcuserpass ), "%s:%s" , datum_config .bitcoind_rpcuser , datum_config .bitcoind_rpcpassword );
352+ } else if (datum_config .bitcoind_rpccookiefile [0 ]) {
353+ update_rpc_cookie (& datum_config );
354+ } else {
355+ const T_DATUM_CONFIG_ITEM * opt ;
356+ DLOG_ERROR ("Either bitcoind.rpcuser (and bitcoind.rpcpassword) or bitcoind.rpccookiefile is required." );
357+ opt = datum_config_get_option_info2 ("bitcoind" , "rpcuser" );
358+ DLOG_ERROR ("--- Config description for %s.%s: \"%s\"" , opt -> category , opt -> name , opt -> description );
359+ opt = datum_config_get_option_info2 ("bitcoind" , "rpccookiefile" );
360+ DLOG_ERROR ("--- Config description for %s.%s: \"%s\"" , opt -> category , opt -> name , opt -> description );
361+ return 0 ;
362+ }
363+
324364 if (datum_config .stratum_v1_max_threads > MAX_THREADS ) {
325365 DLOG_FATAL ("Maximum threads must be less than %d." , MAX_THREADS );
326366 return 0 ;
0 commit comments