ckdb/php/sql - db storage of payout details and calculations
This commit is contained in:
parent
042360bf40
commit
2035db91b6
327
pool/page_pplns2.php
Normal file
327
pool/page_pplns2.php
Normal file
@ -0,0 +1,327 @@
|
||||
<?php
|
||||
#
|
||||
function stnum($num)
|
||||
{
|
||||
$b4 = '';
|
||||
$af = '';
|
||||
$fmt = number_format($num, 0);
|
||||
if ($num > 99999999)
|
||||
$b4 = '<span class=urg>';
|
||||
else if ($num > 9999999)
|
||||
$b4 = '<span class=warn>';
|
||||
if ($b4 != '')
|
||||
$af = '</span>';
|
||||
return $b4.$fmt.$af;
|
||||
}
|
||||
#
|
||||
# ... Of course ... check the output and add the txin ... etc.
|
||||
function calctx($ans, $count, $miner_sat, $diffacc_total)
|
||||
{
|
||||
$pg = '<br><table cellpadding=0 cellspacing=0 border=0>';
|
||||
$pg .= '<tr><td>';
|
||||
|
||||
$dust = getparam('dust', true);
|
||||
if (nuem($dust) || $dust <= 0)
|
||||
$dust = 10000;
|
||||
|
||||
$fee = getparam('fee', true);
|
||||
if (nuem($fee) || $fee < 0)
|
||||
$fee = 0;
|
||||
$fee *= 100000000;
|
||||
|
||||
$adr = array();
|
||||
$ers = '';
|
||||
$unpaid = 0;
|
||||
$change = $miner_sat;
|
||||
$dust_amt = 0; # not included in $change
|
||||
for ($i = 0; $i < $count; $i++)
|
||||
{
|
||||
$username = $ans['user:'.$i];
|
||||
$diffacc_user = $ans['diffacc:'.$i];
|
||||
$pay_sat = $ans['amount:'.$i];
|
||||
$payaddress = $ans['payaddress:'.$i];
|
||||
if ($payaddress == 'none')
|
||||
{
|
||||
$c0 = substr($username, 0, 1);
|
||||
$parts = explode('.', $username);
|
||||
$len = strlen($parts[0]);
|
||||
if (($c0 == '1' || $c0 == '3') && $len > 26 && $len < 37)
|
||||
$payaddress = $parts[0];
|
||||
else
|
||||
{
|
||||
if ($pay_sat > 0)
|
||||
{
|
||||
$dd = '';
|
||||
if ($pay_sat < $dust)
|
||||
$dd = ' (dust)';
|
||||
$ers .= "No address for '$username'$dd<br>";
|
||||
}
|
||||
$unpaid += $pay_sat;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (isset($adr[$payaddress]))
|
||||
$adr[$payaddress] += $pay_sat;
|
||||
else
|
||||
$adr[$payaddress] = $pay_sat;
|
||||
|
||||
$change -= $pay_sat;
|
||||
}
|
||||
|
||||
$txout = '';
|
||||
$comma = '';
|
||||
foreach ($adr as $payaddress => $pay_sat)
|
||||
{
|
||||
if ($pay_sat < $dust)
|
||||
$dust_amt += $pay_sat;
|
||||
else
|
||||
{
|
||||
$txout .= "$comma\"$payaddress\":".btcfmt($pay_sat);
|
||||
$comma = ', ';
|
||||
}
|
||||
}
|
||||
|
||||
if ($change > 0 || $dust_amt > 0 || $change < $fee)
|
||||
{
|
||||
$pg .= "<span class=err>Dust limit = $dust = ".btcfmt($dust);
|
||||
$pg .= ", Dust amount = $dust_amt = ".btcfmt($dust_amt);
|
||||
$pg .= ",<br>Upaid = $unpaid = ".btcfmt($unpaid);
|
||||
$pg .= ", Change = $change = ".btcfmt($change);
|
||||
$pg .= ",<br>Fee = $fee = ".btcfmt($fee)."</span><br>";
|
||||
|
||||
if ($change < $fee)
|
||||
$ers .= "Change ($change) is less than Fee ($fee)<br>";
|
||||
|
||||
if (($dust_amt + $change - $fee) > 0)
|
||||
{
|
||||
$txout .= "$comma\"<changeaddress>\":";
|
||||
$txout .= btcfmt($dust_amt + $change - $fee);
|
||||
$comma = ', ';
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen($ers) > 0)
|
||||
$pg .= "<span class=err>$ers</span><br>";
|
||||
|
||||
$txn = '[{"txid":"<txid1>","vout":<n>},';
|
||||
$txn .= '{"txid":"<txid2>","vout":<n>}] ';
|
||||
$txn .= '{'.$txout.'}<br>';
|
||||
|
||||
$pg .= $txn.'</td></tr></table>';
|
||||
return $pg;
|
||||
}
|
||||
#
|
||||
function fmtdata($code, $val)
|
||||
{
|
||||
switch ($code)
|
||||
{
|
||||
case ',':
|
||||
$ret = number_format($val);
|
||||
break;
|
||||
case '.':
|
||||
$ret = number_format($val, 1);
|
||||
break;
|
||||
default:
|
||||
$ret = $val;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
#
|
||||
function dopplns2($data, $user)
|
||||
{
|
||||
global $send_sep;
|
||||
|
||||
$pg = '<h1>CKPool</h1>';
|
||||
|
||||
$blk = getparam('blk', true);
|
||||
if (nuem($blk))
|
||||
{
|
||||
$tx = '';
|
||||
# so can make a link
|
||||
$blkuse = getparam('blkuse', true);
|
||||
if (nuem($blkuse))
|
||||
$blkuse = '';
|
||||
else
|
||||
$tx = 'y';
|
||||
$pg = '<br>'.makeForm('pplns2')."
|
||||
Block: <input type=text name=blk size=10 value='$blkuse'>
|
||||
Tx: <input type=text name=tx size=1 value='$tx'>
|
||||
Dust (Satoshi): <input type=text name=dust size=5 value='10000'>
|
||||
Fee (BTC): <input type=text name=fee size=5 value='0.0'>
|
||||
<input type=submit name=Calc value=Calc>
|
||||
</form>";
|
||||
}
|
||||
else
|
||||
{
|
||||
$tx = getparam('tx', true);
|
||||
if (nuem($tx) || substr($tx, 0, 1) != 'y')
|
||||
$dotx = false;
|
||||
else
|
||||
$dotx = true;
|
||||
|
||||
$flds = array('height' => $blk);
|
||||
$msg = msgEncode('pplns2', 'pplns2', $flds, $user);
|
||||
$rep = sendsockreply('pplns2', $msg, 4);
|
||||
if ($rep == false)
|
||||
$ans = array();
|
||||
else
|
||||
$ans = repDecode($rep);
|
||||
|
||||
|
||||
if ($ans['ERROR'] != null)
|
||||
return '<font color=red size=+1><br>'.$ans['STATUS'].': '.$ans['ERROR'].'</font>';
|
||||
|
||||
if (!isset($ans['pplns_last']))
|
||||
return '<font color=red size=+1><br>Partial data returned</font>';
|
||||
|
||||
$reward_sat = $ans['block_reward'];
|
||||
$miner_sat = $ans['miner_reward'];
|
||||
$ans['miner_sat'] = $miner_sat;
|
||||
|
||||
$data = array( 'Block' => 'block',
|
||||
'Block Status' => 'block_status',
|
||||
'Block Hash' => 'block_hash',
|
||||
'Block Reward (Satoshis)' => 'block_reward',
|
||||
'Miner Reward (Satoshis)' => 'miner_sat',
|
||||
'PPLNS Wanted' => '.diff_want',
|
||||
'PPLNS Used' => '.diffacc_total',
|
||||
'Elapsed Seconds' => ',pplns_elapsed',
|
||||
'Users' => 'rows',
|
||||
'Oldest Workinfoid' => 'begin_workinfoid',
|
||||
# 'Oldest Time' => 'begin_stamp',
|
||||
# 'Oldest Epoch' => 'begin_epoch',
|
||||
'Block Workinfoid' => 'block_workinfoid',
|
||||
# 'Block Time' => 'block_stamp',
|
||||
# 'Block Epoch' => 'block_epoch',
|
||||
'Newest Workinfoid' => 'end_workinfoid',
|
||||
# 'Newest Share Time' => 'end_stamp',
|
||||
# 'Newest Share Epoch' => 'end_epoch',
|
||||
'Network Difficulty' => 'block_ndiff',
|
||||
'PPLNS Factor' => 'diff_times',
|
||||
'PPLNS Added' => 'diff_add',
|
||||
'Accepted Share Count' => ',acc_share_count',
|
||||
'Total Share Count' => ',total_share_count',
|
||||
'ShareSummary Count' => ',ss_count',
|
||||
'WorkMarkers Count' => ',wm_count',
|
||||
'MarkerSummary Count' => ',ms_count');
|
||||
|
||||
$pg = '<br><a href=https://blockchain.info/block-height/';
|
||||
$pg .= $ans['block'].'>Blockchain '.$ans['block']."</a><br>\n";
|
||||
|
||||
if (strlen($ans['marks_status']) > 0)
|
||||
{
|
||||
$pg .= '<br><span class=err>';
|
||||
$msg = $ans['marks_status'];
|
||||
$pg .= str_replace(' ', ' ', $msg)."</span><br>\n";
|
||||
}
|
||||
|
||||
if (strlen($ans['block_extra']) > 0)
|
||||
{
|
||||
$pg .= '<br><span class=err>';
|
||||
$msg = $ans['block_status'].' - '.$ans['block_extra'];
|
||||
$pg .= str_replace(' ', ' ', $msg)."</span><br>\n";
|
||||
}
|
||||
|
||||
if (strlen($ans['share_status']) > 0)
|
||||
{
|
||||
$pg .= '<br><span class=err>';
|
||||
$msg = $ans['share_status']." - Can't be paid out yet";
|
||||
$pg .= str_replace(' ', ' ', $msg)."</span><br>\n";
|
||||
}
|
||||
|
||||
$pg .= "<br><table callpadding=0 cellspacing=0 border=0>\n";
|
||||
$pg .= '<tr class=title>';
|
||||
$pg .= '<td class=dl>Name</td>';
|
||||
$pg .= '<td class=dr>Value</td>';
|
||||
$pg .= "</tr>\n";
|
||||
$i = 0;
|
||||
foreach ($data as $dsp => $name)
|
||||
{
|
||||
if (($i++ % 2) == 0)
|
||||
$row = 'even';
|
||||
else
|
||||
$row = 'odd';
|
||||
|
||||
$pg .= "<tr class=$row>";
|
||||
$pg .= "<td class=dl>$dsp</td>";
|
||||
switch ($name[0])
|
||||
{
|
||||
case ',':
|
||||
case '.':
|
||||
$nm = substr($name, 1);
|
||||
$fmt = fmtdata($name[0], $ans[$nm]);
|
||||
break;
|
||||
default:
|
||||
$fmt = $ans[$name];
|
||||
break;
|
||||
}
|
||||
$pg .= "<td class=dr>$fmt</td>";
|
||||
$pg .= "</tr>\n";
|
||||
}
|
||||
|
||||
$pg .= "</table><br><table cellpadding=0 cellspacing=0 border=0>\n";
|
||||
$pg .= '<tr class=title>';
|
||||
$pg .= '<td class=dl>User</td>';
|
||||
$pg .= '<td class=dr>Diff Accepted</td>';
|
||||
$pg .= '<td class=dr>%</td>';
|
||||
$pg .= '<td class=dr>Avg Hashrate</td>';
|
||||
$pg .= '<td class=dr>BTC -0.9%</td>';
|
||||
$pg .= '<td class=dr>Address</td>';
|
||||
$pg .= "</tr>\n";
|
||||
|
||||
$diffacc_total = $ans['diffacc_total'];
|
||||
if ($diffacc_total == 0)
|
||||
$diffacc_total = pow(10,15);
|
||||
$elapsed = $ans['pplns_elapsed'];
|
||||
$count = $ans['rows'];
|
||||
$tot_pay = 0;
|
||||
for ($i = 0; $i < $count; $i++)
|
||||
{
|
||||
$diffacc_user = $ans['diffacc:'.$i];
|
||||
$diffacc_percent = number_format(100.0 * $diffacc_user / $diffacc_total, 3).'%';
|
||||
$avg_hash = number_format($diffacc_user / $elapsed * pow(2,32), 0);
|
||||
$pay_sat = $ans['amount:'.$i];
|
||||
$payaddress = $ans['payaddress:'.$i];
|
||||
|
||||
if (($i % 2) == 0)
|
||||
$row = 'even';
|
||||
else
|
||||
$row = 'odd';
|
||||
|
||||
$pg .= "<tr class=$row>";
|
||||
$pg .= '<td class=dl>'.$ans['user:'.$i].'</td>';
|
||||
$pg .= "<td class=dr>$diffacc_user</td>";
|
||||
$pg .= "<td class=dr>$diffacc_percent</td>";
|
||||
$pg .= "<td class=dr>$avg_hash</td>";
|
||||
$pg .= '<td class=dr>'.btcfmt($pay_sat).'</td>';
|
||||
$pg .= "<td class=dr>$payaddress</td>";
|
||||
$pg .= "</tr>\n";
|
||||
|
||||
$tot_pay += $pay_sat;
|
||||
}
|
||||
if (($i % 2) == 0)
|
||||
$row = 'even';
|
||||
else
|
||||
$row = 'odd';
|
||||
|
||||
$pg .= "<tr class=$row>";
|
||||
$pg .= '<td class=dl colspan=3></td>';
|
||||
$pg .= '<td class=dr></td>';
|
||||
$pg .= '<td class=dr>'.btcfmt($tot_pay).'</td>';
|
||||
$pg .= '<td class=dr></td>';
|
||||
$pg .= "</tr>\n";
|
||||
$pg .= "</table>\n";
|
||||
|
||||
if ($dotx === true)
|
||||
$pg .= calctx($ans, $count, $miner_sat, $diffacc_total);
|
||||
}
|
||||
|
||||
return $pg;
|
||||
}
|
||||
#
|
||||
function show_pplns2($info, $page, $menu, $name, $user)
|
||||
{
|
||||
gopage($info, NULL, 'dopplns2', $page, $menu, $name, $user);
|
||||
}
|
||||
#
|
||||
?>
|
||||
@ -19,6 +19,7 @@ function process($p, $user, $menu)
|
||||
if ($user == 'Kano' || $user == 'ckolivas')
|
||||
{
|
||||
$menu['Admin']['ckp'] = 'ckp';
|
||||
$menu['Admin']['PPLNS2'] = 'pplns2';
|
||||
$menu['Admin']['PPLNS'] = 'pplns';
|
||||
$menu['Admin']['AllWork'] = 'allwork';
|
||||
}
|
||||
|
||||
53
sql/ckdb.sql
53
sql/ckdb.sql
@ -84,11 +84,14 @@ CREATE UNIQUE INDEX payadduserid ON paymentaddresses USING btree (userid, payadd
|
||||
|
||||
CREATE TABLE payments (
|
||||
paymentid bigint NOT NULL, -- unique per record
|
||||
payoutid bigint NOT NULL,
|
||||
userid bigint NOT NULL,
|
||||
subname character varying(256) NOT NULL,
|
||||
paydate timestamp with time zone NOT NULL,
|
||||
payaddress character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
originaltxn character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
amount bigint NOT NULL, -- satoshis
|
||||
diffacc float DEFAULT 0 NOT NULL,
|
||||
committxn character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
commitblockhash character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
@ -98,10 +101,10 @@ CREATE TABLE payments (
|
||||
expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
PRIMARY KEY (paymentid, expirydate)
|
||||
);
|
||||
CREATE UNIQUE INDEX payuserid ON payments USING btree (userid, payaddress, originaltxn, expirydate);
|
||||
CREATE UNIQUE INDEX payuserid ON payments USING btree (payoutid, userid, subname, payaddress, originaltxn, expirydate);
|
||||
|
||||
|
||||
CREATE TABLE accountbalance ( -- summarised from miningpayouts and payments
|
||||
CREATE TABLE accountbalance ( -- summarised from miningpayouts and payments - RAM only
|
||||
userid bigint NOT NULL,
|
||||
confirmedpaid bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
confirmedunpaid bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
@ -111,8 +114,11 @@ CREATE TABLE accountbalance ( -- summarised from miningpayouts and payments
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
createcode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
createinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
PRIMARY KEY (userid, expirydate)
|
||||
modifydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
modifyby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
modifycode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
modifyinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
PRIMARY KEY (userid)
|
||||
);
|
||||
|
||||
|
||||
@ -120,6 +126,7 @@ CREATE TABLE accountadjustment ( -- manual corrections
|
||||
userid bigint NOT NULL,
|
||||
authority character varying(256) NOT NULL,
|
||||
reason text NOT NULL,
|
||||
message character varying(256) NOT NULL,
|
||||
amount bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
@ -341,22 +348,42 @@ CREATE TABLE blocks (
|
||||
);
|
||||
|
||||
|
||||
-- calculation for the given block - orphans will be here also (not deleted later)
|
||||
-- rules for orphans/next block will be pool dependent
|
||||
CREATE TABLE miningpayouts (
|
||||
miningpayoutid bigint NOT NULL, -- unique per record
|
||||
payoutid bigint NOT NULL,
|
||||
userid bigint NOT NULL,
|
||||
height integer not NULL,
|
||||
blockhash character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
amount bigint DEFAULT 0 NOT NULL,
|
||||
diffacc float DEFAULT 0 NOT NULL,
|
||||
amount bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
createcode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
createinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
PRIMARY KEY (miningpayoutid, expirydate)
|
||||
PRIMARY KEY (payoutid, userid, expirydate)
|
||||
);
|
||||
CREATE UNIQUE INDEX minpayuserid ON miningpayouts USING btree (userid, blockhash, expirydate);
|
||||
|
||||
|
||||
CREATE TABLE payouts (
|
||||
payoutid bigint NOT NULL, -- unique per record
|
||||
height integer not NULL,
|
||||
blockhash character varying(256) NOT NULL,
|
||||
minerreward bigint NOT NULL, -- satoshis
|
||||
workinfoidstart bigint NOT NULL,
|
||||
workinfoidend bigint NOT NULL, -- should be block workinfoid
|
||||
elapsed bigint NOT NULL,
|
||||
status char DEFAULT ' ' NOT NULL,
|
||||
diffwanted float DEFAULT 0 NOT NULL,
|
||||
diffused float DEFAULT 0 NOT NULL,
|
||||
shareacc float DEFAULT 0 NOT NULL,
|
||||
lastshareacc timestamp with time zone NOT NULL,
|
||||
stats text DEFAULT ''::text NOT NULL,
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
createcode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
createinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
PRIMARY KEY (payoutid, expirydate)
|
||||
);
|
||||
CREATE UNIQUE INDEX payoutsblock ON payouts USING btree (height, blockhash, expirydate);
|
||||
|
||||
|
||||
CREATE TABLE eventlog (
|
||||
@ -433,4 +460,4 @@ CREATE TABLE version (
|
||||
PRIMARY KEY (vlock)
|
||||
);
|
||||
|
||||
insert into version (vlock,version) values (1,'0.9.6');
|
||||
insert into version (vlock,version) values (1,'1.0.0');
|
||||
|
||||
@ -20,3 +20,4 @@ addid authid ${now}300000
|
||||
addid userid ${now}400000
|
||||
addid markerid ${now}500000
|
||||
addid paymentaddressid ${now}600000
|
||||
addid payoutid ${now}700000
|
||||
|
||||
101
sql/v0.9.6-v1.0.0.sql
Normal file
101
sql/v0.9.6-v1.0.0.sql
Normal file
@ -0,0 +1,101 @@
|
||||
SET SESSION AUTHORIZATION 'postgres';
|
||||
|
||||
BEGIN transaction;
|
||||
|
||||
DO $$
|
||||
DECLARE ver TEXT;
|
||||
BEGIN
|
||||
|
||||
UPDATE version set version='1.0.0' where vlock=1 and version='0.9.6';
|
||||
|
||||
IF found THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
SELECT version into ver from version
|
||||
WHERE vlock=1;
|
||||
|
||||
RAISE EXCEPTION 'Wrong DB version - expect "0.9.6" - found "%"', ver;
|
||||
|
||||
END $$;
|
||||
|
||||
DROP TABLE payments;
|
||||
CREATE TABLE payments (
|
||||
paymentid bigint NOT NULL, -- unique per record
|
||||
payoutid bigint NOT NULL,
|
||||
userid bigint NOT NULL,
|
||||
subname character varying(256) NOT NULL,
|
||||
paydate timestamp with time zone NOT NULL,
|
||||
payaddress character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
originaltxn character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
amount bigint NOT NULL, -- satoshis
|
||||
diffacc float DEFAULT 0 NOT NULL,
|
||||
committxn character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
commitblockhash character varying(256) DEFAULT ''::character varying NOT NULL,
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
createcode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
createinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
PRIMARY KEY (paymentid, expirydate)
|
||||
);
|
||||
CREATE UNIQUE INDEX payuserid ON payments USING btree (payoutid, userid, subname, payaddress, originaltxn, expirydate);
|
||||
|
||||
DROP TABLE accountbalance;
|
||||
CREATE TABLE accountbalance ( -- summarised from miningpayouts and payments - RAM only
|
||||
userid bigint NOT NULL,
|
||||
confirmedpaid bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
confirmedunpaid bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
pendingconfirm bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
heightupdate integer not NULL,
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
createcode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
createinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
modifydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
modifyby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
modifycode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
modifyinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
PRIMARY KEY (userid)
|
||||
);
|
||||
|
||||
DROP TABLE miningpayouts;
|
||||
CREATE TABLE miningpayouts (
|
||||
payoutid bigint NOT NULL,
|
||||
userid bigint NOT NULL,
|
||||
diffacc float DEFAULT 0 NOT NULL,
|
||||
amount bigint DEFAULT 0 NOT NULL, -- satoshis
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
createcode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
createinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
PRIMARY KEY (payoutid, userid, expirydate)
|
||||
);
|
||||
|
||||
CREATE TABLE payouts (
|
||||
payoutid bigint NOT NULL, -- unique per record
|
||||
height integer not NULL,
|
||||
blockhash character varying(256) NOT NULL,
|
||||
minerreward bigint NOT NULL, -- satoshis
|
||||
workinfoidstart bigint NOT NULL,
|
||||
workinfoidend bigint NOT NULL, -- should be block workinfoid
|
||||
elapsed bigint NOT NULL,
|
||||
status char DEFAULT ' ' NOT NULL,
|
||||
diffwanted float DEFAULT 0 NOT NULL,
|
||||
diffused float DEFAULT 0 NOT NULL,
|
||||
shareacc float DEFAULT 0 NOT NULL,
|
||||
lastshareacc timestamp with time zone NOT NULL,
|
||||
stats text DEFAULT ''::text NOT NULL,
|
||||
createdate timestamp with time zone NOT NULL,
|
||||
createby character varying(64) DEFAULT ''::character varying NOT NULL,
|
||||
createcode character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
createinet character varying(128) DEFAULT ''::character varying NOT NULL,
|
||||
expirydate timestamp with time zone DEFAULT '6666-06-06 06:06:06+00',
|
||||
PRIMARY KEY (payoutid, expirydate)
|
||||
);
|
||||
CREATE UNIQUE INDEX payoutsblock ON payouts USING btree (height, blockhash, expirydate);
|
||||
|
||||
insert into idcontrol (idname,lastid,createdate,createby) values ('payoutid',999,now(),'1.0.0update');
|
||||
|
||||
END transaction;
|
||||
78
src/ckdb.c
78
src/ckdb.c
@ -27,7 +27,7 @@
|
||||
* and ckpool only verifies authorise responses
|
||||
* Thus we can queue all messages:
|
||||
* workinfo, shares, shareerror, ageworkinfo, poolstats, userstats
|
||||
* and block
|
||||
* and blocks
|
||||
* with an ok.queued reply to ckpool, to be processed after the reload
|
||||
* completes and just process authorise messages immediately while the
|
||||
* reload runs
|
||||
@ -61,7 +61,7 @@
|
||||
* it would break the synchronisation and could cause DB problems, so
|
||||
* ckdb aborting and needing a complete restart resolves it
|
||||
* The users table, required for the authorise messages, is always updated
|
||||
* immediately and is not affected by ckpool messages until we
|
||||
* immediately
|
||||
*/
|
||||
|
||||
/* Reload data needed
|
||||
@ -92,17 +92,17 @@
|
||||
* already exist
|
||||
* DB+RAM blocks: resolved by workinfo - any unsaved blocks (if any)
|
||||
* will be after the last DB workinfo
|
||||
* DB+RAM accountbalance (TODO): resolved by shares/workinfo/blocks
|
||||
* RAM workerstatus: all except last_idle are set at the end of the
|
||||
* CCL reload
|
||||
* Code currently doesn't use last_idle
|
||||
* RAM accountbalance: TODO: created as data is loaded
|
||||
*
|
||||
* idcontrol: only userid reuse is critical and the user is added
|
||||
* immeditately to the DB before replying to the add message
|
||||
*
|
||||
* Tables that are/will be written straight to the DB, so are OK:
|
||||
* users, useraccounts, paymentaddresses, payments,
|
||||
* accountadjustment, optioncontrol, miningpayouts,
|
||||
* accountadjustment, optioncontrol, miningpayouts, payouts,
|
||||
* eventlog, workmarkers, markersummary
|
||||
*
|
||||
* The code deals with the issue of 'now' when reloading by:
|
||||
@ -329,6 +329,7 @@ K_STORE *workers_store;
|
||||
|
||||
// PAYMENTADDRESSES
|
||||
K_TREE *paymentaddresses_root;
|
||||
K_TREE *paymentaddresses_create_root;
|
||||
K_LIST *paymentaddresses_free;
|
||||
K_STORE *paymentaddresses_store;
|
||||
|
||||
@ -337,7 +338,6 @@ K_TREE *payments_root;
|
||||
K_LIST *payments_free;
|
||||
K_STORE *payments_store;
|
||||
|
||||
/* unused yet
|
||||
// ACCOUNTBALANCE
|
||||
K_TREE *accountbalance_root;
|
||||
K_LIST *accountbalance_free;
|
||||
@ -347,7 +347,6 @@ K_STORE *accountbalance_store;
|
||||
K_TREE *accountadjustment_root;
|
||||
K_LIST *accountadjustment_free;
|
||||
K_STORE *accountadjustment_store;
|
||||
*/
|
||||
|
||||
// IDCONTROL
|
||||
// These are only used for db access - not stored in memory
|
||||
@ -405,6 +404,13 @@ K_TREE *miningpayouts_root;
|
||||
K_LIST *miningpayouts_free;
|
||||
K_STORE *miningpayouts_store;
|
||||
|
||||
// PAYOUTS
|
||||
K_TREE *payouts_root;
|
||||
K_TREE *payouts_id_root;
|
||||
K_LIST *payouts_free;
|
||||
K_STORE *payouts_store;
|
||||
cklock_t process_pplns_lock;
|
||||
|
||||
/*
|
||||
// EVENTLOG
|
||||
K_TREE *eventlog_root;
|
||||
@ -742,6 +748,10 @@ static bool getdata3()
|
||||
goto sukamudai;
|
||||
if (!(ok = payments_fill(conn)) || everyone_die)
|
||||
goto sukamudai;
|
||||
if (!(ok = miningpayouts_fill(conn)) || everyone_die)
|
||||
goto sukamudai;
|
||||
if (!(ok = payouts_fill(conn)) || everyone_die)
|
||||
goto sukamudai;
|
||||
}
|
||||
if (!(ok = workinfo_fill(conn)) || everyone_die)
|
||||
goto sukamudai;
|
||||
@ -953,6 +963,7 @@ static void alloc_storage()
|
||||
LIMIT_PAYMENTADDRESSES, true);
|
||||
paymentaddresses_store = k_new_store(paymentaddresses_free);
|
||||
paymentaddresses_root = new_ktree();
|
||||
paymentaddresses_create_root = new_ktree();
|
||||
paymentaddresses_free->dsp_func = dsp_paymentaddresses;
|
||||
|
||||
payments_free = k_new_list("Payments", sizeof(PAYMENTS),
|
||||
@ -960,6 +971,11 @@ static void alloc_storage()
|
||||
payments_store = k_new_store(payments_free);
|
||||
payments_root = new_ktree();
|
||||
|
||||
accountbalance_free = k_new_list("AccountBalance", sizeof(ACCOUNTBALANCE),
|
||||
ALLOC_ACCOUNTBALANCE, LIMIT_ACCOUNTBALANCE, true);
|
||||
accountbalance_store = k_new_store(accountbalance_free);
|
||||
accountbalance_root = new_ktree();
|
||||
|
||||
idcontrol_free = k_new_list("IDControl", sizeof(IDCONTROL),
|
||||
ALLOC_IDCONTROL, LIMIT_IDCONTROL, true);
|
||||
idcontrol_store = k_new_store(idcontrol_free);
|
||||
@ -999,6 +1015,12 @@ static void alloc_storage()
|
||||
miningpayouts_store = k_new_store(miningpayouts_free);
|
||||
miningpayouts_root = new_ktree();
|
||||
|
||||
payouts_free = k_new_list("Payouts", sizeof(PAYOUTS),
|
||||
ALLOC_PAYOUTS, LIMIT_PAYOUTS, true);
|
||||
payouts_store = k_new_store(payouts_free);
|
||||
payouts_root = new_ktree();
|
||||
payouts_id_root = new_ktree();
|
||||
|
||||
auths_free = k_new_list("Auths", sizeof(AUTHS),
|
||||
ALLOC_AUTHS, LIMIT_AUTHS, true);
|
||||
auths_store = k_new_store(auths_free);
|
||||
@ -1110,6 +1132,10 @@ static void dealloc_storage()
|
||||
|
||||
FREE_ALL(poolstats);
|
||||
FREE_ALL(auths);
|
||||
|
||||
FREE_TREE(payouts_id);
|
||||
FREE_ALL(payouts);
|
||||
|
||||
FREE_ALL(miningpayouts);
|
||||
FREE_ALL(blocks);
|
||||
|
||||
@ -1131,7 +1157,10 @@ static void dealloc_storage()
|
||||
FREE_LIST_DATA(workinfo);
|
||||
|
||||
FREE_LISTS(idcontrol);
|
||||
FREE_ALL(accountbalance);
|
||||
FREE_ALL(payments);
|
||||
|
||||
FREE_TREE(paymentaddresses_create);
|
||||
FREE_ALL(paymentaddresses);
|
||||
FREE_ALL(workers);
|
||||
|
||||
@ -1534,6 +1563,20 @@ static void check_blocks()
|
||||
btc_blockstatus(blocks);
|
||||
}
|
||||
|
||||
static void pplns_block(BLOCKS *blocks)
|
||||
{
|
||||
if (sharesummary_marks_limit) {
|
||||
LOGEMERG("%s() sharesummary marks limit, block %"PRId32" payout skipped",
|
||||
__func__, blocks->height);
|
||||
return;
|
||||
}
|
||||
|
||||
// Give it a sec after the block summarisation
|
||||
sleep(1);
|
||||
|
||||
process_pplns(blocks->height, blocks->blockhash, NULL);
|
||||
}
|
||||
|
||||
static void summarise_blocks()
|
||||
{
|
||||
K_ITEM *b_item, *b_prev, *wi_item, ss_look, *ss_item;
|
||||
@ -1733,17 +1776,15 @@ static void summarise_blocks()
|
||||
"%0.f/%.0f/%.0f/%.0f/%"PRId64,
|
||||
__func__, blocks->height,
|
||||
diffacc, diffinv, shareacc, shareinv, elapsed);
|
||||
|
||||
// Now the summarisation is confirmed, generate the payout data
|
||||
pplns_block(blocks);
|
||||
} else {
|
||||
LOGERR("%s() block %d, failed to confirm stats",
|
||||
__func__, blocks->height);
|
||||
}
|
||||
}
|
||||
|
||||
static void summarise_poolstats()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
static void *summariser(__maybe_unused void *arg)
|
||||
{
|
||||
int i;
|
||||
@ -1752,7 +1793,7 @@ static void *summariser(__maybe_unused void *arg)
|
||||
|
||||
rename_proc("db_summariser");
|
||||
|
||||
while (!everyone_die && !db_load_complete)
|
||||
while (!everyone_die && !startup_complete)
|
||||
cksleep_ms(42);
|
||||
|
||||
summariser_using_data = true;
|
||||
@ -1764,12 +1805,8 @@ static void *summariser(__maybe_unused void *arg)
|
||||
}
|
||||
if (everyone_die)
|
||||
break;
|
||||
else {
|
||||
if (startup_complete)
|
||||
check_blocks();
|
||||
if (!everyone_die)
|
||||
summarise_blocks();
|
||||
}
|
||||
else
|
||||
check_blocks();
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (!everyone_die)
|
||||
@ -1778,7 +1815,7 @@ static void *summariser(__maybe_unused void *arg)
|
||||
if (everyone_die)
|
||||
break;
|
||||
else
|
||||
summarise_poolstats();
|
||||
summarise_blocks();
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (!everyone_die)
|
||||
@ -2624,6 +2661,7 @@ static void *socketer(__maybe_unused void *arg)
|
||||
case CMD_WORKERS:
|
||||
case CMD_PAYMENTS:
|
||||
case CMD_PPLNS:
|
||||
case CMD_PPLNS2:
|
||||
case CMD_DSP:
|
||||
case CMD_BLOCKSTATUS:
|
||||
if (!startup_complete) {
|
||||
@ -2841,6 +2879,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
|
||||
case CMD_DSP:
|
||||
case CMD_STATS:
|
||||
case CMD_PPLNS:
|
||||
case CMD_PPLNS2:
|
||||
case CMD_USERSTATUS:
|
||||
case CMD_MARKS:
|
||||
LOGERR("%s() Message line %"PRIu64" '%s' - invalid - ignored",
|
||||
@ -4062,6 +4101,7 @@ int main(int argc, char **argv)
|
||||
ckp.main.processname = strdup("main");
|
||||
|
||||
cklock_init(&last_lock);
|
||||
cklock_init(&process_pplns_lock);
|
||||
|
||||
if (confirm_sharesummary) {
|
||||
// TODO: add a system lock to stop running 2 at once?
|
||||
|
||||
125
src/ckdb.h
125
src/ckdb.h
@ -51,8 +51,8 @@
|
||||
*/
|
||||
|
||||
#define DB_VLOCK "1"
|
||||
#define DB_VERSION "0.9.6"
|
||||
#define CKDB_VERSION DB_VERSION"-0.920"
|
||||
#define DB_VERSION "1.0.0"
|
||||
#define CKDB_VERSION DB_VERSION"-1.000"
|
||||
|
||||
#define WHERE_FFL " - from %s %s() line %d"
|
||||
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__
|
||||
@ -94,6 +94,9 @@ extern const char *addrpatt;
|
||||
// BTC address size
|
||||
#define ADDR_MIN_LEN 26
|
||||
#define ADDR_MAX_LEN 34
|
||||
/* All characters in a payaddress are less than this
|
||||
* thus setting the 1st char to this will be greater than any payaddress */
|
||||
#define MAX_PAYADDR '~'
|
||||
|
||||
typedef struct loadstatus {
|
||||
tv_t oldest_sharesummary_firstshare_n;
|
||||
@ -336,6 +339,8 @@ enum cmd_values {
|
||||
CMD_DSP,
|
||||
CMD_STATS,
|
||||
CMD_PPLNS,
|
||||
CMD_PPLNS2,
|
||||
CMD_PAYOUT,
|
||||
CMD_USERSTATUS,
|
||||
CMD_MARKS,
|
||||
CMD_END
|
||||
@ -816,6 +821,7 @@ typedef struct paymentaddresses {
|
||||
#define DATA_PAYMENTADDRESSES_NULL(_var, _item) DATA_GENERIC(_var, _item, paymentaddresses, false)
|
||||
|
||||
extern K_TREE *paymentaddresses_root;
|
||||
extern K_TREE *paymentaddresses_create_root;
|
||||
extern K_LIST *paymentaddresses_free;
|
||||
extern K_STORE *paymentaddresses_store;
|
||||
|
||||
@ -824,14 +830,18 @@ extern K_STORE *paymentaddresses_store;
|
||||
// PAYMENTS
|
||||
typedef struct payments {
|
||||
int64_t paymentid;
|
||||
int64_t payoutid;
|
||||
int64_t userid;
|
||||
char subname[TXT_BIG+1];
|
||||
tv_t paydate;
|
||||
char payaddress[TXT_BIG+1];
|
||||
char originaltxn[TXT_BIG+1];
|
||||
int64_t amount;
|
||||
double diffacc;
|
||||
char committxn[TXT_BIG+1];
|
||||
char commitblockhash[TXT_BIG+1];
|
||||
HISTORYDATECONTROLFIELDS;
|
||||
K_ITEM *old_item; // Non-db field
|
||||
} PAYMENTS;
|
||||
|
||||
#define ALLOC_PAYMENTS 1024
|
||||
@ -844,7 +854,6 @@ extern K_TREE *payments_root;
|
||||
extern K_LIST *payments_free;
|
||||
extern K_STORE *payments_store;
|
||||
|
||||
/* unused yet
|
||||
// ACCOUNTBALANCE
|
||||
typedef struct accountbalance {
|
||||
int64_t userid;
|
||||
@ -852,7 +861,7 @@ typedef struct accountbalance {
|
||||
int64_t confirmedunpaid;
|
||||
int64_t pendingconfirm;
|
||||
int32_t heightupdate;
|
||||
HISTORYDATECONTROLFIELDS;
|
||||
MODIFYDATECONTROLFIELDS;
|
||||
} ACCOUNTBALANCE;
|
||||
|
||||
#define ALLOC_ACCOUNTBALANCE 1024
|
||||
@ -881,7 +890,6 @@ typedef struct accountadjustment {
|
||||
extern K_TREE *accountadjustment_root;
|
||||
extern K_LIST *accountadjustment_free;
|
||||
extern K_STORE *accountadjustment_store;
|
||||
*/
|
||||
|
||||
// IDCONTROL
|
||||
typedef struct idcontrol {
|
||||
@ -1126,23 +1134,62 @@ extern K_STORE *blocks_store;
|
||||
|
||||
// MININGPAYOUTS
|
||||
typedef struct miningpayouts {
|
||||
int64_t miningpayoutid;
|
||||
int64_t payoutid;
|
||||
int64_t userid;
|
||||
int32_t height;
|
||||
char blockhash[TXT_BIG+1];
|
||||
double diffacc;
|
||||
int64_t amount;
|
||||
HISTORYDATECONTROLFIELDS;
|
||||
K_ITEM *old_item; // Non-db field
|
||||
} MININGPAYOUTS;
|
||||
|
||||
#define ALLOC_MININGPAYOUTS 1000
|
||||
#define LIMIT_MININGPAYOUTS 0
|
||||
#define INIT_MININGPAYOUTS(_item) INIT_GENERIC(_item, miningpayouts)
|
||||
#define DATA_MININGPAYOUTS(_var, _item) DATA_GENERIC(_var, _item, miningpayouts, true)
|
||||
#define DATA_MININGPAYOUTS_NULL(_var, _item) DATA_GENERIC(_var, _item, miningpayouts, false)
|
||||
|
||||
extern K_TREE *miningpayouts_root;
|
||||
extern K_LIST *miningpayouts_free;
|
||||
extern K_STORE *miningpayouts_store;
|
||||
|
||||
// PAYOUTS
|
||||
typedef struct payouts {
|
||||
int64_t payoutid;
|
||||
int32_t height;
|
||||
char blockhash[TXT_BIG+1];
|
||||
int64_t minerreward;
|
||||
int64_t workinfoidstart;
|
||||
int64_t workinfoidend;
|
||||
int64_t elapsed;
|
||||
char status[TXT_FLAG+1];
|
||||
double diffwanted;
|
||||
double diffused;
|
||||
double shareacc;
|
||||
tv_t lastshareacc;
|
||||
char *stats;
|
||||
HISTORYDATECONTROLFIELDS;
|
||||
} PAYOUTS;
|
||||
|
||||
#define ALLOC_PAYOUTS 1000
|
||||
#define LIMIT_PAYOUTS 0
|
||||
#define INIT_PAYOUTS(_item) INIT_GENERIC(_item, payouts)
|
||||
#define DATA_PAYOUTS(_var, _item) DATA_GENERIC(_var, _item, payouts, true)
|
||||
#define DATA_PAYOUTS_NULL(_var, _item) DATA_GENERIC(_var, _item, payouts, false)
|
||||
|
||||
extern K_TREE *payouts_root;
|
||||
extern K_TREE *payouts_id_root;
|
||||
extern K_LIST *payouts_free;
|
||||
extern K_STORE *payouts_store;
|
||||
extern cklock_t process_pplns_lock;
|
||||
|
||||
#define PAYOUTS_GENERATED 'G'
|
||||
#define PAYOUTS_GENERATED_STR "G"
|
||||
#define PAYGENERATED(_status) ((_status)[0] == PAYOUTS_GENERATED)
|
||||
// A processing payout must be ignored
|
||||
#define PAYOUTS_PROCESSING 'P'
|
||||
#define PAYOUTS_PROCESSING_STR "P"
|
||||
#define PAYPROCESSING(_status) ((_status)[0] == PAYOUTS_PROCESSING)
|
||||
|
||||
/*
|
||||
// EVENTLOG
|
||||
typedef struct eventlog {
|
||||
@ -1527,6 +1574,20 @@ extern PGconn *dbconnect();
|
||||
// *** ckdb_data.c ***
|
||||
// ***
|
||||
|
||||
/* Blocks after 334106 were set to 5xN
|
||||
* however, they cannot count back to include the workinfoid of 333809
|
||||
* due to the markersummaries that were created.
|
||||
* Code checks that if the block is after FIVExSTT then it must stop
|
||||
* counting back shares at - and not include - FIVExWID */
|
||||
#define FIVExSTT 334106
|
||||
#define FIVExLIM 333809
|
||||
// 333809 workinfoid
|
||||
#define FIVExWID 6085620100361140756
|
||||
|
||||
// optioncontrol names for PPLNS N diff calculation
|
||||
#define PPLNSDIFFTIMES "pplns_diff_times"
|
||||
#define PPLNSDIFFADD "pplns_diff_add"
|
||||
|
||||
// Data free functions (first)
|
||||
extern void free_workinfo_data(K_ITEM *item);
|
||||
extern void free_sharesummary_data(K_ITEM *item);
|
||||
@ -1635,12 +1696,19 @@ extern K_ITEM *new_default_worker(PGconn *conn, bool update, int64_t userid, cha
|
||||
char *by, char *code, char *inet, tv_t *cd, K_TREE *trf_root);
|
||||
extern void dsp_paymentaddresses(K_ITEM *item, FILE *stream);
|
||||
extern cmp_t cmp_paymentaddresses(K_ITEM *a, K_ITEM *b);
|
||||
extern cmp_t cmp_payaddr_create(K_ITEM *a, K_ITEM *b);
|
||||
extern K_ITEM *find_paymentaddresses(int64_t userid, K_TREE_CTX *ctx);
|
||||
extern K_ITEM *find_paymentaddresses_create(int64_t userid, K_TREE_CTX *ctx);
|
||||
extern K_ITEM *find_one_payaddress(int64_t userid, char *payaddress, K_TREE_CTX *ctx);
|
||||
extern K_ITEM *find_any_payaddress(char *payaddress);
|
||||
extern cmp_t cmp_payments(K_ITEM *a, K_ITEM *b);
|
||||
extern K_ITEM *find_payments(int64_t payoutid, int64_t userid, char *subname);
|
||||
extern K_ITEM *find_first_payments(int64_t userid, K_TREE_CTX *ctx);
|
||||
extern K_ITEM *find_first_paypayid(int64_t userid, int64_t payoutid, K_TREE_CTX *ctx);
|
||||
extern cmp_t cmp_accountbalance(K_ITEM *a, K_ITEM *b);
|
||||
extern K_ITEM *find_accountbalance(int64_t userid);
|
||||
extern cmp_t cmp_optioncontrol(K_ITEM *a, K_ITEM *b);
|
||||
extern K_ITEM *find_optioncontrol(char *optionname, tv_t *now);
|
||||
extern K_ITEM *find_optioncontrol(char *optionname, tv_t *now, int32_t height);
|
||||
extern cmp_t cmp_workinfo(K_ITEM *a, K_ITEM *b);
|
||||
#define coinbase1height(_cb1) _coinbase1height(_cb1, WHERE_FFL_HERE)
|
||||
extern int32_t _coinbase1height(char *coinbase1, WHERE_FFL_ARGS);
|
||||
@ -1670,12 +1738,23 @@ void _dbhash2btchash(char *hash, char *buf, size_t siz, WHERE_FFL_ARGS);
|
||||
extern void _dsp_hash(char *hash, char *buf, size_t siz, WHERE_FFL_ARGS);
|
||||
extern void dsp_blocks(K_ITEM *item, FILE *stream);
|
||||
extern cmp_t cmp_blocks(K_ITEM *a, K_ITEM *b);
|
||||
extern K_ITEM *find_blocks(int32_t height, char *blockhash);
|
||||
extern K_ITEM *find_blocks(int32_t height, char *blockhash, K_TREE_CTX *ctx);
|
||||
extern K_ITEM *find_prev_blocks(int32_t height);
|
||||
extern const char *blocks_confirmed(char *confirmed);
|
||||
extern void zero_on_new_block();
|
||||
extern void set_block_share_counters();
|
||||
extern cmp_t cmp_miningpayouts(K_ITEM *a, K_ITEM *b);
|
||||
extern K_ITEM *find_miningpayouts(int64_t payoutid, int64_t userid);
|
||||
extern K_ITEM *first_miningpayouts(int64_t payoutid, K_TREE_CTX *ctx);
|
||||
extern cmp_t cmp_mu(K_ITEM *a, K_ITEM *b);
|
||||
extern K_TREE *upd_add_mu(K_TREE *mu_root, K_STORE *mu_store, int64_t userid,
|
||||
double diffacc);
|
||||
extern cmp_t cmp_payouts(K_ITEM *a, K_ITEM *b);
|
||||
extern cmp_t cmp_payouts_id(K_ITEM *a, K_ITEM *b);
|
||||
extern K_ITEM *find_payouts(int32_t height, char *blockhash);
|
||||
extern K_ITEM *find_last_payouts();
|
||||
extern K_ITEM *find_payoutid(int64_t payoutid);
|
||||
extern void process_pplns(int32_t height, char *blockhash, tv_t *now);
|
||||
extern cmp_t cmp_auths(K_ITEM *a, K_ITEM *b);
|
||||
extern cmp_t cmp_poolstats(K_ITEM *a, K_ITEM *b);
|
||||
extern void dsp_userstats(K_ITEM *item, FILE *stream);
|
||||
@ -1751,6 +1830,12 @@ extern PGresult *_CKPQexecParams(PGconn *conn, const char *qry,
|
||||
#define PGLOGEMERG(_str, _rescode, _conn) PGLOG(LOGEMERG, _str, _rescode, _conn)
|
||||
|
||||
extern char *pqerrmsg(PGconn *conn);
|
||||
extern bool CKPQConn(PGconn **conn);
|
||||
extern void CKPQDisco(PGconn **conn, bool conned);
|
||||
extern bool _CKPQBegin(PGconn *conn, WHERE_FFL_ARGS);
|
||||
#define CKPQBegin(_conn) _CKPQBegin(conn, WHERE_FFL_HERE)
|
||||
extern void _CKPQEnd(PGconn *conn, bool commit, WHERE_FFL_ARGS);
|
||||
#define CKPQEnd(_conn, _commit) _CKPQEnd(_conn, _commit, WHERE_FFL_HERE)
|
||||
|
||||
extern int64_t nextid(PGconn *conn, char *idname, int64_t increment,
|
||||
tv_t *cd, char *by, char *code, char *inet);
|
||||
@ -1783,6 +1868,11 @@ extern bool paymentaddresses_set(PGconn *conn, int64_t userid, K_LIST *pa_store,
|
||||
char *by, char *code, char *inet, tv_t *cd,
|
||||
K_TREE *trf_root);
|
||||
extern bool paymentaddresses_fill(PGconn *conn);
|
||||
extern void payments_add_ram(bool ok, K_ITEM *mp_item, K_ITEM *old_mp_item,
|
||||
tv_t *cd);
|
||||
extern bool payments_add(PGconn *conn, bool add, K_ITEM *p_item,
|
||||
K_ITEM **old_p_item, char *by, char *code, char *inet,
|
||||
tv_t *cd, K_TREE *trf_root, bool already);
|
||||
extern bool payments_fill(PGconn *conn);
|
||||
extern bool idcontrol_add(PGconn *conn, char *idname, char *idvalue, char *by,
|
||||
char *code, char *inet, tv_t *cd, K_TREE *trf_root);
|
||||
@ -1827,10 +1917,19 @@ extern bool blocks_add(PGconn *conn, char *height, char *blockhash,
|
||||
char *by, char *code, char *inet, tv_t *cd,
|
||||
bool igndup, char *id, K_TREE *trf_root);
|
||||
extern bool blocks_fill(PGconn *conn);
|
||||
extern bool miningpayouts_add(PGconn *conn, char *username, char *height,
|
||||
char *blockhash, char *amount, char *by,
|
||||
char *code, char *inet, tv_t *cd, K_TREE *trf_root);
|
||||
extern void miningpayouts_add_ram(bool ok, K_ITEM *mp_item, K_ITEM *old_mp_item,
|
||||
tv_t *cd);
|
||||
extern bool miningpayouts_add(PGconn *conn, bool add, K_ITEM *mp_item,
|
||||
K_ITEM **old_mp_item, char *by, char *code,
|
||||
char *inet, tv_t *cd, K_TREE *trf_root,
|
||||
bool already);
|
||||
extern bool miningpayouts_fill(PGconn *conn);
|
||||
extern void payouts_add_ram(bool ok, K_ITEM *p_item, K_ITEM *old_p_item,
|
||||
tv_t *cd);
|
||||
extern bool payouts_add(PGconn *conn, bool add, K_ITEM *p_item,
|
||||
K_ITEM **old_p_item, char *by, char *code, char *inet,
|
||||
tv_t *cd, K_TREE *trf_root, bool already);
|
||||
extern bool payouts_fill(PGconn *conn);
|
||||
extern bool auths_add(PGconn *conn, char *poolinstance, char *username,
|
||||
char *workername, char *clientid, char *enonce1,
|
||||
char *useragent, char *preauth, char *by, char *code,
|
||||
|
||||
366
src/ckdb_cmd.c
366
src/ckdb_cmd.c
@ -971,7 +971,7 @@ static char *cmd_blockstatus(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
action = transfer_data(i_action);
|
||||
|
||||
K_RLOCK(blocks_free);
|
||||
b_item = find_blocks(height, transfer_data(i_blockhash));
|
||||
b_item = find_blocks(height, transfer_data(i_blockhash), NULL);
|
||||
K_RUNLOCK(blocks_free);
|
||||
|
||||
if (!b_item) {
|
||||
@ -1092,9 +1092,9 @@ static char *cmd_payments(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
__maybe_unused tv_t *notcd,
|
||||
__maybe_unused K_TREE *trf_root)
|
||||
{
|
||||
K_ITEM *i_username, look, *u_item, *p_item;
|
||||
K_ITEM *i_username, *u_item, *p_item;
|
||||
K_TREE_CTX ctx[1];
|
||||
PAYMENTS lookpayments, *payments;
|
||||
PAYMENTS *payments, curr;
|
||||
USERS *users;
|
||||
char reply[1024] = "";
|
||||
char tmp[1024];
|
||||
@ -1116,33 +1116,62 @@ static char *cmd_payments(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
return strdup("bad");
|
||||
DATA_USERS(users, u_item);
|
||||
|
||||
lookpayments.userid = users->userid;
|
||||
lookpayments.paydate.tv_sec = 0;
|
||||
lookpayments.paydate.tv_usec = 0;
|
||||
INIT_PAYMENTS(&look);
|
||||
look.data = (void *)(&lookpayments);
|
||||
p_item = find_after_in_ktree(payments_root, &look, cmp_payments, ctx);
|
||||
DATA_PAYMENTS_NULL(payments, p_item);
|
||||
bzero(&curr, sizeof(curr));
|
||||
APPEND_REALLOC_INIT(buf, off, len);
|
||||
APPEND_REALLOC(buf, off, len, "ok.");
|
||||
rows = 0;
|
||||
|
||||
K_RLOCK(payments_free);
|
||||
p_item = find_first_payments(users->userid, ctx);
|
||||
DATA_PAYMENTS_NULL(payments, p_item);
|
||||
/* TODO: allow to see details of a single payoutid
|
||||
* if it has multiple items (percent payout user) */
|
||||
while (p_item && payments->userid == users->userid) {
|
||||
tv_to_buf(&(payments->paydate), reply, sizeof(reply));
|
||||
if (CURRENT(&(payments->expirydate))) {
|
||||
if (curr.payoutid && curr.payoutid != payments->payoutid) {
|
||||
tv_to_buf(&(curr.paydate), reply, sizeof(reply));
|
||||
snprintf(tmp, sizeof(tmp), "paydate:%d=%s%c", rows, reply, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
str_to_buf(curr.payaddress, reply, sizeof(reply));
|
||||
snprintf(tmp, sizeof(tmp), "payaddress:%d=%s%c", rows, reply, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
bigint_to_buf(curr.amount, reply, sizeof(reply));
|
||||
snprintf(tmp, sizeof(tmp), "amount:%d=%s%c", rows, reply, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
rows++;
|
||||
bzero(&curr, sizeof(curr));
|
||||
}
|
||||
if (!curr.payoutid) {
|
||||
curr.payoutid = payments->payoutid;
|
||||
copy_tv(&(curr.paydate), &(payments->paydate));
|
||||
STRNCPY(curr.payaddress, payments->payaddress);
|
||||
} else
|
||||
STRNCPY(curr.payaddress, "*Multiple");
|
||||
curr.amount += payments->amount;
|
||||
}
|
||||
p_item = next_in_ktree(ctx);
|
||||
DATA_PAYMENTS_NULL(payments, p_item);
|
||||
}
|
||||
K_RUNLOCK(payments_free);
|
||||
if (curr.payoutid) {
|
||||
tv_to_buf(&(curr.paydate), reply, sizeof(reply));
|
||||
snprintf(tmp, sizeof(tmp), "paydate:%d=%s%c", rows, reply, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
str_to_buf(payments->payaddress, reply, sizeof(reply));
|
||||
str_to_buf(curr.payaddress, reply, sizeof(reply));
|
||||
snprintf(tmp, sizeof(tmp), "payaddress:%d=%s%c", rows, reply, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
bigint_to_buf(payments->amount, reply, sizeof(reply));
|
||||
bigint_to_buf(curr.amount, reply, sizeof(reply));
|
||||
snprintf(tmp, sizeof(tmp), "amount:%d=%s%c", rows, reply, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
rows++;
|
||||
p_item = next_in_ktree(ctx);
|
||||
DATA_PAYMENTS_NULL(payments, p_item);
|
||||
}
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "rows=%d%cflds=%s%c",
|
||||
rows, FLDSEP,
|
||||
"paydate,payaddress,amount", FLDSEP);
|
||||
@ -2220,7 +2249,7 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
|
||||
i_preauth = &auth_preauth;
|
||||
|
||||
K_RLOCK(optioncontrol_free);
|
||||
oc_item = find_optioncontrol(OPTIONCONTROL_AUTOADDUSER, cd);
|
||||
oc_item = find_optioncontrol(OPTIONCONTROL_AUTOADDUSER, cd, pool.height);
|
||||
K_RUNLOCK(optioncontrol_free);
|
||||
if (oc_item) {
|
||||
K_RLOCK(users_free);
|
||||
@ -3112,7 +3141,7 @@ static char *cmd_getopts(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
if (comma)
|
||||
*(comma++) = '\0';
|
||||
K_RLOCK(optioncontrol_free);
|
||||
oc_item = find_optioncontrol(ptr, now);
|
||||
oc_item = find_optioncontrol(ptr, now, pool.height);
|
||||
K_RUNLOCK(optioncontrol_free);
|
||||
/* web code must check the existance of the optionname
|
||||
* in the reply since it will be missing if it doesn't
|
||||
@ -3305,81 +3334,12 @@ rollback:
|
||||
return strdup(reply);
|
||||
}
|
||||
|
||||
// order by userid asc
|
||||
static cmp_t cmp_mu(K_ITEM *a, K_ITEM *b)
|
||||
{
|
||||
MININGPAYOUTS *ma, *mb;
|
||||
DATA_MININGPAYOUTS(ma, a);
|
||||
DATA_MININGPAYOUTS(mb, b);
|
||||
return CMP_BIGINT(ma->userid, mb->userid);
|
||||
}
|
||||
|
||||
static K_TREE *upd_add_mu(K_TREE *mu_root, K_STORE *mu_store, int64_t userid, int64_t diffacc)
|
||||
{
|
||||
MININGPAYOUTS lookminingpayouts, *miningpayouts;
|
||||
K_ITEM look, *mu_item;
|
||||
K_TREE_CTX ctx[1];
|
||||
|
||||
lookminingpayouts.userid = userid;
|
||||
INIT_MININGPAYOUTS(&look);
|
||||
look.data = (void *)(&lookminingpayouts);
|
||||
mu_item = find_in_ktree(mu_root, &look, cmp_mu, ctx);
|
||||
if (mu_item) {
|
||||
DATA_MININGPAYOUTS(miningpayouts, mu_item);
|
||||
miningpayouts->amount += diffacc;
|
||||
} else {
|
||||
K_WLOCK(mu_store);
|
||||
mu_item = k_unlink_head(miningpayouts_free);
|
||||
DATA_MININGPAYOUTS(miningpayouts, mu_item);
|
||||
miningpayouts->userid = userid;
|
||||
miningpayouts->amount = diffacc;
|
||||
mu_root = add_to_ktree(mu_root, mu_item, cmp_mu);
|
||||
k_add_head(mu_store, mu_item);
|
||||
K_WUNLOCK(mu_store);
|
||||
}
|
||||
|
||||
return mu_root;
|
||||
}
|
||||
|
||||
/* Find the block_workinfoid of the block requested
|
||||
then add all it's diffacc shares
|
||||
then keep stepping back shares until diffacc_total matches or exceeds
|
||||
the number required (diff_want) - this is begin_workinfoid
|
||||
(also summarising diffacc per user)
|
||||
then keep stepping back until we complete the current begin_workinfoid
|
||||
(also summarising diffacc per user)
|
||||
While we are still below diff_want
|
||||
find each workmarker and add on the full set of worksummary
|
||||
diffacc shares (also summarising diffacc per user)
|
||||
This will give us the total number of diff1 shares (diffacc_total)
|
||||
to use for the payment calculations
|
||||
The value of diff_want defaults to the block's network difficulty
|
||||
(block_ndiff) but can be changed with diff_times and diff_add to:
|
||||
block_ndiff * diff_times + diff_add
|
||||
N.B. diff_times and diff_add can be zero, positive or negative
|
||||
The pplns_elapsed time of the shares is from the createdate of the
|
||||
begin_workinfoid that has shares accounted to the total,
|
||||
up to the createdate of the last share
|
||||
The user average hashrate would be:
|
||||
diffacc_user * 2^32 / pplns_elapsed
|
||||
PPLNS fraction of the payout would be:
|
||||
diffacc_user / diffacc_total
|
||||
|
||||
N.B. 'begin' means the oldest back in time and 'end' means the newest
|
||||
'end' should usually be the info of the found block with the pplns
|
||||
data going back in time to 'begin'
|
||||
*/
|
||||
|
||||
/* Blocks after 334106 were set to 5xN
|
||||
* however, they cannot count back to include the workinfoid of 333809
|
||||
* due to the markersummaries that were created.
|
||||
* Code checks that if the block is after FIVExSTT then it must stop
|
||||
* counting back shares at - and not include - FIVExWID */
|
||||
#define FIVExSTT 334106
|
||||
#define FIVExLIM 333809
|
||||
// 333809 workinfoid
|
||||
#define FIVExWID 6085620100361140756
|
||||
|
||||
/* Kept for reference/comparison to cmd_pplns2()
|
||||
* This will get different results due to the fact that it uses the current
|
||||
* contents of the payoutaddresses table
|
||||
* However, the only differences should be the addresses,
|
||||
* and the breakdown for percent address users,
|
||||
* the totals per user and per payout should still be the same */
|
||||
static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
__maybe_unused tv_t *now, __maybe_unused char *by,
|
||||
__maybe_unused char *code, __maybe_unused char *inet,
|
||||
@ -3857,6 +3817,219 @@ shazbot:
|
||||
return strdup(reply);
|
||||
}
|
||||
|
||||
// Generated from the payouts, miningpayouts and payments data
|
||||
static char *cmd_pplns2(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
__maybe_unused tv_t *now, __maybe_unused char *by,
|
||||
__maybe_unused char *code, __maybe_unused char *inet,
|
||||
__maybe_unused tv_t *notcd, K_TREE *trf_root)
|
||||
{
|
||||
char reply[1024], tmp[1024], *buf;
|
||||
char *block_extra, *marks_status = EMPTY;
|
||||
size_t siz = sizeof(reply);
|
||||
K_ITEM *i_height;
|
||||
K_ITEM b_look, *b_item, *p_item, *mp_item, *pay_item, *u_item;
|
||||
MININGPAYOUTS *miningpayouts;
|
||||
PAYMENTS *payments;
|
||||
PAYOUTS *payouts;
|
||||
BLOCKS lookblocks, *blocks;
|
||||
USERS *users;
|
||||
int32_t height;
|
||||
K_TREE_CTX b_ctx[1], mp_ctx[1], pay_ctx[1];
|
||||
size_t len, off;
|
||||
int rows;
|
||||
bool pok;
|
||||
|
||||
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
|
||||
|
||||
if (sharesummary_marks_limit)
|
||||
marks_status = "ckdb -w load value means pplns may be incorrect";
|
||||
|
||||
i_height = require_name(trf_root, "height", 1, NULL, reply, siz);
|
||||
if (!i_height)
|
||||
return strdup(reply);
|
||||
TXT_TO_INT("height", transfer_data(i_height), height);
|
||||
|
||||
LOGDEBUG("%s(): height %"PRId32, __func__, height);
|
||||
|
||||
lookblocks.height = height;
|
||||
lookblocks.blockhash[0] = '\0';
|
||||
INIT_BLOCKS(&b_look);
|
||||
b_look.data = (void *)(&lookblocks);
|
||||
K_RLOCK(blocks_free);
|
||||
b_item = find_after_in_ktree(blocks_root, &b_look, cmp_blocks, b_ctx);
|
||||
K_RUNLOCK(blocks_free);
|
||||
DATA_BLOCKS_NULL(blocks, b_item);
|
||||
if (!b_item || blocks->height != height) {
|
||||
snprintf(reply, siz, "ERR.no block height %"PRId32, height);
|
||||
return strdup(reply);
|
||||
}
|
||||
if (!CURRENT(&(blocks->expirydate))) {
|
||||
snprintf(reply, siz, "ERR.no CURRENT block %d"PRId32, height);
|
||||
return strdup(reply);
|
||||
}
|
||||
LOGDEBUG("%s(): block %"PRId32"/%"PRId64"/%s/%s/%"PRId64,
|
||||
__func__, blocks->height, blocks->workinfoid,
|
||||
blocks->workername, blocks->confirmed, blocks->reward);
|
||||
switch (blocks->confirmed[0]) {
|
||||
case BLOCKS_NEW:
|
||||
block_extra = "Can't be paid out yet";
|
||||
break;
|
||||
case BLOCKS_ORPHAN:
|
||||
block_extra = "Can't be paid out";
|
||||
break;
|
||||
default:
|
||||
block_extra = EMPTY;
|
||||
break;
|
||||
}
|
||||
|
||||
pok = false;
|
||||
K_RLOCK(payouts_free);
|
||||
p_item = find_payouts(height, blocks->blockhash);
|
||||
DATA_PAYOUTS_NULL(payouts, p_item);
|
||||
if (p_item && PAYGENERATED(payouts->status))
|
||||
pok = true;
|
||||
K_RUNLOCK(payouts_free);
|
||||
if (!p_item) {
|
||||
snprintf(reply, siz, "ERR.no payout for %"PRId32"/%s",
|
||||
height, blocks->blockhash);
|
||||
return strdup(reply);
|
||||
}
|
||||
if (!pok) {
|
||||
snprintf(reply, siz, "ERR.payout %"PRId64" status=%s "
|
||||
"for %"PRId32"/%s",
|
||||
payouts->payoutid, payouts->status, height,
|
||||
blocks->blockhash);
|
||||
return strdup(reply);
|
||||
}
|
||||
|
||||
LOGDEBUG("%s(): total %.1f want %.1f",
|
||||
__func__, payouts->diffused, payouts->diffwanted);
|
||||
|
||||
APPEND_REALLOC_INIT(buf, off, len);
|
||||
APPEND_REALLOC(buf, off, len, "ok.");
|
||||
snprintf(tmp, sizeof(tmp), "block=%d%c", height, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "block_hash=%s%c", blocks->blockhash, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "block_reward=%"PRId64"%c", blocks->reward, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "miner_reward=%"PRId64"%c", payouts->minerreward, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "block_status=%s%c",
|
||||
blocks_confirmed(blocks->confirmed), FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "block_extra=%s%c", block_extra, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "marks_status=%s%c", marks_status, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "workername=%s%c", blocks->workername, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "nonce=%s%c", blocks->nonce, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "begin_workinfoid=%"PRId64"%c", payouts->workinfoidstart, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "block_workinfoid=%"PRId64"%c", blocks->workinfoid, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "end_workinfoid=%"PRId64"%c", payouts->workinfoidend, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "diffacc_total=%.1f%c", payouts->diffused, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "pplns_elapsed=%"PRId64"%c", payouts->elapsed, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
rows = 0;
|
||||
K_RLOCK(miningpayouts_free);
|
||||
mp_item = first_miningpayouts(payouts->payoutid, mp_ctx);
|
||||
K_RUNLOCK(miningpayouts_free);
|
||||
DATA_MININGPAYOUTS_NULL(miningpayouts, mp_item);
|
||||
while (mp_item && miningpayouts->payoutid == payouts->payoutid) {
|
||||
if (CURRENT(&(miningpayouts->expirydate))) {
|
||||
int out = 0;
|
||||
K_RLOCK(users_free);
|
||||
u_item = find_userid(miningpayouts->userid);
|
||||
K_RUNLOCK(users_free);
|
||||
if (!u_item) {
|
||||
snprintf(reply, siz,
|
||||
"ERR.unknown userid %"PRId64,
|
||||
miningpayouts->userid);
|
||||
goto shazbot;
|
||||
}
|
||||
DATA_USERS(users, u_item);
|
||||
|
||||
K_RLOCK(payments_free);
|
||||
pay_item = find_first_paypayid(miningpayouts->userid,
|
||||
payouts->payoutid,
|
||||
pay_ctx);
|
||||
DATA_PAYMENTS_NULL(payments, pay_item);
|
||||
while (pay_item &&
|
||||
payments->userid == miningpayouts->userid &&
|
||||
payments->payoutid == payouts->payoutid) {
|
||||
if (CURRENT(&(payments->expirydate))) {
|
||||
snprintf(tmp, sizeof(tmp),
|
||||
"user:%d=%s%c"
|
||||
"payaddress:%d=%s%c"
|
||||
"amount:%d=%"PRId64"%c"
|
||||
"diffacc:%d=%.1f%c",
|
||||
rows, payments->subname, FLDSEP,
|
||||
rows, payments->payaddress, FLDSEP,
|
||||
rows, payments->amount, FLDSEP,
|
||||
rows, payments->diffacc, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
rows++;
|
||||
out++;
|
||||
}
|
||||
pay_item = next_in_ktree(pay_ctx);
|
||||
DATA_PAYMENTS_NULL(payments, pay_item);
|
||||
}
|
||||
K_RUNLOCK(payments_free);
|
||||
if (out == 0) {
|
||||
snprintf(tmp, sizeof(tmp),
|
||||
"user:%d=%s.0%c"
|
||||
"payaddress:%d=%s%c"
|
||||
"amount:%d=%"PRId64"%c"
|
||||
"diffacc:%d=%.1f%c",
|
||||
rows, users->username, FLDSEP,
|
||||
rows, "none", FLDSEP,
|
||||
rows, miningpayouts->amount, FLDSEP,
|
||||
rows, miningpayouts->diffacc, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
rows++;
|
||||
}
|
||||
}
|
||||
K_RLOCK(miningpayouts_free);
|
||||
mp_item = next_in_ktree(mp_ctx);
|
||||
K_RUNLOCK(miningpayouts_free);
|
||||
DATA_MININGPAYOUTS_NULL(miningpayouts, mp_item);
|
||||
}
|
||||
|
||||
snprintf(tmp, sizeof(tmp),
|
||||
"rows=%d%cflds=%s%c",
|
||||
rows, FLDSEP,
|
||||
"user,payaddress,amount,diffacc", FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "arn=%s%carp=%s%c",
|
||||
"Users", FLDSEP, "", FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s%c", payouts->stats, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "diff_want=%.1f%c",
|
||||
payouts->diffwanted, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
snprintf(tmp, sizeof(tmp), "acc_share_count=%.0f%c",
|
||||
payouts->shareacc, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
// So web can always verify it received all data
|
||||
APPEND_REALLOC(buf, off, len, "pplns_last=1");
|
||||
|
||||
LOGDEBUG("%s.ok.pplns.%s", id, buf);
|
||||
return buf;
|
||||
|
||||
shazbot:
|
||||
return strdup(reply);
|
||||
}
|
||||
|
||||
static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd,
|
||||
char *id, __maybe_unused tv_t *now,
|
||||
__maybe_unused char *by, __maybe_unused char *code,
|
||||
@ -3884,6 +4057,9 @@ static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd,
|
||||
dsp_ktree(paymentaddresses_free, paymentaddresses_root,
|
||||
transfer_data(i_file), NULL);
|
||||
|
||||
dsp_ktree(paymentaddresses_create_free, paymentaddresses_root,
|
||||
transfer_data(i_file), NULL);
|
||||
|
||||
dsp_ktree(sharesummary_free, sharesummary_root,
|
||||
transfer_data(i_file), NULL);
|
||||
|
||||
@ -3944,8 +4120,9 @@ static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
USEINFO(users, 1, 2);
|
||||
USEINFO(useratts, 1, 1);
|
||||
USEINFO(workers, 1, 1);
|
||||
USEINFO(paymentaddresses, 1, 1);
|
||||
USEINFO(paymentaddresses, 1, 2);
|
||||
USEINFO(payments, 1, 1);
|
||||
USEINFO(accountbalance, 1, 1);
|
||||
USEINFO(idcontrol, 1, 0);
|
||||
USEINFO(optioncontrol, 1, 1);
|
||||
USEINFO(workinfo, 1, 1);
|
||||
@ -3957,6 +4134,7 @@ static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
USEINFO(marks, 1, 1);
|
||||
USEINFO(blocks, 1, 1);
|
||||
USEINFO(miningpayouts, 1, 1);
|
||||
USEINFO(payouts, 1, 2);
|
||||
USEINFO(auths, 1, 1);
|
||||
USEINFO(poolstats, 1, 1);
|
||||
USEINFO(userstats, 2, 1);
|
||||
@ -4511,6 +4689,8 @@ struct CMDS ckdb_cmds[] = {
|
||||
{ CMD_DSP, "dsp", false, false, cmd_dsp, ACCESS_SYSTEM },
|
||||
{ CMD_STATS, "stats", true, false, cmd_stats, ACCESS_SYSTEM ACCESS_WEB },
|
||||
{ CMD_PPLNS, "pplns", false, false, cmd_pplns, ACCESS_SYSTEM ACCESS_WEB },
|
||||
{ CMD_PPLNS2, "pplns2", false, false, cmd_pplns2, ACCESS_SYSTEM ACCESS_WEB },
|
||||
// { CMD_PAYOUT, "payout", false, false, cmd_payout, ACCESS_SYSTEM },
|
||||
{ CMD_USERSTATUS,"userstatus", false, false, cmd_userstatus, ACCESS_SYSTEM ACCESS_WEB },
|
||||
{ CMD_MARKS, "marks", false, false, cmd_marks, ACCESS_SYSTEM },
|
||||
{ CMD_END, NULL, false, false, NULL, NULL }
|
||||
|
||||
1040
src/ckdb_data.c
1040
src/ckdb_data.c
File diff suppressed because it is too large
Load Diff
761
src/ckdb_dbio.c
761
src/ckdb_dbio.c
@ -167,6 +167,8 @@ char *pqerrmsg(PGconn *conn)
|
||||
#define PQPARAM14 PQPARAM8 ",$9,$10,$11,$12,$13,$14"
|
||||
#define PQPARAM15 PQPARAM8 ",$9,$10,$11,$12,$13,$14,$15"
|
||||
#define PQPARAM16 PQPARAM8 ",$9,$10,$11,$12,$13,$14,$15,$16"
|
||||
#define PQPARAM17 PQPARAM16 ",$17"
|
||||
#define PQPARAM18 PQPARAM16 ",$17,$18"
|
||||
#define PQPARAM22 PQPARAM16 ",$17,$18,$19,$20,$21,$22"
|
||||
#define PQPARAM26 PQPARAM22 ",$23,$24,$25,$26"
|
||||
#define PQPARAM27 PQPARAM26 ",$27"
|
||||
@ -222,6 +224,70 @@ PGresult *_CKPQexecParams(PGconn *conn, const char *qry,
|
||||
#define PQexec CKPQexec
|
||||
#define PQexecParams CKPQexecParams
|
||||
|
||||
// TODO: switch all to use this
|
||||
bool CKPQConn(PGconn **conn)
|
||||
{
|
||||
if (*conn == NULL) {
|
||||
LOGDEBUG("%s(): connecting", __func__);
|
||||
*conn = dbconnect();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: switch all to use this
|
||||
void CKPQDisco(PGconn **conn, bool conned)
|
||||
{
|
||||
if (conned) {
|
||||
LOGDEBUG("%s(): disco", __func__);
|
||||
PQfinish(*conn);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: switch all to use this
|
||||
bool _CKPQBegin(PGconn *conn, WHERE_FFL_ARGS)
|
||||
{
|
||||
ExecStatusType rescode;
|
||||
PGresult *res;
|
||||
|
||||
res = PQexec(conn, "Begin", CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
PQclear(res);
|
||||
if (!PGOK(rescode)) {
|
||||
char *buf = pqerrmsg(conn);
|
||||
LOGEMERG("%s(): Begin failed (%d) '%s'" WHERE_FFL,
|
||||
__func__, (int)rescode, buf, WHERE_FFL_PASS);
|
||||
free(buf);
|
||||
return false;
|
||||
}
|
||||
LOGDEBUG("%s(): begin", __func__);
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: switch all to use this
|
||||
void _CKPQEnd(PGconn *conn, bool commit, WHERE_FFL_ARGS)
|
||||
{
|
||||
ExecStatusType rescode;
|
||||
PGresult *res;
|
||||
|
||||
if (commit) {
|
||||
LOGDEBUG("%s(): commit", __func__);
|
||||
res = PQexec(conn, "Commit", CKPQ_WRITE);
|
||||
} else {
|
||||
LOGDEBUG("%s(): rollback", __func__);
|
||||
res = PQexec(conn, "Rollback", CKPQ_WRITE);
|
||||
}
|
||||
rescode = PQresultStatus(res);
|
||||
PQclear(res);
|
||||
if (!PGOK(rescode)) {
|
||||
char *buf = pqerrmsg(conn);
|
||||
LOGEMERG("%s(): %s failed (%d) '%s'" WHERE_FFL,
|
||||
__func__, commit ? "commit" : "rollback",
|
||||
(int)rescode, buf, WHERE_FFL_PASS);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t nextid(PGconn *conn, char *idname, int64_t increment,
|
||||
tv_t *cd, char *by, char *code, char *inet)
|
||||
{
|
||||
@ -1642,9 +1708,13 @@ unparam:
|
||||
n++;
|
||||
paymentaddresses_root = remove_from_ktree(paymentaddresses_root, item,
|
||||
cmp_paymentaddresses);
|
||||
paymentaddresses_create_root = remove_from_ktree(paymentaddresses_create_root,
|
||||
item, cmp_payaddr_create);
|
||||
copy_tv(&(row->expirydate), cd);
|
||||
paymentaddresses_root = add_to_ktree(paymentaddresses_root, item,
|
||||
cmp_paymentaddresses);
|
||||
paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root,
|
||||
item, cmp_payaddr_create);
|
||||
}
|
||||
item = prev;
|
||||
DATA_PAYMENTADDRESSES_NULL(row, item);
|
||||
@ -1658,6 +1728,8 @@ unparam:
|
||||
if (!pa->match) {
|
||||
paymentaddresses_root = add_to_ktree(paymentaddresses_root, match,
|
||||
cmp_paymentaddresses);
|
||||
paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root,
|
||||
match, cmp_payaddr_create);
|
||||
k_unlink_item(pa_store, match);
|
||||
k_add_head(paymentaddresses_store, match);
|
||||
count++;
|
||||
@ -1745,7 +1817,10 @@ bool paymentaddresses_fill(PGconn *conn)
|
||||
if (!ok)
|
||||
break;
|
||||
|
||||
paymentaddresses_root = add_to_ktree(paymentaddresses_root, item, cmp_paymentaddresses);
|
||||
paymentaddresses_root = add_to_ktree(paymentaddresses_root, item,
|
||||
cmp_paymentaddresses);
|
||||
paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root,
|
||||
item, cmp_payaddr_create);
|
||||
k_add_head(paymentaddresses_store, item);
|
||||
}
|
||||
if (!ok)
|
||||
@ -1762,30 +1837,169 @@ bool paymentaddresses_fill(PGconn *conn)
|
||||
return ok;
|
||||
}
|
||||
|
||||
// The timing of the memory table updates depends on 'already'
|
||||
void payments_add_ram(bool ok, K_ITEM *p_item, K_ITEM *old_p_item, tv_t *cd)
|
||||
{
|
||||
PAYMENTS *oldp;
|
||||
|
||||
LOGDEBUG("%s(): ok %c", __func__, ok ? 'Y' : 'N');
|
||||
|
||||
K_WLOCK(payments_free);
|
||||
if (!ok) {
|
||||
// Cleanup for the calling function
|
||||
k_add_head(payments_free, p_item);
|
||||
} else {
|
||||
if (old_p_item) {
|
||||
DATA_PAYMENTS(oldp, old_p_item);
|
||||
payments_root = remove_from_ktree(payments_root, old_p_item, cmp_payments);
|
||||
copy_tv(&(oldp->expirydate), cd);
|
||||
payments_root = add_to_ktree(payments_root, old_p_item, cmp_payments);
|
||||
}
|
||||
payments_root = add_to_ktree(payments_root, p_item, cmp_payments);
|
||||
k_add_head(payments_store, p_item);
|
||||
}
|
||||
K_WUNLOCK(payments_free);
|
||||
}
|
||||
|
||||
/* Add means create a new one and expire the old one if it exists,
|
||||
* otherwise we only expire the old one if it exists
|
||||
* It's the calling functions job to determine if a new one is required
|
||||
* - i.e. if there is a difference between the old and new
|
||||
* already = already begun a transaction - and don't update the ram table */
|
||||
bool payments_add(PGconn *conn, bool add, K_ITEM *p_item, K_ITEM **old_p_item,
|
||||
char *by, char *code, char *inet, tv_t *cd, K_TREE *trf_root,
|
||||
bool already)
|
||||
{
|
||||
ExecStatusType rescode;
|
||||
bool conned = false;
|
||||
PGresult *res;
|
||||
bool ok = false, begun = false;
|
||||
PAYMENTS *row, *oldp = NULL;
|
||||
char *upd, *ins;
|
||||
char *params[11 + HISTORYDATECOUNT];
|
||||
int n, par = 0;
|
||||
|
||||
LOGDEBUG("%s(): add %c already %c", __func__,
|
||||
add ? 'Y' : 'N', already ? 'Y' : 'N');
|
||||
|
||||
DATA_PAYMENTS(row, p_item);
|
||||
K_RLOCK(payments_free);
|
||||
*old_p_item = find_payments(row->payoutid, row->userid, row->subname);
|
||||
K_RUNLOCK(payments_free);
|
||||
|
||||
conned = CKPQConn(&conn);
|
||||
if (!already) {
|
||||
begun = CKPQBegin(conn);
|
||||
if (!begun)
|
||||
goto unparam;
|
||||
}
|
||||
|
||||
if (*old_p_item) {
|
||||
LOGDEBUG("%s(): updating old", __func__);
|
||||
|
||||
DATA_PAYMENTS(oldp, *old_p_item);
|
||||
|
||||
upd = "update payments set expirydate=$1 where paymentid=$2"
|
||||
" and expirydate=$3";
|
||||
par = 0;
|
||||
params[par++] = tv_to_buf(cd, NULL, 0);
|
||||
params[par++] = bigint_to_buf(oldp->paymentid, NULL, 0);
|
||||
params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0);
|
||||
PARCHKVAL(par, 3, params);
|
||||
|
||||
res = PQexecParams(conn, upd, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
PQclear(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Update", rescode, conn);
|
||||
goto rollback;
|
||||
}
|
||||
|
||||
for (n = 0; n < par; n++)
|
||||
free(params[n]);
|
||||
par = 0;
|
||||
|
||||
// Expiring an old record
|
||||
row->paymentid = oldp->paymentid;
|
||||
} else {
|
||||
if (add) {
|
||||
// Creating a new record
|
||||
row->paymentid = nextid(conn, "paymentid", (int64_t)1, cd, by, code, inet);
|
||||
if (row->paymentid == 0)
|
||||
goto rollback;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
LOGDEBUG("%s(): adding new", __func__);
|
||||
|
||||
HISTORYDATEINIT(row, cd, by, code, inet);
|
||||
HISTORYDATETRANSFER(trf_root, row);
|
||||
|
||||
par = 0;
|
||||
params[par++] = bigint_to_buf(row->paymentid, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->payoutid, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->userid, NULL, 0);
|
||||
params[par++] = str_to_buf(row->subname, NULL, 0);
|
||||
params[par++] = tv_to_buf(&(row->paydate), NULL, 0);
|
||||
params[par++] = str_to_buf(row->payaddress, NULL, 0);
|
||||
params[par++] = str_to_buf(row->originaltxn, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->amount, NULL, 0);
|
||||
params[par++] = double_to_buf(row->diffacc, NULL, 0);
|
||||
params[par++] = str_to_buf(row->committxn, NULL, 0);
|
||||
params[par++] = str_to_buf(row->commitblockhash, NULL, 0);
|
||||
HISTORYDATEPARAMS(params, par, row);
|
||||
PARCHK(par, params);
|
||||
|
||||
ins = "insert into payments "
|
||||
"(paymentid,payoutid,userid,subname,paydate,payaddress,"
|
||||
"originaltxn,amount,diffacc,committxn,commitblockhash"
|
||||
HISTORYDATECONTROL ") values (" PQPARAM16 ")";
|
||||
|
||||
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Insert", rescode, conn);
|
||||
goto unparam;
|
||||
}
|
||||
}
|
||||
|
||||
ok = true;
|
||||
rollback:
|
||||
if (begun)
|
||||
CKPQEnd(conn, ok);
|
||||
unparam:
|
||||
for (n = 0; n < par; n++)
|
||||
free(params[n]);
|
||||
|
||||
CKPQDisco(&conn, conned);
|
||||
|
||||
if (!already)
|
||||
payments_add_ram(ok, p_item, *old_p_item, cd);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool payments_fill(PGconn *conn)
|
||||
{
|
||||
ExecStatusType rescode;
|
||||
PGresult *res;
|
||||
K_ITEM *item;
|
||||
PAYMENTS *row;
|
||||
char *params[1];
|
||||
int n, i, par = 0;
|
||||
int n, i;
|
||||
char *field;
|
||||
char *sel;
|
||||
int fields = 8;
|
||||
int fields = 11;
|
||||
bool ok;
|
||||
|
||||
LOGDEBUG("%s(): select", __func__);
|
||||
|
||||
// TODO: handle selecting a subset, eg 20 per web page (in blocklist also)
|
||||
sel = "select "
|
||||
"userid,paydate,payaddress,originaltxn,amount,committxn,commitblockhash"
|
||||
"paymentid,payoutid,userid,subname,paydate,payaddress,"
|
||||
"originaltxn,amount,diffacc,committxn,commitblockhash"
|
||||
HISTORYDATECONTROL
|
||||
",paymentid from payments where expirydate=$1";
|
||||
par = 0;
|
||||
params[par++] = tv_to_buf((tv_t *)(&default_expiry), NULL, 0);
|
||||
PARCHK(par, params);
|
||||
res = PQexecParams(conn, sel, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_READ);
|
||||
" from payments";
|
||||
res = PQexec(conn, sel, CKPQ_READ);
|
||||
rescode = PQresultStatus(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Select", rescode, conn);
|
||||
@ -1814,11 +2028,26 @@ bool payments_fill(PGconn *conn)
|
||||
break;
|
||||
}
|
||||
|
||||
PQ_GET_FLD(res, i, "paymentid", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("paymentid", field, row->paymentid);
|
||||
|
||||
PQ_GET_FLD(res, i, "payoutid", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("payoutid", field, row->payoutid);
|
||||
|
||||
PQ_GET_FLD(res, i, "userid", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("userid", field, row->userid);
|
||||
|
||||
PQ_GET_FLD(res, i, "subname", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_STR("subname", field, row->subname);
|
||||
|
||||
PQ_GET_FLD(res, i, "paydate", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
@ -1839,6 +2068,11 @@ bool payments_fill(PGconn *conn)
|
||||
break;
|
||||
TXT_TO_BIGINT("amount", field, row->amount);
|
||||
|
||||
PQ_GET_FLD(res, i, "diffacc", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_DOUBLE("diffacc", field, row->diffacc);
|
||||
|
||||
PQ_GET_FLD(res, i, "committxn", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
@ -1853,11 +2087,6 @@ bool payments_fill(PGconn *conn)
|
||||
if (!ok)
|
||||
break;
|
||||
|
||||
PQ_GET_FLD(res, i, "paymentid", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("paymentid", field, row->paymentid);
|
||||
|
||||
payments_root = add_to_ktree(payments_root, item, cmp_payments);
|
||||
k_add_head(payments_store, item);
|
||||
}
|
||||
@ -3653,7 +3882,7 @@ bool blocks_stats(PGconn *conn, int32_t height, char *blockhash,
|
||||
dsp_hash(blockhash, hash_dsp, sizeof(hash_dsp));
|
||||
|
||||
K_RLOCK(blocks_free);
|
||||
old_b_item = find_blocks(height, blockhash);
|
||||
old_b_item = find_blocks(height, blockhash, NULL);
|
||||
K_RUNLOCK(blocks_free);
|
||||
|
||||
if (!old_b_item) {
|
||||
@ -3811,7 +4040,7 @@ bool blocks_add(PGconn *conn, char *height, char *blockhash,
|
||||
dsp_hash(blockhash, hash_dsp, sizeof(hash_dsp));
|
||||
|
||||
K_RLOCK(blocks_free);
|
||||
old_b_item = find_blocks(row->height, blockhash);
|
||||
old_b_item = find_blocks(row->height, blockhash, NULL);
|
||||
K_RUNLOCK(blocks_free);
|
||||
DATA_BLOCKS_NULL(oldblocks, old_b_item);
|
||||
|
||||
@ -4297,96 +4526,128 @@ bool blocks_fill(PGconn *conn)
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool miningpayouts_add(PGconn *conn, char *username, char *height,
|
||||
char *blockhash, char *amount, char *by,
|
||||
char *code, char *inet, tv_t *cd, K_TREE *trf_root)
|
||||
// The timing of the memory table updates depends on 'already'
|
||||
void miningpayouts_add_ram(bool ok, K_ITEM *mp_item, K_ITEM *old_mp_item, tv_t *cd)
|
||||
{
|
||||
MININGPAYOUTS *oldmp;
|
||||
|
||||
LOGDEBUG("%s(): ok %c", __func__, ok ? 'Y' : 'N');
|
||||
|
||||
K_WLOCK(miningpayouts_free);
|
||||
if (!ok) {
|
||||
// Cleanup for the calling function
|
||||
k_add_head(miningpayouts_free, mp_item);
|
||||
} else {
|
||||
if (old_mp_item) {
|
||||
DATA_MININGPAYOUTS(oldmp, old_mp_item);
|
||||
miningpayouts_root = remove_from_ktree(miningpayouts_root, old_mp_item, cmp_miningpayouts);
|
||||
copy_tv(&(oldmp->expirydate), cd);
|
||||
miningpayouts_root = add_to_ktree(miningpayouts_root, old_mp_item, cmp_miningpayouts);
|
||||
}
|
||||
miningpayouts_root = add_to_ktree(miningpayouts_root, mp_item, cmp_miningpayouts);
|
||||
k_add_head(miningpayouts_store, mp_item);
|
||||
}
|
||||
K_WUNLOCK(miningpayouts_free);
|
||||
}
|
||||
|
||||
/* Add means create a new one and expire the old one if it exists,
|
||||
* otherwise we only expire the old one if it exists
|
||||
* It's the calling functions job to determine if a new one is required
|
||||
* - i.e. if there is a difference between the old and new
|
||||
* already = already begun a transaction - and don't update the ram table */
|
||||
bool miningpayouts_add(PGconn *conn, bool add, K_ITEM *mp_item,
|
||||
K_ITEM **old_mp_item, char *by, char *code, char *inet,
|
||||
tv_t *cd, K_TREE *trf_root, bool already)
|
||||
{
|
||||
ExecStatusType rescode;
|
||||
bool conned = false;
|
||||
PGresult *res;
|
||||
K_ITEM *m_item, *u_item;
|
||||
bool ok = false;
|
||||
MININGPAYOUTS *row;
|
||||
USERS *users;
|
||||
char *ins;
|
||||
char *params[5 + HISTORYDATECOUNT];
|
||||
bool ok = false, begun = false;
|
||||
MININGPAYOUTS *row, *oldmp = NULL;
|
||||
char *upd, *ins;
|
||||
char *params[4 + HISTORYDATECOUNT];
|
||||
int n, par = 0;
|
||||
|
||||
LOGDEBUG("%s(): add", __func__);
|
||||
LOGDEBUG("%s(): add %c already %c", __func__,
|
||||
add ? 'Y' : 'N', already ? 'Y' : 'N');
|
||||
|
||||
K_WLOCK(miningpayouts_free);
|
||||
m_item = k_unlink_head(miningpayouts_free);
|
||||
K_WUNLOCK(miningpayouts_free);
|
||||
DATA_MININGPAYOUTS(row, mp_item);
|
||||
K_RLOCK(miningpayouts_free);
|
||||
*old_mp_item = find_miningpayouts(row->payoutid, row->userid);
|
||||
K_RUNLOCK(miningpayouts_free);
|
||||
|
||||
DATA_MININGPAYOUTS(row, m_item);
|
||||
conned = CKPQConn(&conn);
|
||||
if (!already) {
|
||||
begun = CKPQBegin(conn);
|
||||
if (!begun)
|
||||
goto unparam;
|
||||
}
|
||||
|
||||
if (*old_mp_item) {
|
||||
LOGDEBUG("%s(): updating old", __func__);
|
||||
|
||||
if (conn == NULL) {
|
||||
conn = dbconnect();
|
||||
conned = true;
|
||||
DATA_MININGPAYOUTS(oldmp, *old_mp_item);
|
||||
|
||||
upd = "update miningpayouts set expirydate=$1 where payoutid=$2"
|
||||
" and userid=$3 and expirydate=$4";
|
||||
par = 0;
|
||||
params[par++] = tv_to_buf(cd, NULL, 0);
|
||||
params[par++] = bigint_to_buf(oldmp->payoutid, NULL, 0);
|
||||
params[par++] = bigint_to_buf(oldmp->userid, NULL, 0);
|
||||
params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0);
|
||||
PARCHKVAL(par, 4, params);
|
||||
|
||||
res = PQexecParams(conn, upd, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
PQclear(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Update", rescode, conn);
|
||||
goto rollback;
|
||||
}
|
||||
|
||||
for (n = 0; n < par; n++)
|
||||
free(params[n]);
|
||||
par = 0;
|
||||
}
|
||||
|
||||
row->miningpayoutid = nextid(conn, "miningpayoutid", (int64_t)1, cd, by, code, inet);
|
||||
if (row->miningpayoutid == 0)
|
||||
goto unitem;
|
||||
if (add) {
|
||||
LOGDEBUG("%s(): adding new", __func__);
|
||||
|
||||
K_RLOCK(users_free);
|
||||
u_item = find_users(username);
|
||||
K_RUNLOCK(users_free);
|
||||
if (!u_item) {
|
||||
char *txt;
|
||||
LOGERR("%s(): unknown user '%s'",
|
||||
__func__,
|
||||
txt = safe_text(username));
|
||||
free(txt);
|
||||
goto unitem;
|
||||
}
|
||||
DATA_USERS(users, u_item);
|
||||
HISTORYDATEINIT(row, cd, by, code, inet);
|
||||
HISTORYDATETRANSFER(trf_root, row);
|
||||
|
||||
row->userid = users->userid;
|
||||
TXT_TO_INT("height", height, row->height);
|
||||
STRNCPY(row->blockhash, blockhash);
|
||||
TXT_TO_BIGINT("amount", amount, row->amount);
|
||||
par = 0;
|
||||
params[par++] = bigint_to_buf(row->payoutid, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->userid, NULL, 0);
|
||||
params[par++] = double_to_buf(row->diffacc, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->amount, NULL, 0);
|
||||
HISTORYDATEPARAMS(params, par, row);
|
||||
PARCHK(par, params);
|
||||
|
||||
HISTORYDATEINIT(row, cd, by, code, inet);
|
||||
HISTORYDATETRANSFER(trf_root, row);
|
||||
ins = "insert into miningpayouts "
|
||||
"(payoutid,userid,diffacc,amount"
|
||||
HISTORYDATECONTROL ") values (" PQPARAM9 ")";
|
||||
|
||||
par = 0;
|
||||
params[par++] = bigint_to_buf(row->miningpayoutid, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->userid, NULL, 0);
|
||||
params[par++] = int_to_buf(row->height, NULL, 0);
|
||||
params[par++] = str_to_buf(row->blockhash, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->amount, NULL, 0);
|
||||
HISTORYDATEPARAMS(params, par, row);
|
||||
PARCHK(par, params);
|
||||
|
||||
ins = "insert into miningpayouts "
|
||||
"(miningpayoutid,userid,height,blockhash,amount"
|
||||
HISTORYDATECONTROL ") values (" PQPARAM10 ")";
|
||||
|
||||
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Insert", rescode, conn);
|
||||
goto unparam;
|
||||
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Insert", rescode, conn);
|
||||
goto unparam;
|
||||
}
|
||||
}
|
||||
|
||||
ok = true;
|
||||
|
||||
rollback:
|
||||
if (begun)
|
||||
CKPQEnd(conn, ok);
|
||||
unparam:
|
||||
PQclear(res);
|
||||
for (n = 0; n < par; n++)
|
||||
free(params[n]);
|
||||
unitem:
|
||||
if (conned)
|
||||
PQfinish(conn);
|
||||
K_WLOCK(miningpayouts_free);
|
||||
if (!ok)
|
||||
k_add_head(miningpayouts_free, m_item);
|
||||
else {
|
||||
miningpayouts_root = add_to_ktree(miningpayouts_root, m_item, cmp_miningpayouts);
|
||||
k_add_head(miningpayouts_store, m_item);
|
||||
}
|
||||
K_WUNLOCK(miningpayouts_free);
|
||||
|
||||
CKPQDisco(&conn, conned);
|
||||
|
||||
if (!already)
|
||||
miningpayouts_add_ram(ok, mp_item, *old_mp_item, cd);
|
||||
|
||||
return ok;
|
||||
}
|
||||
@ -4397,23 +4658,19 @@ bool miningpayouts_fill(PGconn *conn)
|
||||
PGresult *res;
|
||||
K_ITEM *item;
|
||||
MININGPAYOUTS *row;
|
||||
char *params[1];
|
||||
int n, i, par = 0;
|
||||
int n, i;
|
||||
char *field;
|
||||
char *sel;
|
||||
int fields = 5;
|
||||
int fields = 4;
|
||||
bool ok;
|
||||
|
||||
LOGDEBUG("%s(): select", __func__);
|
||||
|
||||
sel = "select "
|
||||
"miningpayoutid,userid,height,blockhash,amount"
|
||||
"payoutid,userid,diffacc,amount"
|
||||
HISTORYDATECONTROL
|
||||
" from miningpayouts where expirydate=$1";
|
||||
par = 0;
|
||||
params[par++] = tv_to_buf((tv_t *)(&default_expiry), NULL, 0);
|
||||
PARCHK(par, params);
|
||||
res = PQexecParams(conn, sel, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_READ);
|
||||
" from miningpayouts";
|
||||
res = PQexec(conn, sel, CKPQ_READ);
|
||||
rescode = PQresultStatus(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Select", rescode, conn);
|
||||
@ -4442,25 +4699,20 @@ bool miningpayouts_fill(PGconn *conn)
|
||||
break;
|
||||
}
|
||||
|
||||
PQ_GET_FLD(res, i, "miningpayoutid", field, ok);
|
||||
PQ_GET_FLD(res, i, "payoutid", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("miningpayoutid", field, row->miningpayoutid);
|
||||
TXT_TO_BIGINT("payoutid", field, row->payoutid);
|
||||
|
||||
PQ_GET_FLD(res, i, "userid", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("userid", field, row->userid);
|
||||
|
||||
PQ_GET_FLD(res, i, "height", field, ok);
|
||||
PQ_GET_FLD(res, i, "diffacc", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_INT("height", field, row->height);
|
||||
|
||||
PQ_GET_FLD(res, i, "blockhash", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_STR("blockhash", field, row->blockhash);
|
||||
TXT_TO_DOUBLE("diffacc", field, row->diffacc);
|
||||
|
||||
PQ_GET_FLD(res, i, "amount", field, ok);
|
||||
if (!ok)
|
||||
@ -4490,6 +4742,292 @@ bool miningpayouts_fill(PGconn *conn)
|
||||
return ok;
|
||||
}
|
||||
|
||||
// The timing of the memory table updates depends on 'already'
|
||||
void payouts_add_ram(bool ok, K_ITEM *p_item, K_ITEM *old_p_item, tv_t *cd)
|
||||
{
|
||||
PAYOUTS *oldp;
|
||||
|
||||
LOGDEBUG("%s(): ok %c", __func__, ok ? 'Y' : 'N');
|
||||
|
||||
K_WLOCK(payouts_free);
|
||||
if (!ok) {
|
||||
// Cleanup for the calling function
|
||||
k_add_head(payouts_free, p_item);
|
||||
} else {
|
||||
if (old_p_item) {
|
||||
DATA_PAYOUTS(oldp, old_p_item);
|
||||
payouts_root = remove_from_ktree(payouts_root, old_p_item, cmp_payouts);
|
||||
payouts_id_root = remove_from_ktree(payouts_id_root, old_p_item, cmp_payouts_id);
|
||||
copy_tv(&(oldp->expirydate), cd);
|
||||
payouts_root = add_to_ktree(payouts_root, old_p_item, cmp_payouts);
|
||||
payouts_id_root = add_to_ktree(payouts_id_root, old_p_item, cmp_payouts_id);
|
||||
}
|
||||
payouts_root = add_to_ktree(payouts_root, p_item, cmp_payouts);
|
||||
payouts_id_root = add_to_ktree(payouts_id_root, p_item, cmp_payouts_id);
|
||||
k_add_head(payouts_store, p_item);
|
||||
}
|
||||
K_WUNLOCK(payouts_free);
|
||||
}
|
||||
|
||||
/* Add means create a new one and expire the old one if it exists,
|
||||
* otherwise we only expire the old one if it exists
|
||||
* It's the calling functions job to determine if a new one is required
|
||||
* - i.e. if there is a difference between the old and new
|
||||
* already = already begun a transaction - and don't update the ram table */
|
||||
bool payouts_add(PGconn *conn, bool add, K_ITEM *p_item, K_ITEM **old_p_item,
|
||||
char *by, char *code, char *inet, tv_t *cd, K_TREE *trf_root,
|
||||
bool already)
|
||||
{
|
||||
ExecStatusType rescode;
|
||||
bool conned = false;
|
||||
PGresult *res;
|
||||
bool ok = false, begun = false;
|
||||
PAYOUTS *row, *oldpayouts = NULL;
|
||||
char *upd, *ins;
|
||||
char *params[13 + HISTORYDATECOUNT];
|
||||
int n, par = 0;
|
||||
|
||||
LOGDEBUG("%s(): add %c already %c", __func__,
|
||||
add ? 'Y' : 'N', already ? 'Y' : 'N');
|
||||
|
||||
DATA_PAYOUTS(row, p_item);
|
||||
K_RLOCK(payouts_free);
|
||||
*old_p_item = find_payouts(row->height, row->blockhash);
|
||||
K_RUNLOCK(payouts_free);
|
||||
|
||||
conned = CKPQConn(&conn);
|
||||
if (!already) {
|
||||
begun = CKPQBegin(conn);
|
||||
if (!begun)
|
||||
goto unparam;
|
||||
}
|
||||
|
||||
if (*old_p_item) {
|
||||
LOGDEBUG("%s(): updating old", __func__);
|
||||
|
||||
DATA_PAYOUTS(oldpayouts, *old_p_item);
|
||||
|
||||
upd = "update payouts set expirydate=$1 where payoutid=$2"
|
||||
" and expirydate=$3";
|
||||
par = 0;
|
||||
params[par++] = tv_to_buf(cd, NULL, 0);
|
||||
params[par++] = bigint_to_buf(oldpayouts->payoutid, NULL, 0);
|
||||
params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0);
|
||||
PARCHKVAL(par, 3, params);
|
||||
|
||||
res = PQexecParams(conn, upd, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
PQclear(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Update", rescode, conn);
|
||||
goto rollback;
|
||||
}
|
||||
|
||||
for (n = 0; n < par; n++)
|
||||
free(params[n]);
|
||||
par = 0;
|
||||
|
||||
// Expiring an old record
|
||||
row->payoutid = oldpayouts->payoutid;
|
||||
} else {
|
||||
if (add) {
|
||||
// Creating a new record
|
||||
row->payoutid = nextid(conn, "payoutid", (int64_t)1, cd, by, code, inet);
|
||||
if (row->payoutid == 0)
|
||||
goto rollback;
|
||||
}
|
||||
}
|
||||
|
||||
if (add) {
|
||||
LOGDEBUG("%s(): adding new", __func__);
|
||||
|
||||
HISTORYDATEINIT(row, cd, by, code, inet);
|
||||
HISTORYDATETRANSFER(trf_root, row);
|
||||
|
||||
par = 0;
|
||||
params[par++] = bigint_to_buf(row->payoutid, NULL, 0);
|
||||
params[par++] = int_to_buf(row->height, NULL, 0);
|
||||
params[par++] = str_to_buf(row->blockhash, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->minerreward, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->workinfoidstart, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->workinfoidend, NULL, 0);
|
||||
params[par++] = bigint_to_buf(row->elapsed, NULL, 0);
|
||||
params[par++] = str_to_buf(row->status, NULL, 0);
|
||||
params[par++] = double_to_buf(row->diffwanted, NULL, 0);
|
||||
params[par++] = double_to_buf(row->diffused, NULL, 0);
|
||||
params[par++] = double_to_buf(row->shareacc, NULL, 0);
|
||||
params[par++] = tv_to_buf(&(row->lastshareacc), NULL, 0);
|
||||
params[par++] = str_to_buf(row->stats, NULL, 0);
|
||||
HISTORYDATEPARAMS(params, par, row);
|
||||
PARCHK(par, params);
|
||||
|
||||
ins = "insert into payouts "
|
||||
"(payoutid,height,blockhash,minerreward,workinfoidstart,"
|
||||
"workinfoidend,elapsed,status,diffwanted,diffused,shareacc,"
|
||||
"lastshareacc,stats"
|
||||
HISTORYDATECONTROL ") values (" PQPARAM18 ")";
|
||||
|
||||
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
|
||||
rescode = PQresultStatus(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Insert", rescode, conn);
|
||||
goto unparam;
|
||||
}
|
||||
}
|
||||
|
||||
ok = true;
|
||||
rollback:
|
||||
if (begun)
|
||||
CKPQEnd(conn, ok);
|
||||
unparam:
|
||||
for (n = 0; n < par; n++)
|
||||
free(params[n]);
|
||||
|
||||
CKPQDisco(&conn, conned);
|
||||
|
||||
if (!already)
|
||||
payouts_add_ram(ok, p_item, *old_p_item, cd);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool payouts_fill(PGconn *conn)
|
||||
{
|
||||
ExecStatusType rescode;
|
||||
PGresult *res;
|
||||
K_ITEM *item;
|
||||
PAYOUTS *row;
|
||||
int n, i;
|
||||
char *field;
|
||||
char *sel;
|
||||
int fields = 13;
|
||||
bool ok;
|
||||
|
||||
LOGDEBUG("%s(): select", __func__);
|
||||
|
||||
sel = "select "
|
||||
"payoutid,height,blockhash,minerreward,workinfoidstart,workinfoidend,"
|
||||
"elapsed,status,diffwanted,diffused,shareacc,lastshareacc,stats"
|
||||
HISTORYDATECONTROL
|
||||
" from payouts";
|
||||
res = PQexec(conn, sel, CKPQ_READ);
|
||||
rescode = PQresultStatus(res);
|
||||
if (!PGOK(rescode)) {
|
||||
PGLOGERR("Select", rescode, conn);
|
||||
PQclear(res);
|
||||
return false;
|
||||
}
|
||||
|
||||
n = PQnfields(res);
|
||||
if (n != (fields + HISTORYDATECOUNT)) {
|
||||
LOGERR("%s(): Invalid field count - should be %d, but is %d",
|
||||
__func__, fields + HISTORYDATECOUNT, n);
|
||||
PQclear(res);
|
||||
return false;
|
||||
}
|
||||
|
||||
n = PQntuples(res);
|
||||
LOGDEBUG("%s(): tree build count %d", __func__, n);
|
||||
ok = true;
|
||||
K_WLOCK(payouts_free);
|
||||
for (i = 0; i < n; i++) {
|
||||
item = k_unlink_head(payouts_free);
|
||||
DATA_PAYOUTS(row, item);
|
||||
|
||||
if (everyone_die) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
PQ_GET_FLD(res, i, "payoutid", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("payoutid", field, row->payoutid);
|
||||
|
||||
PQ_GET_FLD(res, i, "height", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_INT("height", field, row->height);
|
||||
|
||||
PQ_GET_FLD(res, i, "blockhash", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_STR("blockhash", field, row->blockhash);
|
||||
|
||||
PQ_GET_FLD(res, i, "minerreward", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("minerreward", field, row->minerreward);
|
||||
|
||||
PQ_GET_FLD(res, i, "workinfoidstart", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("workinfoidstart", field, row->workinfoidstart);
|
||||
|
||||
PQ_GET_FLD(res, i, "workinfoidend", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("workinfoidend", field, row->workinfoidend);
|
||||
|
||||
PQ_GET_FLD(res, i, "elapsed", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BIGINT("elapsed", field, row->elapsed);
|
||||
|
||||
PQ_GET_FLD(res, i, "status", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_STR("status", field, row->status);
|
||||
|
||||
PQ_GET_FLD(res, i, "diffwanted", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_DOUBLE("diffwanted", field, row->diffwanted);
|
||||
|
||||
PQ_GET_FLD(res, i, "diffused", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_DOUBLE("diffused", field, row->diffused);
|
||||
|
||||
PQ_GET_FLD(res, i, "shareacc", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_DOUBLE("shareacc", field, row->shareacc);
|
||||
|
||||
PQ_GET_FLD(res, i, "lastshareacc", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_TV("lastshareacc", field, row->lastshareacc);
|
||||
|
||||
PQ_GET_FLD(res, i, "stats", field, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
TXT_TO_BLOB("stats", field, row->stats);
|
||||
|
||||
HISTORYDATEFLDS(res, i, row, ok);
|
||||
if (!ok)
|
||||
break;
|
||||
|
||||
payouts_root = add_to_ktree(payouts_root, item, cmp_payouts);
|
||||
payouts_id_root = add_to_ktree(payouts_id_root, item, cmp_payouts_id);
|
||||
k_add_head(payouts_store, item);
|
||||
|
||||
tick();
|
||||
}
|
||||
if (!ok)
|
||||
k_add_head(payouts_free, item);
|
||||
|
||||
K_WUNLOCK(payouts_free);
|
||||
PQclear(res);
|
||||
|
||||
if (ok) {
|
||||
LOGDEBUG("%s(): built", __func__);
|
||||
LOGWARNING("%s(): loaded %d payout records", __func__, n);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// TODO: discard them from RAM
|
||||
bool auths_add(PGconn *conn, char *poolinstance, char *username,
|
||||
char *workername, char *clientid, char *enonce1,
|
||||
@ -5312,7 +5850,8 @@ bool _workmarkers_process(PGconn *conn, bool already, bool add,
|
||||
bool ok = false, begun = false;
|
||||
int n, par = 0;
|
||||
|
||||
LOGDEBUG("%s(): add", __func__);
|
||||
LOGDEBUG("%s(): add %c already %c", __func__,
|
||||
add ? 'Y' : 'N', already ? 'Y' : 'N');
|
||||
|
||||
if (markerid == 0) {
|
||||
K_RLOCK(workmarkers_free);
|
||||
@ -5324,6 +5863,8 @@ bool _workmarkers_process(PGconn *conn, bool already, bool add,
|
||||
K_RUNLOCK(workmarkers_free);
|
||||
}
|
||||
if (old_wm_item) {
|
||||
LOGDEBUG("%s(): updating old", __func__);
|
||||
|
||||
DATA_WORKMARKERS(oldworkmarkers, old_wm_item);
|
||||
if (!conn) {
|
||||
conn = dbconnect();
|
||||
@ -5363,6 +5904,8 @@ bool _workmarkers_process(PGconn *conn, bool already, bool add,
|
||||
}
|
||||
|
||||
if (add) {
|
||||
LOGDEBUG("%s(): adding new", __func__);
|
||||
|
||||
if (poolinstance == NULL || description == NULL ||
|
||||
status == NULL) {
|
||||
LOGEMERG("%s(): NULL field(s) passed:%s%s%s"
|
||||
@ -5639,12 +6182,14 @@ bool _marks_process(PGconn *conn, bool add, char *poolinstance,
|
||||
bool ok = false, begun = false;
|
||||
int n, par = 0;
|
||||
|
||||
LOGDEBUG("%s(): add", __func__);
|
||||
LOGDEBUG("%s(): add %c", __func__, add ? 'Y' : 'N');
|
||||
|
||||
K_RLOCK(marks_free);
|
||||
old_m_item = find_marks(workinfoid);
|
||||
K_RUNLOCK(marks_free);
|
||||
if (old_m_item) {
|
||||
LOGDEBUG("%s(): updating old", __func__);
|
||||
|
||||
DATA_MARKS(oldmarks, old_m_item);
|
||||
if (!conn) {
|
||||
conn = dbconnect();
|
||||
@ -5682,6 +6227,8 @@ bool _marks_process(PGconn *conn, bool add, char *poolinstance,
|
||||
}
|
||||
|
||||
if (add) {
|
||||
LOGDEBUG("%s(): adding new", __func__);
|
||||
|
||||
if (poolinstance == NULL || description == NULL ||
|
||||
extra == NULL || marktype == NULL || status == NULL) {
|
||||
LOGEMERG("%s(): NULL field(s) passed:%s%s%s%s%s"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user