assets system

This commit is contained in:
admin@arionum.com
2019-04-14 22:55:16 +03:00
parent 7e28ce9246
commit 1baba2ab3a
8 changed files with 686 additions and 40 deletions

View File

@@ -37,7 +37,7 @@ class Block
}
}
// lock table to avoid race conditions on blocks
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE, masternode WRITE, peers write, config WRITE");
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE, masternode WRITE, peers write, config WRITE, assets WRITE, assets_balance WRITE, assets_market WRITE");
$reward = $this->reward($height, $data);
@@ -157,8 +157,12 @@ class Block
$db->exec("UNLOCK TABLES");
return false;
}
$this->do_hard_forks($height, $hash);
}
// parse the block's transactions and insert them to db
@@ -168,6 +172,16 @@ class Block
$this->blacklist_masternodes();
$this->reset_fails_masternodes($public_key, $height, $hash);
}
// automated asset distribution, checked only every 1000 blocks to reduce load. Payouts every 10000 blocks.
if($height>11111 && $height%50==1 && $res==true){ // every 50 for testing. No initial height set yet.
$res=$this->asset_distribute_dividends($height, $hash, $public_key, $date, $signature);
}
if($height>11111 && $res==true){
$res=$this->asset_market_orders($height, $hash, $public_key, $date, $signature);
}
// if any fails, rollback
if ($res == false) {
$db->rollback();
@@ -179,6 +193,110 @@ class Block
return true;
}
public function asset_market_orders($height, $hash, $public_key, $date, $signature)
{
global $db;
$trx=new Transaction;
// checks all bid market orders ordered in the same way on all nodes
$r=$db->run("SELECT * FROM assets_market WHERE status=0 and val_done<val AND type='bid' ORDER by asset ASC, id ASC");
foreach($r as $x){
$finished=0;
//remaining part of the order
$val=$x['val']-$x['val_done'];
// starts checking all ask orders that are still valid and are on the same price. should probably adapt this to allow lower price as well in the future.
$asks=$db->run("SELECT * FROM assets_market WHERE status=0 and val_done<val AND asset=:asset AND price=:price AND type='ask' ORDER by price ASC, id ASC", [":asset"=>$x['asset'], ":price"=>$x['price']]);
foreach($asks as $ask){
//remaining part of the order
$remaining=$ask['val']-$ask['val_done'];
// how much of the ask should we use to fill the bid order
$use=0;
if($remaining>$val){
$use=$remaining-$val;
} else {
$use=$remaining;
}
$val-=$use;
$db->run("UPDATE assets_market SET val_done=val_done+:done WHERE id=:id",[":id"=>$ask['id'], ":done"=>$use]);
$db->run("UPDATE assets_market SET val_done=val_done+:done WHERE id=:id",[":id"=>$x['id'], ":done"=>$use]);
// if we filled the order, we should exit the loop
$db->run("INSERT into assets_balance SET account=:account, asset=:asset, balance=:balance ON DUPLICATE KEY UPDATE balance=balance+:balance2",[":account"=>$x['account'], ":asset"=>$x['asset'], ":balance"=>$use, ":balance2"=>$use]);
$aro=$use*$x['price'];
$db->run("UPDATE accounts SET balance=balance+:balance WHERE id=:id",[":balance"=>$aro, ":id"=>$ask['account']]);
$random = hex2coin(hash("sha512", $x['id'].$ask['id'].$val.$hash));
$new = [
"id" => $random,
"public_key" => $x['id'],
"dst" => $ask['id'],
"val" => $aro,
"fee" => 0,
"signature" => $signature,
"version" => 58,
"date" => $date,
"message" => $use
];
$res=$trx->add($hash,$height,$new);
if(!$res){
return false;
}
if($val<=0){
break;
}
}
}
return true;
}
public function asset_distribute_dividends($height, $hash, $public_key, $date, $signature)
{
global $db;
$trx=new Transaction;
_log("Starting automated dividend distribution",3);
// just the assets with autodividend
$r=$db->run("SELECT * FROM assets WHERE auto_dividend=1");
if($r===false){
return true;
}
foreach($r as $x){
$asset=$db->row("SELECT id, public_key, balance FROM accounts WHERE id=:id",[":id"=>$x['id']]);
// minimum balance 1 aro
if($asset['balance']<1) {
_log("Asset $asset[id] not enough balance",3);
continue;
}
_log("Autodividend $asset[id] - $asset[balance] ARO",3);
// every 10000 blocks and at minimum 10000 of asset creation or last distribution, manual or automated
$last=$db->single("SELECT height FROM transactions WHERE (version=54 OR version=50 or version=57) AND public_key=:pub ORDER by height DESC LIMIT 1",[":pub"=>$asset['public_key']]);
if($height<$last+100){ // 100 for testnet
continue;
}
// generate a pseudorandom id and version 54 transaction for automated dividend distribution. No fees for such automated distributions to encourage the system
$random = hex2coin(hash("sha512", $x['id'].$hash.$height));
$new = [
"id" => $random,
"public_key" => $asset['public_key'],
"dst" => $asset['id'],
"val" => $asset['balance'],
"fee" => 0,
"signature" => $signature,
"version" => 57,
"date" => $date,
"src" => $asset['id'],
"message" => '',
];
$res=$trx->add($hash,$height,$new);
if(!$res){
return false;
}
}
return true;
}
public function do_hard_forks($height, $block)
{
global $db;
@@ -965,7 +1083,8 @@ class Block
return;
}
$db->beginTransaction();
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE, masternode WRITE");
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE, masternode WRITE, peers write, config WRITE, assets WRITE, assets_balance WRITE, assets_market WRITE");
foreach ($r as $x) {
$res = $trx->reverse($x['id']);
if ($res === false) {
@@ -1002,7 +1121,8 @@ class Block
}
// avoid race conditions on blockchain manipulations
$db->beginTransaction();
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE");
$db->exec("LOCK TABLES blocks WRITE, accounts WRITE, transactions WRITE, mempool WRITE, masternode WRITE, peers write, config WRITE, assets WRITE, assets_balance WRITE, assets_market WRITE");
// reverse all transactions of the block
$res = $trx->reverse($x['id']);
if ($res === false) {
@@ -1066,7 +1186,7 @@ class Block
$r = $db->run("SELECT * FROM transactions WHERE version>0 AND block=:block", [":block" => $block['id']]);
$transactions = [];
foreach ($r as $x) {
if ($x['version']>110) {
if ($x['version']>110||$x['version']==57||$x['version']==58||$x['version']==59) {
//internal transactions
continue;
}