This commit is contained in:
Arionum
2018-08-30 01:24:39 +03:00
parent 6a6005ca4c
commit 616dde11ea
7 changed files with 416 additions and 189 deletions

17
api.php
View File

@@ -670,6 +670,23 @@ if ($q == "getAddress") {
$account = san($account); $account = san($account);
api_echo($acc->account2alias($account)); api_echo($acc->account2alias($account));
} elseif ($q=="sanity"){
$sanity=false;
if(file_exists("tmp/sanity-lock")) {
$sanity=true;
}
$last_sanity=$db->single("SELECT val FROM config WHERE cfg='sanity_last'");
$sanity_sync=$db->single("SELECT val FROM config WHERE cfg='sanity_sync'");
api_echo(["sanity_running"=>$sanity,"last_sanity"=>$last_sanity, "sanity_sync"=>$sanity_sync]);
} elseif ($q=="node-info"){
$dbversion=$db->single("SELECT val FROM config WHERE cfg='dbversion'");
$hostname=$db->single("SELECT val FROM config WHERE cfg='hostname'");
$acc=$db->single("SELECT COUNT(1) FROM accounts");
$tr=$db->single("SELECT COUNT(1) FROM transactions");
$mns=$db->single("SELECT COUNT(1) FROM masternode");
$mempool=$db->single("SELECT COUNT(1) FROM mempool");
api_echo(["hostname"=>$hostname, "version"=>VERSION,"dbversion"=>$dbversion, "accounts"=>$acc, "transactions"=>$tr, "mempool"=>$mempool, "masternodes"=>$mns]);
} else { } else {
api_err("Invalid request"); api_err("Invalid request");
} }

View File

@@ -115,12 +115,16 @@ class Account
} }
//check if an account already has an alias //check if an account already has an alias
public function has_alias($public_key){ public function has_alias($public_key)
{
global $db; global $db;
$public_key=san($public_key); $public_key=san($public_key);
$res=$db->single("SELECT COUNT(1) FROM accounts WHERE public_key=:public_key AND alias IS NOT NULL", [":public_key"=>$public_key]); $res=$db->single("SELECT COUNT(1) FROM accounts WHERE public_key=:public_key AND alias IS NOT NULL", [":public_key"=>$public_key]);
if($res!=0) return true; if ($res!=0) {
else return false; return true;
} else {
return false;
}
} }
//check alias validity //check alias validity
@@ -144,7 +148,8 @@ class Account
} }
//returns the account of an alias //returns the account of an alias
public function alias2account($alias){ public function alias2account($alias)
{
global $db; global $db;
$alias=strtoupper($alias); $alias=strtoupper($alias);
$res=$db->single("SELECT id FROM accounts WHERE alias=:alias LIMIT 1", [":alias"=>$alias]); $res=$db->single("SELECT id FROM accounts WHERE alias=:alias LIMIT 1", [":alias"=>$alias]);
@@ -152,7 +157,8 @@ class Account
} }
//returns the alias of an account //returns the alias of an account
public function account2alias($id){ public function account2alias($id)
{
global $db; global $db;
$id=san($id); $id=san($id);
$res=$db->single("SELECT alias FROM accounts WHERE id=:id LIMIT 1", [":id"=>$id]); $res=$db->single("SELECT alias FROM accounts WHERE id=:id LIMIT 1", [":id"=>$id]);
@@ -300,11 +306,13 @@ class Account
return $res; return $res;
} }
public function get_masternode($public_key){ public function get_masternode($public_key)
{
global $db; global $db;
$res = $db->row("SELECT * FROM masternode WHERE public_key=:public_key", [":public_key" => $public_key]); $res = $db->row("SELECT * FROM masternode WHERE public_key=:public_key", [":public_key" => $public_key]);
if(empty($res['public_key'])) return false; if (empty($res['public_key'])) {
return false;
}
return $res; return $res;
} }
} }

View File

@@ -58,7 +58,6 @@ class Block
$mn_reward=number_format($mn_reward, 8, ".", ""); $mn_reward=number_format($mn_reward, 8, ".", "");
_log("MN Reward: $mn_reward", 2); _log("MN Reward: $mn_reward", 2);
} }
} }
@@ -115,8 +114,14 @@ class Block
} }
// insert the reward transaction in the db // insert the reward transaction in the db
$trx->add($hash, $height, $transaction); $res=$trx->add($hash, $height, $transaction);
if ($res == false) {
// rollback and exit if it fails
_log("Reward DB insert failed");
$db->rollback();
$db->exec("UNLOCK TABLES");
return false;
}
if ($mn_winner!==false&&$height>=80458&&$mn_reward>0) { if ($mn_winner!==false&&$height>=80458&&$mn_reward>0) {
$db->run("UPDATE accounts SET balance=balance+:bal WHERE public_key=:pub", [":pub"=>$mn_winner, ":bal"=>$mn_reward]); $db->run("UPDATE accounts SET balance=balance+:bal WHERE public_key=:pub", [":pub"=>$mn_winner, ":bal"=>$mn_reward]);
$bind = [ $bind = [
@@ -136,8 +141,22 @@ if($mn_winner!==false&&$height>=80458&&$mn_reward>0){
"INSERT into transactions SET id=:id, public_key=:public_key, block=:block, height=:height, dst=:dst, val=:val, fee=:fee, signature=:signature, version=:version, message=:message, `date`=:date", "INSERT into transactions SET id=:id, public_key=:public_key, block=:block, height=:height, dst=:dst, val=:val, fee=:fee, signature=:signature, version=:version, message=:message, `date`=:date",
$bind $bind
); );
$this->reset_fails_masternodes($mn_winner, $height, $hash); if ($res != 1) {
// rollback and exit if it fails
_log("Masternode reward DB insert failed");
$db->rollback();
$db->exec("UNLOCK TABLES");
return false;
}
$res=$this->reset_fails_masternodes($mn_winner, $height, $hash);
if (!$res) {
// rollback and exit if it fails
_log("Masternode log DB insert failed");
$db->rollback();
$db->exec("UNLOCK TABLES");
return false;
}
} }
// parse the block's transactions and insert them to db // parse the block's transactions and insert them to db
@@ -164,11 +183,18 @@ $this->reset_fails_masternodes($mn_winner, $height, $hash);
{ {
global $db; global $db;
$res=$this->masternode_log($public_key, $height, $hash); $res=$this->masternode_log($public_key, $height, $hash);
if ($res===5) {
return false;
}
if ($res) { if ($res) {
$db->run("UPDATE masternode SET last_won=:last_won,fails=0 WHERE public_key=:public_key", [":public_key"=>$public_key, ":last_won"=>$height]); $rez=$db->run("UPDATE masternode SET last_won=:last_won,fails=0 WHERE public_key=:public_key", [":public_key"=>$public_key, ":last_won"=>$height]);
if ($rez!=1) {
return false;
} }
} }
return true;
}
//logs the current masternode status //logs the current masternode status
public function masternode_log($public_key, $height, $hash) public function masternode_log($public_key, $height, $hash)
@@ -184,12 +210,15 @@ $this->reset_fails_masternodes($mn_winner, $height, $hash);
$id = hex2coin(hash("sha512", "resetfails-$hash-$height-$public_key")); $id = hex2coin(hash("sha512", "resetfails-$hash-$height-$public_key"));
$msg="$mn[blacklist],$mn[last_won],$mn[fails]"; $msg="$mn[blacklist],$mn[last_won],$mn[fails]";
$db->run( $res=$db->run(
"INSERT into transactions SET id=:id, block=:block, height=:height, dst=:dst, val=0, fee=0, signature=:sig, version=111, message=:msg, date=:date, public_key=:public_key", "INSERT into transactions SET id=:id, block=:block, height=:height, dst=:dst, val=0, fee=0, signature=:sig, version=111, message=:msg, date=:date, public_key=:public_key",
[":id"=>$id, ":block"=>$hash, ":height"=>$height, ":dst"=>$hash, ":sig"=>$hash, ":msg"=>$msg, ":date"=>time(), ":public_key"=>$public_key] [":id"=>$id, ":block"=>$hash, ":height"=>$height, ":dst"=>$hash, ":sig"=>$hash, ":msg"=>$msg, ":date"=>time(), ":public_key"=>$public_key]
); );
if ($res!=1) {
return 5;
}
return true; return true;
} }
@@ -291,8 +320,6 @@ $this->reset_fails_masternodes($mn_winner, $height, $hash);
// keep current difficulty // keep current difficulty
$dif = $current['difficulty']; $dif = $current['difficulty'];
} }
} else { } else {
// hardfork 80000, fix difficulty targetting // hardfork 80000, fix difficulty targetting
@@ -475,7 +502,6 @@ if($height>=80458){
$mn_reward=number_format($mn_reward, 8, ".", ""); $mn_reward=number_format($mn_reward, 8, ".", "");
_log("MN Reward: $mn_reward", 2); _log("MN Reward: $mn_reward", 2);
} }
} }
$msg = ''; $msg = '';
@@ -532,7 +558,9 @@ if($height>=80458){
if ($current['height']>=80500) { if ($current['height']>=80500) {
$total_time-=360; $total_time-=360;
$tem=floor($total_time/120)+1; $tem=floor($total_time/120)+1;
if($tem>5) $tem=5; if ($tem>5) {
$tem=5;
}
} else { } else {
$tem=floor($total_time/600); $tem=floor($total_time/600);
} }
@@ -547,7 +575,9 @@ if($height>=80458){
$this->masternode_log($b['public_key'], $current['height'], $current['id']); $this->masternode_log($b['public_key'], $current['height'], $current['id']);
_log("Blacklisting masternode - $i $b[public_key]", 2); _log("Blacklisting masternode - $i $b[public_key]", 2);
$btime=10; $btime=10;
if($current['height']>83000) $btime=360; if ($current['height']>83000) {
$btime=360;
}
$db->run("UPDATE masternode SET fails=fails+1, blacklist=:blacklist WHERE public_key=:public_key", [":public_key"=>$b['public_key'], ":blacklist"=> $current['height']+(($b['fails']+1)*$btime)]); $db->run("UPDATE masternode SET fails=fails+1, blacklist=:blacklist WHERE public_key=:public_key", [":public_key"=>$b['public_key'], ":blacklist"=> $current['height']+(($b['fails']+1)*$btime)]);
$i++; $i++;
} }
@@ -594,7 +624,6 @@ if($height>=80458){
_log("Block below 10800, using 16MB argon", 2); _log("Block below 10800, using 16MB argon", 2);
$argon = '$argon2i$v=19$m=16384,t=4,p=4'.$argon; $argon = '$argon2i$v=19$m=16384,t=4,p=4'.$argon;
} }
} elseif ($current_height>=80458) { } elseif ($current_height>=80458) {
if ($current_height%2==0) { if ($current_height%2==0) {
// cpu mining // cpu mining
@@ -605,7 +634,6 @@ if($height>=80458){
_log("GPU Mining - $current_height", 2); _log("GPU Mining - $current_height", 2);
$argon = '$argon2i$v=19$m=16384,t=4,p=4'.$argon; $argon = '$argon2i$v=19$m=16384,t=4,p=4'.$argon;
} }
} else { } else {
_log("Block > 80000 - $current_height", 2); _log("Block > 80000 - $current_height", 2);
if ($current_height%3==0) { if ($current_height%3==0) {
@@ -657,7 +685,6 @@ if($height>=80458){
$total_time=$time-$last_time; $total_time=$time-$last_time;
$total_time-=360; $total_time-=360;
$tem=floor($total_time/120)+1; $tem=floor($total_time/120)+1;
} else { } else {
$tem=floor(($time-$last_time)/600); $tem=floor(($time-$last_time)/600);
} }
@@ -734,6 +761,7 @@ if($height>=80458){
global $db; global $db;
// data must be array // data must be array
if ($data === false) { if ($data === false) {
_log("Block data is false", 3);
return false; return false;
} }
$acc = new Account(); $acc = new Account();
@@ -746,6 +774,7 @@ if($height>=80458){
// check if the number of transactions is not bigger than current block size // check if the number of transactions is not bigger than current block size
$max = $this->max_transactions(); $max = $this->max_transactions();
if (count($data) > $max) { if (count($data) > $max) {
_log("Too many transactions in block", 3);
return false; return false;
} }
@@ -760,6 +789,7 @@ if($height>=80458){
if (!$bootstrapping) { if (!$bootstrapping) {
//validate the transaction //validate the transaction
if (!$trx->check($x, $height)) { if (!$trx->check($x, $height)) {
_log("Transaction check failed - $x[id]", 3);
return false; return false;
} }
if ($x['version']>=100&&$x['version']<110) { if ($x['version']>=100&&$x['version']<110) {
@@ -772,6 +802,7 @@ if($height>=80458){
// check if the transaction is already on the blockchain // check if the transaction is already on the blockchain
if ($db->single("SELECT COUNT(1) FROM transactions WHERE id=:id", [":id" => $x['id']]) > 0) { if ($db->single("SELECT COUNT(1) FROM transactions WHERE id=:id", [":id" => $x['id']]) > 0) {
_log("Transaction already on the blockchain - $x[id]", 3);
return false; return false;
} }
} }
@@ -790,6 +821,7 @@ if($height>=80458){
[":id" => $id, ":balance" => $bal] [":id" => $id, ":balance" => $bal]
); );
if ($res == 0) { if ($res == 0) {
_log("Not enough balance for transaction - $id", 3);
return false; // not enough balance for the transactions return false; // not enough balance for the transactions
} }
} }
@@ -867,12 +899,14 @@ if($height>=80458){
foreach ($r as $x) { foreach ($r as $x) {
$res = $trx->reverse($x['id']); $res = $trx->reverse($x['id']);
if ($res === false) { if ($res === false) {
_log("A transaction could not be reversed. Delete block failed.");
$db->rollback(); $db->rollback();
$db->exec("UNLOCK TABLES"); $db->exec("UNLOCK TABLES");
return false; return false;
} }
$res = $db->run("DELETE FROM blocks WHERE id=:id", [":id" => $x['id']]); $res = $db->run("DELETE FROM blocks WHERE id=:id", [":id" => $x['id']]);
if ($res != 1) { if ($res != 1) {
_log("Delete block failed.");
$db->rollback(); $db->rollback();
$db->exec("UNLOCK TABLES"); $db->exec("UNLOCK TABLES");
return false; return false;

View File

@@ -39,6 +39,10 @@ function api_echo($data)
// log function, shows only in cli atm // log function, shows only in cli atm
function _log($data, $verbosity = 0) function _log($data, $verbosity = 0)
{ {
global $_config;
if ($_config['log_verbosity'] < $verbosity) {
return;
}
$date = date("[Y-m-d H:i:s]"); $date = date("[Y-m-d H:i:s]");
$trace = debug_backtrace(); $trace = debug_backtrace();
$loc = count($trace) - 1; $loc = count($trace) - 1;
@@ -56,7 +60,6 @@ function _log($data, $verbosity = 0)
if (php_sapi_name() === 'cli') { if (php_sapi_name() === 'cli') {
echo $res; echo $res;
} }
global $_config;
if ($_config['enable_logging'] == true && $_config['log_verbosity'] >= $verbosity) { if ($_config['enable_logging'] == true && $_config['log_verbosity'] >= $verbosity) {
@file_put_contents($_config['log_file'], $res, FILE_APPEND); @file_put_contents($_config['log_file'], $res, FILE_APPEND);
} }

View File

@@ -6,54 +6,78 @@ class Transaction
public function reverse($block) public function reverse($block)
{ {
global $db; global $db;
$acc = new Account(); $acc = new Account();
$r = $db->run("SELECT * FROM transactions WHERE block=:block ORDER by `version` ASC", [":block" => $block]); $r = $db->run("SELECT * FROM transactions WHERE block=:block ORDER by `version` ASC", [":block" => $block]);
foreach ($r as $x) { foreach ($r as $x) {
_log("Reversing transaction $x[id]",4);
if (empty($x['src'])) { if (empty($x['src'])) {
$x['src'] = $acc->get_address($x['public_key']); $x['src'] = $acc->get_address($x['public_key']);
} }
if ($x['version'] == 2) { if ($x['version'] == 2) {
// payment sent to alias // payment sent to alias
$db->run( $rez=$db->run(
"UPDATE accounts SET balance=balance-:val WHERE alias=:alias", "UPDATE accounts SET balance=balance-:val WHERE alias=:alias",
[":alias" => $x['dst'], ":val" => $x['val']] [":alias" => $x['dst'], ":val" => $x['val']]
); );
if($rez!=1) {
_log("Update alias balance minus failed",3);
return false;
}
} else { } else {
// other type of transactions // other type of transactions
if($x['version']!=100) { $db->run( if ($x['version']!=100&&$x['version']<111) {
$rez=$db->run(
"UPDATE accounts SET balance=balance-:val WHERE id=:id", "UPDATE accounts SET balance=balance-:val WHERE id=:id",
[":id" => $x['dst'], ":val" => $x['val']] [":id" => $x['dst'], ":val" => $x['val']]
); );
if($rez!=1) {
_log("Update accounts balance minus failed",3);
return false;
}
} }
} }
// on version 0 / reward transaction, don't credit anyone // on version 0 / reward transaction, don't credit anyone
if ($x['version'] > 0) { if ($x['version'] > 0 && $x['version']<111) {
$db->run( $rez=$db->run(
"UPDATE accounts SET balance=balance+:val WHERE id=:id", "UPDATE accounts SET balance=balance+:val WHERE id=:id",
[":id" => $x['src'], ":val" => $x['val'] + $x['fee']] [":id" => $x['src'], ":val" => $x['val'] + $x['fee']]
); );
if($rez!=1) {
_log("Update account balance plus failed",3);
return false;
}
} }
// removing the alias if the alias transaction is reversed // removing the alias if the alias transaction is reversed
if ($x['version']==3) { if ($x['version']==3) {
$db->run( $rez=$db->run(
"UPDATE accounts SET alias=NULL WHERE id=:id", "UPDATE accounts SET alias=NULL WHERE id=:id",
[":id" => $x['src']] [":id" => $x['src']]
); );
if($rez!=1) {
_log("Clear alias failed",3);
return false;
}
} }
if ($x['version']>=100&&$x['version']<110&&$x['height']>=80000) { if ($x['version']>=100&&$x['version']<110&&$x['height']>=80000) {
if ($x['version']==100) { if ($x['version']==100) {
$db->run("DELETE FROM masternode WHERE public_key=:public_key", [':public_key'=>$x['public_key']]); $rez=$db->run("DELETE FROM masternode WHERE public_key=:public_key", [':public_key'=>$x['public_key']]);
if($rez!=1) {
_log("Delete from masternode failed",3);
return false;
}
} elseif ($x['version']==101) { } elseif ($x['version']==101) {
$db->run( $rez=$db->run(
"UPDATE masternode SET status=1 WHERE public_key=:public_key", "UPDATE masternode SET status=1 WHERE public_key=:public_key",
[':public_key'=>$x['public_key']] [':public_key'=>$x['public_key']]
); );
} elseif ($x['version']==102) { } elseif ($x['version']==102) {
$db->run("UPDATE masternode SET status=0 WHERE public_key=:public_key", [':public_key'=>$x['public_key']]); $rez=$db->run("UPDATE masternode SET status=0 WHERE public_key=:public_key", [':public_key'=>$x['public_key']]);
} elseif ($x['version']==103) { } elseif ($x['version']==103) {
$mnt=$db->row("SELECT height, `message` FROM transactions WHERE version=100 AND public_key=:public_key ORDER by height DESC LIMIT 1", [":public_key"=>$x['public_key']]); $mnt=$db->row("SELECT height, `message` FROM transactions WHERE version=100 AND public_key=:public_key ORDER by height DESC LIMIT 1", [":public_key"=>$x['public_key']]);
$vers=$db->single( $vers=$db->single(
@@ -67,21 +91,35 @@ class Transaction
$status=0; $status=0;
} }
$db->run( $rez=$db->run(
"INSERT into masternode SET `public_key`=:public_key, `height`=:height, `ip`=:ip, `status`=:status", "INSERT into masternode SET `public_key`=:public_key, `height`=:height, `ip`=:ip, `status`=:status",
[":public_key"=>$x['public_key'], ":height"=>$mnt['height'], ":ip"=>$mnt['message'], ":status"=>$status] [":public_key"=>$x['public_key'], ":height"=>$mnt['height'], ":ip"=>$mnt['message'], ":status"=>$status]
); );
$db->run("UPDATE accounts SET balance=balance-100000 WHERE public_key=:public_key", [':public_key'=>$x['public_key']]); if($rez!=1) {
_log("Insert into masternode failed",3);
return false;
}
$rez=$db->run("UPDATE accounts SET balance=balance-100000 WHERE public_key=:public_key", [':public_key'=>$x['public_key']]);
if($rez!=1) {
_log("Update masternode balance failed",3);
return false;
}
} }
} }
// internal masternode history // internal masternode history
if ($x['version']==111) { if ($x['version']==111) {
_log("Masternode reverse: $x[message]",4);
$m=explode(",", $x['message']); $m=explode(",", $x['message']);
$db->run( $rez=$db->run(
"UPDATE masternode SET fails=:fails, blacklist=:blacklist, last_won=:last_won WHERE public_key=:public_key", "UPDATE masternode SET fails=:fails, blacklist=:blacklist, last_won=:last_won WHERE public_key=:public_key",
[":public_key"=>$x['public_key'], ":blacklist"=> $m[0], ":fails"=>$m[2], ":last_won"=>$m[1]] [":public_key"=>$x['public_key'], ":blacklist"=> $m[0], ":fails"=>$m[2], ":last_won"=>$m[1]]
); );
if($rez!=1) {
_log("Update masternode log failed",3);
return false;
}
} }
// add the transactions to mempool // add the transactions to mempool
@@ -90,6 +128,7 @@ class Transaction
} }
$res = $db->run("DELETE FROM transactions WHERE id=:id", [":id" => $x['id']]); $res = $db->run("DELETE FROM transactions WHERE id=:id", [":id" => $x['id']]);
if ($res != 1) { if ($res != 1) {
_log("Delete transaction failed",3);
return false; return false;
} }
} }

View File

@@ -63,6 +63,11 @@ if ($arg != "microsanity") {
require_once("include/init.inc.php"); require_once("include/init.inc.php");
if ($argv[1]=="dev") {
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE);
ini_set("display_errors", "on");
}
// the sanity can't run without the schema being installed // the sanity can't run without the schema being installed
if ($_config['dbversion'] < 2) { if ($_config['dbversion'] < 2) {
die("DB schema not created"); die("DB schema not created");
@@ -76,6 +81,11 @@ $block = new Block();
$acc = new Account(); $acc = new Account();
$current = $block->current(); $current = $block->current();
// bootstrapping the initial sync // bootstrapping the initial sync
if ($current['height']==1) { if ($current['height']==1) {
echo "Bootstrapping!\n"; echo "Bootstrapping!\n";
@@ -441,7 +451,7 @@ echo "Most common: $most_common\n";
echo "Most common block: $most_common_size\n"; echo "Most common block: $most_common_size\n";
echo "Max height: $largest_height\n"; echo "Max height: $largest_height\n";
echo "Current block: $current[height]\n"; echo "Current block: $current[height]\n";
$block_parse_failed=false;
// if we're not on the largest height // if we're not on the largest height
if ($current['height'] < $largest_height && $largest_height > 1) { if ($current['height'] < $largest_height && $largest_height > 1) {
// start sanity sync / block all other transactions/blocks // start sanity sync / block all other transactions/blocks
@@ -553,6 +563,7 @@ if ($current['height'] < $largest_height && $largest_height > 1) {
$b['height'] = san($b['height']); $b['height'] = san($b['height']);
if (!$block->check($b)) { if (!$block->check($b)) {
$block_parse_failed=true;
_log("Block check: could not add block - $b[id] - $b[height]"); _log("Block check: could not add block - $b[id] - $b[height]");
$good_peer = false; $good_peer = false;
break; break;
@@ -569,6 +580,7 @@ if ($current['height'] < $largest_height && $largest_height > 1) {
$b['argon'] $b['argon']
); );
if (!$res) { if (!$res) {
$block_parse_failed=true;
_log("Block add: could not add block - $b[id] - $b[height]"); _log("Block add: could not add block - $b[id] - $b[height]");
$good_peer = false; $good_peer = false;
break; break;
@@ -585,6 +597,71 @@ if ($current['height'] < $largest_height && $largest_height > 1) {
break; break;
} }
} }
$resyncing=false;
if ($block_parse_failed==true&&$current['date']<time()-(3600*24)) {
_log("Rechecking reward transactions");
$current = $block->current();
$rwpb=$db->single("SELECT COUNT(1) FROM transactions WHERE version=0 AND message=''");
if($rwpb!=$current['height']){
$failed=$db->single("SELECT blocks.height FROM blocks LEFT JOIN transactions ON transactions.block=blocks.id and transactions.version=0 and transactions.message='' WHERE transactions.height is NULL ORDER by blocks.height ASC LIMIT 1");
if($failed>1){
_log("Found failed block - $faield");
$block->delete($failed);
$block_parse_failed==false;
}
}
}
if ($block_parse_failed==true||$argv[1]=="resync") {
$last_resync=$db->single("SELECT val FROM config WHERE cfg='last_resync'");
if ($last_resync<time()-(3600*24)||$argv[1]=="resync") {
if ($current['date']<time()-(3600*72)||$argv[1]=="resync") {
$to_remove=3000;
if(intval($argv[2])>0){
$to_remove=intval($argv[2]);
}
_log("Removing $to_remove blocks, the blockchain is stale.");
$block->pop(to_remove);
$resyncing=true;
} elseif ($current['date']<time()-(3600*24)) {
_log("Removing 200 blocks, the blockchain is stale.");
$block->pop(200);
$resyncing=true;
}
if ($resyncing==true) {
_log("Resyncing accounts");
$db->run("INSERT into config SET val=UNIX_TIMESTAMP(), cfg='last_resync' ON DUPLICATE KEY UPDATE val=UNIX_TIMESTAMP()");
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE");
$r=$db->run("SELECT * FROM accounts");
foreach ($r as $x) {
$alias=$x['alias'];
if (empty($alias)) {
$alias="A";
}
$rec=$db->single("SELECT SUM(val) FROM transactions WHERE (dst=:id or dst=:alias) AND (height<80000 OR (version!=100 AND version!=103)) and version<111", [":id"=>$x['id'], ":alias"=>$alias]);
$spent=$db->single("SELECT SUM(val+fee) FROM transactions WHERE public_key=:pub AND version>0", [":pub"=>$x['public_key']]);
if ($spent==false) {
$spent=0;
}
$balance=round(($rec-$spent), 8);
if ($x['balance']!=$balance) {
// echo "rec: $rec, spent: $spent, bal: $x[balance], should be: $balance - $x[id] $x[public_key]\n";
if (trim($argv[2])!="check") {
$db->run("UPDATE accounts SET balance=:bal WHERE id=:id", [":id"=>$x['id'], ":bal"=>$balance]);
}
}
}
$current = $block->current();
$db->run("DELETE FROM masternode WHERE height>:h",[":h"=>$current['height']]);
$db->exec("UNLOCK TABLES");
}
}
}
$db->run("UPDATE config SET val=0 WHERE cfg='sanity_sync'", [":time" => $t]); $db->run("UPDATE config SET val=0 WHERE cfg='sanity_sync'", [":time" => $t]);
} }

View File

@@ -43,6 +43,8 @@ $cmd = trim($argv[1]);
*/ */
if ($cmd == 'clean') { if ($cmd == 'clean') {
if(file_exists("tmp/sanity-lock")) die("Sanity running. Wait for it to finish");
touch("tmp/sanity-lock");
$db->run("SET foreign_key_checks=0;"); $db->run("SET foreign_key_checks=0;");
$tables = ["accounts", "transactions", "mempool", "masternode","blocks"]; $tables = ["accounts", "transactions", "mempool", "masternode","blocks"];
foreach ($tables as $table) { foreach ($tables as $table) {
@@ -51,6 +53,7 @@ if ($cmd == 'clean') {
$db->run("SET foreign_key_checks=1;"); $db->run("SET foreign_key_checks=1;");
echo "\n The database has been cleared\n"; echo "\n The database has been cleared\n";
unlink("tmp/sanity-lock");
} /** } /**
* @api {php util.php} pop Pop * @api {php util.php} pop Pop
* @apiName pop * @apiName pop
@@ -64,9 +67,12 @@ if ($cmd == 'clean') {
*/ */
elseif ($cmd == 'pop') { elseif ($cmd == 'pop') {
if(file_exists("tmp/sanity-lock")) die("Sanity running. Wait for it to finish");
touch("tmp/sanity-lock");
$no = intval($argv[2]); $no = intval($argv[2]);
$block = new Block(); $block = new Block();
$block->pop($no); $block->pop($no);
unlink("tmp/sanity-lock");
} /** } /**
* @api {php util.php} block-time Block-time * @api {php util.php} block-time Block-time
* @apiName block-time * @apiName block-time
@@ -443,7 +449,6 @@ elseif ($cmd == 'get-address') {
* php util.php clean-blacklist * php util.php clean-blacklist
* *
*/ */
} elseif ($cmd == 'clean-blacklist') { } elseif ($cmd == 'clean-blacklist') {
$db->run("UPDATE peers SET blacklisted=0, fails=0, stuckfail=0"); $db->run("UPDATE peers SET blacklisted=0, fails=0, stuckfail=0");
echo "All the peers have been removed from the blacklist\n"; echo "All the peers have been removed from the blacklist\n";
@@ -456,10 +461,14 @@ elseif ($cmd == 'get-address') {
$r=$db->run("SELECT * FROM accounts"); $r=$db->run("SELECT * FROM accounts");
foreach ($r as $x) { foreach ($r as $x) {
$alias=$x['alias']; $alias=$x['alias'];
if(empty($alias)) $alias="A"; if (empty($alias)) {
$alias="A";
}
$rec=$db->single("SELECT SUM(val) FROM transactions WHERE (dst=:id or dst=:alias) AND (height<80000 OR (version!=100 AND version!=103)) and version<111", [":id"=>$x['id'], ":alias"=>$alias]); $rec=$db->single("SELECT SUM(val) FROM transactions WHERE (dst=:id or dst=:alias) AND (height<80000 OR (version!=100 AND version!=103)) and version<111", [":id"=>$x['id'], ":alias"=>$alias]);
$spent=$db->single("SELECT SUM(val+fee) FROM transactions WHERE public_key=:pub AND version>0", [":pub"=>$x['public_key']]); $spent=$db->single("SELECT SUM(val+fee) FROM transactions WHERE public_key=:pub AND version>0", [":pub"=>$x['public_key']]);
if($spent==false) $spent=0; if ($spent==false) {
$spent=0;
}
$balance=round(($rec-$spent), 8); $balance=round(($rec-$spent), 8);
if ($x['balance']!=$balance) { if ($x['balance']!=$balance) {
echo "rec: $rec, spent: $spent, bal: $x[balance], should be: $balance - $x[id] $x[public_key]\n"; echo "rec: $rec, spent: $spent, bal: $x[balance], should be: $balance - $x[id] $x[public_key]\n";
@@ -470,7 +479,47 @@ foreach($r as $x){
} }
$db->exec("UNLOCK TABLES"); $db->exec("UNLOCK TABLES");
echo "All done"; echo "All done";
} elseif ($cmd=="compare-blocks") {
$block=new Block();
$current=$block->current();
$peer=trim($argv[2]);
$limit=intval($argv[3]);
if($limit==0) $limit=5000;
for($i=$current['height']-$limit;$i<=$current['height'];$i++){
$data=peer_post($peer."/peer.php?q=getBlock",["height" => $i]);
if($data==false) {
continue;
}
$our=$block->export(false,$i);
if($data!=$our) {
echo "Failed block -> $i\n";
if($argv[4]=="dump"){
echo "\n\n ---- Internal ----\n\n";
var_dump($our);
echo "\n\n ---- External ----\n\n";
var_dump($data);
}
}
}
} elseif ($cmd=='compare-accounts'){
$peer=trim($argv[2]);
$r=$db->run("SELECT id,balance FROM accounts");
foreach($r as $x){
$data=peer_post($peer."/api.php?q=getBalance",["account" => $x['id']]);
if($data==false) {
continue;
}
if($data!=$x['balance']) {
echo "$x[id]\t\t$x[balance]\t$data\n";
}
}
} elseif ($cmd=='masternode-hash'){
$res=$db->run("SELECT * FROM masternode ORDER by public_key ASC");
$block=new Block();
$current=$block->current();
echo "Height:\t\t$current[height]\n";
echo "Hash:\t\t".md5(json_encode($res))."\n\n";
} else { } else {
echo "Invalid command\n"; echo "Invalid command\n";