Browse Source

Merge branch 'master' of bitbucket.org:ckolivas/ckpool

master
Con Kolivas 9 years ago
parent
commit
542e8a1bde
  1. 2
      pool/page.php
  2. 2
      pool/page_addrmgt.php
  3. 4
      pool/page_blocks.php
  4. 2
      pool/page_ckp.php
  5. 65
      pool/page_events.php
  6. 2
      pool/page_ips.php
  7. 2
      pool/page_mpayouts.php
  8. 2
      pool/page_payments.php
  9. 2
      pool/page_percent.php
  10. 2
      pool/page_pplns.php
  11. 2
      pool/page_pplns2.php
  12. 3
      pool/page_settings.php
  13. 2
      pool/page_shifts.php
  14. 2
      pool/page_stats.php
  15. 2
      pool/page_userinfo.php
  16. 21
      pool/page_usperf.php
  17. 2
      pool/page_workers.php
  18. 2
      pool/page_workmgt.php
  19. 1271
      src/ckdb.c
  20. 72
      src/ckdb.h
  21. 216
      src/ckdb_cmd.c
  22. 32
      src/ckdb_data.c
  23. 148
      src/ckdb_dbio.c

2
pool/page.php

@ -25,7 +25,7 @@ function getPage()
return ''; return '';
$vals = explode('&', trim($names[1])); $vals = explode('&', trim($names[1]));
if ($count($vals) < 1) if (count($vals) < 1)
return ''; return '';
return trim($vals[0]); return trim($vals[0]);

2
pool/page_addrmgt.php

@ -8,7 +8,7 @@ function addrmgtuser($data, $user, $err)
$pg .= "<span class=err>$err<br><br></span>"; $pg .= "<span class=err>$err<br><br></span>";
$pg .= makeForm('addrmgt'); $pg .= makeForm('addrmgt');
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dc>#</td>'; $pg .= '<td class=dc>#</td>';
$pg .= '<td class=dl>Address</td>'; $pg .= '<td class=dl>Address</td>';

4
pool/page_blocks.php

@ -90,7 +90,7 @@ function doblocks($data, $user)
if ($ans['STATUS'] == 'ok' and isset($ans['s_rows']) and $ans['s_rows'] > 0) if ($ans['STATUS'] == 'ok' and isset($ans['s_rows']) and $ans['s_rows'] > 0)
{ {
$pg .= '<h1>Block Statistics</h1>'; $pg .= '<h1>Block Statistics</h1>';
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= "<thead><tr class=title>"; $pg .= "<thead><tr class=title>";
$pg .= "<td class=dl>Description</td>"; $pg .= "<td class=dl>Description</td>";
$pg .= "<td class=dr>Time</td>"; $pg .= "<td class=dr>Time</td>";
@ -169,7 +169,7 @@ function doblocks($data, $user)
$pg .= "&nbsp;Red&nbsp;</span>&nbsp;"; $pg .= "&nbsp;Red&nbsp;</span>&nbsp;";
$pg .= 'is bad luck. Higher Diff% and brighter red is worse luck.<br><br>'; $pg .= 'is bad luck. Higher Diff% and brighter red is worse luck.<br><br>';
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= "<thead><tr class=title>"; $pg .= "<thead><tr class=title>";
$pg .= "<td class=dr>#</td>"; $pg .= "<td class=dr>#</td>";
$pg .= "<td class=dl>Height</td>"; $pg .= "<td class=dl>Height</td>";

2
pool/page_ckp.php

@ -26,7 +26,7 @@ function dockp($data, $user)
$ans = repDecode($rep); $ans = repDecode($rep);
$pg .= 'TotalRAM: '.stnum($ans['totalram']).'<br>'; $pg .= 'TotalRAM: '.stnum($ans['totalram']).'<br>';
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dl>Name</td>'; $pg .= '<td class=dl>Name</td>';
$pg .= '<td class=dr>Initial</td>'; $pg .= '<td class=dr>Initial</td>';

65
pool/page_events.php

@ -20,7 +20,7 @@ What: <input type=text name=what size=10 value='$wh'>
$other = array('event_limits_hash_lifetime', $other = array('event_limits_hash_lifetime',
'ovent_limits_ipc_factor'); 'ovent_limits_ipc_factor');
$pg .= "<br><br><table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<br><br><table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dr>#</td>'; $pg .= '<td class=dr>#</td>';
$pg .= '<td class=dl>Name</td>'; $pg .= '<td class=dl>Name</td>';
@ -60,7 +60,7 @@ What: <input type=text name=what size=10 value='$wh'>
'ip_hi_time_limit' => 'IPHiLim', 'ip_hi_time_limit' => 'IPHiLim',
'lifetime' => 'Life'); 'lifetime' => 'Life');
$pg .= "<br><br><table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<br><br><table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dr>#</td>'; $pg .= '<td class=dr>#</td>';
$pg .= '<td class=dl>Name</td>'; $pg .= '<td class=dl>Name</td>';
@ -103,12 +103,13 @@ What: <input type=text name=what size=10 value='$wh'>
{ {
$ans = eventCmd($user, array('action' => 'events', 'list' => $wh)); $ans = eventCmd($user, array('action' => 'events', 'list' => $wh));
$pg .= "<br><br><table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<br><br><table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dr>#</td>'; $pg .= '<td class=dr>#</td>';
$pg .= '<td class=dl>List</td>'; $pg .= '<td class=dl>List</td>';
$pg .= '<td class=dr>ID</td>'; $pg .= '<td class=dr>ID</td>';
$pg .= '<td class=dr>User</td>'; $pg .= '<td class=dl>IDName</td>';
$pg .= '<td class=dl>User</td>';
$pg .= '<td class=dr>IP</td>'; $pg .= '<td class=dr>IP</td>';
$pg .= '<td class=dr>IPc</td>'; $pg .= '<td class=dr>IPc</td>';
$pg .= '<td class=dr>Hash</td>'; $pg .= '<td class=dr>Hash</td>';
@ -131,7 +132,8 @@ What: <input type=text name=what size=10 value='$wh'>
$pg .= "<td class=dr>$j</td>"; $pg .= "<td class=dr>$j</td>";
$pg .= '<td class=dl>'.$ans['list:'.$i].'</td>'; $pg .= '<td class=dl>'.$ans['list:'.$i].'</td>';
$pg .= '<td class=dr>'.$ans['id:'.$i].'</td>'; $pg .= '<td class=dr>'.$ans['id:'.$i].'</td>';
$pg .= '<td class=dr>'.$ans['user:'.$i].'</td>'; $pg .= '<td class=dl>'.$ans['idname:'.$i].'</td>';
$pg .= '<td class=dl>'.$ans['user:'.$i].'</td>';
$pg .= '<td class=dr>'.isans($ans, 'ip:'.$i).'</td>'; $pg .= '<td class=dr>'.isans($ans, 'ip:'.$i).'</td>';
$pg .= '<td class=dr>'.isans($ans, 'ipc:'.$i).'</td>'; $pg .= '<td class=dr>'.isans($ans, 'ipc:'.$i).'</td>';
$pg .= '<td class=dr>'.isans($ans, 'hash:'.$i).'</td>'; $pg .= '<td class=dr>'.isans($ans, 'hash:'.$i).'</td>';
@ -142,6 +144,59 @@ What: <input type=text name=what size=10 value='$wh'>
} }
} }
if ($wh == 'ovents')
{
$ans = eventCmd($user, array('action' => 'ovents'));
$pg .= "<br><br><table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>';
$pg .= '<td class=dr>#</td>';
$pg .= '<td class=dl>Key</td>';
$pg .= '<td class=dr>ID</td>';
$pg .= '<td class=dl>IDName</td>';
$pg .= '<td class=dr>Hour UTC</td>';
$pg .= '<td class=dl>Count</td>';
$pg .= "</tr></thead>\n";
if ($ans['STATUS'] == 'ok')
{
$pg .= '<tbody>';
$count = $ans['rows'];
for ($i = 0; $i < $count; $i++)
{
if (($i % 2) == 0)
$row = 'even';
else
$row = 'odd';
$j = $i+1;
$pg .= "<tr class=$row>";
$pg .= "<td class=dr>$j</td>";
$pg .= '<td class=dl>'.$ans['key:'.$i].'</td>';
$pg .= '<td class=dr>'.$ans['id:'.$i].'</td>';
$pg .= '<td class=dl>'.$ans['idname:'.$i].'</td>';
$pg .= '<td class=dr>'.gmdate('j/M H:i:s',$ans['hour:'.$i]*3600).'</td>';
$co = '';
for ($k = 0; $k < 60; $k++)
{
if ($k < 10)
$min = '0' . $k;
else
$min = $k;
if (isset($ans["min$min:$i"]))
{
if ($co != '')
$co .= ' ';
$co .= "$min=".$ans["min$min:$i"];
}
}
$pg .= "<td class=dl>$co</td>";
$pg .= "</tr>\n";
}
$pg .= '</tbody>';
}
}
return $pg; return $pg;
} }
# #

2
pool/page_ips.php

@ -6,7 +6,7 @@ function doips($data, $user)
$ans = eventCmd($user, array('action' => 'ips')); $ans = eventCmd($user, array('action' => 'ips'));
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dr>#</td>'; $pg .= '<td class=dr>#</td>';
$pg .= '<td class=dl>Group</td>'; $pg .= '<td class=dl>Group</td>';

2
pool/page_mpayouts.php

@ -11,7 +11,7 @@ function dompayouts($data, $user)
$pg .= makeLink('payments'); $pg .= makeLink('payments');
$pg .= "Payments</a> page for the payments you've been sent.<br><br>"; $pg .= "Payments</a> page for the payments you've been sent.<br><br>";
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dr>Block</td>'; $pg .= '<td class=dr>Block</td>';
$pg .= '<td class=dr>Block UTC</td>'; $pg .= '<td class=dr>Block UTC</td>';

2
pool/page_payments.php

@ -27,7 +27,7 @@ function dopayments($data, $user)
$ans = getPayments($user); $ans = getPayments($user);
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dl>Block</td>'; $pg .= '<td class=dl>Block</td>';
$pg .= '<td class=dl>Address</td>'; $pg .= '<td class=dl>Address</td>';

2
pool/page_percent.php

@ -143,7 +143,7 @@ function dopercent($data, $user)
{ {
$pg = '<h1>Address Percents</h1>'; $pg = '<h1>Address Percents</h1>';
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$totshare = 0; $totshare = 0;
$totdiff = 0; $totdiff = 0;

2
pool/page_pplns.php

@ -231,7 +231,7 @@ Block: <input type=text name=blk size=10 value='$blkuse'>
$pg .= str_replace(' ', '&nbsp;', $msg)."</span><br>\n"; $pg .= str_replace(' ', '&nbsp;', $msg)."</span><br>\n";
} }
$pg .= "<br><table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<br><table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<tr class=title>'; $pg .= '<tr class=title>';
$pg .= '<td class=dl>Name</td>'; $pg .= '<td class=dl>Name</td>';
$pg .= '<td class=dr>Value</td>'; $pg .= '<td class=dr>Value</td>';

2
pool/page_pplns2.php

@ -235,7 +235,7 @@ Block: <input type=text name=blk size=10 value='$blkuse'>
$pg .= str_replace(' ', '&nbsp;', $msg)."</span><br>\n"; $pg .= str_replace(' ', '&nbsp;', $msg)."</span><br>\n";
} }
$pg .= "<br><table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<br><table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<tr class=title>'; $pg .= '<tr class=title>';
$pg .= '<td class=dl>Name</td>'; $pg .= '<td class=dl>Name</td>';
$pg .= '<td class=dr>Value</td>'; $pg .= '<td class=dr>Value</td>';

3
pool/page_settings.php

@ -50,7 +50,8 @@ function settings($data, $user, $email, $addr, $err)
$pg .= makeForm('settings'); $pg .= makeForm('settings');
$pg .= '<table cellpadding=5 cellspacing=0 border=0>'; $pg .= '<table cellpadding=5 cellspacing=0 border=0>';
$pg .= '<tr class=dc><td class=dr colspan=2>'; $pg .= '<tr class=dc><td class=dr colspan=2>';
$pg .= 'To change your payout address, enter a new address and your password'; $pg .= 'To change your payout address, enter a new address and your password.<br>';
$pg .= 'A payout address can only ever be set to one account';
$pg .= '</td></tr>'; $pg .= '</td></tr>';
$pg .= '<tr class=dc><td class=dr>'; $pg .= '<tr class=dc><td class=dr>';
$pg .= 'BTC Address:'; $pg .= 'BTC Address:';

2
pool/page_shifts.php

@ -5,7 +5,7 @@ function doshifts($data, $user)
$ans = getShifts($user); $ans = getShifts($user);
$pg = "Click <a href='#payoutmark'>here</a> to jump to the start of the last payout<br><br>"; $pg = "Click <a href='#payoutmark'>here</a> to jump to the start of the last payout<br><br>";
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dl>Shift</td>'; $pg .= '<td class=dl>Shift</td>';
$pg .= '<td class=dl>Start UTC</td>'; $pg .= '<td class=dl>Start UTC</td>';

2
pool/page_stats.php

@ -65,7 +65,7 @@ function dostats($data, $user)
$ans = getAllUsers($user); $ans = getAllUsers($user);
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dl>Username</td>'; $pg .= '<td class=dl>Username</td>';
$pg .= '<td class=dr>Hash Rate 5m</td>'; $pg .= '<td class=dr>Hash Rate 5m</td>';

2
pool/page_userinfo.php

@ -20,7 +20,7 @@ function douserinfo($data, $user)
$ans = getUserInfo($user); $ans = getUserInfo($user);
$pg = '<h1>Block Acclaim</h1>'; $pg = '<h1>Block Acclaim</h1>';
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<thead><tr class=title>'; $pg .= '<thead><tr class=title>';
$pg .= '<td class=dl>User</td>'; $pg .= '<td class=dl>User</td>';
$pg .= '<td class=dr>Blocks</td>'; $pg .= '<td class=dr>Blocks</td>';

21
pool/page_usperf.php

@ -30,7 +30,8 @@ function dousperf($data, $user)
// This also defines how many worker fields there are // This also defines how many worker fields there are
$cols = array('#0000c0', '#00dd00', '#e06020', '#b020e0'); $cols = array('#0000c0', '#00dd00', '#e06020', '#b020e0');
$nc = count($cols); $cols2 = array('#2090e0', '#e0c040', '#ff6090', '#90e040');
$nc = count($cols)+count($cols2);
$workers = 'all'; $workers = 'all';
if (isset($_COOKIE['workers'])) if (isset($_COOKIE['workers']))
@ -93,9 +94,24 @@ function dousperf($data, $user)
$datacols .= ','; $datacols .= ',';
$datacols .= $col; $datacols .= $col;
} }
$oncl = "wch();location.href=\"".makeURL('usperf')."\""; $oncl = "wch();location.href=\"".makeURL('usperf')."\"";
$pg .= "<button type=button onclick='$oncl'>Update</button></form><div>"; $pg .= "<button type=button onclick='$oncl'>Update</button></form><div>";
# the rest of the workers/colours go below the graph
$pg2 = '<form>';
foreach ($cols2 as $col)
{
$i++;
$pg2 .= " <span class=nb><font color=$col>Worker$i";
$pg2 .= "<input type=checkbox id=lin$i checked onclick='godrw(0)'>:</font>";
$pg2 .= "<input type=text size=10 id=worker$i$onch> </span>";
if ($i > 1)
$datacols .= ',';
$datacols .= $col;
}
$pg2 .= "<button type=button onclick='$oncl'>Update</button></form>\n";
foreach ($cbx as $nam => $txt) foreach ($cbx as $nam => $txt)
{ {
$pg .= ' <span class=nb>'; $pg .= ' <span class=nb>';
@ -107,6 +123,7 @@ function dousperf($data, $user)
$pg .= '<div id=can0><canvas id=can width=1 height=1>'; $pg .= '<div id=can0><canvas id=can width=1 height=1>';
$pg .= 'A graph will show here if your browser supports html5/canvas'; $pg .= 'A graph will show here if your browser supports html5/canvas';
$pg .= "</canvas></div>\n"; $pg .= "</canvas></div>\n";
$pg .= $pg2;
$data = str_replace(array("\\","'"), array("\\\\","\\'"), $ans['DATA']); $data = str_replace(array("\\","'"), array("\\\\","\\'"), $ans['DATA']);
$data .= $fld_sep . 'cols' . $val_sep . $datacols; $data .= $fld_sep . 'cols' . $val_sep . $datacols;
$pg .= "<script type='text/javascript'>\n"; $pg .= "<script type='text/javascript'>\n";

2
pool/page_workers.php

@ -7,7 +7,7 @@ function worktable()
{a=c.getAttribute('data-hid');if(a){if(b){c.className=a}else{c.className='hid'}}}}}"; {a=c.getAttribute('data-hid');if(a){if(b){c.className=a}else{c.className='hid'}}}}}";
$pg .= "</script>\n"; $pg .= "</script>\n";
$pg .= "Show Details for Invalids: <input type=checkbox onclick='wkdet(\"wkt\",this)'><br>"; $pg .= "Show Details for Invalids: <input type=checkbox onclick='wkdet(\"wkt\",this)'><br>";
$pg .= "<table id=wkt callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table id=wkt cellpadding=0 cellspacing=0 border=0>\n";
return $pg; return $pg;
} }
# #

2
pool/page_workmgt.php

@ -23,7 +23,7 @@ function workmgtuser($data, $user, $err)
} }
$pg .= makeForm('workmgt'); $pg .= makeForm('workmgt');
$pg .= "<table callpadding=0 cellspacing=0 border=0>\n"; $pg .= "<table cellpadding=0 cellspacing=0 border=0>\n";
$pg .= '<tr class=title>'; $pg .= '<tr class=title>';
$pg .= '<td class=dl>Worker Name</td>'; $pg .= '<td class=dl>Worker Name</td>';
$pg .= '<td class=dr>Minimum Diff</td>'; $pg .= '<td class=dr>Minimum Diff</td>';

1271
src/ckdb.c

File diff suppressed because it is too large Load Diff

72
src/ckdb.h

@ -51,7 +51,7 @@
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "1.0.5" #define DB_VERSION "1.0.5"
#define CKDB_VERSION DB_VERSION"-1.984" #define CKDB_VERSION DB_VERSION"-2.003"
#define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__ #define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -1037,7 +1037,7 @@ typedef struct msgline {
#define ALLOC_MSGLINE 8192 #define ALLOC_MSGLINE 8192
#define LIMIT_MSGLINE 0 #define LIMIT_MSGLINE 0
#define CULL_MSGLINE 16 #define CULL_MSGLINE 8
#define INIT_MSGLINE(_item) INIT_GENERIC(_item, msgline) #define INIT_MSGLINE(_item) INIT_GENERIC(_item, msgline)
#define DATA_MSGLINE(_var, _item) DATA_GENERIC(_var, _item, msgline, true) #define DATA_MSGLINE(_var, _item) DATA_GENERIC(_var, _item, msgline, true)
#define DATA_MSGLINE_NULL(_var, _item) DATA_GENERIC(_var, _item, msgline, false) #define DATA_MSGLINE_NULL(_var, _item) DATA_GENERIC(_var, _item, msgline, false)
@ -1045,6 +1045,57 @@ typedef struct msgline {
extern K_LIST *msgline_free; extern K_LIST *msgline_free;
extern K_STORE *msgline_store; extern K_STORE *msgline_store;
// BREAKQUEUE
typedef struct breakqueue {
char *buf;
tv_t now;
int seqentryflags;
int sockd;
enum cmd_values cmdnum;
K_ITEM *ml_item;
uint64_t count;
char *filename;
} BREAKQUEUE;
#define ALLOC_BREAKQUEUE 16384
#define LIMIT_BREAKQUEUE 0
#define CULL_BREAKQUEUE 4
#define INIT_BREAKQUEUE(_item) INIT_GENERIC(_item, breakqueue)
#define DATA_BREAKQUEUE(_var, _item) DATA_GENERIC(_var, _item, breakqueue, true)
/* If a breaker() thread's done break queue count hits the LIMIT, or is empty,
* it will sleep for SLEEP ms
* So this means that with a single breaker() thread,
* it can process at most LIMIT records per SLEEP ms
* or: 1000 * LIMIT / SLEEP records per second
* For N breaker() threads, that would mean between 1 and N times that value
* dependent upon the random time spacing of the N thread sleeps
* However, also note that LIMIT defines how much RAM can be used by
* the break queues, so a limit is required
* A breakqueue item can get quite large since it includes both buf
* and ml_item (which has the transfer data) in the 'done' queue
* Of course the processing speed of the ml_items will also decide how big the
* break queue count can get
* Note that if the CMD queues get too large they will be too slow responding
* to the sockets that sent the message, however the CMD ml_item processing
* responds immediately before processing the ml_item for all but ADDRAUTH,
* AUTHORISE and HEARTBEAT
* The reload also uses this limit when filling the reload break queue
* thus limiting the line processing of reload files
*/
// 16300,42 equated to single thread limitation of ~388k per second
#define RELOAD_QUEUE_LIMIT 16300
#define RELOAD_QUEUE_SLEEP 42
#define CMD_QUEUE_LIMIT 16300
#define CMD_QUEUE_SLEEP 42
extern K_LIST *breakqueue_free;
extern K_STORE *reload_breakqueue_store;
extern K_STORE *reload_done_breakqueue_store;
extern K_STORE *cmd_breakqueue_store;
extern K_STORE *cmd_done_breakqueue_store;
extern int max_sockd_count;
// WORKQUEUE // WORKQUEUE
typedef struct workqueue { typedef struct workqueue {
K_ITEM *msgline_item; K_ITEM *msgline_item;
@ -1060,6 +1111,8 @@ typedef struct workqueue {
#define DATA_WORKQUEUE(_var, _item) DATA_GENERIC(_var, _item, workqueue, true) #define DATA_WORKQUEUE(_var, _item) DATA_GENERIC(_var, _item, workqueue, true)
extern K_LIST *workqueue_free; extern K_LIST *workqueue_free;
// pool0 is all pool data during the reload
extern K_STORE *pool0_workqueue_store;
extern K_STORE *pool_workqueue_store; extern K_STORE *pool_workqueue_store;
extern K_STORE *cmd_workqueue_store; extern K_STORE *cmd_workqueue_store;
extern K_STORE *btc_workqueue_store; extern K_STORE *btc_workqueue_store;
@ -1093,7 +1146,7 @@ typedef struct transfer {
// Suggest malloc use MMAP - 1913 = largest under 2MB // Suggest malloc use MMAP - 1913 = largest under 2MB
#define ALLOC_TRANSFER 1913 #define ALLOC_TRANSFER 1913
#define LIMIT_TRANSFER 0 #define LIMIT_TRANSFER 0
#define CULL_TRANSFER 64 #define CULL_TRANSFER 32
#define INIT_TRANSFER(_item) INIT_GENERIC(_item, transfer) #define INIT_TRANSFER(_item) INIT_GENERIC(_item, transfer)
#define DATA_TRANSFER(_var, _item) DATA_GENERIC(_var, _item, transfer, true) #define DATA_TRANSFER(_var, _item) DATA_GENERIC(_var, _item, transfer, true)
@ -1723,6 +1776,9 @@ extern double diff_percent;
* This is set only via the runtime parameter -D or --minsdiff */ * This is set only via the runtime parameter -D or --minsdiff */
extern double share_min_sdiff; extern double share_min_sdiff;
// workinfoid to start loading shares, unset = shares_fill() decides
extern int64_t shares_begin;
// SHAREERRORS shareerrors.id.json={...} // SHAREERRORS shareerrors.id.json={...}
typedef struct shareerrors { typedef struct shareerrors {
int64_t workinfoid; int64_t workinfoid;
@ -2425,7 +2481,8 @@ extern K_TREE *markersummary_pool_root;
extern K_STORE *markersummary_pool_store; extern K_STORE *markersummary_pool_store;
// The markerid load start for markersummary // The markerid load start for markersummary
extern char *mark_start; extern char mark_start_type;
extern int64_t mark_start;
// WORKMARKERS // WORKMARKERS
typedef struct workmarkers { typedef struct workmarkers {
@ -2594,6 +2651,8 @@ extern K_STORE *userinfo_store;
extern void logmsg(int loglevel, const char *fmt, ...); extern void logmsg(int loglevel, const char *fmt, ...);
extern void setnow(tv_t *now); extern void setnow(tv_t *now);
extern void _ckdb_unix_msg(int sockd, const char *msg, WHERE_FFL_ARGS);
#define ckdb_unix_msg(_sockd, _msg) _ckdb_unix_msg(_sockd, _msg, WHERE_FFL_HERE)
extern void tick(); extern void tick();
extern PGconn *dbconnect(); extern PGconn *dbconnect();
extern void sequence_report(bool lock); extern void sequence_report(bool lock);
@ -2814,6 +2873,7 @@ extern bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by,
extern double coinbase_reward(int32_t height); extern double coinbase_reward(int32_t height);
extern double workinfo_pps(K_ITEM *w_item, int64_t workinfoid); extern double workinfo_pps(K_ITEM *w_item, int64_t workinfoid);
extern cmp_t cmp_shares(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_shares(K_ITEM *a, K_ITEM *b);
extern cmp_t cmp_shares_db(K_ITEM *a, K_ITEM *b);
extern cmp_t cmp_shareerrors(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_shareerrors(K_ITEM *a, K_ITEM *b);
extern void dsp_sharesummary(K_ITEM *item, FILE *stream); extern void dsp_sharesummary(K_ITEM *item, FILE *stream);
extern cmp_t cmp_sharesummary(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_sharesummary(K_ITEM *a, K_ITEM *b);
@ -3119,7 +3179,7 @@ extern bool auths_add(PGconn *conn, char *poolinstance, char *username,
char *useragent, char *preauth, char *by, char *code, char *useragent, char *preauth, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root, char *inet, tv_t *cd, K_TREE *trf_root,
bool addressuser, USERS **users, WORKERS **workers, bool addressuser, USERS **users, WORKERS **workers,
int *event); int *event, bool reload_data);
extern bool poolstats_add(PGconn *conn, bool store, char *poolinstance, extern bool poolstats_add(PGconn *conn, bool store, char *poolinstance,
char *elapsed, char *users, char *workers, char *elapsed, char *users, char *workers,
char *hashrate, char *hashrate5m, char *hashrate, char *hashrate5m,
@ -3187,7 +3247,7 @@ struct CMDS {
bool noid; // doesn't require an id bool noid; // doesn't require an id
bool createdate; // requires a createdate bool createdate; // requires a createdate
char *(*func)(PGconn *, char *, char *, tv_t *, char *, char *, char *(*func)(PGconn *, char *, char *, tv_t *, char *, char *,
char *, tv_t *, K_TREE *); char *, tv_t *, K_TREE *, bool);
enum seq_num seq; enum seq_num seq;
int access; int access;
}; };

216
src/ckdb_cmd.c

@ -34,7 +34,7 @@ static K_ITEM *adminuser(K_TREE *trf_root, char *reply, size_t siz)
static char *cmd_adduser(PGconn *conn, char *cmd, char *id, tv_t *now, char *by, static char *cmd_adduser(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
char *code, char *inet, __maybe_unused tv_t *notcd, char *code, char *inet, __maybe_unused tv_t *notcd,
K_TREE *trf_root) K_TREE *trf_root, __maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -87,7 +87,8 @@ static char *cmd_adduser(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
static char *cmd_newpass(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_newpass(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, char *by, char *code, char *inet, tv_t *now, char *by, char *code, char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root) __maybe_unused tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_oldhash, *i_newhash, *i_2fa, *u_item; K_ITEM *i_username, *i_oldhash, *i_newhash, *i_2fa, *u_item;
char reply[1024] = ""; char reply[1024] = "";
@ -166,7 +167,8 @@ static char *cmd_newpass(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_chkpass(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_chkpass(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_passwordhash, *i_2fa, *u_item; K_ITEM *i_username, *i_passwordhash, *i_2fa, *u_item;
char reply[1024] = ""; char reply[1024] = "";
@ -222,7 +224,8 @@ static char *cmd_chkpass(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_2fa(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_2fa(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, char *by, char *code, char *inet, tv_t *now, char *by, char *code, char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_action, *i_entropy, *i_value, *u_item, *u_new; K_ITEM *i_username, *i_action, *i_entropy, *i_value, *u_item, *u_new;
char reply[1024] = ""; char reply[1024] = "";
@ -464,7 +467,8 @@ dame:
static char *cmd_userset(PGconn *conn, char *cmd, char *id, static char *cmd_userset(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_passwordhash, *i_2fa, *i_rows, *i_address; K_ITEM *i_username, *i_passwordhash, *i_2fa, *i_rows, *i_address;
K_ITEM *i_ratio, *i_payname, *i_email, *u_item, *pa_item, *old_pa_item; K_ITEM *i_ratio, *i_payname, *i_email, *u_item, *pa_item, *old_pa_item;
@ -781,7 +785,7 @@ struckout:
static char *cmd_workerset(PGconn *conn, char *cmd, char *id, tv_t *now, static char *cmd_workerset(PGconn *conn, char *cmd, char *id, tv_t *now,
char *by, char *code, char *inet, tv_t *cd, char *by, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, __maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_workername, *i_diffdef, *i_oldworkers; K_ITEM *i_username, *i_workername, *i_diffdef, *i_oldworkers;
K_ITEM *u_item, *ua_item, *w_item; K_ITEM *u_item, *ua_item, *w_item;
@ -1081,7 +1085,7 @@ static char *cmd_poolstats_do(PGconn *conn, char *cmd, char *id, char *by,
static char *cmd_poolstats(PGconn *conn, char *cmd, char *id, static char *cmd_poolstats(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *notnow, char *by, __maybe_unused tv_t *notnow, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, __maybe_unused bool reload_data)
{ {
bool igndup = false; bool igndup = false;
@ -1096,7 +1100,8 @@ static char *cmd_poolstats(PGconn *conn, char *cmd, char *id,
static char *cmd_userstats(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_userstats(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *notnow, char *by, char *code, __maybe_unused tv_t *notnow, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root) char *inet, tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -1180,7 +1185,8 @@ static char *cmd_userstats(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_workerstats(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_workerstats(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *notnow, char *by, char *code, __maybe_unused tv_t *notnow, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root) char *inet, tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -1263,7 +1269,8 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
int ovent = OVENT_OK; int ovent = OVENT_OK;
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
@ -1525,7 +1532,8 @@ redo:
static char *cmd_blockstatus(PGconn *conn, char *cmd, char *id, tv_t *now, static char *cmd_blockstatus(PGconn *conn, char *cmd, char *id, tv_t *now,
char *by, char *code, char *inet, char *by, char *code, char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root) __maybe_unused tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_height, *i_blockhash, *i_action, *i_info; K_ITEM *i_height, *i_blockhash, *i_action, *i_info;
char reply[1024] = ""; char reply[1024] = "";
@ -1682,7 +1690,7 @@ static char *cmd_blockstatus(PGconn *conn, char *cmd, char *id, tv_t *now,
static char *cmd_newid(PGconn *conn, char *cmd, char *id, tv_t *now, char *by, static char *cmd_newid(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
char *code, char *inet, __maybe_unused tv_t *cd, char *code, char *inet, __maybe_unused tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, __maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -1718,7 +1726,8 @@ static char *cmd_payments(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *u_item, *p_item, *p2_item, *po_item; K_ITEM *i_username, *u_item, *p_item, *p2_item, *po_item;
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
@ -2056,7 +2065,8 @@ static char *cmd_percent(char *cmd, char *id, tv_t *now, USERS *users)
static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_stats, *i_percent, w_look, *u_item, *w_item; K_ITEM *i_username, *i_stats, *i_percent, w_look, *u_item, *w_item;
K_ITEM *ua_item, *us_item, *ws_item; K_ITEM *ua_item, *us_item, *ws_item;
@ -2382,7 +2392,8 @@ static char *cmd_allusers(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_STORE *usu_store = k_new_store(userstats_free); K_STORE *usu_store = k_new_store(userstats_free);
K_ITEM *us_item, *usu_item, *u_item; K_ITEM *us_item, *usu_item, *u_item;
@ -2494,7 +2505,8 @@ static char *cmd_allusers(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_sharelog(PGconn *conn, char *cmd, char *id, static char *cmd_sharelog(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *notnow, char *by, __maybe_unused tv_t *notnow, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -2946,7 +2958,7 @@ static char *cmd_blocks_do(PGconn *conn, char *cmd, int32_t height, char *id,
static char *cmd_blocks(PGconn *conn, char *cmd, char *id, static char *cmd_blocks(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *notnow, char *by, __maybe_unused tv_t *notnow, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, __maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -2969,12 +2981,13 @@ static char *cmd_blocks(PGconn *conn, char *cmd, char *id,
igndup = true; igndup = true;
} }
return cmd_blocks_do(conn, cmd, height, id, by, code, inet, cd, igndup, trf_root); return cmd_blocks_do(conn, cmd, height, id, by, code, inet, cd, igndup,
trf_root);
} }
static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by, static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, bool reload_data)
{ {
K_ITEM tmp_poolinstance_item; K_ITEM tmp_poolinstance_item;
TRANSFER tmp_poolinstance; TRANSFER tmp_poolinstance;
@ -3046,7 +3059,8 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
u_item = find_users(username); u_item = find_users(username);
K_RUNLOCK(users_free); K_RUNLOCK(users_free);
if (!u_item) { if (!u_item) {
event = events_add(EVENTID_AUTOACC, trf_root); if (!reload_data)
event = events_add(EVENTID_AUTOACC, trf_root);
if (event == EVENT_OK) { if (event == EVENT_OK) {
DATA_OPTIONCONTROL(optioncontrol, oc_item); DATA_OPTIONCONTROL(optioncontrol, oc_item);
u_item = users_add(conn, username, EMPTY, u_item = users_add(conn, username, EMPTY,
@ -3067,7 +3081,7 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
transfer_data(i_useragent), transfer_data(i_useragent),
transfer_data(i_preauth), transfer_data(i_preauth),
by, code, inet, cd, trf_root, false, by, code, inet, cd, trf_root, false,
&users, &workers, &event); &users, &workers, &event, reload_data);
} }
if (!ok) { if (!ok) {
@ -3123,14 +3137,15 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
static char *cmd_auth(PGconn *conn, char *cmd, char *id, static char *cmd_auth(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, char *by, __maybe_unused tv_t *now, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, bool reload_data)
{ {
return cmd_auth_do(conn, cmd, id, by, code, inet, cd, trf_root); return cmd_auth_do(conn, cmd, id, by, code, inet, cd, trf_root,
reload_data);
} }
static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by, static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, bool reload_data)
{ {
K_ITEM tmp_poolinstance_item; K_ITEM tmp_poolinstance_item;
TRANSFER tmp_poolinstance; TRANSFER tmp_poolinstance;
@ -3201,7 +3216,7 @@ static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by,
transfer_data(i_useragent), transfer_data(i_useragent),
transfer_data(i_preauth), transfer_data(i_preauth),
by, code, inet, cd, trf_root, true, by, code, inet, cd, trf_root, true,
&users, &workers, &event); &users, &workers, &event, reload_data);
if (!ok) { if (!ok) {
LOGDEBUG("%s() %s.failed.DBE", __func__, id); LOGDEBUG("%s() %s.failed.DBE", __func__, id);
@ -3256,16 +3271,18 @@ static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by,
static char *cmd_addrauth(PGconn *conn, char *cmd, char *id, static char *cmd_addrauth(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, char *by, __maybe_unused tv_t *now, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, bool reload_data)
{ {
return cmd_addrauth_do(conn, cmd, id, by, code, inet, cd, trf_root); return cmd_addrauth_do(conn, cmd, id, by, code, inet, cd, trf_root,
reload_data);
} }
static char *cmd_heartbeat(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_heartbeat(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *cd, __maybe_unused tv_t *cd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
HEARTBEATQUEUE *heartbeatqueue; HEARTBEATQUEUE *heartbeatqueue;
K_STORE *hq_store; K_STORE *hq_store;
@ -3331,7 +3348,8 @@ pulse:
static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *u_item, *b_item, *p_item, *us_item, look; K_ITEM *i_username, *u_item, *b_item, *p_item, *us_item, look;
K_ITEM *ua_item, *pa_item; K_ITEM *ua_item, *pa_item;
@ -3506,12 +3524,16 @@ static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id,
int psync = pool_workqueue_store->count; int psync = pool_workqueue_store->count;
int csync = cmd_workqueue_store->count; int csync = cmd_workqueue_store->count;
int bsync = btc_workqueue_store->count; int bsync = btc_workqueue_store->count;
int qsync = breakqueue_free->total - breakqueue_free->count;
snprintf(tmp, sizeof(tmp), "psync=%d%c", psync, FLDSEP); snprintf(tmp, sizeof(tmp), "psync=%d%c", psync, FLDSEP);
APPEND_REALLOC(buf, off, len, tmp); APPEND_REALLOC(buf, off, len, tmp);
snprintf(tmp, sizeof(tmp), "csync=%d%c", csync, FLDSEP); snprintf(tmp, sizeof(tmp), "csync=%d%c", csync, FLDSEP);
APPEND_REALLOC(buf, off, len, tmp); APPEND_REALLOC(buf, off, len, tmp);
snprintf(tmp, sizeof(tmp), "bsync=%d%c", bsync, FLDSEP); snprintf(tmp, sizeof(tmp), "bsync=%d%c", bsync, FLDSEP);
APPEND_REALLOC(buf, off, len, tmp); APPEND_REALLOC(buf, off, len, tmp);
snprintf(tmp, sizeof(tmp), "qsync=%d%c", qsync, FLDSEP);
APPEND_REALLOC(buf, off, len, tmp);
// qsync isn't part of 'sync'
snprintf(tmp, sizeof(tmp), "sync=%d%c", psync + csync + bsync, FLDSEP); snprintf(tmp, sizeof(tmp), "sync=%d%c", psync + csync + bsync, FLDSEP);
APPEND_REALLOC(buf, off, len, tmp); APPEND_REALLOC(buf, off, len, tmp);
@ -3622,7 +3644,8 @@ static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_getatts(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_getatts(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_attlist, *u_item, *ua_item; K_ITEM *i_username, *i_attlist, *u_item, *ua_item;
char reply[1024] = ""; char reply[1024] = "";
@ -3798,7 +3821,8 @@ static void att_to_date(tv_t *date, char *data, tv_t *now)
* */ * */
static char *cmd_setatts(PGconn *conn, char *cmd, char *id, static char *cmd_setatts(PGconn *conn, char *cmd, char *id,
tv_t *now, char *by, char *code, char *inet, tv_t *now, char *by, char *code, char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
ExecStatusType rescode; ExecStatusType rescode;
PGresult *res; PGresult *res;
@ -3967,7 +3991,8 @@ bats:
static char *cmd_expatts(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_expatts(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_attlist, *u_item, *ua_item; K_ITEM *i_username, *i_attlist, *u_item, *ua_item;
char reply[1024] = ""; char reply[1024] = "";
@ -4050,7 +4075,8 @@ rats:
static char *cmd_getopts(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_getopts(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_optlist, *oc_item; K_ITEM *i_optlist, *oc_item;
char reply[1024] = ""; char reply[1024] = "";
@ -4128,7 +4154,8 @@ ruts:
* See opt_set_date() above */ * See opt_set_date() above */
static char *cmd_setopts(PGconn *conn, char *cmd, char *id, static char *cmd_setopts(PGconn *conn, char *cmd, char *id,
tv_t *now, char *by, char *code, char *inet, tv_t *now, char *by, char *code, char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
ExecStatusType rescode; ExecStatusType rescode;
PGresult *res; PGresult *res;
@ -4276,9 +4303,10 @@ rollback:
* and the breakdown for percent address users, * and the breakdown for percent address users,
* the totals per user and per payout should still be the same */ * the totals per user and per payout should still be the same */
static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char reply[1024], tmp[1024], *buf; char reply[1024], tmp[1024], *buf;
char *block_extra, *share_status = EMPTY, *marks_status = EMPTY; char *block_extra, *share_status = EMPTY, *marks_status = EMPTY;
@ -4753,9 +4781,10 @@ shazbot:
// Generated from the payouts, miningpayouts and payments data // Generated from the payouts, miningpayouts and payments data
static char *cmd_pplns2(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_pplns2(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char reply[1024], tmp[1024], *buf; char reply[1024], tmp[1024], *buf;
char *block_extra, *marks_status = EMPTY; char *block_extra, *marks_status = EMPTY;
@ -5022,7 +5051,8 @@ shazbot:
static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now,
char *by, char *code, char *inet, char *by, char *code, char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root) __maybe_unused tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -5274,7 +5304,8 @@ static char *cmd_mpayouts(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *u_item, *mp_item, *po_item; K_ITEM *i_username, *u_item, *mp_item, *po_item;
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
@ -5466,7 +5497,8 @@ static int select_list(WM *wm, char *select)
static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username, *i_select; K_ITEM *i_username, *i_select;
K_ITEM *u_item, *p_item, *m_item, ms_look, *wm_item, *ms_item, *wi_item; K_ITEM *u_item, *p_item, *m_item, ms_look, *wm_item, *ms_item, *wi_item;
@ -5815,7 +5847,8 @@ static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd,
char *id, __maybe_unused tv_t *now, char *id, __maybe_unused tv_t *now,
__maybe_unused char *by, __maybe_unused char *code, __maybe_unused char *by, __maybe_unused char *code,
__maybe_unused char *inet, __maybe_unused tv_t *notcd, __maybe_unused char *inet, __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
__maybe_unused K_ITEM *i_file; __maybe_unused K_ITEM *i_file;
__maybe_unused char reply[1024] = ""; __maybe_unused char reply[1024] = "";
@ -5861,7 +5894,9 @@ static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd,
static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, __maybe_unused K_TREE *trf_root) __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char tmp[1024], *buf; char tmp[1024], *buf;
const char *name; const char *name;
@ -5949,7 +5984,7 @@ static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id,
// TODO: add to heartbeat to disable the miner if active and status != "" // TODO: add to heartbeat to disable the miner if active and status != ""
static char *cmd_userstatus(PGconn *conn, char *cmd, char *id, tv_t *now, char *by, static char *cmd_userstatus(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
char *code, char *inet, __maybe_unused tv_t *cd, char *code, char *inet, __maybe_unused tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, __maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -6016,7 +6051,7 @@ static char *cmd_userstatus(PGconn *conn, char *cmd, char *id, tv_t *now, char *
static char *cmd_marks(PGconn *conn, char *cmd, char *id, static char *cmd_marks(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, char *by, __maybe_unused tv_t *now, char *by,
char *code, char *inet, tv_t *cd, char *code, char *inet, tv_t *cd,
K_TREE *trf_root) K_TREE *trf_root, __maybe_unused bool reload_data)
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
@ -6535,7 +6570,8 @@ dame:
static char *cmd_pshift(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_pshift(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_username; K_ITEM *i_username;
K_ITEM *u_item, *p_item, *m_item, *wm_item, *ms_item, *wi_item; K_ITEM *u_item, *p_item, *m_item, *wm_item, *ms_item, *wi_item;
@ -6740,18 +6776,26 @@ static char *cmd_pshift(__maybe_unused PGconn *conn, char *cmd, char *id,
} }
/* Show a share status report on the console /* Show a share status report on the console
* Currently: sequence status and OoO info */ * Currently: sequence status, OoO info and max_sockd_count */
static char *cmd_shsta(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_shsta(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, __maybe_unused K_TREE *trf_root) __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
char ooo_buf[256]; char ooo_buf[256];
char buf[256]; char buf[256];
int count;
LOGWARNING("OoO %s", ooo_status(ooo_buf, sizeof(ooo_buf))); LOGWARNING("OoO %s", ooo_status(ooo_buf, sizeof(ooo_buf)));
sequence_report(true); sequence_report(true);
K_RLOCK(breakqueue_free);
count = max_sockd_count;
K_RUNLOCK(breakqueue_free);
LOGWARNING(" max_sockd_count=%d", count);
snprintf(buf, sizeof(buf), "ok.%s", cmd); snprintf(buf, sizeof(buf), "ok.%s", cmd);
LOGDEBUG("%s.%s", id, buf); LOGDEBUG("%s.%s", id, buf);
return strdup(buf); return strdup(buf);
@ -6761,7 +6805,8 @@ static char *cmd_userinfo(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, __maybe_unused tv_t *notcd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *ui_item; K_ITEM *ui_item;
USERINFO *userinfo; USERINFO *userinfo;
@ -6850,7 +6895,8 @@ static char *cmd_userinfo(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_btcset(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_btcset(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *notcd, K_TREE *trf_root) __maybe_unused tv_t *notcd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_btcserver, *i_userpass; K_ITEM *i_btcserver, *i_userpass;
char *btcserver = NULL, *userpass = NULL, *tmp; char *btcserver = NULL, *userpass = NULL, *tmp;
@ -6902,7 +6948,8 @@ static char *cmd_btcset(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_query(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_query(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root) __maybe_unused tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
char cd_buf[DATE_BUFSIZ]; char cd_buf[DATE_BUFSIZ];
@ -7498,7 +7545,8 @@ static char *cmd_locks(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *cd, __maybe_unused tv_t *cd,
__maybe_unused K_TREE *trf_root) __maybe_unused K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
bool code_locks = false, code_deadlocks = false; bool code_locks = false, code_deadlocks = false;
bool was_locks = false, was_deadlocks = false; bool was_locks = false, was_deadlocks = false;
@ -7570,11 +7618,12 @@ static void event_tree(K_TREE *the_tree, char *list, char *reply, size_t siz,
snprintf(reply, siz, "list:%d=%s%c", snprintf(reply, siz, "list:%d=%s%c",
*rows, list, FLDSEP); *rows, list, FLDSEP);
APPEND_REALLOC(*buf, *off, *len, reply); APPEND_REALLOC(*buf, *off, *len, reply);
snprintf(reply, siz, "id:%d=%d%c", snprintf(reply, siz, "id:%d=%d%c",
*rows, e->id, FLDSEP); *rows, e->id, FLDSEP);
APPEND_REALLOC(*buf, *off, *len, reply); APPEND_REALLOC(*buf, *off, *len, reply);
snprintf(reply, siz, "idname:%d=%s%c",
*rows, e_limits[e->id].name, FLDSEP);
APPEND_REALLOC(*buf, *off, *len, reply);
snprintf(reply, siz, "user:%d=%s%c", snprintf(reply, siz, "user:%d=%s%c",
*rows, e->createby, FLDSEP); *rows, e->createby, FLDSEP);
APPEND_REALLOC(*buf, *off, *len, reply); APPEND_REALLOC(*buf, *off, *len, reply);
@ -7609,11 +7658,13 @@ static void event_tree(K_TREE *the_tree, char *list, char *reply, size_t siz,
static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id,
tv_t *now, __maybe_unused char *by, tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root) __maybe_unused tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
K_ITEM *i_action, *i_cmd, *i_list, *i_ip, *i_eventname, *i_lifetime; K_ITEM *i_action, *i_cmd, *i_list, *i_ip, *i_eventname, *i_lifetime;
K_ITEM *i_des, *i_item, *next_item; K_ITEM *i_des, *i_item, *next_item, *o_item;
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
OVENTS *ovents;
IPS *ips; IPS *ips;
char *action, *alert_cmd, *list, *ip, *eventname, *des; char *action, *alert_cmd, *list, *ip, *eventname, *des;
char reply[1024] = ""; char reply[1024] = "";
@ -7621,7 +7672,7 @@ static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id,
char tmp[1024] = ""; char tmp[1024] = "";
char *buf = NULL; char *buf = NULL;
size_t len, off; size_t len, off;
int i, rows, oldlife, lifetime; int i, rows, oldlife, lifetime, vid, min;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd); LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@ -8034,6 +8085,50 @@ static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id,
APPEND_REALLOC_INIT(buf, off, len); APPEND_REALLOC_INIT(buf, off, len);
snprintf(tmp, sizeof(tmp), "ok.expired %d", rows); snprintf(tmp, sizeof(tmp), "ok.expired %d", rows);
APPEND_REALLOC(buf, off, len, tmp); APPEND_REALLOC(buf, off, len, tmp);
} else if (strcasecmp(action, "ovents") == 0) {
/* List the ovent tree contents
* Output can be large - check web Admin->ckp for tree sizes */
bool got;
APPEND_REALLOC_INIT(buf, off, len);
APPEND_REALLOC(buf, off, len, "ok.");
rows = 0;
K_RLOCK(ovents_free);
o_item = first_in_ktree(ovents_root, ctx);
while (o_item) {
DATA_OVENTS(ovents, o_item);
for (vid = 0; o_limits[vid].name; vid++) {
got = false;
for (min = 0; min < 60; min++) {
if (ovents->count[IDMIN(vid, min)]) {
if (!got) {
snprintf(reply, siz, "key:%d=%s%c",
rows, ovents->key, FLDSEP);
APPEND_REALLOC(buf, off, len, reply);
snprintf(reply, siz, "id:%d=%d%c",
rows, vid, FLDSEP);
APPEND_REALLOC(buf, off, len, reply);
snprintf(reply, siz, "idname:%d=%s%c",
rows, o_limits[vid].name, FLDSEP);
APPEND_REALLOC(buf, off, len, reply);
snprintf(reply, siz, "hour:%d=%d%c",
rows, ovents->hour, FLDSEP);
APPEND_REALLOC(buf, off, len, reply);
got = true;
}
snprintf(reply, siz, "min%02d:%d=%d%c",
min, rows, ovents->count[IDMIN(vid, min)],
FLDSEP);
APPEND_REALLOC(buf, off, len, reply);
}
}
if (got)
rows++;
}
o_item = next_in_ktree(ctx);
}
K_RUNLOCK(ovents_free);
snprintf(tmp, sizeof(tmp), "rows=%d", rows);
APPEND_REALLOC(buf, off, len, tmp);
} else { } else {
snprintf(reply, siz, "unknown action '%s'", action); snprintf(reply, siz, "unknown action '%s'", action);
LOGERR("%s() %s.%s", __func__, id, reply); LOGERR("%s() %s.%s", __func__, id, reply);
@ -8047,7 +8142,8 @@ static char *cmd_events(__maybe_unused PGconn *conn, char *cmd, char *id,
static char *cmd_high(PGconn *conn, char *cmd, char *id, static char *cmd_high(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root) __maybe_unused tv_t *cd, K_TREE *trf_root,
__maybe_unused bool reload_data)
{ {
bool conned = false; bool conned = false;
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];

32
src/ckdb_data.c

@ -2333,6 +2333,38 @@ cmp_t cmp_shares(K_ITEM *a, K_ITEM *b)
return c; return c;
} }
/* order by workinfoid asc,userid asc,workername asc,enonce1 asc,nonce2 asc,
* nonce asc,expirydate desc
* i.e. match the DB table index so duplicates are ignored and all new shares_db
* can always go in the DB */
cmp_t cmp_shares_db(K_ITEM *a, K_ITEM *b)
{
SHARES *sa, *sb;
DATA_SHARES(sa, a);
DATA_SHARES(sb, b);
cmp_t c = CMP_BIGINT(sa->workinfoid, sb->workinfoid);
if (c == 0) {
c = CMP_BIGINT(sa->userid, sb->userid);
if (c == 0) {
c = CMP_STR(sa->workername, sb->workername);
if (c == 0) {
c = CMP_STR(sa->enonce1, sb->enonce1);
if (c == 0) {
c = CMP_STR(sa->nonce2, sb->nonce2);
if (c == 0) {
c = CMP_STR(sa->nonce, sb->nonce);
if (c == 0) {
c = CMP_TV(sb->expirydate,
sa->expirydate);
}
}
}
}
}
}
return c;
}
// order by workinfoid asc,userid asc,createdate asc,nonce asc,expirydate desc // order by workinfoid asc,userid asc,createdate asc,nonce asc,expirydate desc
cmp_t cmp_shareerrors(K_ITEM *a, K_ITEM *b) cmp_t cmp_shareerrors(K_ITEM *a, K_ITEM *b)
{ {

148
src/ckdb_dbio.c

@ -3625,7 +3625,7 @@ discard:
static void shareerrors_process_early(PGconn *conn, int64_t good_wid, static void shareerrors_process_early(PGconn *conn, int64_t good_wid,
tv_t *good_cd, K_TREE *trf_root); tv_t *good_cd, K_TREE *trf_root);
// DB Shares are stored by by the summariser to ensure the reload is correct // DB Shares are stored by the summariser to ensure the reload is correct
bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername, bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername,
char *clientid, char *errn, char *enonce1, char *nonce2, char *clientid, char *errn, char *enonce1, char *nonce2,
char *nonce, char *diff, char *sdiff, char *secondaryuserid, char *nonce, char *diff, char *sdiff, char *secondaryuserid,
@ -3640,7 +3640,6 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername
USERS *users; USERS *users;
bool ok = false; bool ok = false;
char *st = NULL; char *st = NULL;
int errn_int;
LOGDEBUG("%s(): %s/%s/%s/%s/%ld,%ld", LOGDEBUG("%s(): %s/%s/%s/%s/%ld,%ld",
__func__, __func__,
@ -3649,13 +3648,10 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername
FREENULL(st); FREENULL(st);
TXT_TO_DOUBLE("sdiff", sdiff, sdiff_amt); TXT_TO_DOUBLE("sdiff", sdiff, sdiff_amt);
TXT_TO_INT("errn", errn, errn_int);
K_WLOCK(shares_free); K_WLOCK(shares_free);
s_item = k_unlink_head(shares_free); s_item = k_unlink_head(shares_free);
// Don't store duplicates since they will already exist if (share_min_sdiff > 0 && sdiff_amt >= share_min_sdiff)
if (errn_int != SE_DUPE && share_min_sdiff > 0 &&
sdiff_amt >= share_min_sdiff)
s2_item = k_unlink_head(shares_free); s2_item = k_unlink_head(shares_free);
K_WUNLOCK(shares_free); K_WUNLOCK(shares_free);
@ -3731,7 +3727,9 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername
add_to_ktree(shares_early_root, s_item); add_to_ktree(shares_early_root, s_item);
k_add_head(shares_early_store, s_item); k_add_head(shares_early_store, s_item);
if (s2_item) { if (s2_item) {
// Just ignore duplicates /* Just ignore duplicates - this matches the DB index
N.B. a duplicate share doesn't have to be SE_DUPE,
two shares can be SE_NONE and SE_STALE */
tmp_item = find_in_ktree(shares_db_root, s2_item, ctx); tmp_item = find_in_ktree(shares_db_root, s2_item, ctx);
if (tmp_item == NULL) { if (tmp_item == NULL) {
// Store them in advance - always // Store them in advance - always
@ -3860,16 +3858,51 @@ bool shares_fill(PGconn *conn)
{ {
ExecStatusType rescode; ExecStatusType rescode;
PGresult *res; PGresult *res;
K_ITEM *item = NULL; K_TREE_CTX ctx[1];
K_ITEM *item = NULL, *wi_item;
WORKINFO *workinfo = NULL;
SHARES *row; SHARES *row;
int n, t, i; int n, t, i;
char *field; char *field;
char *sel = NULL; char *sel = NULL;
int fields = 14; char *params[1];
int fields = 14, par = 0;
bool ok = false; bool ok = false;
int64_t workinfoid;
tv_t old;
LOGDEBUG("%s(): select", __func__); LOGDEBUG("%s(): select", __func__);
if (shares_begin >= 0)
workinfoid = shares_begin;
else {
/* Workinfo is already loaded
* CKDB doesn't currently use shares_db in processing,
* but make sure we have enough to avoid loading duplicates
* 1 day should be more than enough for normal running,
* however, if more than 1 day is needed,
* use -b to set the shares_begin workinfoid */
setnow(&old);
old.tv_sec -= 60 * 60 * 24; // 1 day
K_RLOCK(workinfo_free);
wi_item = last_in_ktree(workinfo_root, ctx);
while (wi_item) {
DATA_WORKINFO(workinfo, wi_item);
if (!tv_newer(&old, &(workinfo->createdate)))
break;
wi_item = prev_in_ktree(ctx);
}
if (wi_item)
workinfoid = workinfo->workinfoid;
else {
// none old enough, so just load from them all
workinfoid = 0;
}
K_RUNLOCK(workinfo_free);
}
LOGWARNING("%s(): loading from workinfoid>=%"PRId64, __func__, workinfoid);
printf(TICK_PREFIX"sh 0\r"); printf(TICK_PREFIX"sh 0\r");
fflush(stdout); fflush(stdout);
@ -3877,7 +3910,10 @@ bool shares_fill(PGconn *conn)
"workinfoid,userid,workername,clientid,enonce1,nonce2,nonce," "workinfoid,userid,workername,clientid,enonce1,nonce2,nonce,"
"diff,sdiff,errn,error,secondaryuserid,ntime,minsdiff" "diff,sdiff,errn,error,secondaryuserid,ntime,minsdiff"
HISTORYDATECONTROL HISTORYDATECONTROL
" from shares"; " from shares where workinfoid>=$1";
par = 0;
params[par++] = bigint_to_buf(workinfoid, NULL, 0);
PARCHK(par, params);
res = PQexec(conn, "Begin", CKPQ_READ); res = PQexec(conn, "Begin", CKPQ_READ);
rescode = PQresultStatus(res); rescode = PQresultStatus(res);
@ -3895,7 +3931,7 @@ bool shares_fill(PGconn *conn)
goto flail; goto flail;
} }
res = PQexec(conn, sel, CKPQ_READ); res = PQexecParams(conn, sel, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_READ);
rescode = PQresultStatus(res); rescode = PQresultStatus(res);
PQclear(res); PQclear(res);
if (!PGOK(rescode)) { if (!PGOK(rescode)) {
@ -7064,7 +7100,7 @@ bool auths_add(PGconn *conn, char *poolinstance, char *username,
char *useragent, char *preauth, char *by, char *code, char *useragent, char *preauth, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root, char *inet, tv_t *cd, K_TREE *trf_root,
bool addressuser, USERS **users, WORKERS **workers, bool addressuser, USERS **users, WORKERS **workers,
int *event) int *event, bool reload_data)
{ {
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
K_ITEM *a_item, *u_item, *w_item; K_ITEM *a_item, *u_item, *w_item;
@ -7095,7 +7131,8 @@ bool auths_add(PGconn *conn, char *poolinstance, char *username,
__func__, __func__,
st = safe_text_nonull(username)); st = safe_text_nonull(username));
FREENULL(st); FREENULL(st);
*event = events_add(EVENTID_INVAUTH, trf_root); if (!reload_data)
*event = events_add(EVENTID_INVAUTH, trf_root);
} }
if (!u_item) if (!u_item)
goto unitem; goto unitem;
@ -7719,17 +7756,86 @@ bool markersummary_fill(PGconn *conn)
{ {
ExecStatusType rescode; ExecStatusType rescode;
PGresult *res; PGresult *res;
K_ITEM *item = NULL, *p_item; K_ITEM *item = NULL, *p_item, *wm_item = NULL;
K_TREE_CTX ctx[1];
char cd_buf[DATE_BUFSIZ];
char *cd = NULL, *what = NULL;
int n, t, i, p_n; int n, t, i, p_n;
MARKERSUMMARY *row, *p_row; MARKERSUMMARY *row, *p_row;
WORKMARKERS *workmarkers;
char *params[1]; char *params[1];
char *field; char *field;
char *sel; char *sel;
int fields = 20, par = 0; int fields = 20, par = 0;
int64_t ms = 0, amt = 0;
bool ok = false; bool ok = false;
tv_t old;
LOGDEBUG("%s(): select", __func__); LOGDEBUG("%s(): select", __func__);
if (mark_start < 0)
mark_start = 0;
else {
amt = ms = mark_start;
switch (mark_start_type) {
case 'D': // mark_start days
setnow(&old);
old.tv_sec -= 60 * 60 * 24 * ms;
K_RLOCK(workmarkers_free);
wm_item = last_in_ktree(workmarkers_root, ctx);
while (wm_item) {
// Newest processed workmarker <= old
DATA_WORKMARKERS(workmarkers, wm_item);
if (CURRENT(&(workmarkers->expirydate)) &&
WMPROCESSED(workmarkers->status) &&
!tv_newer(&old, &(workmarkers->createdate)))
break;
wm_item = prev_in_ktree(ctx);
}
if (!wm_item)
mark_start = 0;
else {
mark_start = workmarkers->markerid;
tv_to_buf(&(workmarkers->createdate),
cd_buf, sizeof(cd_buf));
cd = cd_buf;
what = "days";
}
K_RUNLOCK(workmarkers_free);
break;
case 'S': // mark_start shifts (workmarkers)
K_RLOCK(workmarkers_free);
wm_item = last_in_ktree(workmarkers_root, ctx);
while (wm_item) {
DATA_WORKMARKERS(workmarkers, wm_item);
if (CURRENT(&(workmarkers->expirydate)) &&
WMPROCESSED(workmarkers->status)) {
ms--;
if (ms <= 0)
break;
}
wm_item = prev_in_ktree(ctx);
}
if (!wm_item)
mark_start = 0;
else {
mark_start = workmarkers->markerid;
tv_to_buf(&(workmarkers->createdate),
cd_buf, sizeof(cd_buf));
cd = cd_buf;
what = "shifts";
}
K_RUNLOCK(workmarkers_free);
break;
case 'M': // markerid = mark_start
break;
default:
/* Not possible unless ckdb.c is different
* in which case it will just use mark_start */
break;
}
}
// TODO: limit how far back // TODO: limit how far back
sel = "declare ws cursor for select " sel = "declare ws cursor for select "
"markerid,userid,workername,diffacc,diffsta,diffdup,diffhi," "markerid,userid,workername,diffacc,diffsta,diffdup,diffhi,"
@ -7738,14 +7844,16 @@ bool markersummary_fill(PGconn *conn)
"lastshareacc,lastdiffacc" "lastshareacc,lastdiffacc"
MODIFYDATECONTROL MODIFYDATECONTROL
" from markersummary where markerid>=$1"; " from markersummary where markerid>=$1";
par = 0; par = 0;
if (mark_start) params[par++] = bigint_to_buf(mark_start, NULL, 0);
params[par++] = mark_start;
else
params[par++] = "0";
PARCHK(par, params); PARCHK(par, params);
LOGWARNING("%s(): loading from markerid>=%s", __func__, params[0]); LOGWARNING("%s(): loading from markerid>=%s", __func__, params[0]);
if (cd) {
LOGWARNING(" ... %s = %s >= %"PRId64" %s",
params[0], cd, amt, what);
}
printf(TICK_PREFIX"ms 0\r"); printf(TICK_PREFIX"ms 0\r");
fflush(stdout); fflush(stdout);
@ -7980,6 +8088,10 @@ flail:
res = PQexec(conn, "Commit", CKPQ_READ); res = PQexec(conn, "Commit", CKPQ_READ);
PQclear(res); PQclear(res);
for (i = 0; i < par; i++)
free(params[i]);
par = 0;
if (ok) { if (ok) {
LOGDEBUG("%s(): built", __func__); LOGDEBUG("%s(): built", __func__);
LOGWARNING("%s(): fetched %d markersummary records", __func__, n); LOGWARNING("%s(): fetched %d markersummary records", __func__, n);

Loading…
Cancel
Save