From 1f4cd709d1201b420c92b252c3aedadb0180d574 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 19 Mar 2015 20:23:05 +1100 Subject: [PATCH 01/10] php - allow selecting local vs utc time on the shift graph --- html/can.js | 12 +++++++----- pool/page_usperf.php | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/html/can.js b/html/can.js index a7504f93..f4acd2ef 100644 --- a/html/can.js +++ b/html/can.js @@ -1,6 +1,7 @@ function hasCan(){var c0=document.getElementById('can0');c=document.getElementById('can');return !!(c0&&c&&c.getContext&&c.getContext('2d'));} function sep(d){ans={};var ar=d.split("\t");var l=ar.length;for(var i=0;i(zm-0.5)){return(zm-0.5)}return z} function gchx(c,x){return gch(x*c['xm']+c['xo'],c['ctx'].canvas.width)} function gchy(c,y){return gch((1-y)*c['ym']+c['yo'],c['ctx'].canvas.height)} @@ -37,7 +38,7 @@ for(var i=0;i=x0;i-=(6*3600)){var n=dfmt(i);var xo=(i-x0)/(x1-x0);if(c['tkey']){gbe(c,xo,0);gln(c,xo,-0.02);gst(c);gfz(c,xo,0,0,-hi*tpos,n,'brown','center')}if(c['tlines']){gbe(c,xo,0);gln(c,xo,1);gst(c)}} +for(var i=xhr;i>=x0;i-=(6*3600)){var n=dfmt(c,i);var xo=(i-x0)/(x1-x0);if(c['tkey']){gbe(c,xo,0);gln(c,xo,-0.02);gst(c);gfz(c,xo,0,0,-hi*tpos,n,'brown','center')}if(c['tlines']){gbe(c,xo,0);gln(c,xo,1);gst(c)}} glw(c,0.1); gss(c,'black'); if(c['smooth']){var xa=0,ya=0,xb=0,yb=0; @@ -47,11 +48,12 @@ glw(c,0.2); gss(c,'red'); var y=(av-y0)/(y1-y0); gbe(c,0,y);gln(c,1,y);gst(c); -var t=''+av.toFixed(2);gfz(c,1,y,1,0,t,'red','left') +var t=''+av.toFixed(2).'av';gfz(c,1,y,1,0,t,'red','left') } function sn(i,shi){if(shi.indexOf(' Shift ')<0){return ''+(i%10)}else{return shi.replace(/.* ([a-z])[a-z]*$/,'$1')}} -function gc(c){var div=document.getElementById('can0');while(div.firstChild){div.removeChild(div.firstChild)}c['can']=document.createElement('canvas');c['can'].id='can';c['wx']=window.innerWidth;c['wy']=window.innerHeight;c['xm']=Math.round(c['wx']*0.9+0.5);c['ym']=Math.round(c['wy']*0.8+0.5);if(c['ym']>c['xm']){c['ym']=c['xm']}c['xo']=0.0;c['yo']=0.0;c['ctx']=c['can'].getContext('2d');c['ctx'].canvas.width=c['xm']+1;c['ctx'].canvas.height=c['ym']+1;div.appendChild(c['can']);div=document.getElementById('smooth');c['smooth']=(div&&div.checked);div=document.getElementById('over');c['over']=(div&&div.checked);div=document.getElementById('skey');c['skey']=(div&&div.checked);div=document.getElementById('slines');c['slines']=(div&&div.checked);div=document.getElementById('tkey');c['tkey']=(div&&div.checked);div=document.getElementById('tlines');c['tlines']=(div&&div.checked);div=document.getElementById('zerob');c['zerob']=(div&&div.checked)} -function gdrw(d){var c={};gc(c); +function gc(c){var div=document.getElementById('can0');while(div.firstChild){div.removeChild(div.firstChild)}c['can']=document.createElement('canvas');c['can'].id='can';c['wx']=window.innerWidth;c['wy']=window.innerHeight;c['xm']=Math.round(c['wx']*0.9+0.5);c['ym']=Math.round(c['wy']*0.8+0.5);if(c['ym']>c['xm']){c['ym']=c['xm']}c['xo']=0.0;c['yo']=0.0;c['ctx']=c['can'].getContext('2d');c['ctx'].canvas.width=c['xm']+1;c['ctx'].canvas.height=c['ym']+1;div.appendChild(c['can'])} +function gopt(c){ccb(c,'smooth');ccb(c,'over');ccb(c,'skey');ccb(c,'slines');ccb(c,'tkey');ccb(c,'tlines');ccb(c,'zerob');ccb(c,'utc')} +function gdrw(d){var c={};gc(c);gopt(c); gfs(c,'white');gss(c,'#0000c0');glw(c,0.5);gbd(c); var rows=d['rows'],ymin=-1,ymax=0,xmin=-1,xmax=0; var tda=0; diff --git a/pool/page_usperf.php b/pool/page_usperf.php index 650df30f..68794134 100644 --- a/pool/page_usperf.php +++ b/pool/page_usperf.php @@ -10,7 +10,7 @@ function dousperf($data, $user) else $vlines = true; - $pg = '

User Shift Performance


'; + $pg = '

User Shift Reward Performance


'; if ($ans['STATUS'] == 'ok' and $ans['DATA'] != '') { $pg .= "
shift key "; @@ -22,7 +22,8 @@ function dousperf($data, $user) $pg .= " time lines "; $pg .= " key overlap "; $pg .= " smooth "; - $pg .= " zero based
"; + $pg .= " zero based "; + $pg .= " utc"; $pg .= "
"; $pg .= "A graph will show here if your browser supports html5/canvas"; $pg .= "
\n"; From c4dda1d52139bec2f6c7551c311214ee96c52947 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 19 Mar 2015 20:35:46 +1100 Subject: [PATCH 02/10] php - javascript bugs --- html/can.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/html/can.js b/html/can.js index f4acd2ef..d7f05687 100644 --- a/html/can.js +++ b/html/can.js @@ -1,6 +1,6 @@ function hasCan(){var c0=document.getElementById('can0');c=document.getElementById('can');return !!(c0&&c&&c.getContext&&c.getContext('2d'));} function sep(d){ans={};var ar=d.split("\t");var l=ar.length;for(var i=0;i(zm-0.5)){return(zm-0.5)}return z} function gchx(c,x){return gch(x*c['xm']+c['xo'],c['ctx'].canvas.width)} @@ -48,7 +48,7 @@ glw(c,0.2); gss(c,'red'); var y=(av-y0)/(y1-y0); gbe(c,0,y);gln(c,1,y);gst(c); -var t=''+av.toFixed(2).'av';gfz(c,1,y,1,0,t,'red','left') +var t=''+av.toFixed(2)+'av';gfz(c,1,y,1,0,t,'red','left') } function sn(i,shi){if(shi.indexOf(' Shift ')<0){return ''+(i%10)}else{return shi.replace(/.* ([a-z])[a-z]*$/,'$1')}} function gc(c){var div=document.getElementById('can0');while(div.firstChild){div.removeChild(div.firstChild)}c['can']=document.createElement('canvas');c['can'].id='can';c['wx']=window.innerWidth;c['wy']=window.innerHeight;c['xm']=Math.round(c['wx']*0.9+0.5);c['ym']=Math.round(c['wy']*0.8+0.5);if(c['ym']>c['xm']){c['ym']=c['xm']}c['xo']=0.0;c['yo']=0.0;c['ctx']=c['can'].getContext('2d');c['ctx'].canvas.width=c['xm']+1;c['ctx'].canvas.height=c['ym']+1;div.appendChild(c['can'])} From 89935e876cc1e3a2d73743811f4c505e6e0cabcf Mon Sep 17 00:00:00 2001 From: kanoi Date: Sat, 21 Mar 2015 01:37:15 +1100 Subject: [PATCH 03/10] php - store graph settings in a cookie --- html/can.js | 66 ---------------------------------------- pool/page.php | 71 ++++++++++++++++++++++++++++++++++++++++++-- pool/page_usperf.php | 62 ++++++++++++++++++++++++++++---------- 3 files changed, 115 insertions(+), 84 deletions(-) delete mode 100644 html/can.js diff --git a/html/can.js b/html/can.js deleted file mode 100644 index d7f05687..00000000 --- a/html/can.js +++ /dev/null @@ -1,66 +0,0 @@ -function hasCan(){var c0=document.getElementById('can0');c=document.getElementById('can');return !!(c0&&c&&c.getContext&&c.getContext('2d'));} -function sep(d){ans={};var ar=d.split("\t");var l=ar.length;for(var i=0;i(zm-0.5)){return(zm-0.5)}return z} -function gchx(c,x){return gch(x*c['xm']+c['xo'],c['ctx'].canvas.width)} -function gchy(c,y){return gch((1-y)*c['ym']+c['yo'],c['ctx'].canvas.height)} -function gx0(c){return -c['xo']/c['xm']}; -function gy0(c){return -c['yo']/c['ym']}; -function gto(c,xo,yo){c['xo']+=xo;c['yo']+=yo} -function gts(c,xs,ys){c['xm']*=xs;c['ym']*=ys} -function gtso(c,xs,ys){gto(c,c['xm']*(1.0-xs)/2.0,c['ym']*(1.0-ys)/2.0);gts(c,xs,ys)} -function gfs(c,bg){c['ctx'].fillStyle=bg} -function gss(c,fg){c['ctx'].strokeStyle=fg} -function glw(c,pct){c['ctx'].lineWidth=pct*c['ym']/100.0} -function glwr(c,rat){c['ctx'].lineWidth*=rat} -function gfz(c,x,y,ox,oy,t,co,a){gfs(c,co);c['ctx'].textAlign=a;c['ctx'].fillText(t,gchx(c,x)+ox,gchy(c,y)-oy)} -function gbe(c,x,y){c['ctx'].beginPath();c['ctx'].moveTo(gchx(c,x),gchy(c,y))} -function gln(c,x,y){c['ctx'].lineTo(gchx(c,x),gchy(c,y))} -function gct(c,x1,y1,x2,y2,x3,y3){c['ctx'].bezierCurveTo(gchx(c,x1),gchy(c,y1),gchx(c,x2),gchy(c,y2),gchx(c,x3),gchy(c,y3))} -function glm(c,x,y){c['ctx'].moveTo(gchx(c,x),gchy(c,y))} -function gle(c){c['ctx'].closePath()} -function gfl(c){c['ctx'].fill()} -function gst(c){c['ctx'].stroke()} -function gfi(c){gle(c);gst(c)} -function gbd(c){gbe(c,0,0);gln(c,1,0);gln(c,1,1);gln(c,0,1);gle(c);gfl(c);gst(c)} -function ggr(c,xs,ys,yt,xn,x0,x1,y0,y1,ar,nx,vx,vy,av){ -gtso(c,xs,ys); -gss(c,'black');glw(c,0.2); -gbe(c,0,1);gln(c,0,0);gln(c,1,0);gst(c); -glw(c,0.01); -var hi=c['ctx'].measureText('M').width, wi=c['ctx'].measureText('1').width; -for(var i=0;i<11;i++){var y=i/10.0;gbe(c,-0.01,y);gln(c,1,y);gst(c);var t=''+(((y1-y0)*i/10+y0).toFixed(2));gfz(c,0,y,-wi,0,t,'black','end')} -gfz(c,gx0(c),0.55,wi,0,yt,'#0080ff','left'); -var m=Math.round(0.5+xn/20.0); -var f=1; -for(var i=0;i=x0;i-=(6*3600)){var n=dfmt(c,i);var xo=(i-x0)/(x1-x0);if(c['tkey']){gbe(c,xo,0);gln(c,xo,-0.02);gst(c);gfz(c,xo,0,0,-hi*tpos,n,'brown','center')}if(c['tlines']){gbe(c,xo,0);gln(c,xo,1);gst(c)}} -glw(c,0.1); -gss(c,'black'); -if(c['smooth']){var xa=0,ya=0,xb=0,yb=0; -for(var i=0;ic['xm']){c['ym']=c['xm']}c['xo']=0.0;c['yo']=0.0;c['ctx']=c['can'].getContext('2d');c['ctx'].canvas.width=c['xm']+1;c['ctx'].canvas.height=c['ym']+1;div.appendChild(c['can'])} -function gopt(c){ccb(c,'smooth');ccb(c,'over');ccb(c,'skey');ccb(c,'slines');ccb(c,'tkey');ccb(c,'tlines');ccb(c,'zerob');ccb(c,'utc')} -function gdrw(d){var c={};gc(c);gopt(c); -gfs(c,'white');gss(c,'#0000c0');glw(c,0.5);gbd(c); -var rows=d['rows'],ymin=-1,ymax=0,xmin=-1,xmax=0; -var tda=0; -for(var i=0;iths){ymin=ths}if(ths>ymax)ymax=ths;d['nx:'+i]=sn(i,d['shift:'+i]);if(xmin==-1||xmin>s){xmin=s}if(xmax 'shift key', 'slines' => 'shift lines', + 'tkey' => 'time key', 'tlines' => 'times lines', + 'over' => 'key overlap', 'smooth' => 'smooth', + 'zerob' => 'zero based', 'utc' => 'utc'); + $xon = array('skey' => 1, 'utc' => 1); + if ($vlines === true) + $xon['slines'] = 1; + + $pg .= '
'; + foreach ($cbx as $nam => $txt) + $pg .= " $txt "; + + $pg .= '
'; + $pg .= '
'; + $pg .= 'A graph will show here if your browser supports html5/canvas'; $pg .= "
\n"; $data = str_replace(array("\\","'"), array("\\\\","\\'"), $ans['DATA']); - $pg .= "\n"; - $pg .= "\n"; + $pg .= "\n"; } - return $pg; } # From 5da07e5f98ff70d3d24dd9744a5c1a3ad37cd13b Mon Sep 17 00:00:00 2001 From: kanoi Date: Sat, 21 Mar 2015 02:18:29 +1100 Subject: [PATCH 04/10] php - usperf remove duplicate code line --- pool/page_usperf.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pool/page_usperf.php b/pool/page_usperf.php index 1ac1375d..2d9d5fb5 100644 --- a/pool/page_usperf.php +++ b/pool/page_usperf.php @@ -6,7 +6,6 @@ $g = "function gdrw(c,d,cbx){gc(c);ghrs(c);gopt(c,cbx); gfs(c,'white');gss(c,'#0000c0');glw(c,2);gbd(c); var rows=d['rows'],ymin=-1,ymax=0,xmin=-1,xmax=0,tda=0; for(var i=0;iths){ymin=ths}if(ths>ymax)ymax=ths;d['nx:'+i]=sn(i,d['shift:'+i]);if(xmin==-1||xmin>s){xmin=s}if(xmaxths){ymin=ths}if(ths>ymax)ymax=ths;d['nx:'+i]=sn(i,d['shift:'+i]);if(xmin==-1||xmin>s){xmin=s}if(xmax 'shift key', 'slines' => 'shift lines', - 'tkey' => 'time key', 'tlines' => 'times lines', + 'tkey' => 'time key', 'tlines' => 'time lines', 'over' => 'key overlap', 'smooth' => 'smooth', 'zerob' => 'zero based', 'utc' => 'utc'); $xon = array('skey' => 1, 'utc' => 1); From c7dbb0114d8368ad113c865b1dcffcedd5da4afd Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 21 Mar 2015 10:53:45 +1100 Subject: [PATCH 05/10] Rework sessionid matching to not store client structure --- src/stratifier.c | 184 ++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 105 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 32123a6d..fc3fa50d 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -227,6 +227,7 @@ struct stratum_instance { uchar enonce1bin[16]; char enonce1var[12]; uint64_t enonce1_64; + int session_id; int64_t diff; /* Current diff */ int64_t old_diff; /* Previous diff */ @@ -278,6 +279,16 @@ struct share { typedef struct share share_t; +typedef struct session session_t; + +struct session { + UT_hash_handle hh; + int session_id; + uint64_t enonce1_64; + int64_t client_id; + time_t added; +}; + struct stratifier_data { char pubkeytxnbin[25]; char donkeytxnbin[25]; @@ -309,6 +320,7 @@ struct stratifier_data { int64_t workbase_id; int64_t blockchange_id; + int session_id; char lasthash[68]; char lastswaphash[68]; @@ -321,14 +333,12 @@ struct stratifier_data { int64_t user_instance_id; - /* Stratum_instances hashlist is stored by id, whereas disconnected_instances - * is sorted by enonce1_64. */ stratum_instance_t *stratum_instances; - stratum_instance_t *disconnected_instances; stratum_instance_t *recycled_instances; int stratum_generated; int disconnected_generated; + session_t *disconnected_sessions; user_instance_t *user_instances; @@ -938,13 +948,6 @@ static void __kill_instance(sdata_t *sdata, stratum_instance_t *client) DL_APPEND(sdata->recycled_instances, client); } -static void __del_disconnected(sdata_t *sdata, stratum_instance_t *client) -{ - HASH_DEL(sdata->disconnected_instances, client); - sdata->stats.disconnected--; - __kill_instance(sdata, client); -} - /* Called with instance_lock held. Note stats.users is protected by * instance lock to avoid recursive locking. */ static void __inc_worker(sdata_t *sdata, user_instance_t *instance) @@ -961,6 +964,35 @@ static void __dec_worker(sdata_t *sdata, user_instance_t *instance) sdata->stats.users--; } +static void __disconnect_session(sdata_t *sdata, const stratum_instance_t *client) +{ + time_t now_t = time(NULL); + session_t *session, *tmp; + + /* Opportunity to age old sessions */ + HASH_ITER(hh, sdata->disconnected_sessions, session, tmp) { + if (now_t - session->added > 600) { + HASH_DEL(sdata->disconnected_sessions, session); + dealloc(session); + sdata->stats.disconnected--; + } + } + + if (!client->enonce1_64) + return; + HASH_FIND_INT(sdata->disconnected_sessions, &client->session_id, session); + if (session) + return; + session = ckalloc(sizeof(session_t)); + session->enonce1_64 = client->enonce1_64; + session->session_id = client->session_id; + session->client_id = client->id; + session->added = now_t; + HASH_ADD_INT(sdata->disconnected_sessions, session_id, session); + sdata->stats.disconnected++; + sdata->disconnected_generated++; +} + /* Removes a client instance we know is on the stratum_instances list and from * the user client list if it's been placed on it */ static void __del_client(sdata_t *sdata, stratum_instance_t *client, user_instance_t *user) @@ -970,13 +1002,14 @@ static void __del_client(sdata_t *sdata, stratum_instance_t *client, user_instan DL_DELETE(user->clients, client); __dec_worker(sdata, user); } + } static void drop_allclients(ckpool_t *ckp) { stratum_instance_t *client, *tmp; - int disconnects = 0, kills = 0; sdata_t *sdata = ckp->data; + int kills = 0; char buf[128]; ck_wlock(&sdata->instance_lock); @@ -992,15 +1025,9 @@ static void drop_allclients(ckpool_t *ckp) sprintf(buf, "dropclient=%"PRId64, client_id); send_proc(ckp->connector, buf); } - HASH_ITER(hh, sdata->disconnected_instances, client, tmp) { - disconnects++; - __del_disconnected(sdata, client); - } sdata->stats.users = sdata->stats.workers = 0; ck_wunlock(&sdata->instance_lock); - if (disconnects) - LOGNOTICE("Disconnected %d instances", disconnects); if (kills) LOGNOTICE("Dropped %d instances", kills); } @@ -1223,56 +1250,26 @@ static stratum_instance_t *ref_instance_by_id(sdata_t *sdata, const int64_t id) return client; } -/* Has this client_id already been used and is now in one of the dropped lists */ -static bool __dropped_instance(sdata_t *sdata, const int64_t id) -{ - stratum_instance_t *client, *tmp; - bool ret = false; - - HASH_ITER(hh, sdata->disconnected_instances, client, tmp) { - if (unlikely(client->id == id)) { - ret = true; - goto out; - } - } -out: - return ret; -} - -/* Ret = 1 is disconnected, 2 is killed, 3 is workerless killed */ static void __drop_client(sdata_t *sdata, stratum_instance_t *client, user_instance_t *user, bool lazily, char **msg) { - stratum_instance_t *old_client = NULL; __del_client(sdata, client, user); - HASH_FIND(hh, sdata->disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client); - /* Only keep around one copy of the old client in server mode */ - if (!client->ckp->proxy && !old_client && client->enonce1_64 && client->authorised) { - ASPRINTF(msg, "Client %"PRId64" %s %suser %s worker %s disconnected %s", - client->id, client->address, user->throttled ? "throttled " : "", - user->username, client->workername, lazily ? "lazily" : ""); - HASH_ADD(hh, sdata->disconnected_instances, enonce1_64, sizeof(uint64_t), client); - sdata->stats.disconnected++; - sdata->disconnected_generated++; - client->disconnected_time = time(NULL); - } else { - if (client->workername) { - if (user) { - ASPRINTF(msg, "Client %"PRId64" %s %suser %s worker %s dropped %s", - client->id, client->address, user->throttled ? "throttled " : "", - user->username, client->workername, lazily ? "lazily" : ""); - } else { - ASPRINTF(msg, "Client %"PRId64" %s no user worker %s dropped %s", - client->id, client->address, client->workername, - lazily ? "lazily" : ""); - } + if (client->workername) { + if (user) { + ASPRINTF(msg, "Client %"PRId64" %s %suser %s worker %s dropped %s", + client->id, client->address, user->throttled ? "throttled " : "", + user->username, client->workername, lazily ? "lazily" : ""); } else { - ASPRINTF(msg, "Workerless client %"PRId64" %s dropped %s", - client->id, client->address, lazily ? "lazily" : ""); + ASPRINTF(msg, "Client %"PRId64" %s no user worker %s dropped %s", + client->id, client->address, client->workername, + lazily ? "lazily" : ""); } - __kill_instance(sdata, client); + } else { + ASPRINTF(msg, "Workerless client %"PRId64" %s dropped %s", + client->id, client->address, lazily ? "lazily" : ""); } + __kill_instance(sdata, client); } /* Decrease the reference count of instance. */ @@ -1326,6 +1323,7 @@ static stratum_instance_t *__stratum_add_instance(ckpool_t *ckp, const int64_t i client = __recruit_stratum_instance(sdata); client->id = id; + client->session_id = ++sdata->session_id; strcpy(client->address, address); client->server = server; client->diff = client->old_diff = ckp->startdiff; @@ -1337,42 +1335,31 @@ static stratum_instance_t *__stratum_add_instance(ckpool_t *ckp, const int64_t i static uint64_t disconnected_sessionid_exists(sdata_t *sdata, const char *sessionid, const int64_t id) { - stratum_instance_t *client, *tmp; - uint64_t enonce1_64 = 0, ret = 0; + int session_id, slen; + session_t *session; int64_t old_id = 0; - int slen; + uint64_t ret = 0; if (!sessionid) goto out; slen = strlen(sessionid) / 2; - if (slen < 1 || slen > 8) + if (slen < 1 || slen > 4) goto out; if (!validhex(sessionid)) goto out; - /* Number is in BE but we don't swap either of them */ - hex2bin(&enonce1_64, sessionid, slen); + sscanf(sessionid, "%x", &session_id); ck_wlock(&sdata->instance_lock); - HASH_ITER(hh, sdata->stratum_instances, client, tmp) { - if (client->id == id) - continue; - if (client->enonce1_64 == enonce1_64) { - /* Only allow one connected instance per enonce1 */ - goto out_unlock; - } - } - client = NULL; - HASH_FIND(hh, sdata->disconnected_instances, &enonce1_64, sizeof(uint64_t), client); - if (client) { - /* Delete the entry once we are going to use it since there - * will be a new instance with the enonce1_64 */ - old_id = client->id; - __del_disconnected(sdata, client); - - ret = enonce1_64; - } + HASH_FIND_INT(sdata->disconnected_sessions, &session_id, session); + if (!session) + goto out_unlock; + HASH_DEL(sdata->disconnected_sessions, session); + sdata->stats.disconnected--; + ret = session->enonce1_64; + old_id = session->client_id; + dealloc(session); out_unlock: ck_wunlock(&sdata->instance_lock); out: @@ -1444,11 +1431,9 @@ static void stratum_add_send(sdata_t *sdata, json_t *val, const int64_t client_i static void drop_client(sdata_t *sdata, const int64_t id) { - stratum_instance_t *client, *tmp; char_entry_t *entries = NULL; user_instance_t *user = NULL; - time_t now_t = time(NULL); - int aged = 0; + stratum_instance_t *client; char *msg; LOGINFO("Stratifier asked to drop client %"PRId64, id); @@ -1456,6 +1441,7 @@ static void drop_client(sdata_t *sdata, const int64_t id) ck_wlock(&sdata->instance_lock); client = __instance_by_id(sdata, id); if (client && !client->dropped) { + __disconnect_session(sdata, client); user = client->user_instance; /* If the client is still holding a reference, don't drop them * now but wait till the reference is dropped */ @@ -1465,21 +1451,9 @@ static void drop_client(sdata_t *sdata, const int64_t id) } else client->dropped = true; } - - /* Old disconnected instances will not have any valid shares so remove - * them from the disconnected instances list if they've been dead for - * more than 10 minutes */ - HASH_ITER(hh, sdata->disconnected_instances, client, tmp) { - if (now_t - client->disconnected_time < 600) - continue; - aged++; - __del_disconnected(sdata, client); - } ck_wunlock(&sdata->instance_lock); notice_msg_entries(&entries); - if (aged) - LOGINFO("Aged %d disconnected instances to dead", aged); } static void stratum_broadcast_message(sdata_t *sdata, const char *msg) @@ -1696,7 +1670,8 @@ static char *stratifier_stats(ckpool_t *ckp, sdata_t *sdata) objects = sdata->stats.disconnected; generated = sdata->disconnected_generated; - memsize = sizeof(stratum_instance_t) * sdata->stats.disconnected; + memsize = SAFE_HASH_OVERHEAD(sdata->disconnected_sessions); + memsize += sizeof(session_t) * sdata->stats.disconnected; JSON_CPACK(subval, "{si,si,si}", "count", objects, "memory", memsize, "generated", generated); json_set_object(val, "disconnected", subval); ck_runlock(&sdata->instance_lock); @@ -1978,6 +1953,7 @@ static json_t *parse_subscribe(stratum_instance_t *client, const int64_t client_ { sdata_t *sdata = client->ckp->data; bool old_match = false; + char sessionid[12]; int arr_size; json_t *ret; int n2len; @@ -2039,7 +2015,8 @@ static json_t *parse_subscribe(stratum_instance_t *client, const int64_t client_ n2len = sdata->workbases->enonce2varlen; else n2len = 8; - JSON_CPACK(ret, "[[[s,s]],s,i]", "mining.notify", client->enonce1, client->enonce1, + sprintf(sessionid, "%x", client->session_id); + JSON_CPACK(ret, "[[[s,s]],s,i]", "mining.notify", sessionid, client->enonce1, n2len); ck_runlock(&sdata->workbase_lock); @@ -3572,11 +3549,8 @@ static void srecv_process(ckpool_t *ckp, char *buf) client = __instance_by_id(sdata, msg->client_id); /* If client_id instance doesn't exist yet, create one */ if (unlikely(!client)) { - if (likely(!__dropped_instance(sdata, msg->client_id))) { - noid = true; - client = __stratum_add_instance(ckp, msg->client_id, address, server); - } else - dropped = true; + noid = true; + client = __stratum_add_instance(ckp, msg->client_id, address, server); } else if (unlikely(client->dropped)) dropped = true; if (likely(!dropped)) From 08622a4b617324b99c4785d56d867e4850fe0179 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 21 Mar 2015 11:56:01 +1100 Subject: [PATCH 06/10] Hand old sessionid to new client --- src/stratifier.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index fc3fa50d..5904b56a 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1333,12 +1333,13 @@ static stratum_instance_t *__stratum_add_instance(ckpool_t *ckp, const int64_t i return client; } -static uint64_t disconnected_sessionid_exists(sdata_t *sdata, const char *sessionid, const int64_t id) +static uint64_t disconnected_sessionid_exists(sdata_t *sdata, const char *sessionid, + int *session_id, const int64_t id) { - int session_id, slen; session_t *session; int64_t old_id = 0; uint64_t ret = 0; + int slen; if (!sessionid) goto out; @@ -1349,10 +1350,11 @@ static uint64_t disconnected_sessionid_exists(sdata_t *sdata, const char *sessio if (!validhex(sessionid)) goto out; - sscanf(sessionid, "%x", &session_id); + sscanf(sessionid, "%x", session_id); + LOGDEBUG("Testing for sessionid %s %x", sessionid, *session_id); ck_wlock(&sdata->instance_lock); - HASH_FIND_INT(sdata->disconnected_sessions, &session_id, session); + HASH_FIND_INT(sdata->disconnected_sessions, session_id, session); if (!session) goto out_unlock; HASH_DEL(sdata->disconnected_sessions, session); @@ -1983,9 +1985,9 @@ static json_t *parse_subscribe(stratum_instance_t *client, const int64_t client_ /* This would be the session id for reconnect, it will * not work for clients on a proxied connection. */ buf = json_string_value(json_array_get(params_val, 1)); - LOGDEBUG("Found old session id %s", buf); + LOGWARNING("Found old session id %s", buf); /* Add matching here */ - if ((client->enonce1_64 = disconnected_sessionid_exists(sdata, buf, client_id))) { + if ((client->enonce1_64 = disconnected_sessionid_exists(sdata, buf, &client->session_id, client_id))) { sprintf(client->enonce1, "%016lx", client->enonce1_64); old_match = true; @@ -2015,7 +2017,7 @@ static json_t *parse_subscribe(stratum_instance_t *client, const int64_t client_ n2len = sdata->workbases->enonce2varlen; else n2len = 8; - sprintf(sessionid, "%x", client->session_id); + sprintf(sessionid, "%08x", client->session_id); JSON_CPACK(ret, "[[[s,s]],s,i]", "mining.notify", sessionid, client->enonce1, n2len); ck_runlock(&sdata->workbase_lock); From 6e41ff823f0f8ee897a9c4a64ba4e1419d4088cf Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 21 Mar 2015 11:58:16 +1100 Subject: [PATCH 07/10] Demote debug --- src/stratifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stratifier.c b/src/stratifier.c index 5904b56a..35eba5bb 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1985,7 +1985,7 @@ static json_t *parse_subscribe(stratum_instance_t *client, const int64_t client_ /* This would be the session id for reconnect, it will * not work for clients on a proxied connection. */ buf = json_string_value(json_array_get(params_val, 1)); - LOGWARNING("Found old session id %s", buf); + LOGDEBUG("Found old session id %s", buf); /* Add matching here */ if ((client->enonce1_64 = disconnected_sessionid_exists(sdata, buf, &client->session_id, client_id))) { sprintf(client->enonce1, "%016lx", client->enonce1_64); From cecf6406e244002be6ed4baca06cd28cbe058f2b Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 21 Mar 2015 12:23:12 +1100 Subject: [PATCH 08/10] Fix memory leak --- src/stratifier.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stratifier.c b/src/stratifier.c index 32123a6d..9449dec9 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -4182,6 +4182,7 @@ static void *statsupdate(void *arg) char_t = ckalloc(sizeof(char_entry_t)); s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); ASPRINTF(&char_t->buf, "User %s:%s", user->username, s); + dealloc(s); DL_APPEND(char_list, char_t); } json_decref(val); From a8b7916829a55fff021e39fca8760a57e11b48b1 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 21 Mar 2015 12:23:12 +1100 Subject: [PATCH 09/10] Fix memory leak --- src/stratifier.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stratifier.c b/src/stratifier.c index 35eba5bb..0562741a 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -4158,6 +4158,7 @@ static void *statsupdate(void *arg) char_t = ckalloc(sizeof(char_entry_t)); s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); ASPRINTF(&char_t->buf, "User %s:%s", user->username, s); + dealloc(s); DL_APPEND(char_list, char_t); } json_decref(val); From 3ea6fa5dfeed414d1c430a2e88a9dcf2f50abd20 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 21 Mar 2015 12:58:39 +1100 Subject: [PATCH 10/10] Don't bother storing the session of clients without a user set up or not authorised --- src/stratifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stratifier.c b/src/stratifier.c index 0562741a..4f50c4cb 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -978,7 +978,7 @@ static void __disconnect_session(sdata_t *sdata, const stratum_instance_t *clien } } - if (!client->enonce1_64) + if (!client->enonce1_64 || !client->user_instance || !client->authorised) return; HASH_FIND_INT(sdata->disconnected_sessions, &client->session_id, session); if (session)