diff --git a/pool/base.php b/pool/base.php
index 4f94e55f..1c9824f2 100644
--- a/pool/base.php
+++ b/pool/base.php
@@ -238,7 +238,7 @@ function dbd($data, $user)
#
function dbdown()
{
- gopage(NULL, 'dbd', 'dbd', def_menu(), '', '', true, false, false);
+ gopage(NULL, NULL, 'dbd', 'dbd', def_menu(), '', '', true, false, false);
}
#
function syse($data, $user)
@@ -248,7 +248,7 @@ function syse($data, $user)
#
function syserror()
{
- gopage(NULL, 'syse', 'syse', def_menu(), '', '', true, false, false);
+ gopage(NULL, NULL, 'syse', 'syse', def_menu(), '', '', true, false, false);
}
#
function f404($data)
@@ -258,10 +258,10 @@ function f404($data)
#
function do404()
{
- gopage(NULL, 'f404', 'f404', def_menu(), '', '', true, false, false);
+ gopage(NULL, NULL, 'f404', 'f404', def_menu(), '', '', true, false, false);
}
#
-function showPage($page, $menu, $name, $user)
+function showPage($info, $page, $menu, $name, $user)
{
# If you are doing development, use without '@'
# Then switch to '@' when finished
@@ -270,14 +270,14 @@ function showPage($page, $menu, $name, $user)
$fun = 'show_' . $page;
if (function_exists($fun))
- $fun($page, $menu, $name, $user);
+ $fun($info, $page, $menu, $name, $user);
else
do404();
}
#
function showIndex()
{
- showPage('index', def_menu(), '', false);
+ showPage(NULL, 'index', def_menu(), '', false);
}
#
function offline()
@@ -286,7 +286,7 @@ function offline()
{
$ip = $_SERVER['REMOTE_ADDR'];
if ($ip != '192.168.1.666')
- gopage(NULL, file_get_contents('./maintenance.txt'),
+ gopage(NULL, NULL, file_get_contents('./maintenance.txt'),
'offline', NULL, '', '', false, false, false);
}
}
diff --git a/pool/db.php b/pool/db.php
index f8764876..02028a90 100644
--- a/pool/db.php
+++ b/pool/db.php
@@ -180,7 +180,17 @@ function userSettings($user, $email = null, $addr = null, $pass = null)
$flds['email'] = $email;
if ($addr != null)
{
- $flds['address'] = $addr;
+ $rows = count($addr);
+ $i = 0;
+ foreach ($addr as $ar)
+ {
+ $flds['address:'.$i] = $ar['addr'];
+ // optional - missing = use default
+ if (isset($ar['ratio']))
+ $flds['ratio:'.$i] = $ar['ratio'];
+ $i++;
+ }
+ $flds['rows'] = $rows;
$tmo = 3; # 3x the timeout
}
if ($pass != null)
diff --git a/pool/page.php b/pool/page.php
index 2f335fcf..64b095eb 100644
--- a/pool/page.php
+++ b/pool/page.php
@@ -88,6 +88,8 @@ function pghead($script_marker, $name)
$head .= "
';
+ }
$pg .= makeForm('settings');
$pg .= '';
@@ -101,10 +104,14 @@ function dosettings($data, $user)
$check = true;
break;
case 'Address':
- $addr = getparam('baddr', false);
- $pass = getparam('pass', false);
- $ans = userSettings($user, null, $addr, $pass);
- $check = true;
+ if (!isset($data['info']['u_multiaddr']))
+ {
+ $addr = getparam('baddr', false);
+ $addrarr = array(array('addr' => $addr));
+ $pass = getparam('pass', false);
+ $ans = userSettings($user, null, $addrarr, $pass);
+ $check = true;
+ }
break;
case 'Password':
$oldpass = getparam('oldpass', false);
@@ -139,17 +146,18 @@ function dosettings($data, $user)
$email = $ans['email'];
else
$email = '';
- if (isset($ans['addr']))
- $addr = $ans['addr'];
+ // Use the first one - updating will expire all others
+ if (isset($ans['rows']) and $ans['rows'] > 0)
+ $addr = $ans['addr:0'];
else
$addr = '';
$pg = settings($data, $user, $email, $addr, $err);
return $pg;
}
#
-function show_settings($page, $menu, $name, $user)
+function show_settings($info, $page, $menu, $name, $user)
{
- gopage(NULL, 'dosettings', $page, $menu, $name, $user);
+ gopage($info, NULL, 'dosettings', $page, $menu, $name, $user);
}
#
?>
diff --git a/pool/page_stats.php b/pool/page_stats.php
index 203de795..90768813 100644
--- a/pool/page_stats.php
+++ b/pool/page_stats.php
@@ -99,9 +99,9 @@ function dostats($data, $user)
return $pg;
}
#
-function show_stats($page, $menu, $name, $user)
+function show_stats($info, $page, $menu, $name, $user)
{
- gopage(NULL, 'dostats', $page, $menu, $name, $user);
+ gopage($info, NULL, 'dostats', $page, $menu, $name, $user);
}
#
?>
diff --git a/pool/page_userset.php b/pool/page_userset.php
index 9764fa5f..ae4b382c 100644
--- a/pool/page_userset.php
+++ b/pool/page_userset.php
@@ -92,9 +92,9 @@ function douserset($data, $user)
return $pg;
}
#
-function show_userset($page, $menu, $name, $user)
+function show_userset($info, $page, $menu, $name, $user)
{
- gopage(NULL, 'douserset', $page, $menu, $name, $user);
+ gopage($info, NULL, 'douserset', $page, $menu, $name, $user);
}
#
?>
diff --git a/pool/page_workers.php b/pool/page_workers.php
index 938aee9a..dcbfa46c 100644
--- a/pool/page_workers.php
+++ b/pool/page_workers.php
@@ -188,9 +188,9 @@ function doworkers($data, $user)
return $pg;
}
#
-function show_workers($page, $menu, $name, $user)
+function show_workers($info, $page, $menu, $name, $user)
{
- gopage(NULL, 'doworkers', $page, $menu, $name, $user);
+ gopage($info, NULL, 'doworkers', $page, $menu, $name, $user);
}
#
?>
diff --git a/pool/page_workmgt.php b/pool/page_workmgt.php
index 4cea1569..e7ad249a 100644
--- a/pool/page_workmgt.php
+++ b/pool/page_workmgt.php
@@ -86,9 +86,9 @@ function doworkmgt($data, $user)
return $pg;
}
#
-function show_workmgt($page, $menu, $name, $user)
+function show_workmgt($info, $page, $menu, $name, $user)
{
- gopage(NULL, 'doworkmgt', $page, $menu, $name, $user);
+ gopage($info, NULL, 'doworkmgt', $page, $menu, $name, $user);
}
#
?>
diff --git a/pool/prime.php b/pool/prime.php
index c50c69f7..af2bf796 100644
--- a/pool/prime.php
+++ b/pool/prime.php
@@ -8,6 +8,12 @@ include_once('base.php');
#
function process($p, $user, $menu)
{
+ $info = homeInfo($user);
+ if (is_array($info) && isset($info['u_multiaddr']))
+ {
+ if (isset($menu['Account']))
+ $menu['Account']['Addresses'] = 'addrmgt';
+ }
if ($user == 'Kano' || $user == 'ckolivas' || $user == 'wvr2' || $user == 'aphorise')
{
$menu['Admin']['ckp'] = 'ckp';
@@ -26,9 +32,9 @@ function process($p, $user, $menu)
}
if ($page === '')
- showPage('index', $menu, '', $user);
+ showPage($info, 'index', $menu, '', $user);
else
- showPage($page, $menu, $n, $user);
+ showPage($info, $page, $menu, $n, $user);
}
#
function def_menu()
@@ -80,11 +86,11 @@ function check()
{
$p = getparam('k', true);
if ($p == 'reset')
- showPage('reset', $dmenu, '', $who);
+ showPage(NULL, 'reset', $dmenu, '', $who);
else
{
if (requestRegister() == true)
- showPage('reg', $dmenu, '', $who);
+ showPage(NULL, 'reg', $dmenu, '', $who);
else
{
$p = getparam('k', true);
diff --git a/pool/socket.php b/pool/socket.php
index 46f96d69..202dc9c9 100644
--- a/pool/socket.php
+++ b/pool/socket.php
@@ -9,7 +9,7 @@ function socktmo($socket, $factor)
$factor = 1;
# on a slower server increase this base value
- $tmo = 2;
+ $tmo = 8;
$usetmo = $tmo * $factor;
$sec = floor($usetmo);
diff --git a/src/ckdb.c b/src/ckdb.c
index 71e5eed3..22a9d01b 100644
--- a/src/ckdb.c
+++ b/src/ckdb.c
@@ -1070,9 +1070,9 @@ static void free_workinfo_data(K_ITEM *item)
DATA_WORKINFO(workinfo, item);
if (workinfo->transactiontree)
- free(workinfo->transactiontree);
+ FREENULL(workinfo->transactiontree);
if (workinfo->merklehash)
- free(workinfo->merklehash);
+ FREENULL(workinfo->merklehash);
}
static void free_sharesummary_data(K_ITEM *item)
@@ -1082,8 +1082,7 @@ static void free_sharesummary_data(K_ITEM *item)
DATA_SHARESUMMARY(sharesummary, item);
if (sharesummary->workername) {
LIST_MEM_SUB(sharesummary_free, sharesummary->workername);
- free(sharesummary->workername);
- sharesummary->workername = NULL;
+ FREENULL(sharesummary->workername);
}
SET_CREATEBY(sharesummary_free, sharesummary->createby, EMPTY);
SET_CREATECODE(sharesummary_free, sharesummary->createcode, EMPTY);
@@ -1099,7 +1098,7 @@ static void free_optioncontrol_data(K_ITEM *item)
DATA_OPTIONCONTROL(optioncontrol, item);
if (optioncontrol->optionvalue)
- free(optioncontrol->optionvalue);
+ FREENULL(optioncontrol->optionvalue);
}
static void free_markersummary_data(K_ITEM *item)
@@ -1108,7 +1107,7 @@ static void free_markersummary_data(K_ITEM *item)
DATA_MARKERSUMMARY(markersummary, item);
if (markersummary->workername)
- free(markersummary->workername);
+ FREENULL(markersummary->workername);
SET_CREATEBY(markersummary_free, markersummary->createby, EMPTY);
SET_CREATECODE(markersummary_free, markersummary->createcode, EMPTY);
SET_CREATEINET(markersummary_free, markersummary->createinet, EMPTY);
@@ -1123,9 +1122,9 @@ static void free_workmarkers_data(K_ITEM *item)
DATA_WORKMARKERS(workmarkers, item);
if (workmarkers->poolinstance)
- free(workmarkers->poolinstance);
+ FREENULL(workmarkers->poolinstance);
if (workmarkers->description)
- free(workmarkers->description);
+ FREENULL(workmarkers->description);
}
static void free_marks_data(K_ITEM *item)
@@ -1134,11 +1133,11 @@ static void free_marks_data(K_ITEM *item)
DATA_MARKS(marks, item);
if (marks->poolinstance && marks->poolinstance != EMPTY)
- free(marks->poolinstance);
+ FREENULL(marks->poolinstance);
if (marks->description && marks->description != EMPTY)
- free(marks->description);
+ FREENULL(marks->description);
if (marks->extra && marks->extra != EMPTY)
- free(marks->extra);
+ FREENULL(marks->extra);
}
#define FREE_TREE(_tree) \
@@ -1473,7 +1472,7 @@ static enum cmd_values breakdown(K_TREE **trf_root, K_STORE **trf_store,
STRNCPY(transfer->name, json_key);
if (!ok || find_in_ktree(*trf_root, item, cmp_transfer, ctx)) {
if (transfer->mvalue != transfer->svalue)
- free(transfer->mvalue);
+ FREENULL(transfer->mvalue);
k_add_head(transfer_free, item);
} else {
*trf_root = add_to_ktree(*trf_root, item, cmp_transfer);
@@ -1505,7 +1504,7 @@ static enum cmd_values breakdown(K_TREE **trf_root, K_STORE **trf_store,
if (find_in_ktree(*trf_root, item, cmp_transfer, ctx)) {
if (transfer->mvalue != transfer->svalue)
- free(transfer->mvalue);
+ FREENULL(transfer->mvalue);
k_add_head(transfer_free, item);
} else {
*trf_root = add_to_ktree(*trf_root, item, cmp_transfer);
@@ -1946,7 +1945,7 @@ static void summarise_userstats()
//upgrade = false;
if (error[0])
- LOGERR(error);
+ LOGERR("%s", error);
}
if (locked) {
@@ -2016,7 +2015,8 @@ static void *logger(__maybe_unused void *arg)
K_ITEM *lq_item;
LOGQUEUE *lq;
char buf[128];
- tv_t now;
+ tv_t now, then;
+ int count;
pthread_detach(pthread_self());
@@ -2037,7 +2037,7 @@ static void *logger(__maybe_unused void *arg)
while (lq_item) {
DATA_LOGQUEUE(lq, lq_item);
LOGFILE(lq->msg);
- free(lq->msg);
+ FREENULL(lq->msg);
K_WLOCK(logqueue_free);
k_add_head(logqueue_free, lq_item);
@@ -2051,18 +2051,26 @@ static void *logger(__maybe_unused void *arg)
}
K_WLOCK(logqueue_free);
+ count = logqueue_store->count;
setnow(&now);
snprintf(buf, sizeof(buf), "logstopping.%d.%ld,%ld",
- logqueue_store->count,
- now.tv_sec, now.tv_usec);
+ count, now.tv_sec, now.tv_usec);
LOGFILE(buf);
- if (logqueue_store->count)
+ if (count)
LOGERR("%s", buf);
lq_item = logqueue_store->head;
+ copy_tv(&then, &now);
while (lq_item) {
DATA_LOGQUEUE(lq, lq_item);
LOGFILE(lq->msg);
- free(lq->msg);
+ FREENULL(lq->msg);
+ count--;
+ setnow(&now);
+ if ((now.tv_sec - then.tv_sec) > 10) {
+ snprintf(buf, sizeof(buf), "logging ... %d", count);
+ LOGERR("%s", buf);
+ copy_tv(&then, &now);
+ }
lq_item = lq_item->next;
}
K_WUNLOCK(logqueue_free);
@@ -2073,6 +2081,7 @@ static void *logger(__maybe_unused void *arg)
snprintf(buf, sizeof(buf), "logstop.%ld,%ld",
now.tv_sec, now.tv_usec);
LOGFILE(buf);
+ LOGWARNING("%s", buf);
return NULL;
}
@@ -2320,8 +2329,7 @@ static void *socketer(__maybe_unused void *arg)
rep = malloc(siz);
snprintf(rep, siz, "%s.%ld.%s", id, now.tv_sec, ans);
send_unix_msg(sockd, rep);
- free(ans);
- ans = NULL;
+ FREENULL(ans);
switch (cmdnum) {
case CMD_AUTH:
STORELASTREPLY(auth);
@@ -2385,8 +2393,7 @@ static void *socketer(__maybe_unused void *arg)
rep = malloc(siz);
snprintf(rep, siz, "%s.%ld.%s", id, now.tv_sec, ans);
send_unix_msg(sockd, rep);
- free(ans);
- ans = NULL;
+ FREENULL(ans);
if (cmdnum == CMD_DSP)
free(rep);
else {
@@ -2419,10 +2426,8 @@ static void *socketer(__maybe_unused void *arg)
rep = malloc(siz);
snprintf(rep, siz, "%s.%ld.%s", id, now.tv_sec, ans);
send_unix_msg(sockd, rep);
- free(ans);
- ans = NULL;
- free(rep);
- rep = NULL;
+ FREENULL(ans);
+ FREENULL(rep);
}
break;
// Always queue (ok.queued)
@@ -2494,7 +2499,7 @@ static void *socketer(__maybe_unused void *arg)
while (item) {
DATA_TRANSFER(transfer, item);
if (transfer->mvalue != transfer->svalue)
- free(transfer->mvalue);
+ FREENULL(transfer->mvalue);
item = item->next;
}
K_WLOCK(transfer_free);
@@ -2622,7 +2627,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
while (item) {
DATA_TRANSFER(transfer, item);
if (transfer->mvalue != transfer->svalue)
- free(transfer->mvalue);
+ FREENULL(transfer->mvalue);
item = item->next;
}
K_WLOCK(transfer_free);
@@ -2641,6 +2646,73 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
#define MAX_READ (10 * 1024 * 1024)
static char *reload_buf;
+static bool logline(char *buf, int siz, FILE *fp, char *filename)
+{
+ char *ret;
+
+ ret = fgets_unlocked(buf, siz, fp);
+ if (!ret && ferror(fp)) {
+ int err = errno;
+ quithere(1, "Read failed on %s (%d) '%s'",
+ filename, err, strerror(err));
+ }
+ if (ret)
+ return true;
+ else
+ return false;
+}
+
+static struct decomp {
+ char *ext;
+ char *fmt;
+} dec_list[] = {
+ { ".bz2", "bzcat -q '%s'" },
+ { ".gz", "zcat -q '%s'" },
+ { ".lrz", "lrzip -q -d -o - '%s'" },
+ { NULL, NULL }
+};
+
+static bool logopen(char **filename, FILE **fp, bool *apipe)
+{
+ char buf[1024];
+ char *name;
+ size_t len;
+ int i;
+
+ *apipe = false;
+
+ *fp = NULL;
+ *fp = fopen(*filename, "re");
+ if (*fp)
+ return true;
+
+ for (i = 0; dec_list[i].ext; i++) {
+ len = strlen(*filename) + strlen(dec_list[i].ext);
+ name = malloc(len + 1);
+ if (!name)
+ quithere(1, "(%d) OOM", (int)len);
+ strcpy(name, *filename);
+ strcat(name, dec_list[i].ext);
+ if (access(name, R_OK))
+ free(name);
+ else {
+ snprintf(buf, sizeof(buf), dec_list[i].fmt, name);
+ *fp = popen(buf, "re");
+ if (!(*fp)) {
+ int errn = errno;
+ quithere(1, "Failed to pipe (%d) \"%s\"",
+ errn, buf);
+ } else {
+ *apipe = true;
+ free(*filename);
+ *filename = name;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/* If the reload start file is missing and -r was specified correctly:
* touch the filename reported in "Failed to open 'filename'",
* if ckdb aborts at the beginning of the reload, then start again */
@@ -2652,7 +2724,7 @@ static bool reload_from(tv_t *start)
char *missingfirst = NULL, *missinglast = NULL;
int missing_count;
int processing;
- bool finished = false, matched = false, ret = true;
+ bool finished = false, matched = false, ret = true, ok, apipe = false;
char *filename = NULL;
uint64_t count, total;
tv_t now;
@@ -2672,8 +2744,7 @@ static bool reload_from(tv_t *start)
LOGWARNING("%s(): from %s (stamp %s)", __func__, buf, run);
filename = rotating_filename(restorefrom, reload_timestamp.tv_sec);
- fp = fopen(filename, "re");
- if (!fp)
+ if (!logopen(&filename, &fp, &apipe))
quithere(1, "Failed to open '%s'", filename);
setnow(&now);
@@ -2690,14 +2761,9 @@ static bool reload_from(tv_t *start)
processing++;
count = 0;
- while (!everyone_die && !matched && fgets_unlocked(reload_buf, MAX_READ, fp))
- matched = reload_line(conn, filename, ++count, reload_buf);
-
- if (ferror(fp)) {
- int err = errno;
- quithere(1, "Read failed on %s (%d) '%s'",
- filename, err, strerror(err));
- }
+ while (!everyone_die && !matched &&
+ logline(reload_buf, MAX_READ, fp, filename))
+ matched = reload_line(conn, filename, ++count, reload_buf);
LOGWARNING("%s(): %sread %"PRIu64" line%s from %s",
__func__,
@@ -2705,7 +2771,15 @@ static bool reload_from(tv_t *start)
count, count == 1 ? "" : "s",
filename);
total += count;
- fclose(fp);
+ if (apipe) {
+ pclose(fp);
+ if (count == 0) {
+ quithere(1, "ABORTING - No data returned from "
+ "compressed file \"%s\"",
+ filename);
+ }
+ } else
+ fclose(fp);
free(filename);
if (everyone_die || matched)
break;
@@ -2715,11 +2789,10 @@ static bool reload_from(tv_t *start)
break;
}
filename = rotating_filename(restorefrom, reload_timestamp.tv_sec);
- fp = fopen(filename, "re");
- if (!fp) {
+ ok = logopen(&filename, &fp, &apipe);
+ if (!ok) {
missingfirst = strdup(filename);
- free(filename);
- filename = NULL;
+ FREENULL(filename);
errno = 0;
missing_count = 1;
setnow(&now);
@@ -2736,26 +2809,23 @@ static bool reload_from(tv_t *start)
break;
}
filename = rotating_filename(restorefrom, reload_timestamp.tv_sec);
- fp = fopen(filename, "re");
- if (fp)
+ ok = logopen(&filename, &fp, &apipe);
+ if (ok)
break;
errno = 0;
if (missing_count++ > 1)
free(missinglast);
missinglast = strdup(filename);
- free(filename);
- filename = NULL;
+ FREENULL(filename);
}
if (missing_count == 1)
LOGWARNING("%s(): skipped %s", __func__, missingfirst+rflen);
else {
LOGWARNING("%s(): skipped %d files from %s to %s",
__func__, missing_count, missingfirst+rflen, missinglast+rflen);
- free(missinglast);
- missinglast = NULL;
+ FREENULL(missinglast);
}
- free(missingfirst);
- missingfirst = NULL;
+ FREENULL(missingfirst);
}
}
@@ -2783,10 +2853,7 @@ static bool reload_from(tv_t *start)
}
reloading = false;
-
- free(reload_buf);
- reload_buf = NULL;
-
+ FREENULL(reload_buf);
return ret;
}
@@ -2818,7 +2885,7 @@ static void process_queued(PGconn *conn, K_ITEM *wq_item)
while (item) {
DATA_TRANSFER(transfer, item);
if (transfer->mvalue != transfer->svalue)
- free(transfer->mvalue);
+ FREENULL(transfer->mvalue);
item = item->next;
}
K_WLOCK(transfer_free);
@@ -3150,7 +3217,7 @@ static void confirm_reload()
}
if (confirm_last_workinfoid == 0) {
LOGWARNING("%s(): there are no unconfirmed sharesummary records in the DB",
- __func__, buf);
+ __func__);
return;
}
@@ -3220,7 +3287,7 @@ static void confirm_reload()
// last from default
if (confirm_last_workinfoid < confirm_first_workinfoid) {
LOGWARNING("%s(): no unconfirmed sharesummary records before start",
- __func__, buf);
+ __func__);
return;
}
first_reason = "start range";
diff --git a/src/ckdb.h b/src/ckdb.h
index 9ed96f68..1beaf0eb 100644
--- a/src/ckdb.h
+++ b/src/ckdb.h
@@ -52,7 +52,7 @@
#define DB_VLOCK "1"
#define DB_VERSION "0.9.6"
-#define CKDB_VERSION DB_VERSION"-0.665"
+#define CKDB_VERSION DB_VERSION"-0.744"
#define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@@ -64,6 +64,13 @@
#define STRINT(x) STRINT2(x)
#define STRINT2(x) #x
+#define FREENULL(mem) do { \
+ if (mem) { \
+ free(mem); \
+ mem = NULL; \
+ } \
+ } while (0)
+
// So they can fit into a 1 byte flag field
#define TRUE_STR "Y"
#define FALSE_STR "N"
@@ -702,6 +709,9 @@ extern K_TREE *useratts_root;
extern K_LIST *useratts_free;
extern K_STORE *useratts_store;
+// This att means the user uses multiple % based payout addresses
+#define USER_MULTI_PAYOUT "PayAddresses"
+
// WORKERS
typedef struct workers {
int64_t workerid;
@@ -744,17 +754,21 @@ typedef struct paymentaddresses {
char payaddress[TXT_BIG+1];
int32_t payratio;
HISTORYDATECONTROLFIELDS;
+ bool match; // Non-db field
} PAYMENTADDRESSES;
#define ALLOC_PAYMENTADDRESSES 1024
#define LIMIT_PAYMENTADDRESSES 0
#define INIT_PAYMENTADDRESSES(_item) INIT_GENERIC(_item, paymentaddresses)
#define DATA_PAYMENTADDRESSES(_var, _item) DATA_GENERIC(_var, _item, paymentaddresses, true)
+#define DATA_PAYMENTADDRESSES_NULL(_var, _item) DATA_GENERIC(_var, _item, paymentaddresses, false)
extern K_TREE *paymentaddresses_root;
extern K_LIST *paymentaddresses_free;
extern K_STORE *paymentaddresses_store;
+#define PAYRATIODEF 1000000
+
// PAYMENTS
typedef struct payments {
int64_t paymentid;
@@ -857,6 +871,12 @@ typedef struct optioncontrol {
#error "START_POOL_HEIGHT must = (OPTIONCONTROL_HEIGHT+1)"
#endif
+/* If set, then cmd_auth() will create unknown users
+ * It will use the optionvalue as the hex sha256 password hash
+ * A blank or random/invalid hash will mean the accounts created
+ * are password locked, like an address account is */
+#define OPTIONCONTROL_AUTOADDUSER "AutoAddUser"
+
extern K_TREE *optioncontrol_root;
extern K_LIST *optioncontrol_free;
extern K_STORE *optioncontrol_store;
@@ -1540,7 +1560,9 @@ extern K_ITEM *new_default_worker(PGconn *conn, bool update, int64_t userid, cha
char *by, char *code, char *inet, tv_t *cd, K_TREE *trf_root);
extern void dsp_paymentaddresses(K_ITEM *item, FILE *stream);
extern cmp_t cmp_paymentaddresses(K_ITEM *a, K_ITEM *b);
-extern K_ITEM *find_paymentaddresses(int64_t userid);
+extern K_ITEM *find_paymentaddresses(int64_t userid, K_TREE_CTX *ctx);
+extern K_ITEM *find_one_payaddress(int64_t userid, char *payaddress, K_TREE_CTX *ctx);
+extern K_ITEM *find_any_payaddress(char *payaddress);
extern cmp_t cmp_payments(K_ITEM *a, K_ITEM *b);
extern cmp_t cmp_optioncontrol(K_ITEM *a, K_ITEM *b);
extern K_ITEM *find_optioncontrol(char *optionname, tv_t *now);
@@ -1682,9 +1704,9 @@ extern bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault,
char *idlenotificationtime, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root, bool check);
extern bool workers_fill(PGconn *conn);
-extern K_ITEM *paymentaddresses_set(PGconn *conn, int64_t userid, char *payaddress,
- char *by, char *code, char *inet, tv_t *cd,
- K_TREE *trf_root);
+extern bool paymentaddresses_set(PGconn *conn, int64_t userid, K_LIST *pa_store,
+ char *by, char *code, char *inet, tv_t *cd,
+ K_TREE *trf_root);
extern bool paymentaddresses_fill(PGconn *conn);
extern bool payments_fill(PGconn *conn);
extern bool idcontrol_add(PGconn *conn, char *idname, char *idvalue, char *by,
diff --git a/src/ckdb_btc.c b/src/ckdb_btc.c
index 7ede69e5..0523b164 100644
--- a/src/ckdb_btc.c
+++ b/src/ckdb_btc.c
@@ -329,7 +329,7 @@ void btc_blockstatus(BLOCKS *blocks)
len = strlen(blocks->blockhash);
if (len != SHA256SIZHEX) {
LOGERR("%s() invalid blockhash size %d (%d) for block %d",
- __func__, len, SHA256SIZHEX, blocks->height);
+ __func__, (int)len, SHA256SIZHEX, blocks->height);
/* So we don't keep repeating the message
* This should never happen */
diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c
index 1e9ac011..369d7a73 100644
--- a/src/ckdb_cmd.c
+++ b/src/ckdb_cmd.c
@@ -161,16 +161,21 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id,
__maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root)
{
- K_ITEM *i_username, *i_passwordhash, *i_address, *i_email, *u_item, *pa_item;
+ K_ITEM *i_username, *i_passwordhash, *i_rows, *i_address, *i_ratio;
+ K_ITEM *i_email, *u_item, *pa_item, *old_pa_item;
char *email, *address;
char reply[1024] = "";
size_t siz = sizeof(reply);
char tmp[1024];
- PAYMENTADDRESSES *paymentaddresses;
+ PAYMENTADDRESSES *row, *pa;
+ K_STORE *pa_store = NULL;
+ K_TREE_CTX ctx[1];
USERS *users;
char *reason = NULL;
char *answer = NULL;
size_t len, off;
+ int32_t ratio;
+ int rows, i;
bool ok;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@@ -206,18 +211,33 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id,
APPEND_REALLOC(answer, off, len, tmp);
K_RLOCK(paymentaddresses_free);
- pa_item = find_paymentaddresses(users->userid);
- K_RUNLOCK(paymentaddresses_free);
-
+ pa_item = find_paymentaddresses(users->userid, ctx);
+ rows = 0;
if (pa_item) {
- DATA_PAYMENTADDRESSES(paymentaddresses, pa_item);
- snprintf(tmp, sizeof(tmp), "addr=%s",
- paymentaddresses->payaddress);
- APPEND_REALLOC(answer, off, len, tmp);
- } else {
- snprintf(tmp, sizeof(tmp), "addr=");
- APPEND_REALLOC(answer, off, len, tmp);
+ DATA_PAYMENTADDRESSES(row, pa_item);
+ while (pa_item && CURRENT(&(row->expirydate)) &&
+ row->userid == users->userid) {
+ snprintf(tmp, sizeof(tmp), "addr:%d=%s%c",
+ rows, row->payaddress, FLDSEP);
+ APPEND_REALLOC(answer, off, len, tmp);
+ snprintf(tmp, sizeof(tmp), "ratio:%d=%d%c",
+ rows, row->payratio, FLDSEP);
+ APPEND_REALLOC(answer, off, len, tmp);
+ rows++;
+
+ pa_item = prev_in_ktree(ctx);
+ DATA_PAYMENTADDRESSES_NULL(row, pa_item);
+ }
}
+ K_RUNLOCK(paymentaddresses_free);
+
+ snprintf(tmp, sizeof(tmp), "rows=%d%cflds=%s%c",
+ rows, FLDSEP,
+ "addr,ratio", FLDSEP);
+ APPEND_REALLOC(answer, off, len, tmp);
+ snprintf(tmp, sizeof(tmp), "arn=%s%carp=%s",
+ "PaymentAddresses", FLDSEP, "");
+ APPEND_REALLOC(answer, off, len, tmp);
} else {
if (!check_hash(users, transfer_data(i_passwordhash))) {
reason = "Incorrect password";
@@ -235,29 +255,104 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id,
}
email = NULL;
}
- i_address = optional_name(trf_root, "address",
- ADDR_MIN_LEN,
- (char *)addrpatt,
- reply, siz);
- if (i_address)
- address = transfer_data(i_address);
- else {
- if (*reply) {
- reason = "Invalid address";
+
+ // address rows
+ i_rows = optional_name(trf_root, "rows",
+ 1, (char *)intpatt,
+ reply, siz);
+ if (!i_rows && *reply) {
+ // Exists, but invalid
+ reason = "System error";
+ goto struckout;
+ }
+ if (i_rows) {
+ rows = atoi(transfer_data(i_rows));
+ if (rows < 0) {
+ reason = "System error";
goto struckout;
}
- address = NULL;
+ if (rows > 0) {
+ pa_store = k_new_store(paymentaddresses_free);
+ K_WLOCK(paymentaddresses_free);
+ for (i = 0; i < rows; i++) {
+ snprintf(tmp, sizeof(tmp), "ratio:%d", i);
+ i_ratio = optional_name(trf_root, tmp,
+ 1, (char *)intpatt,
+ reply, siz);
+ if (*reply) {
+ K_WUNLOCK(paymentaddresses_free);
+ reason = "Invalid ratio";
+ goto struckout;
+ }
+ if (i_ratio)
+ ratio = atoi(transfer_data(i_ratio));
+ else
+ ratio = PAYRATIODEF;
+
+ /* 0 = expire/remove the address
+ * intpatt means it will be >= 0 */
+ if (ratio == 0)
+ continue;
+
+ snprintf(tmp, sizeof(tmp), "address:%d", i);
+ i_address = require_name(trf_root, tmp,
+ ADDR_MIN_LEN,
+ (char *)addrpatt,
+ reply, siz);
+ if (!i_address) {
+ K_WUNLOCK(paymentaddresses_free);
+ reason = "Invalid address";
+ goto struckout;
+ }
+ address = transfer_data(i_address);
+ pa_item = pa_store->head;
+ while (pa_item) {
+ DATA_PAYMENTADDRESSES(row, pa_item);
+ if (strcmp(row->payaddress, address) == 0) {
+ K_WUNLOCK(paymentaddresses_free);
+ reason = "Duplicate address";
+ goto struckout;
+ }
+ pa_item = pa_item->next;
+ }
+ pa_item = k_unlink_head(paymentaddresses_free);
+ DATA_PAYMENTADDRESSES(row, pa_item);
+ bzero(row, sizeof(*row));
+ STRNCPY(row->payaddress, address);
+ row->payratio = ratio;
+ k_add_head(pa_store, pa_item);
+ }
+ K_WUNLOCK(paymentaddresses_free);
+ }
}
+ /* If all addresses have a ratio of zero
+ * pa_store->count will be 0 */
if ((email == NULL || *email == '\0') &&
- (address == NULL || *address == '\0')) {
+ (pa_store == NULL || pa_store->count == 0)) {
reason = "Missing/Invalid value";
goto struckout;
}
- if (address && *address) {
- if (!btc_valid_address(address)) {
- reason = "Invalid BTC address";
- goto struckout;
+ if (pa_store && pa_store->count > 0) {
+ pa_item = pa_store->head;
+ while (pa_item) {
+ DATA_PAYMENTADDRESSES(row, pa_item);
+ // Only EVER validate addresses once ... for now
+ old_pa_item = find_any_payaddress(row->payaddress);
+ if (old_pa_item) {
+ /* This test effectively means that
+ * two users can never add the same
+ * payout address */
+ DATA_PAYMENTADDRESSES(pa, old_pa_item);
+ if (pa->userid != users->userid) {
+ reason = "Unavailable BTC address";
+ goto struckout;
+ }
+ } else if (!btc_valid_address(row->payaddress)) {
+ reason = "Invalid BTC address";
+ goto struckout;
+ }
+ pa_item = pa_item->next;
}
}
@@ -274,9 +369,9 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id,
}
}
- if (address && *address) {
+ if (pa_store && pa_store->count > 0) {
ok = paymentaddresses_set(conn, users->userid,
- address, by,
+ pa_store, by,
code, inet,
now, trf_root);
if (!ok) {
@@ -289,6 +384,15 @@ static char *cmd_userset(PGconn *conn, char *cmd, char *id,
}
struckout:
+ if (pa_store) {
+ if (pa_store->count) {
+ K_WLOCK(paymentaddresses_free);
+ k_list_transfer_to_head(pa_store, paymentaddresses_free);
+ K_WUNLOCK(paymentaddresses_free);
+ }
+ k_free_store(pa_store);
+ pa_store = NULL;
+ }
if (reason) {
snprintf(reply, siz, "ERR.%s", reason);
LOGERR("%s.%s.%s", cmd, id, reply);
@@ -1665,7 +1769,7 @@ awconf:
return strdup(reply);
}
- LOGERR("%s.bad.cmd %s", cmd);
+ LOGERR("%s.bad.cmd %s", id, cmd);
return strdup("bad.cmd");
}
@@ -1801,9 +1905,11 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
char reply[1024] = "";
size_t siz = sizeof(reply);
K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid;
- K_ITEM *i_enonce1, *i_useragent, *i_preauth;
+ K_ITEM *i_enonce1, *i_useragent, *i_preauth, *u_item, *oc_item;
USERS *users = NULL;
+ char *username;
WORKERS *workers = NULL;
+ OPTIONCONTROL *optioncontrol;
bool ok;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@@ -1816,6 +1922,7 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
i_username = require_name(trf_root, "username", 1, NULL, reply, siz);
if (!i_username)
return strdup(reply);
+ username = transfer_data(i_username);
i_workername = require_name(trf_root, "workername", 1, NULL, reply, siz);
if (!i_workername)
@@ -1837,8 +1944,23 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
if (!i_preauth)
i_preauth = &auth_preauth;
+ K_RLOCK(optioncontrol_free);
+ oc_item = find_optioncontrol(OPTIONCONTROL_AUTOADDUSER, cd);
+ K_RUNLOCK(optioncontrol_free);
+ if (oc_item) {
+ K_RLOCK(users_free);
+ u_item = find_users(username);
+ K_RUNLOCK(users_free);
+ if (!u_item) {
+ DATA_OPTIONCONTROL(optioncontrol, oc_item);
+ u_item = users_add(conn, username, EMPTY,
+ optioncontrol->optionvalue,
+ by, code, inet, cd, trf_root);
+ }
+ }
+
ok = auths_add(conn, transfer_data(i_poolinstance),
- transfer_data(i_username),
+ username,
transfer_data(i_workername),
transfer_data(i_clientid),
transfer_data(i_enonce1),
@@ -2031,6 +2153,7 @@ static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *notcd, K_TREE *trf_root)
{
K_ITEM *i_username, *u_item, *b_item, *p_item, *us_item, look;
+ K_ITEM *ua_item, *pa_item;
double u_hashrate5m, u_hashrate1hr;
char reply[1024], tmp[1024], *buf;
size_t siz = sizeof(reply);
@@ -2171,9 +2294,34 @@ static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id,
K_RUNLOCK(users_free);
}
+ // User info to add to or affect the web site display
+ if (u_item) {
+ DATA_USERS(users, u_item);
+ K_RLOCK(useratts_free);
+ ua_item = find_useratts(users->userid, USER_MULTI_PAYOUT);
+ K_RUNLOCK(useratts_free);
+ if (ua_item) {
+ snprintf(tmp, sizeof(tmp),
+ "u_multiaddr=1%c", FLDSEP);
+ APPEND_REALLOC(buf, off, len, tmp);
+ }
+ if (!(*(users->emailaddress))) {
+ snprintf(tmp, sizeof(tmp),
+ "u_noemail=1%c", FLDSEP);
+ APPEND_REALLOC(buf, off, len, tmp);
+ }
+ K_RLOCK(paymentaddresses_free);
+ pa_item = find_paymentaddresses(users->userid, ctx);
+ K_RUNLOCK(paymentaddresses_free);
+ if (!pa_item) {
+ snprintf(tmp, sizeof(tmp),
+ "u_nopayaddr=1%c", FLDSEP);
+ APPEND_REALLOC(buf, off, len, tmp);
+ }
+ }
+
has_uhr = false;
if (p_item && u_item) {
- DATA_USERS(users, u_item);
K_TREE *userstats_workername_root = new_ktree();
u_hashrate5m = u_hashrate1hr = 0.0;
u_elapsed = -1;
@@ -2740,7 +2888,7 @@ static char *cmd_setopts(PGconn *conn, char *cmd, char *id,
ExecStatusType rescode;
PGresult *res;
bool conned = false;
- K_ITEM *t_item, *oc_item = NULL;
+ K_ITEM *t_item, *oc_item = NULL, *ok = NULL;
K_TREE_CTX ctx[1];
char reply[1024] = "";
size_t siz = sizeof(reply);
@@ -2788,10 +2936,11 @@ static char *cmd_setopts(PGconn *conn, char *cmd, char *id,
}
begun = true;
}
- if (optioncontrol_item_add(conn, oc_item, now, begun)) {
- oc_item = NULL;
+ ok = optioncontrol_item_add(conn, oc_item, now, begun);
+ oc_item = NULL;
+ if (ok)
db++;
- } else {
+ else {
reason = "DBERR";
goto rollback;
}
@@ -2845,11 +2994,14 @@ static char *cmd_setopts(PGconn *conn, char *cmd, char *id,
}
begun = true;
}
- if (!optioncontrol_item_add(conn, oc_item, now, begun)) {
+ ok = optioncontrol_item_add(conn, oc_item, now, begun);
+ oc_item = NULL;
+ if (ok)
+ db++;
+ else {
reason = "DBERR";
goto rollback;
}
- db++;
}
rollback:
if (begun) {
@@ -2864,15 +3016,6 @@ rollback:
if (conned)
PQfinish(conn);
if (reason) {
- if (oc_item) {
- if (optioncontrol->optionvalue) {
- free(optioncontrol->optionvalue);
- optioncontrol->optionvalue = NULL;
- }
- K_WLOCK(optioncontrol_free);
- k_add_head(optioncontrol_free, oc_item);
- K_WUNLOCK(optioncontrol_free);
- }
snprintf(reply, siz, "ERR.%s", reason);
LOGERR("%s.%s.%s", cmd, id, reply);
return strdup(reply);
@@ -2975,7 +3118,7 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
int64_t ss_count, wm_count, ms_count;
char tv_buf[DATE_BUFSIZ];
tv_t cd, begin_tv, block_tv, end_tv;
- K_TREE_CTX ctx[1], wm_ctx[1], ms_ctx[1];
+ K_TREE_CTX ctx[1], wm_ctx[1], ms_ctx[1], pay_ctx[1];
double ndiff, total_diff, elapsed;
double diff_times = 1.0;
double diff_add = 0.0;
@@ -3258,41 +3401,71 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
K_RLOCK(users_free);
u_item = find_userid(miningpayouts->userid);
K_RUNLOCK(users_free);
- if (u_item) {
- K_ITEM *pa_item;
- PAYMENTADDRESSES *pa;
- char *payaddress;
+ if (!u_item) {
+ snprintf(reply, siz,
+ "ERR.unknown userid %"PRId64,
+ miningpayouts->userid);
+ goto shazbot;
+ }
- pa_item = find_paymentaddresses(miningpayouts->userid);
- if (pa_item) {
- DATA_PAYMENTADDRESSES(pa, pa_item);
- payaddress = pa->payaddress;
- } else
- payaddress = "none";
+ DATA_USERS(users, u_item);
- DATA_USERS(users, u_item);
- snprintf(tmp, sizeof(tmp),
- "user:%d=%s%cpayaddress:%d=%s%c",
- rows, users->username, FLDSEP,
- rows, payaddress, FLDSEP);
+ K_ITEM *pa_item;
+ PAYMENTADDRESSES *pa;
+ int64_t paytotal;
+ double amount;
+ int count;
+
+ K_RLOCK(paymentaddresses_free);
+ pa_item = find_paymentaddresses(miningpayouts->userid, pay_ctx);
+ if (pa_item) {
+ paytotal = 0;
+ DATA_PAYMENTADDRESSES(pa, pa_item);
+ while (pa_item && CURRENT(&(pa->expirydate)) &&
+ pa->userid == miningpayouts->userid) {
+ paytotal += pa->payratio;
+ pa_item = prev_in_ktree(pay_ctx);
+ DATA_PAYMENTADDRESSES_NULL(pa, pa_item);
+ }
+ count = 0;
+ pa_item = find_paymentaddresses(miningpayouts->userid, pay_ctx);
+ DATA_PAYMENTADDRESSES_NULL(pa, pa_item);
+ while (pa_item && CURRENT(&(pa->expirydate)) &&
+ pa->userid == miningpayouts->userid) {
+ amount = (double)(miningpayouts->amount) *
+ (double)pa->payratio / (double)paytotal;
+
+ snprintf(tmp, sizeof(tmp),
+ "user:%d=%s.%d%cpayaddress:%d=%s%c",
+ rows, users->username, ++count, FLDSEP,
+ rows, pa->payaddress, FLDSEP);
+ APPEND_REALLOC(buf, off, len, tmp);
+ snprintf(tmp, sizeof(tmp),
+ "diffacc_user:%d=%.1f%c",
+ rows, amount, FLDSEP);
+ APPEND_REALLOC(buf, off, len, tmp);
+ rows++;
+ pa_item = prev_in_ktree(pay_ctx);
+ DATA_PAYMENTADDRESSES_NULL(pa, pa_item);
+ }
+ K_RUNLOCK(paymentaddresses_free);
} else {
+ K_RUNLOCK(paymentaddresses_free);
+ snprintf(tmp, sizeof(tmp),
+ "user:%d=%s.0%cpayaddress:%d=%s%c",
+ rows, users->username, FLDSEP,
+ rows, "none", FLDSEP);
+ APPEND_REALLOC(buf, off, len, tmp);
snprintf(tmp, sizeof(tmp),
- "user:%d=%"PRId64"%cpayaddress:%d=none%c",
- rows, miningpayouts->userid, FLDSEP,
- rows, FLDSEP);
- }
- APPEND_REALLOC(buf, off, len, tmp);
-
- snprintf(tmp, sizeof(tmp),
"diffacc_user:%d=%"PRId64"%c",
rows,
miningpayouts->amount,
FLDSEP);
- APPEND_REALLOC(buf, off, len, tmp);
-
+ APPEND_REALLOC(buf, off, len, tmp);
+ rows++;
+ }
mu_item = next_in_ktree(ctx);
- rows++;
}
snprintf(tmp, sizeof(tmp),
"rows=%d%cflds=%s%c",
diff --git a/src/ckdb_data.c b/src/ckdb_data.c
index e7005975..5730261b 100644
--- a/src/ckdb_data.c
+++ b/src/ckdb_data.c
@@ -488,7 +488,7 @@ K_ITEM *_optional_name(K_TREE *trf_root, char *name, int len, char *patt,
dlen = 0;
if (!mvalue || (int)dlen < len) {
if (!mvalue) {
- LOGERR("%s(): field '%s' NULL (%d) from %s():%d",
+ LOGERR("%s(): field '%s' NULL (%d:%d) from %s():%d",
__func__, name, (int)dlen, len, func, line);
} else
snprintf(reply, siz, "failed.short %s", name);
@@ -1108,35 +1108,37 @@ void dsp_paymentaddresses(K_ITEM *item, FILE *stream)
}
}
-// order by userid asc,expirydate desc,payaddress asc
+// order by expirydate asc,userid asc,payaddress asc
cmp_t cmp_paymentaddresses(K_ITEM *a, K_ITEM *b)
{
PAYMENTADDRESSES *pa, *pb;
DATA_PAYMENTADDRESSES(pa, a);
DATA_PAYMENTADDRESSES(pb, b);
- cmp_t c = CMP_BIGINT(pa->userid, pb->userid);
+ cmp_t c = CMP_TV(pa->expirydate, pb->expirydate);
if (c == 0) {
- c = CMP_TV(pb->expirydate, pa->expirydate);
+ c = CMP_BIGINT(pa->userid, pb->userid);
if (c == 0)
c = CMP_STR(pa->payaddress, pb->payaddress);
}
return c;
}
-// Only one for now ...
-K_ITEM *find_paymentaddresses(int64_t userid)
+/* Find the last CURRENT paymentaddresses for the given userid
+ * N.B. there can be more than one
+ * any more will be prev_in_ktree(ctx): CURRENT and userid matches */
+K_ITEM *find_paymentaddresses(int64_t userid, K_TREE_CTX *ctx)
{
PAYMENTADDRESSES paymentaddresses, *pa;
- K_TREE_CTX ctx[1];
K_ITEM look, *item;
- paymentaddresses.userid = userid;
+ paymentaddresses.expirydate.tv_sec = default_expiry.tv_sec;
+ paymentaddresses.expirydate.tv_usec = default_expiry.tv_usec;
+ paymentaddresses.userid = userid+1;
paymentaddresses.payaddress[0] = '\0';
- paymentaddresses.expirydate.tv_sec = DATE_S_EOT;
INIT_PAYMENTADDRESSES(&look);
look.data = (void *)(&paymentaddresses);
- item = find_after_in_ktree(paymentaddresses_root, &look, cmp_paymentaddresses, ctx);
+ item = find_before_in_ktree(paymentaddresses_root, &look, cmp_paymentaddresses, ctx);
if (item) {
DATA_PAYMENTADDRESSES(pa, item);
if (pa->userid == userid && CURRENT(&(pa->expirydate)))
@@ -1147,6 +1149,43 @@ K_ITEM *find_paymentaddresses(int64_t userid)
return NULL;
}
+K_ITEM *find_one_payaddress(int64_t userid, char *payaddress, K_TREE_CTX *ctx)
+{
+ PAYMENTADDRESSES paymentaddresses;
+ K_ITEM look;
+
+ paymentaddresses.expirydate.tv_sec = default_expiry.tv_sec;
+ paymentaddresses.expirydate.tv_usec = default_expiry.tv_usec;
+ paymentaddresses.userid = userid;
+ STRNCPY(paymentaddresses.payaddress, payaddress);
+
+ INIT_PAYMENTADDRESSES(&look);
+ look.data = (void *)(&paymentaddresses);
+ return find_in_ktree(paymentaddresses_root, &look, cmp_paymentaddresses, ctx);
+}
+
+/* This will match any user that has the payaddress
+ * This avoids the bitcoind delay of rechecking an address
+ * that has EVER been seen before
+ * However, also, cmd_userset() that uses it, effectively ensures
+ * that 2 standard users, that mine to a username rather than
+ * a bitcoin address, cannot ever use the same bitcoin address */
+K_ITEM *find_any_payaddress(char *payaddress)
+{
+ PAYMENTADDRESSES *pa;
+ K_TREE_CTX ctx[1];
+ K_ITEM *item;
+
+ item = first_in_ktree(paymentaddresses_root, ctx);
+ DATA_PAYMENTADDRESSES_NULL(pa, item);
+ while (item) {
+ if (strcmp(pa->payaddress, payaddress) == 0)
+ return item;
+ item = next_in_ktree(ctx);
+ }
+ return NULL;
+}
+
// order by userid asc,paydate asc,payaddress asc,expirydate desc
cmp_t cmp_payments(K_ITEM *a, K_ITEM *b)
{
@@ -1749,8 +1788,8 @@ void auto_age_older(PGconn *conn, int64_t workinfoid, char *poolinstance,
min_buf, max_buf);
}
LOGWARNING("%s() Auto-aged %"PRId64"(%"PRId64") "
- "share%s %d sharesummar%s %d workinfoid%s "
- "%s %s",
+ "share%s %"PRId64" sharesummar%s %"PRId32
+ " workinfoid%s %s %s",
__func__,
s_count_tot, s_diff_tot,
(s_count_tot == 1) ? "" : "s",
@@ -2028,7 +2067,7 @@ void set_block_share_counters()
LOGEMERG("%s(): ERROR workmarker %"PRId64" has an invalid"
" workinfoid range start=%"PRId64" end=%"PRId64
" due to pool lastblock=%"PRId32
- " workinfoid="PRId64,
+ " workinfoid=%"PRId64,
__func__, workmarkers->markerid,
workmarkers->workinfoidstart,
workmarkers->workinfoidend,
diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c
index 79ddfb85..42be0f87 100644
--- a/src/ckdb_dbio.c
+++ b/src/ckdb_dbio.c
@@ -1427,56 +1427,44 @@ bool workers_fill(PGconn *conn)
return ok;
}
-/* Whatever the current paymentaddresses are, replace them with this one
- * Code allows for zero, one or more current payment address
- * even though there currently can only be zero or one */
-K_ITEM *paymentaddresses_set(PGconn *conn, int64_t userid, char *payaddress,
- char *by, char *code, char *inet, tv_t *cd,
- K_TREE *trf_root)
+/* Whatever the current paymentaddresses are, replace them with the list
+ * in pa_store
+ * Code allows for zero, one or more current payment address */
+bool paymentaddresses_set(PGconn *conn, int64_t userid, K_STORE *pa_store,
+ char *by, char *code, char *inet, tv_t *cd,
+ K_TREE *trf_root)
{
ExecStatusType rescode;
bool conned = false;
PGresult *res;
K_TREE_CTX ctx[1];
- K_ITEM *item, *old, *this, look;
- PAYMENTADDRESSES *row, pa, *thispa;
- char *upd, *ins;
- bool ok = false;
- char *params[4 + HISTORYDATECOUNT];
- int n, par = 0;
+ K_ITEM *item, *match, *next, *prev;
+ PAYMENTADDRESSES *row, *pa;
+ char *upd = NULL, *ins;
+ size_t len, off;
+ bool ok = false, first;
+ char *params[1002]; // Limit of 999 addresses per user
+ char tmp[1024];
+ int n, par = 0, count, matches;
LOGDEBUG("%s(): add", __func__);
- K_WLOCK(paymentaddresses_free);
- item = k_unlink_head(paymentaddresses_free);
- K_WUNLOCK(paymentaddresses_free);
-
- DATA_PAYMENTADDRESSES(row, item);
-
- row->paymentaddressid = nextid(conn, "paymentaddressid", 1,
- cd, by, code, inet);
- if (row->paymentaddressid == 0)
- goto unitem;
-
- row->userid = userid;
- STRNCPY(row->payaddress, payaddress);
- row->payratio = 1000000;
-
- HISTORYDATEINIT(row, cd, by, code, inet);
- HISTORYDATETRANSFER(trf_root, row);
+ // Quick early abort
+ if (pa_store->count > 999)
+ return false;
- upd = "update paymentaddresses set expirydate=$1 where userid=$2 and expirydate=$3";
- par = 0;
- params[par++] = tv_to_buf(cd, NULL, 0);
- params[par++] = bigint_to_buf(row->userid, NULL, 0);
- params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0);
- PARCHKVAL(par, 3, params);
+ /* Since we are merging the changes in rather than just
+ * replacing the db contents, lock the data for the duration
+ * of the update to ensure nothing else changes it */
+ K_WLOCK(paymentaddresses_free);
if (conn == NULL) {
conn = dbconnect();
conned = true;
}
+ /* This means the nextid updates will rollback on an error, but also
+ * means that it will lock the nextid record for the whole update */
res = PQexec(conn, "Begin", CKPQ_WRITE);
rescode = PQresultStatus(res);
if (!PGOK(rescode)) {
@@ -1485,36 +1473,126 @@ K_ITEM *paymentaddresses_set(PGconn *conn, int64_t userid, char *payaddress,
}
PQclear(res);
- res = PQexecParams(conn, upd, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
- rescode = PQresultStatus(res);
- PQclear(res);
- if (!PGOK(rescode)) {
- PGLOGERR("Update", rescode, conn);
- goto rollback;
+ // First step - DB expire all the old/changed records in RAM
+ LOGDEBUG("%s(): Step 1 userid=%"PRId64, __func__, userid);
+ count = matches = 0;
+ APPEND_REALLOC_INIT(upd, off, len);
+ APPEND_REALLOC(upd, off, len,
+ "update paymentaddresses set expirydate=$1 where "
+ "userid=$2 and expirydate=$3 and payaddress in (");
+ par = 0;
+ params[par++] = tv_to_buf(cd, NULL, 0);
+ params[par++] = bigint_to_buf(userid, NULL, 0);
+ params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0);
+
+ first = true;
+ item = find_paymentaddresses(userid, ctx);
+ DATA_PAYMENTADDRESSES_NULL(row, item);
+ while (item && CURRENT(&(row->expirydate)) && row->userid == userid) {
+ /* This is only possible if the DB was directly updated with
+ * more than 999 records then reloaded (or a code bug) */
+ if (++count > 999)
+ break;
+
+ // Find the RAM record in pa_store
+ match = pa_store->head;
+ while (match) {
+ DATA_PAYMENTADDRESSES(pa, match);
+ if (strcmp(pa->payaddress, row->payaddress) == 0 &&
+ pa->payratio == row->payratio) {
+ pa->match = true; // Don't store it
+ matches++;
+ break;
+ }
+ match = match->next;
+ }
+ if (!match) {
+ // No matching replacement, so expire 'row'
+ params[par++] = str_to_buf(row->payaddress, NULL, 0);
+ if (!first)
+ APPEND_REALLOC(upd, off, len, ",");
+ first = false;
+ snprintf(tmp, sizeof(tmp), "$%d", par);
+ APPEND_REALLOC(upd, off, len, tmp);
+ }
+ item = prev_in_ktree(ctx);
+ DATA_PAYMENTADDRESSES_NULL(row, item);
}
+ LOGDEBUG("%s(): Step 1 par=%d count=%d matches=%d first=%s", __func__,
+ par, count, matches, first ? "true" : "false");
+ // Too many, or none need expiring = don't do the update
+ if (count > 999 || first == true) {
+ for (n = 0; n < par; n++)
+ free(params[n]);
+ par = 0;
+ // Too many
+ if (count > 999)
+ goto rollback;
+ } else {
+ APPEND_REALLOC(upd, off, len, ")");
+ PARCHKVAL(par, par, params);
+ res = PQexecParams(conn, upd, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
+ rescode = PQresultStatus(res);
+ PQclear(res);
+ if (!PGOK(rescode)) {
+ PGLOGERR("Update", rescode, conn);
+ goto rollback;
+ }
- for (n = 0; n < par; n++)
- free(params[n]);
+ LOGDEBUG("%s(): Step 1 expired %d", __func__, par-3);
+
+ for (n = 0; n < par; n++)
+ free(params[n]);
+ par = 0;
+ }
+ // Second step - add the non-matching records to the DB
+ LOGDEBUG("%s(): Step 2", __func__);
ins = "insert into paymentaddresses "
"(paymentaddressid,userid,payaddress,payratio"
HISTORYDATECONTROL ") values (" PQPARAM9 ")";
- par = 0;
- params[par++] = bigint_to_buf(row->paymentaddressid, NULL, 0);
- params[par++] = bigint_to_buf(row->userid, NULL, 0);
- params[par++] = str_to_buf(row->payaddress, NULL, 0);
- params[par++] = int_to_buf(row->payratio, NULL, 0);
- HISTORYDATEPARAMS(params, par, row);
- PARCHK(par, params);
+ count = 0;
+ match = pa_store->head;
+ while (match) {
+ DATA_PAYMENTADDRESSES(row, match);
+ if (!row->match) {
+ row->paymentaddressid = nextid(conn, "paymentaddressid", 1,
+ cd, by, code, inet);
+ if (row->paymentaddressid == 0)
+ goto rollback;
- res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
- rescode = PQresultStatus(res);
- PQclear(res);
- if (!PGOK(rescode)) {
- PGLOGERR("Insert", rescode, conn);
- goto rollback;
+ row->userid = userid;
+
+ HISTORYDATEINIT(row, cd, by, code, inet);
+ HISTORYDATETRANSFER(trf_root, row);
+
+ par = 0;
+ params[par++] = bigint_to_buf(row->paymentaddressid, NULL, 0);
+ params[par++] = bigint_to_buf(row->userid, NULL, 0);
+ params[par++] = str_to_buf(row->payaddress, NULL, 0);
+ params[par++] = int_to_buf(row->payratio, NULL, 0);
+ HISTORYDATEPARAMS(params, par, row);
+ PARCHKVAL(par, 9, params); // As per PQPARAM9 above
+
+ res = PQexecParams(conn, ins, par, NULL, (const char **)params,
+ NULL, NULL, 0, CKPQ_WRITE);
+ rescode = PQresultStatus(res);
+ PQclear(res);
+ if (!PGOK(rescode)) {
+ PGLOGERR("Insert", rescode, conn);
+ goto rollback;
+ }
+
+ for (n = 0; n < par; n++)
+ free(params[n]);
+ par = 0;
+
+ count++;
+ }
+ match = match->next;
}
+ LOGDEBUG("%s(): Step 2 inserted %d", __func__, count);
ok = true;
rollback:
@@ -1529,46 +1607,62 @@ unparam:
PQfinish(conn);
for (n = 0; n < par; n++)
free(params[n]);
-unitem:
- K_WLOCK(paymentaddresses_free);
- if (!ok)
- k_add_head(paymentaddresses_free, item);
- else {
- // Change the expiry on all the old ones
- pa.userid = userid;
- pa.expirydate.tv_sec = DATE_S_EOT;
- pa.payaddress[0] = '\0';
- INIT_PAYMENTADDRESSES(&look);
- look.data = (void *)(&pa);
- // Tree order is expirydate desc
- old = find_after_in_ktree(paymentaddresses_root, &look,
- cmp_paymentaddresses, ctx);
- while (old) {
- this = old;
- DATA_PAYMENTADDRESSES(thispa, this);
- if (thispa->userid != userid)
- break;
- old = next_in_ktree(ctx);
- /* Tree remove+add below doesn't matter since
- * this test will avoid reprocessing */
- if (CURRENT(&(thispa->expirydate))) {
- paymentaddresses_root = remove_from_ktree(paymentaddresses_root, this,
+ FREENULL(upd);
+ // Third step - do step 1 and 2 to the RAM version of the DB
+ LOGDEBUG("%s(): Step 3, ok=%s", __func__, ok ? "true" : "false");
+ matches = count = n = 0;
+ if (ok) {
+ // Change the expiry on all records that we expired in the DB
+ item = find_paymentaddresses(userid, ctx);
+ DATA_PAYMENTADDRESSES_NULL(row, item);
+ while (item && CURRENT(&(row->expirydate)) && row->userid == userid) {
+ prev = prev_in_ktree(ctx);
+ // Find the RAM record in pa_store
+ match = pa_store->head;
+ while (match) {
+ DATA_PAYMENTADDRESSES(pa, match);
+ if (strcmp(pa->payaddress, row->payaddress) == 0 &&
+ pa->payratio == row->payratio) {
+ break;
+ }
+ match = match->next;
+ }
+ if (match)
+ matches++;
+ else {
+ // It wasn't a match, thus it was expired
+ n++;
+ paymentaddresses_root = remove_from_ktree(paymentaddresses_root, item,
cmp_paymentaddresses);
- copy_tv(&(thispa->expirydate), cd);
- paymentaddresses_root = add_to_ktree(paymentaddresses_root, this,
+ copy_tv(&(row->expirydate), cd);
+ paymentaddresses_root = add_to_ktree(paymentaddresses_root, item,
cmp_paymentaddresses);
}
+ item = prev;
+ DATA_PAYMENTADDRESSES_NULL(row, item);
+ }
+
+ // Add in all the non-matching ps_store
+ match = pa_store->head;
+ while (match) {
+ next = match->next;
+ DATA_PAYMENTADDRESSES(pa, match);
+ if (!pa->match) {
+ paymentaddresses_root = add_to_ktree(paymentaddresses_root, match,
+ cmp_paymentaddresses);
+ k_unlink_item(pa_store, match);
+ k_add_head(paymentaddresses_store, match);
+ count++;
+ }
+ match = next;
}
- paymentaddresses_root = add_to_ktree(paymentaddresses_root, item,
- cmp_paymentaddresses);
- k_add_head(paymentaddresses_store, item);
}
+ LOGDEBUG("%s(): Step 3, untouched %d expired %d added %d", __func__, matches, n, count);
+
K_WUNLOCK(paymentaddresses_free);
- if (ok)
- return item;
- else
- return NULL;
+ // Calling function must clean up anything left in pa_store
+ return ok;
}
bool paymentaddresses_fill(PGconn *conn)
@@ -1841,7 +1935,7 @@ K_ITEM *optioncontrol_item_add(PGconn *conn, K_ITEM *oc_item, tv_t *cd, bool beg
K_TREE_CTX ctx[1];
PGresult *res;
K_ITEM *old_item, look;
- OPTIONCONTROL *row;
+ OPTIONCONTROL *row, *optioncontrol;
char *upd, *ins;
bool ok = false;
char *params[4 + HISTORYDATECOUNT];
@@ -1935,13 +2029,17 @@ nostart:
free(params[n]);
K_WLOCK(optioncontrol_free);
- if (!ok)
+ if (!ok) {
+ // Cleanup item passed in
+ FREENULL(row->optionvalue);
k_add_head(optioncontrol_free, oc_item);
- else {
- // Discard it
+ } else {
+ // Discard old
if (old_item) {
+ DATA_OPTIONCONTROL(optioncontrol, old_item);
optioncontrol_root = remove_from_ktree(optioncontrol_root, old_item,
cmp_optioncontrol);
+ FREENULL(optioncontrol->optionvalue);
k_add_head(optioncontrol_free, old_item);
}
optioncontrol_root = add_to_ktree(optioncontrol_root, oc_item, cmp_optioncontrol);
@@ -1962,7 +2060,6 @@ K_ITEM *optioncontrol_add(PGconn *conn, char *optionname, char *optionvalue,
{
K_ITEM *item;
OPTIONCONTROL *row;
- bool ok = false;
LOGDEBUG("%s(): add", __func__);
@@ -1990,19 +2087,7 @@ K_ITEM *optioncontrol_add(PGconn *conn, char *optionname, char *optionvalue,
HISTORYDATEINIT(row, cd, by, code, inet);
HISTORYDATETRANSFER(trf_root, row);
- ok = optioncontrol_item_add(conn, item, cd, begun);
-
- if (!ok) {
- free(row->optionvalue);
- K_WLOCK(optioncontrol_free);
- k_add_head(optioncontrol_free, item);
- K_WUNLOCK(optioncontrol_free);
- }
-
- if (ok)
- return item;
- else
- return NULL;
+ return optioncontrol_item_add(conn, item, cd, begun);
}
bool optioncontrol_fill(PGconn *conn)
@@ -2084,8 +2169,10 @@ bool optioncontrol_fill(PGconn *conn)
optioncontrol_root = add_to_ktree(optioncontrol_root, item, cmp_optioncontrol);
k_add_head(optioncontrol_store, item);
}
- if (!ok)
+ if (!ok) {
+ FREENULL(row->optionvalue);
k_add_head(optioncontrol_free, item);
+ }
K_WUNLOCK(optioncontrol_free);
PQclear(res);
@@ -2148,10 +2235,8 @@ int64_t workinfo_add(PGconn *conn, char *workinfoidstr, char *poolinstance,
K_WLOCK(workinfo_free);
if (find_in_ktree(workinfo_root, item, cmp_workinfo, ctx)) {
- free(row->transactiontree);
- row->transactiontree = NULL;
- free(row->merklehash);
- row->merklehash = NULL;
+ FREENULL(row->transactiontree);
+ FREENULL(row->merklehash);
workinfoid = row->workinfoid;
k_add_head(workinfo_free, item);
K_WUNLOCK(workinfo_free);
@@ -2213,10 +2298,8 @@ unparam:
K_WLOCK(workinfo_free);
if (workinfoid == -1) {
- free(row->transactiontree);
- row->transactiontree = NULL;
- free(row->merklehash);
- row->merklehash = NULL;
+ FREENULL(row->transactiontree);
+ FREENULL(row->merklehash);
k_add_head(workinfo_free, item);
} else {
if (row->transactiontree && *(row->transactiontree)) {
@@ -3165,8 +3248,7 @@ bool sharesummary_fill(PGconn *conn)
DATA_SHARESUMMARY(row, item);
if (row->workername) {
LIST_MEM_SUB(sharesummary_free, row->workername);
- free(row->workername);
- row->workername = NULL;
+ FREENULL(row->workername);
}
k_add_head(sharesummary_free, item);
}
diff --git a/src/ckpmsg.c b/src/ckpmsg.c
index c6f4e387..6f007df7 100644
--- a/src/ckpmsg.c
+++ b/src/ckpmsg.c
@@ -130,7 +130,7 @@ int main(int argc, char **argv)
continue;
}
mkstamp(stamp, sizeof(stamp));
- LOGNOTICE("%s Received response: %s", stamp, buf);
+ LOGMSGSIZ(65536, LOG_NOTICE, "%s Received response: %s", stamp, buf);
}
dealloc(buf);
diff --git a/src/ckpool.c b/src/ckpool.c
index 078cd1c3..46ee4edf 100644
--- a/src/ckpool.c
+++ b/src/ckpool.c
@@ -694,7 +694,7 @@ static bool write_pid(ckpool_t *ckp, const char *path, pid_t pid)
if (ckp->handover) {
if (pid_wait(oldpid, 500))
goto out;
- LOGWARNING("Old process pid %d failed to shutdown cleanly, terminating");
+ LOGWARNING("Old process pid %d failed to shutdown cleanly, terminating", oldpid);
}
if (!ckp->killold) {
LOGEMERG("Process %s pid %d still exists, start ckpool with -k if you wish to kill it",
diff --git a/src/connector.c b/src/connector.c
index 9b5e626c..7355f9aa 100644
--- a/src/connector.c
+++ b/src/connector.c
@@ -219,7 +219,7 @@ static int drop_client(cdata_t *cdata, client_instance_t *client)
ck_wunlock(&cdata->lock);
if (fd > -1)
- LOGINFO("Connector dropped client %d fd %d", client->id, fd);
+ LOGINFO("Connector dropped client %"PRId64" fd %d", client->id, fd);
return fd;
}
@@ -320,7 +320,7 @@ reparse:
if (!(val = json_loads(msg, 0, NULL))) {
char *buf = strdup("Invalid JSON, disconnecting\n");
- LOGINFO("Client id %d sent invalid json message %s", client->id, msg);
+ LOGINFO("Client id %ld sent invalid json message %s", client->id, msg);
send_client(cdata, client->id, buf);
invalidate_client(ckp, cdata, client);
return;
@@ -480,11 +480,11 @@ void *sender(void *arg)
ret = wait_write_select(fd, 0);
if (ret < 1) {
if (ret < 0) {
- LOGINFO("Client id %d fd %d interrupted", client->id, fd);
+ LOGINFO("Client id %ld fd %d interrupted", client->id, fd);
invalidate_client(ckp, cdata, client);
goto contfree;
}
- LOGDEBUG("Client %d not ready for writes", client->id);
+ LOGDEBUG("Client %"PRId64" not ready for writes", client->id);
/* Append it to the tail of the delayed sends list.
* This is the only function that alters it so no
@@ -496,7 +496,7 @@ void *sender(void *arg)
while (sender_send->len) {
ret = send(fd, sender_send->buf + ofs, sender_send->len , 0);
if (unlikely(ret < 0)) {
- LOGINFO("Client id %d fd %d disconnected", client->id, fd);
+ LOGINFO("Client id %ld fd %d disconnected", client->id, fd);
invalidate_client(ckp, cdata, client);
break;
}
@@ -589,7 +589,7 @@ static void passthrough_client(cdata_t *cdata, client_instance_t *client)
{
char *buf;
- LOGINFO("Connector adding passthrough client %d", client->id);
+ LOGINFO("Connector adding passthrough client %"PRId64, client->id);
client->passthrough = true;
ASPRINTF(&buf, "{\"result\": true}\n");
send_client(cdata, client->id, buf);
diff --git a/src/libckpool.h b/src/libckpool.h
index 3401e11a..ac865046 100644
--- a/src/libckpool.h
+++ b/src/libckpool.h
@@ -191,14 +191,25 @@ static inline void flip_80(void *dest_p, const void *src_p)
void logmsg(int loglevel, const char *fmt, ...);
-#define LOGEMERG(fmt, ...) logmsg(LOG_EMERG, fmt, ##__VA_ARGS__)
-#define LOGALERT(fmt, ...) logmsg(LOG_ALERT, fmt, ##__VA_ARGS__)
-#define LOGCRIT(fmt, ...) logmsg(LOG_CRIT, fmt, ##__VA_ARGS__)
-#define LOGERR(fmt, ...) logmsg(LOG_ERR, fmt, ##__VA_ARGS__)
-#define LOGWARNING(fmt, ...) logmsg(LOG_WARNING, fmt, ##__VA_ARGS__)
-#define LOGNOTICE(fmt, ...) logmsg(LOG_NOTICE, fmt, ##__VA_ARGS__)
-#define LOGINFO(fmt, ...) logmsg(LOG_INFO, fmt, ##__VA_ARGS__)
-#define LOGDEBUG(fmt, ...) logmsg(LOG_DEBUG, fmt, ##__VA_ARGS__)
+#define DEFLOGBUFSIZ 512
+
+#define LOGMSGSIZ(__siz, __lvl, __fmt, ...) do { \
+ char tmp42[__siz]; \
+ snprintf(tmp42, sizeof(tmp42), __fmt, ##__VA_ARGS__); \
+ logmsg(__lvl, "%s", tmp42); \
+ } while(0)
+
+#define LOGMSG(_lvl, _fmt, ...) \
+ LOGMSGSIZ(DEFLOGBUFSIZ, _lvl, _fmt, ##__VA_ARGS__)
+
+#define LOGEMERG(fmt, ...) LOGMSG(LOG_EMERG, fmt, ##__VA_ARGS__)
+#define LOGALERT(fmt, ...) LOGMSG(LOG_ALERT, fmt, ##__VA_ARGS__)
+#define LOGCRIT(fmt, ...) LOGMSG(LOG_CRIT, fmt, ##__VA_ARGS__)
+#define LOGERR(fmt, ...) LOGMSG(LOG_ERR, fmt, ##__VA_ARGS__)
+#define LOGWARNING(fmt, ...) LOGMSG(LOG_WARNING, fmt, ##__VA_ARGS__)
+#define LOGNOTICE(fmt, ...) LOGMSG(LOG_NOTICE, fmt, ##__VA_ARGS__)
+#define LOGINFO(fmt, ...) LOGMSG(LOG_INFO, fmt, ##__VA_ARGS__)
+#define LOGDEBUG(fmt, ...) LOGMSG(LOG_DEBUG, fmt, ##__VA_ARGS__)
#define IN_FMT_FFL " in %s %s():%d"
#define quitfrom(status, _file, _func, _line, fmt, ...) do { \
diff --git a/src/stratifier.c b/src/stratifier.c
index 1813aab1..4d34a3a1 100644
--- a/src/stratifier.c
+++ b/src/stratifier.c
@@ -2636,12 +2636,12 @@ out:
if (client->first_invalid < client->last_share.tv_sec || !client->first_invalid)
client->first_invalid = now_t;
else if (client->first_invalid && client->first_invalid < now_t - 120) {
- LOGNOTICE("Client %d rejecting for 120s, disconnecting", client->id);
+ LOGNOTICE("Client %ld rejecting for 120s, disconnecting", client->id);
stratum_send_message(sdata, client, "Disconnecting for continuous invalid shares");
client->reject = 2;
} else if (client->first_invalid && client->first_invalid < now_t - 60) {
if (!client->reject) {
- LOGINFO("Client %d rejecting for 60s, sending diff", client->id);
+ LOGINFO("Client %ld rejecting for 60s, sending diff", client->id);
stratum_send_diff(sdata, client);
client->reject = 1;
}
@@ -2763,8 +2763,10 @@ static void set_worker_mindiff(ckpool_t *ckp, const char *workername, int mindif
ck_runlock(&sdata->instance_lock);
/* They may just have not connected yet */
- if (!instance)
- return LOGINFO("Failed to find user %s in set_worker_mindiff", username);
+ if (!instance) {
+ LOGINFO("Failed to find user %s in set_worker_mindiff", username);
+ return;
+ }
/* Then find the matching worker instance */
ck_rlock(&sdata->instance_lock);
@@ -2777,11 +2779,15 @@ static void set_worker_mindiff(ckpool_t *ckp, const char *workername, int mindif
ck_runlock(&sdata->instance_lock);
/* They may just not be connected at the moment */
- if (!worker)
- return LOGINFO("Failed to find worker %s in set_worker_mindiff", workername);
+ if (!worker) {
+ LOGINFO("Failed to find worker %s in set_worker_mindiff", workername);
+ return;
+ }
- if (mindiff < 1)
- return LOGINFO("Worker %s requested invalid diff %ld", worker->workername, mindiff);
+ if (mindiff < 1) {
+ LOGINFO("Worker %s requested invalid diff %d", worker->workername, mindiff);
+ return;
+ }
if (mindiff < ckp->mindiff)
mindiff = ckp->mindiff;
if (mindiff == worker->mindiff)
@@ -2816,12 +2822,16 @@ static void suggest_diff(stratum_instance_t *client, const char *method, json_t
sdata_t *sdata = client->ckp->data;
int64_t sdiff;
- if (unlikely(!client->authorised))
- return LOGWARNING("Attempted to suggest diff on unauthorised client %ld", client->id);
+ if (unlikely(!client->authorised)) {
+ LOGWARNING("Attempted to suggest diff on unauthorised client %ld", client->id);
+ return;
+ }
if (arr_val && json_is_integer(arr_val))
sdiff = json_integer_value(arr_val);
- else if (sscanf(method, "mining.suggest_difficulty(%ld", &sdiff) != 1)
- return LOGINFO("Failed to parse suggest_difficulty for client %ld", client->id);
+ else if (sscanf(method, "mining.suggest_difficulty(%ld", &sdiff) != 1) {
+ LOGINFO("Failed to parse suggest_difficulty for client %"PRId64, client->id);
+ return;
+ }
if (sdiff == client->suggest_diff)
return;
client->suggest_diff = sdiff;
@@ -2848,7 +2858,7 @@ static void parse_method(sdata_t *sdata, const int64_t client_id, json_t *id_val
}
if (unlikely(client->reject == 2)) {
- LOGINFO("Dropping client %d tagged for lazy invalidation", client_id);
+ LOGINFO("Dropping client %"PRId64" tagged for lazy invalidation", client_id);
snprintf(buf, 255, "dropclient=%ld", client->id);
send_proc(client->ckp->connector, buf);
goto out;
|