Ejemplo n.º 1
0
// наш последний блок-1
$block_id = get_block_id($db) - 1;
if ($block_id < 1) {
    exit;
}
$hash = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tSELECT `hash`\n\t\tFROM `" . DB_PREFIX . "block_chain`\n\t\tWHERE `id`= {$block_id}\n\t\t", 'fetch_one');
$res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tSELECT `host`,\n\t\t\t\t\t `user_id`\n\t\tFROM `" . DB_PREFIX . "miners_data`\n\t\tWHERE `miner_id`> 0\n\t\tGROUP BY `host`\n\t\tORDER BY RAND()\n\t\tLIMIT " . COUNT_CONFIRMED_NODES . "\n\t\t");
$i = 0;
$urls = array();
while ($row = $db->fetchArray($res)) {
    $urls[$i]['url'] = $row['host'] . 'tools/check_node.php?block_id=' . $block_id;
    $urls[$i]['user_id'] = $row['user_id'];
    $i++;
}
if (empty($urls)) {
    exit;
}
print_R($urls);
$result = m_curl($urls, '', '', '', 10, true, false);
debug_print("result=" . print_r_hex($result), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
print_R($result);
$status[0] = 0;
$status[1] = 0;
foreach ($result as $user_id => $answer) {
    if ($answer != $hash) {
        $status[0]++;
    } else {
        $status[1]++;
    }
}
$db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tINSERT INTO `" . DB_PREFIX . "confirmations` (\n\t\t\t`block_id`,\n\t\t\t`good`,\n\t\t\t`bad`,\n\t\t\t`time`\n\t\t)\n\t\tVALUES (\n\t\t\t{$block_id},\n\t\t\t" . intval($status[1]) . ",\n\t\t\t" . intval($status[0]) . ",\n\t\t\t" . time() . "\n\t\t)\n\t\tON DUPLICATE KEY UPDATE  `good` = {$status[1]}, `bad` = {$status[0]}, `time` = " . time() . "\n\t\t");
Ejemplo n.º 2
0
            debug_print($urls, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
            $rez = m_curl($urls, $to_be_sent, $db, 'data', 20, true);
            debug_print($rez, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        }
    } else {
        // если просто юзер или работаю в защищенном режиме, то шлю тр-ии целиком. слать блоки не имею права.
        if ($my_config['local_gate_ip']) {
            $gate = 'protected_gate_tx.php';
            // Чтобы protected_gate_tx.php мог понять, какому ноду слать эту тр-ию, пишем в первые 100 байт host
            $remote_node_host = $node_data['host'];
        } else {
            $gate = 'gate_tx.php';
            $remote_node_host = '';
        }
        for ($i = 0; $i < sizeof($hosts); $i++) {
            $urls[$i] = array('url' => $hosts[$i]['host'] . $gate, 'node_public_key' => $hosts[$i]['node_public_key'], 'user_id' => $hosts[$i]['user_id']);
        }
        debug_print($urls, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        // возьмем хэши и сами тр-ии
        $tx_data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT `hash`, `data`\n\t\t\t\tFROM `" . DB_PREFIX . "transactions`\n\t\t\t\tWHERE `sent` = 0\n\t\t\t\t", 'fetch_array');
        debug_print('$tx_data: ' . print_r_hex($tx_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        if ($tx_data['hash']) {
            $hex_hash = bin2hex($tx_data['hash']);
            $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tUPDATE `" . DB_PREFIX . "transactions`\n\t\t\t\t\tSET `sent` = 1\n\t\t\t\t\tWHERE `hash` = 0x{$hex_hash}\n\t\t\t\t\t");
            // в первые 5 байт tx_data['data'] m_curl допишет user_id получателя, если вдруг там пул
            $rez = m_curl($urls, $tx_data['data'], $db, 'data', 20, true, true, $remote_node_host);
            debug_print($rez, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        }
    }
    sleep(1);
}
Ejemplo n.º 3
0
         // откатываем по фронту все свежие тр-ии
         $parsedata = new ParseData($transactions, $db);
         $parsedata->ParseDataRollbackFront();
         unset($parsedata);
     }
     $LOG_MARKER = "Вилка на {$block_id}";
     rollback_transactions_testblock($db, true);
     $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tTRUNCATE TABLE `" . DB_PREFIX . "testblock`\n\t\t\t\t\t");
 }
 //print '$binary_block_full='.$binary_block_full."\n";
 // теперь у нас в таблицах всё тоже самое, что у нода, у которого качаем блок
 // и можем этот блок проверить и занести в нашу БД
 $LOG_MARKER = "new block_id = " . $block_id;
 $parsedata = new ParseData($binary_block_full, $db);
 $error = $parsedata->ParseDataFull();
 debug_print("parsedata->block_data " . print_r_hex($parsedata->block_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 if (!$error) {
     $parsedata->insert_into_blockchain();
 }
 unset($parsedata);
 //main_unlock();
 // начинаем всё с начала уже с другими нодами. Но у нас уже могут быть новые блоки до $block_id, взятые от нода, которого с в итоге мы баним
 if ($error) {
     //$block_id--;
     nodes_ban($db, $max_block_id_user_id, '$block_id=' . $block_id . "\n" . $error . "\n" . __FILE__ . ', ' . __LINE__ . ', ' . __FUNCTION__ . ', ' . __CLASS__ . ', ' . __METHOD__);
     debug_print("[[error]] ## пробуем взять этот же блок у другого нода ParseDataFull error={$error}", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     //ob_save();
     main_unlock();
     sleep(1);
     continue 2;
 }
Ejemplo n.º 4
0
         while ($row = $db->fetchArray($res)) {
             if (array_key_exists($row['host'], $nodes_ban)) {
                 if ($nodes_ban[$row['host']] > time() - NODE_BAN_TIME) {
                     continue;
                 }
             }
             $hosts[] = $row['host'];
             $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\t\tINSERT IGNORE INTO `" . DB_PREFIX . "nodes_connection` (\n\t\t\t\t\t\t\t`host`,\n\t\t\t\t\t\t\t`user_id`\n\t\t\t\t\t\t)\n\t\t\t\t\t\tVALUES (\n\t\t\t\t\t\t\t'{$row['host']}',\n\t\t\t\t\t\t\t{$row['user_id']}\n\t\t\t\t\t\t)");
         }
     }
 }
 debug_print($hosts, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 // если хосты не набрались из miner_data, то берем из файла
 if (!$hosts) {
     $hosts = file(ABSPATH . 'nodes.inc');
     debug_print(ABSPATH . 'nodes.inc ' . print_r_hex($hosts), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     $r = array_rand($hosts, sizeof($hosts) > $max_hosts - 1 ? $max_hosts : sizeof($hosts));
     $r = is_array($r) ? $r : array($r);
     for ($i = 0; $i < sizeof($r); $i++) {
         list($host, $user_id) = explode(';', $hosts[$r[$i]]);
         if (in_array($user_id, $collective)) {
             continue;
         }
         if (array_key_exists($host, $nodes_ban)) {
             if ($nodes_ban[$host] > time() - NODE_BAN_TIME) {
                 continue;
             }
         }
         $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tINSERT IGNORE INTO `" . DB_PREFIX . "nodes_connection` (\n\t\t\t\t\t\t`host`,\n\t\t\t\t\t\t`user_id`\n\t\t\t\t\t)\n\t\t\t\t\tVALUES (\n\t\t\t\t\t\t'{$host}',\n\t\t\t\t\t\t{$user_id}\n\t\t\t\t\t)");
     }
 }
Ejemplo n.º 5
0
         $order_array[] = bin2hex(ParseData::string_shift($binary_data, 16));
     }
 } while ($binary_data);
 $order_array = array_flip($order_array);
 debug_print('$tr_array:' . print_r_hex($tr_array), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 debug_print('$order_array:' . print_r_hex($order_array), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 // сортируем и наши и полученные транзакции
 $transactions = '';
 //$merkle_array = array();
 foreach ($order_array as $md5 => $id) {
     $ordered_transactions[$id] = $tr_array[$md5];
     $transactions .= ParseData::encode_length_plus_data($tr_array[$md5]);
     //$merkle_array[] = hash('sha256', hash('sha256', $tr_array[$md5]));
 }
 debug_print('strlen($transactions)=' . strlen($transactions), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 debug_print('$ordered_transactions:' . print_r_hex($ordered_transactions), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 // формируем блок, который далее будем тщательно проверять
 /*
 Заголовок (от 143 до 527 байт )
 TYPE (0-блок, 1-тр-я)     1
 BLOCK_ID   				       4
 TIME       					       4
 USER_ID                         5
 LEVEL                              1
 SIGN                               от 128 до 512 байт. Подпись от TYPE, BLOCK_ID, PREV_BLOCK_HASH, TIME, USER_ID, LEVEL, MRKL_ROOT
 Далее - тело блока (Тр-ии)
 */
 //$merkle_root = $testBlock->merkle_tree_root($merkle_array);
 //$merkle_root_binary = pack( "H*", $merkle_root);
 $new_block_id_binary = dec_binary($new_testblock['block_id'], 4);
 //$prev_block_hash_binary = $testBlock->block_info['hash'];
Ejemplo n.º 6
0
 private function query_($query, $self = false)
 {
     global $global_current_block_id;
     $this->query = $query;
     $mysql_error = '';
     $i1 = 0;
     do {
         if (!($this->result = $this->_mysqli->query($this->query))) {
             if (substr_count($this->_mysqli->error, 'Deadlock') == 0) {
                 $mysql_error = $this->_mysqli->error;
                 if (preg_match('/(has gone away)/i', $mysql_error)) {
                     sleep(300);
                     $i1++;
                 } else {
                     trigger_error('Error performing query ' . $query . ' - Error message : ' . $mysql_error, E_USER_ERROR);
                 }
             } else {
                 usleep(10);
                 file_put_contents(ABSPATH . 'log/error_deadlock.log', date('H:i:s') . " : " . $query . "\n", FILE_APPEND);
             }
         }
     } while (preg_match('/(has gone away)/i', $mysql_error) && $i1 < 10);
     $ini_array = parse_ini_file(ABSPATH . "config.ini", true);
     $this->logging = false;
     //debug_print( "{$global_current_block_id} >= {$ini_array['main']['log_block_id_begin']} && {$global_current_block_id} <= {$ini_array['main']['log_block_id_end']}", $this->file, $this->line,  $this->fns,  $this->class, $this->method);
     //if (!$self)
     //debug_print( '!$self', $this->file, $this->line,  $this->fns,  $this->class, $this->method);
     if (!$self && ($ini_array['main']['log'] == 1 || $global_current_block_id >= $ini_array['main']['log_block_id_begin'] && $global_current_block_id <= $ini_array['main']['log_block_id_end'] && $ini_array['main']['log_block_id_begin'] && $ini_array['main']['log_block_id_end'])) {
         $this->logging = true;
         $this->AffectedRows = $this->getAffectedRows(true);
         debug_print("AffectedRows= {$this->AffectedRows}", $this->file, $this->line, $this->fns, $this->class, $this->method);
         if ($ini_array['main']['log_tables']) {
             $table = $this->parse_table($query);
             $rexp = '/\\`(' . $ini_array['main']['log_tables'] . ')\\`\\s/i';
             //$rexp = '/sssss/';
             if (preg_match($rexp, $query) && $table) {
                 $result00 = $this->result;
                 $res = $this->_mysqli->query("SELECT * FROM `{$table}`");
                 $data = array();
                 $i = 0;
                 while ($row = $res->fetch_array(MYSQLI_ASSOC)) {
                     foreach ($row as $name => $value) {
                         $data[$i][$name] = $value;
                     }
                     $i++;
                 }
                 debug_print('$table:' . $table . "\n" . print_r_hex($data), $this->file, $this->line, $this->fns, $this->class, $this->method);
                 $this->result = $result00;
             }
         }
     }
     return $this->result;
 }
Ejemplo n.º 7
0
function tx_parser($new_tx_data, $my_tx = false)
{
    global $db;
    $error = '';
    $binary_tx = $new_tx_data['data'];
    debug_print('$new_tx_data=' . print_r_hex($new_tx_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    // проверим, нет ли несовместимых тр-ий
    // 	$wait_error  -	 значит просто откладываем обработку тр-ии на после того, как сформируются блок
    // $fatal_error - удаляем тр-ию, т.к. она некорректная
    list($fatal_error, $wait_error, $for_self_use, $type, $user_id, $third_var) = clear_incompatible_tx($binary_tx, $db, $my_tx);
    if (!$fatal_error && !$wait_error) {
        $parsedata = new ParseData($binary_tx, $db);
        $error = $parsedata->ParseData_gate();
        unset($parsedata);
    }
    if ($error || $fatal_error) {
        delete_queue_tx($new_tx_data);
    }
    // удалим тр-ию из очереди
    if (!$error) {
        $error = $fatal_error;
    }
    if (!$error) {
        $error = $wait_error;
    }
    if ($error) {
        /* не актуально
        		 * if (substr_count($error, '[limit_requests]')>0) {
        			debug_print('----------------[error]'.$error.'-------------------', __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__);
        			$parsedata = new ParseData(ParseData::encode_length_plus_data($binary_tx), $db);
        			$parsedata->ParseDataRollbackFront();
        			unset($parsedata);
        		}
        		else {*/
        debug_print('error wo rollback----------------[error]' . $error . '-------------------', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        // пишем в отдельный лог невалидных тр-ий
        $ini_array = parse_ini_file(ABSPATH . "config.ini", true);
        if ($ini_array['main']['bad_tx_log'] == 1) {
            $file = ABSPATH . 'log/bad_tx.log';
            $text = "time: " . date('d-m-Y H:i:s') . "\n";
            $text .= "script: " . get_script_name() . "\n";
            $text .= "error: {$error}\n";
            $text .= "md5_hash: " . md5($binary_tx) . "\n";
            $text .= "data: {$binary_tx}\n";
            @file_put_contents($file, $text, FILE_APPEND);
        }
        $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tUPDATE `" . DB_PREFIX . "transactions_status`\n\t\t\t\t\tSET `error` = '" . $db->escape($error) . "'\n\t\t\t\t\tWHERE `hash` = 0x" . md5($binary_tx) . "\n\t\t\t\t\t");
        /*}*/
        //delete_queue_tx();
        //main_unlock();
        //ob_save();
        //sleep(1);
        //return 'continue';
    } else {
        list(, $data_hex) = unpack("H*", $binary_tx);
        list(, $hash_hex) = unpack("H*", $new_tx_data['hash']);
        // счтечик, чтобы не было зацикливания
        $counter = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT `counter`\n\t\t\t\tFROM `" . DB_PREFIX . "transactions`\n\t\t\t\tWHERE `hash` = 0x{$hash_hex}\n\t\t\t\t", 'fetch_one');
        $counter = intval($counter);
        $counter++;
        $data = "{$hash_hex}\t{$data_hex}\t{$for_self_use}\t{$type}\t{$user_id}\t{$third_var}\t{$counter}";
        $file = save_tmp_644('FTX', $data);
        debug_print($data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        // используем REPLACE т.к. тр-ия уже может быть в transactions с verified=0
        $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tLOAD DATA LOCAL INFILE  '{$file}'\n\t\t\t\tREPLACE INTO TABLE `" . DB_PREFIX . "transactions`\n\t\t\t\tFIELDS TERMINATED BY '\t'\n\t\t\t\t(@hash, @data, `for_self_use`, `type`, `user_id`, `third_var`, `counter`)\n\t\t\t\tSET `hash` = UNHEX(@hash),\n\t\t\t\t\t   `data` = UNHEX(@data)\n\t\t\t\t");
        unlink($file);
        // удалим тр-ию из очереди
        delete_queue_tx($new_tx_data);
    }
}
Ejemplo n.º 8
0
 *
 * */
do {
    debug_print("START", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    // отметимся в БД, что мы живы.
    upd_deamon_time($db);
    // проверим, не нужно нам выйти, т.к. обновилась версия скрипта
    if (check_deamon_restart($db)) {
        exit;
    }
    $blocks = array();
    //print 'memory='.memory_get_usage()."\n---------------------------------\n";
    // ждем, пока разлочится и лочим сами, чтобы не попасть в тот момент, когда данные из блока уже занесены в БД, а info_block еще не успел обновиться
    main_lock();
    $prev_block_data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT *\n\t\t\tFROM `" . DB_PREFIX . "info_block`\n\t\t\t", 'fetch_array');
    debug_print('info_block:' . print_r_hex($prev_block_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    $new_block_data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT *\n\t\t\tFROM `" . DB_PREFIX . "queue_blocks`\n\t\t\tLIMIT 1\n\t\t\t", 'fetch_array');
    //print '$new_block_data:';
    //print_r($new_block_data);
    if (!$new_block_data) {
        main_unlock();
        debug_print("continue", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        sleep(1);
        continue;
    }
    $new_block_data['head_hash_hex'] = bin2hex($new_block_data['head_hash']);
    $prev_block_data['head_hash_hex'] = bin2hex($prev_block_data['head_hash']);
    $new_block_data['hash_hex'] = bin2hex($new_block_data['hash']);
    $prev_block_data['hash_hex'] = bin2hex($prev_block_data['hash']);
    $variables = ParseData::get_variables($db, array('rollback_blocks_1', 'max_block_size', 'max_tx_size', 'max_tx_count'));
    /*
Ejemplo n.º 9
0
 // также, нужно блокировать main, т.к. изменение в info_block и block_chain ведут к изменению подписи в testblock
 //main_lock();
 testblock_lock();
 // за промежуток в main_unlock и main_lock мог прийти новый блок
 $testBlock = new testblock($db, true);
 // на всякий случай убедимся, что блок не изменился
 if ($testBlock->prev_block['head_hash'] != $prev_head_hash) {
     main_unlock();
     unset($testBlock);
     debug_print("continue", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     sleep(1);
     continue;
 }
 // составим блок. заголовок + тело + подпись
 $testblock_data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT *\n\t\t\tFROM `" . DB_PREFIX . "testblock`\n\t\t\tWHERE `status` = 'active'\n\t\t\t", 'fetch_array');
 debug_print(print_r_hex($testblock_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 debug_print("testBlock->prev_block['block_id']={$testBlock->prev_block['block_id']} // testblock_data['block_id'] = {$testblock_data['block_id']} ", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 if (!$testblock_data) {
     //main_unlock();
     testblock_unlock();
     print 'null $testblock_data' . "\n";
     unset($testBlock);
     sleep(1);
     print ">>continue\n";
     //ob_save();
     continue;
 }
 // получим транзакции
 $testblock_data['tx'] = '';
 $res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT *\n\t\t\t\tFROM `" . DB_PREFIX . "transactions_testblock`\n\t\t\t\tORDER BY `id` ASC\n\t\t\t\t");
 while ($row = $db->fetchArray($res)) {
Ejemplo n.º 10
0
 function CheckBlockHeader()
 {
     // инфа о предыдущем блоке (т.е. последнем занесенном)
     if (!$this->prev_block) {
         // инфа может быть передана прямо в массиве
         $this->get_prev_block($this->block_data['block_id'] - 1);
     }
     //$this->get_info_block(); убрано, т.к. CheckBlockHeader используется и при сборе новых блоков при вилке
     // для локальных тестов
     if ($this->prev_block['block_id'] == 1) {
         $ini_array = parse_ini_file(ABSPATH . "config.ini", true);
         if (isset($ini_array['local']['start_block_id'])) {
             $this->prev_block['block_id'] = $ini_array['local']['start_block_id'];
         }
     }
     debug_print("this->prev_block: " . print_r_hex($this->prev_block), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     debug_print("this->block_data: " . print_r_hex($this->block_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     // меркель рут нужен для проверки подписи блока, а также проверки лимитов MAX_TX_SIZE и MAX_TX_COUNT
     if ($this->block_data['block_id'] == 1) {
         $this->global_variables['max_tx_size'] = 1024 * 1024;
         $first = true;
     } else {
         $first = false;
     }
     $this->mrkl_root = self::getMrklroot($this->binary_data, $this->global_variables, $first);
     // проверим время
     if (!check_input_data($this->block_data['time'], 'int')) {
         return 'error time';
     }
     // проверим уровень
     if (!check_input_data($this->block_data['level'], 'level')) {
         return 'error level';
     }
     // получим значения для сна
     $sleep_data = $this->db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tSELECT `value`\n\t\t\t\t\tFROM `" . DB_PREFIX . "variables`\n\t\t\t\t\tWHERE `name` = 'sleep'\n\t\t\t\t\t", 'fetch_one');
     $sleep_data = json_decode($sleep_data, true);
     debug_print("sleep_data:", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     //print_R($sleep_data);
     // узнаем время, которые было затрачено в ожидании is_ready предыдущим блоком
     $is_ready_sleep = testblock::get_is_ready_sleep($this->prev_block['level'], $sleep_data['is_ready']);
     // сколько сек должен ждать нод, перед тем, как начать генерить блок, если нашел себя в одном из уровней.
     $generator_sleep = testblock::get_generator_sleep($this->block_data['level'], $sleep_data['generator']);
     // сумма is_ready всех предыдущих уровней, которые не успели сгенерить блок
     $is_ready_sleep2 = testblock::get_is_ready_sleep_sum($this->block_data['level'], $sleep_data['is_ready']);
     debug_print("is_ready_sleep={$is_ready_sleep}\ngenerator_sleep={$generator_sleep}\nis_ready_sleep2={$is_ready_sleep2}", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     debug_print('prev_block:' . print_r_hex($this->prev_block), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     debug_print('block_data:' . print_r_hex($this->block_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     // не слишком ли рано прислан этот блок. допустима погрешность = error_time
     if (!$first) {
         if ($this->prev_block['time'] + $is_ready_sleep + $generator_sleep + $is_ready_sleep2 - $this->block_data['time'] > $this->global_variables['error_time']) {
             return "error block time {$this->prev_block['time']} + {$is_ready_sleep} + {$generator_sleep} + {$is_ready_sleep2} - {$this->block_data['time']} > {$this->global_variables['error_time']}\n";
         }
     }
     // исключим тех, кто сгенерил блок с бегущими часами
     if ($this->block_data['time'] > time()) {
         return "error block time";
     }
     // проверим ID блока
     if (!check_input_data($this->block_data['block_id'], 'int')) {
         return 'block_id';
     }
     // проверим, верный ли ID блока
     if (!$first) {
         if ($this->block_data['block_id'] != $this->prev_block['block_id'] + 1) {
             return "error block_id ({$this->block_data['block_id']}!=" . ($this->prev_block['block_id'] + 1) . ")";
         }
     }
     // проверим, есть ли такой майнер и заодно получим public_key
     // ================================== my_table заменить ===============================================
     $this->node_public_key = $this->db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tSELECT `node_public_key`\n\t\t\t\t\tFROM `" . DB_PREFIX . "miners_data`\n\t\t\t\t\tWHERE `user_id` = {$this->block_data['user_id']}\n\t\t\t\t\tLIMIT 1\n\t\t\t\t\t", 'fetch_one');
     if (!$first) {
         if (!$this->node_public_key) {
             return 'user_id';
         }
     }
     // SIGN от 128 байта до 512 байт. Подпись от TYPE, BLOCK_ID, PREV_BLOCK_HASH, TIME, USER_ID, LEVEL, MRKL_ROOT
     $for_sign = "0,{$this->block_data['block_id']},{$this->prev_block['hash']},{$this->block_data['time']},{$this->block_data['user_id']},{$this->block_data['level']},{$this->mrkl_root}";
     debug_print("checkSign", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     // проверяем подпись
     if (!$first) {
         $error = self::checkSign($this->node_public_key, $for_sign, $this->block_data['sign'], true);
         if ($error) {
             return $error;
         }
     }
 }
Ejemplo n.º 11
0
    unset($testBlock);
    die('!$my_miner_id');
}
$variables = ParseData::get_all_variables($db);
$time = time();
$reduction_tx_data = '';
$promised_amount = array();
$reduction_currency_id = false;
$reduction_type = '';
// ===== ручное урезание денежной массы
// получаем кол-во обещанных сумм у разных юзеров по каждой валюте. start_time есть только у тех, у кого статус mining/repaid
$res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tSELECT `currency_id`, count(`user_id`) as `count`\n\t\tFROM (\n\t\t\t\tSELECT `currency_id`, `user_id`\n\t\t\t\tFROM `" . DB_PREFIX . "promised_amount`\n\t\t\t\tWHERE `start_time` < " . ($time - $variables['min_hold_time_promise_amount']) . "  AND\n\t\t\t\t\t\t\t `del_block_id` = 0 AND\n\t\t\t\t\t\t\t `status` IN ('mining', 'repaid')\n\t\t\t\tGROUP BY  `user_id`, `currency_id`\n\t\t\t\t) as t1\n\t\tGROUP BY  `currency_id`\n\t\t");
while ($row = $db->fetchArray($res)) {
    $promised_amount[$row['currency_id']] = $row['count'];
}
debug_print('$promised_amount_:' . print_r_hex($promised_amount), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
// берем все голоса юзеров
$res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT `currency_id`,\n\t\t\t\t\t\t  `pct`,\n\t\t\t\t\t\t  count(`currency_id`) as `votes`\n\t\t\tFROM `" . DB_PREFIX . "votes_reduction`\n\t\t\tWHERE `time` > " . ($time - $variables['reduction_period']) . "\n\t\t\tGROUP BY  `currency_id`, `pct`\n\t\t\t");
while ($row = $db->fetchArray($res)) {
    debug_print($row, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    if (!isset($promised_amount[$row['currency_id']])) {
        continue;
    }
    // если голосов за урезание > 50% от числа всех держателей данной валюты
    if ($row['votes'] >= $promised_amount[$row['currency_id']] / 2) {
        // проверим, прошло ли 2 недели с последнего урезания
        $reduction_time = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tSELECT max(`time`)\n\t\t\t\t\tFROM `" . DB_PREFIX . "reduction`\n\t\t\t\t\tWHERE `currency_id` = {$row['currency_id']} AND\n\t\t\t\t\t\t\t\t `type` = 'manual'\n\t\t\t\t\t", 'fetch_one');
        $reduction_time = intval($reduction_time);
        if ($time - $reduction_time > $variables['reduction_period']) {
            $reduction_currency_id = $row['currency_id'];
            $reduction_pct = $row['pct'];