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

11
api.php
View File

@@ -422,12 +422,20 @@ if ($q == "getAddress") {
}
}
$public_key = san($data['public_key']);
if (!$acc->valid_key($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']);
if (!$acc->valid_key($private_key)) {
api_err("Invalid private key");
@@ -559,6 +567,7 @@ if ($q == "getAddress") {
$trx->add_mempool($transaction, "local");
$hash=escapeshellarg(san($hash));
system("php propagate.php transaction $hash > /dev/null 2>&1 &");
api_echo($hash);
} elseif ($q == "mempoolSize") {

View File

@@ -276,7 +276,7 @@ class Block
// before mnn hf
if ($height<80000) {
// 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'];
// avg block time
@@ -566,8 +566,8 @@ class Block
}
_log("We have masternodes to blacklist - $tem", 2);
$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",
[":current"=>$last['height'], ":start"=>$last['height']-360]
"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, ":limit"=>$tem]
);
_log(json_encode($ban));
$i=0;
@@ -689,8 +689,8 @@ class Block
$tem=floor(($time-$last_time)/600);
}
$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",
[":current"=>$current_height, ":start"=>$current_height-360]
"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, ":tem"=>$tem]
);
_log("Moving to the next masternode - $tem - $winner", 1);
// if all masternodes are dead, give the block to gpu

View File

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

View File

@@ -218,10 +218,21 @@ class Transaction
public function add_mempool($x, $peer = "")
{
global $db;
global $_config;
$block = new Block();
if ($x['version']>110) {
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();
$height = $current['height'];
$x['id'] = san($x['id']);

View File

@@ -118,6 +118,7 @@ if ($q == "info") {
if ($res) {
//if the new block is generated, propagate it to all peers in background
$current = $block->current();
$current['id']=escapeshellarg(san($current['id']));
system("php propagate.php block $current[id] > /dev/null 2>&1 &");
api_echo("accepted");
}
@@ -193,6 +194,7 @@ if ($q == "info") {
if ($res) {
//if the new block is generated, propagate it to all peers in background
$current = $block->current();
$current['id']=escapeshellarg(san($current['id']));
system("php propagate.php block $current[id] > /dev/null 2>&1 &");
api_echo("accepted");
} 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
$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']) {
$data['id']=escapeshellarg(san($data['id']));
system("php propagate.php transaction '$data[id]' > /dev/null 2>&1 &");
}
api_echo("transaction-ok");
@@ -185,6 +186,7 @@ if ($q == "peer") {
if ($accept_new) {
// if the new block is accepted, run a microsanity to sync it
_log('['.$ip."] Starting microsanity - $data[height]");
$ip=escapeshellarg($ip);
system("php sanity.php microsanity '$ip' > /dev/null 2>&1 &");
api_echo("microsanity");
} else {
@@ -200,7 +202,7 @@ if ($q == "peer") {
if (!$pr) {
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']));
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]");
@@ -243,6 +245,7 @@ if ($q == "peer") {
_log('['.$ip."] block ok, repropagating - $data[height]");
// 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 &");
api_echo("block-ok");
} // return the current block, used in syncing

View File

@@ -69,9 +69,13 @@ if ((empty($peer) || $peer == 'all') && $type == "block") {
foreach ($r as $x) {
if($x['hostname']==$_config['hostname']) continue;
// encode the hostname in base58 and sanitize the IP to avoid any second order shell injections
$host = base58_encode($x['hostname']);
$ip = filter_var($x['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
$host = escapeshellcmd(base58_encode($x['hostname']));
$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
$type=escapeshellcmd(san($type));
$id=escapeshellcmd(san($id));
if ($debug) {
system("php propagate.php '$type' '$id' '$host' '$ip' debug");
} elseif ($linear) {
@@ -166,7 +170,8 @@ if ($type == "transaction") {
if ($data['peer'] == "local") {
$r = $db->run("SELECT hostname FROM peers WHERE blacklisted < UNIX_TIMESTAMP()");
} 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) {
$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
if ($_config['sanity_rebroadcast_locals'] == true) {
if ($_config['sanity_rebroadcast_locals'] == true && $_config['disable_repropagation'] == false) {
$r = $db->run(
"SELECT id FROM mempool WHERE height>=:current and peer='local' order by `height` asc LIMIT 20",
[":current" => $current['height']]
);
_log("Rebroadcasting local transactions - ".count($r));
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 &");
$db->run(
"UPDATE mempool SET height=:current WHERE id=:id",
@@ -687,21 +687,22 @@ if ($_config['sanity_rebroadcast_locals'] == true) {
}
//rebroadcasting transactions
$forgotten = $current['height'] - $_config['sanity_rebroadcast_height'];
$r = $db->run(
if ($_config['disable_repropagation'] == false) {
$forgotten = $current['height'] - $_config['sanity_rebroadcast_height'];
$r = $db->run(
"SELECT id FROM mempool WHERE height<:forgotten ORDER by val DESC LIMIT 10",
[":forgotten" => $forgotten]
);
_log("Rebroadcasting external transactions - ".count($r));
_log("Rebroadcasting external transactions - ".count($r));
foreach ($r as $x) {
$x['id'] = san($x['id']);
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']]);
foreach ($r as $x) {
$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 &");
$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
if ($total_peers < $_config['max_peers'] * 0.7) {
$res = $_config['max_peers'] - $total_peers;
@@ -709,7 +710,7 @@ if ($total_peers < $_config['max_peers'] * 0.7) {
}
//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) {
$url = $x['hostname']."/peer.php?q=";
$data = peer_post($url."ping", [], 5);

View File

@@ -193,7 +193,7 @@ elseif ($cmd == "blocks") {
if ($limit < 1) {
$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) {
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";
} elseif ($cmd == 'resync-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
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE");
@@ -483,6 +486,7 @@ elseif ($cmd == 'get-address') {
}
$db->exec("UNLOCK TABLES");
echo "All done";
unlink("tmp/sanity-lock");
} elseif ($cmd=="compare-blocks") {
$block=new Block();
@@ -526,15 +530,67 @@ elseif ($cmd == 'get-address') {
$current=$block->current();
echo "Height:\t\t$current[height]\n";
echo "Hash:\t\t".md5(json_encode($res))."\n\n";
} 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();
$current=$block->current();
echo "Height:\t\t$current[height]\n";
echo "Hash:\t\t".md5(json_encode($res))."\n\n";
} elseif ($cmd == "version") {
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 {
echo "Invalid command\n";
}