paranoid and blacklist

This commit is contained in:
admin@arionum.com
2018-09-05 16:06:23 +03:00
parent a03484adee
commit 0b73adb3d8
9 changed files with 119 additions and 25 deletions

View File

@@ -428,6 +428,14 @@ if ($q == "getAddress") {
if (!$acc->valid_key($public_key)) { if (!$acc->valid_key($public_key)) {
api_err("Invalid public key"); api_err("Invalid public key");
} }
if ($_config['use_official_blacklist']!==false) {
$blacklisted=["PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCvVQcHHCNLfiP9LmzWhhpCHx39Bhc67P5HMQM9cctEFvcsUdgrkGqy18taz9ZMrAGtq7NhBYpQ4ZTHkKYiZDaSUqQ", //faucet abuser
"PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCxYDeQHk7Ke66UB2Un3UMmMoJ7RF5vDZXihdEXi8gk8ZBRAi35aFrER2ZLX1mgND7sLFXKETGTjRYjoHcuRNiJN1g" // octaex
];
if (in_array($public_key, $blacklisted)) {
api_err("Blacklisted account");
}
}
$private_key = san($data['private_key']); $private_key = san($data['private_key']);
if (!$acc->valid_key($private_key)) { if (!$acc->valid_key($private_key)) {
api_err("Invalid private key"); api_err("Invalid private key");
@@ -559,6 +567,7 @@ if ($q == "getAddress") {
$trx->add_mempool($transaction, "local"); $trx->add_mempool($transaction, "local");
$hash=escapeshellarg(san($hash));
system("php propagate.php transaction $hash > /dev/null 2>&1 &"); system("php propagate.php transaction $hash > /dev/null 2>&1 &");
api_echo($hash); api_echo($hash);
} elseif ($q == "mempoolSize") { } elseif ($q == "mempoolSize") {

View File

@@ -276,7 +276,7 @@ class Block
// before mnn hf // before mnn hf
if ($height<80000) { if ($height<80000) {
// elapsed time between the last 20 blocks // elapsed time between the last 20 blocks
$first = $db->row("SELECT `date` FROM blocks ORDER by height DESC LIMIT $limit,1"); $first = $db->row("SELECT `date` FROM blocks ORDER by height DESC LIMIT :limit,1",[":limit"=>$limit]);
$time = $current['date'] - $first['date']; $time = $current['date'] - $first['date'];
// avg block time // avg block time
@@ -566,8 +566,8 @@ class Block
} }
_log("We have masternodes to blacklist - $tem", 2); _log("We have masternodes to blacklist - $tem", 2);
$ban=$db->run( $ban=$db->run(
"SELECT public_key, blacklist, fails, last_won FROM masternode WHERE status=1 AND blacklist<:current AND height<:start ORDER by last_won ASC, public_key ASC LIMIT 0,$tem", "SELECT public_key, blacklist, fails, last_won FROM masternode WHERE status=1 AND blacklist<:current AND height<:start ORDER by last_won ASC, public_key ASC LIMIT 0,:limit",
[":current"=>$last['height'], ":start"=>$last['height']-360] [":current"=>$last['height'], ":start"=>$last['height']-360, ":limit"=>$tem]
); );
_log(json_encode($ban)); _log(json_encode($ban));
$i=0; $i=0;
@@ -689,8 +689,8 @@ class Block
$tem=floor(($time-$last_time)/600); $tem=floor(($time-$last_time)/600);
} }
$winner=$db->single( $winner=$db->single(
"SELECT public_key FROM masternode WHERE status=1 AND blacklist<:current AND height<:start ORDER by last_won ASC, public_key ASC LIMIT $tem,1", "SELECT public_key FROM masternode WHERE status=1 AND blacklist<:current AND height<:start ORDER by last_won ASC, public_key ASC LIMIT :tem,1",
[":current"=>$current_height, ":start"=>$current_height-360] [":current"=>$current_height, ":start"=>$current_height-360, ":tem"=>$tem]
); );
_log("Moving to the next masternode - $tem - $winner", 1); _log("Moving to the next masternode - $tem - $winner", 1);
// if all masternodes are dead, give the block to gpu // if all masternodes are dead, give the block to gpu

View File

@@ -38,6 +38,10 @@ $_config['allowed_hosts'] = [
'127.0.0.1', '127.0.0.1',
]; ];
// Disable transactions and block repropagation
$_config['disable_repropagation'] = false;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Peer Configuration | Peer Configuration
@@ -65,6 +69,9 @@ $_config['max_mempool_rebroadcast'] = 5000;
// The number of blocks between rebroadcasting transactions // The number of blocks between rebroadcasting transactions
$_config['sanity_rebroadcast_height'] = 30; $_config['sanity_rebroadcast_height'] = 30;
// Block accepting transfers from addresses blacklisted by the Arionum devs
$_config['use_official_blacklist'] = true;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Sanity Configuration | Sanity Configuration

View File

@@ -218,10 +218,21 @@ class Transaction
public function add_mempool($x, $peer = "") public function add_mempool($x, $peer = "")
{ {
global $db; global $db;
global $_config;
$block = new Block(); $block = new Block();
if ($x['version']>110) { if ($x['version']>110) {
return true; return true;
} }
if ($_config['use_official_blacklist']!==false) {
$blacklisted=[
"PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCvVQcHHCNLfiP9LmzWhhpCHx39Bhc67P5HMQM9cctEFvcsUdgrkGqy18taz9ZMrAGtq7NhBYpQ4ZTHkKYiZDaSUqQ", //faucet abuser
"PZ8Tyr4Nx8MHsRAGMpZmZ6TWY63dXWSCxYDeQHk7Ke66UB2Un3UMmMoJ7RF5vDZXihdEXi8gk8ZBRAi35aFrER2ZLX1mgND7sLFXKETGTjRYjoHcuRNiJN1g" // octaex
];
if (in_array($public_key, $blacklisted)) {
return true;
}
}
$current = $block->current(); $current = $block->current();
$height = $current['height']; $height = $current['height'];
$x['id'] = san($x['id']); $x['id'] = san($x['id']);

View File

@@ -118,6 +118,7 @@ if ($q == "info") {
if ($res) { if ($res) {
//if the new block is generated, propagate it to all peers in background //if the new block is generated, propagate it to all peers in background
$current = $block->current(); $current = $block->current();
$current['id']=escapeshellarg(san($current['id']));
system("php propagate.php block $current[id] > /dev/null 2>&1 &"); system("php propagate.php block $current[id] > /dev/null 2>&1 &");
api_echo("accepted"); api_echo("accepted");
} }
@@ -193,6 +194,7 @@ if ($q == "info") {
if ($res) { if ($res) {
//if the new block is generated, propagate it to all peers in background //if the new block is generated, propagate it to all peers in background
$current = $block->current(); $current = $block->current();
$current['id']=escapeshellarg(san($current['id']));
system("php propagate.php block $current[id] > /dev/null 2>&1 &"); system("php propagate.php block $current[id] > /dev/null 2>&1 &");
api_echo("accepted"); api_echo("accepted");
} else { } else {

View File

@@ -150,6 +150,7 @@ if ($q == "peer") {
// rebroadcast the transaction to some peers unless the transaction is smaller than the average size of transactions in mempool - protect against garbage data flooding // rebroadcast the transaction to some peers unless the transaction is smaller than the average size of transactions in mempool - protect against garbage data flooding
$res = $db->row("SELECT COUNT(1) as c, sum(val) as v FROM mempool ", [":src" => $data['src']]); $res = $db->row("SELECT COUNT(1) as c, sum(val) as v FROM mempool ", [":src" => $data['src']]);
if ($res['c'] < $_config['max_mempool_rebroadcast'] && $res['v'] / $res['c'] < $data['val']) { if ($res['c'] < $_config['max_mempool_rebroadcast'] && $res['v'] / $res['c'] < $data['val']) {
$data['id']=escapeshellarg(san($data['id']));
system("php propagate.php transaction '$data[id]' > /dev/null 2>&1 &"); system("php propagate.php transaction '$data[id]' > /dev/null 2>&1 &");
} }
api_echo("transaction-ok"); api_echo("transaction-ok");
@@ -185,6 +186,7 @@ if ($q == "peer") {
if ($accept_new) { if ($accept_new) {
// if the new block is accepted, run a microsanity to sync it // if the new block is accepted, run a microsanity to sync it
_log('['.$ip."] Starting microsanity - $data[height]"); _log('['.$ip."] Starting microsanity - $data[height]");
$ip=escapeshellarg($ip);
system("php sanity.php microsanity '$ip' > /dev/null 2>&1 &"); system("php sanity.php microsanity '$ip' > /dev/null 2>&1 &");
api_echo("microsanity"); api_echo("microsanity");
} else { } else {
@@ -200,7 +202,7 @@ if ($q == "peer") {
if (!$pr) { if (!$pr) {
api_err("block-too-old"); api_err("block-too-old");
} }
$peer_host = base58_encode($pr['hostname']); $peer_host = escapeshellcmd(base58_encode($pr['hostname']));
$pr['ip'] = escapeshellcmd(san_ip($pr['ip'])); $pr['ip'] = escapeshellcmd(san_ip($pr['ip']));
system("php propagate.php block current '$peer_host' '$pr[ip]' > /dev/null 2>&1 &"); system("php propagate.php block current '$peer_host' '$pr[ip]' > /dev/null 2>&1 &");
_log('['.$ip."] block too old, sending our current block - $data[height]"); _log('['.$ip."] block too old, sending our current block - $data[height]");
@@ -243,6 +245,7 @@ if ($q == "peer") {
_log('['.$ip."] block ok, repropagating - $data[height]"); _log('['.$ip."] block ok, repropagating - $data[height]");
// send it to all our peers // send it to all our peers
$data['id']=escapeshellcmd(san($data['id']));
system("php propagate.php block '$data[id]' all all linear > /dev/null 2>&1 &"); system("php propagate.php block '$data[id]' all all linear > /dev/null 2>&1 &");
api_echo("block-ok"); api_echo("block-ok");
} // return the current block, used in syncing } // return the current block, used in syncing

View File

@@ -69,9 +69,13 @@ if ((empty($peer) || $peer == 'all') && $type == "block") {
foreach ($r as $x) { foreach ($r as $x) {
if($x['hostname']==$_config['hostname']) continue; if($x['hostname']==$_config['hostname']) continue;
// encode the hostname in base58 and sanitize the IP to avoid any second order shell injections // encode the hostname in base58 and sanitize the IP to avoid any second order shell injections
$host = base58_encode($x['hostname']); $host = escapeshellcmd(base58_encode($x['hostname']));
$ip = filter_var($x['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); $ip = escapeshellcmd(filter_var($x['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE));
// fork a new process to send the blocks async // fork a new process to send the blocks async
$type=escapeshellcmd(san($type));
$id=escapeshellcmd(san($id));
if ($debug) { if ($debug) {
system("php propagate.php '$type' '$id' '$host' '$ip' debug"); system("php propagate.php '$type' '$id' '$host' '$ip' debug");
} elseif ($linear) { } elseif ($linear) {
@@ -166,7 +170,8 @@ if ($type == "transaction") {
if ($data['peer'] == "local") { if ($data['peer'] == "local") {
$r = $db->run("SELECT hostname FROM peers WHERE blacklisted < UNIX_TIMESTAMP()"); $r = $db->run("SELECT hostname FROM peers WHERE blacklisted < UNIX_TIMESTAMP()");
} else { } else {
$r = $db->run("SELECT hostname FROM peers WHERE blacklisted < UNIX_TIMESTAMP() AND reserve=0 ORDER by RAND() LIMIT ".intval($_config['transaction_propagation_peers']));
$r = $db->run("SELECT hostname FROM peers WHERE blacklisted < UNIX_TIMESTAMP() AND reserve=0 ORDER by RAND() LIMIT :limit",["limit"=>intval($_config['transaction_propagation_peers'])]);
} }
foreach ($r as $x) { foreach ($r as $x) {
$res = peer_post($x['hostname']."/peer.php?q=submitTransaction", $data); $res = peer_post($x['hostname']."/peer.php?q=submitTransaction", $data);

View File

@@ -670,14 +670,14 @@ $db->run("DELETE FROM `mempool` WHERE `date` < UNIX_TIMESTAMP()-(3600*24*14)");
//rebroadcasting local transactions //rebroadcasting local transactions
if ($_config['sanity_rebroadcast_locals'] == true) { if ($_config['sanity_rebroadcast_locals'] == true && $_config['disable_repropagation'] == false) {
$r = $db->run( $r = $db->run(
"SELECT id FROM mempool WHERE height>=:current and peer='local' order by `height` asc LIMIT 20", "SELECT id FROM mempool WHERE height>=:current and peer='local' order by `height` asc LIMIT 20",
[":current" => $current['height']] [":current" => $current['height']]
); );
_log("Rebroadcasting local transactions - ".count($r)); _log("Rebroadcasting local transactions - ".count($r));
foreach ($r as $x) { foreach ($r as $x) {
$x['id'] = san($x['id']); $x['id'] = escapeshellarg(san($x['id'])); // i know it's redundant due to san(), but some people are too scared of any exec
system("php propagate.php transaction $x[id] > /dev/null 2>&1 &"); system("php propagate.php transaction $x[id] > /dev/null 2>&1 &");
$db->run( $db->run(
"UPDATE mempool SET height=:current WHERE id=:id", "UPDATE mempool SET height=:current WHERE id=:id",
@@ -687,6 +687,7 @@ if ($_config['sanity_rebroadcast_locals'] == true) {
} }
//rebroadcasting transactions //rebroadcasting transactions
if ($_config['disable_repropagation'] == false) {
$forgotten = $current['height'] - $_config['sanity_rebroadcast_height']; $forgotten = $current['height'] - $_config['sanity_rebroadcast_height'];
$r = $db->run( $r = $db->run(
"SELECT id FROM mempool WHERE height<:forgotten ORDER by val DESC LIMIT 10", "SELECT id FROM mempool WHERE height<:forgotten ORDER by val DESC LIMIT 10",
@@ -696,11 +697,11 @@ $r = $db->run(
_log("Rebroadcasting external transactions - ".count($r)); _log("Rebroadcasting external transactions - ".count($r));
foreach ($r as $x) { foreach ($r as $x) {
$x['id'] = san($x['id']); $x['id'] = escapeshellarg(san($x['id'])); // i know it's redundant due to san(), but some people are too scared of any exec
system("php propagate.php transaction $x[id] > /dev/null 2>&1 &"); system("php propagate.php transaction $x[id] > /dev/null 2>&1 &");
$db->run("UPDATE mempool SET height=:current WHERE id=:id", [":id" => $x['id'], ":current" => $current['height']]); $db->run("UPDATE mempool SET height=:current WHERE id=:id", [":id" => $x['id'], ":current" => $current['height']]);
} }
}
//add new peers if there aren't enough active //add new peers if there aren't enough active
if ($total_peers < $_config['max_peers'] * 0.7) { if ($total_peers < $_config['max_peers'] * 0.7) {
@@ -709,7 +710,7 @@ if ($total_peers < $_config['max_peers'] * 0.7) {
} }
//random peer check //random peer check
$r = $db->run("SELECT * FROM peers WHERE blacklisted<UNIX_TIMESTAMP() and reserve=1 LIMIT ".$_config['max_test_peers']); $r = $db->run("SELECT * FROM peers WHERE blacklisted<UNIX_TIMESTAMP() and reserve=1 LIMIT :limit", [":limit"=>intval($_config['max_test_peers'])]);
foreach ($r as $x) { foreach ($r as $x) {
$url = $x['hostname']."/peer.php?q="; $url = $x['hostname']."/peer.php?q=";
$data = peer_post($url."ping", [], 5); $data = peer_post($url."ping", [], 5);

View File

@@ -193,7 +193,7 @@ elseif ($cmd == "blocks") {
if ($limit < 1) { if ($limit < 1) {
$limit = 100; $limit = 100;
} }
$r = $db->run("SELECT * FROM blocks WHERE height>:height ORDER by height ASC LIMIT $limit", [":height" => $height]); $r = $db->run("SELECT * FROM blocks WHERE height>:height ORDER by height ASC LIMIT :limit", [":height" => $height, ":limit"=>$limit]);
foreach ($r as $x) { foreach ($r as $x) {
echo "$x[height]\t$x[id]\n"; echo "$x[height]\t$x[id]\n";
} }
@@ -458,7 +458,10 @@ elseif ($cmd == 'get-address') {
echo "All the peers have been removed from the blacklist\n"; echo "All the peers have been removed from the blacklist\n";
} elseif ($cmd == 'resync-accounts') { } elseif ($cmd == 'resync-accounts') {
// resyncs the balance on all accounts // resyncs the balance on all accounts
if (file_exists("tmp/sanity-lock")) {
die("Sanity running. Wait for it to finish");
}
touch("tmp/sanity-lock");
// lock table to avoid race conditions on blocks // lock table to avoid race conditions on blocks
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE"); $db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE");
@@ -483,6 +486,7 @@ elseif ($cmd == 'get-address') {
} }
$db->exec("UNLOCK TABLES"); $db->exec("UNLOCK TABLES");
echo "All done"; echo "All done";
unlink("tmp/sanity-lock");
} elseif ($cmd=="compare-blocks") { } elseif ($cmd=="compare-blocks") {
$block=new Block(); $block=new Block();
@@ -526,15 +530,67 @@ elseif ($cmd == 'get-address') {
$current=$block->current(); $current=$block->current();
echo "Height:\t\t$current[height]\n"; echo "Height:\t\t$current[height]\n";
echo "Hash:\t\t".md5(json_encode($res))."\n\n"; echo "Hash:\t\t".md5(json_encode($res))."\n\n";
} elseif ($cmd=='accounts-hash') { } elseif ($cmd=='accounts-hash') {
$res=$db->run("SELECT * FROM accounts ORDER by public_key ASC"); $res=$db->run("SELECT * FROM accounts ORDER by id ASC");
$block=new Block(); $block=new Block();
$current=$block->current(); $current=$block->current();
echo "Height:\t\t$current[height]\n"; echo "Height:\t\t$current[height]\n";
echo "Hash:\t\t".md5(json_encode($res))."\n\n"; echo "Hash:\t\t".md5(json_encode($res))."\n\n";
} elseif ($cmd == "version") { } elseif ($cmd == "version") {
echo "\n\n".VERSION."\n\n"; echo "\n\n".VERSION."\n\n";
} elseif ($cmd == "sendblock"){
$peer=trim($argv[3]);
if (!filter_var($peer, FILTER_VALIDATE_URL)) {
die("Invalid peer hostname");
}
$peer = filter_var($peer, FILTER_SANITIZE_URL);
$height=intval($argv[2]);
$block=new Block();
$data = $block->export("", $height);
if($data===false){
die("Could not find this block");
}
$response = peer_post($peer."/peer.php?q=submitBlock", $data, 60, true);
var_dump($response);
}elseif ($cmd == "recheck-external-blocks") {
$peer=trim($argv[2]);
if (!filter_var($peer, FILTER_VALIDATE_URL)) {
die("Invalid peer hostname");
}
$peer = filter_var($peer, FILTER_SANITIZE_URL);
$blocks = [];
$block = new Block();
$height=intval($argv[3]);
$last=peer_post($peer."/peer.php?q=currentBlock");
$b=peer_post($peer."/peer.php?q=getBlock",["height"=>$height]);
for ($i = $height+1; $i <= $last['height']; $i++) {
$c=peer_post($peer."/peer.php?q=getBlock",["height"=>$i]);
if (!$block->mine(
$c['public_key'],
$c['nonce'],
$c['argon'],
$c['difficulty'],
$b['id'],
$b['height'],
$c['date']
)) {
print("Invalid block detected. $c[height] - $c[id]\n");
break;
}
echo "Block $i -> ok\n";
$b=$c;
}
} else { } else {
echo "Invalid command\n"; echo "Invalid command\n";
} }