main_unlock();
        exit;
    }
    debug_print($max_other_currencies_votes, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    $total_count_currencies = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT count(`id`)\n\t\t\tFROM `" . DB_PREFIX . "currency`\n\t\t\t", 'fetch_one');
    foreach ($max_other_currencies_votes as $currency_id => $count_and_votes) {
        $new_max_other_currencies[$currency_id] = get_max_vote($count_and_votes, 0, $total_count_currencies, 10);
    }
    if (get_community_users($db)) {
        $my_prefix = $testBlock->user_id . '_';
    } else {
        $my_prefix = '';
    }
    $node_private_key = get_node_private_key($db, $my_prefix);
    $json_data = json_encode($new_max_other_currencies);
    // подписываем нашим нод-ключем данные транзакции
    $data_for_sign = ParseData::findType('new_max_other_currencies') . ",{$time},{$my_user_id},{$json_data}";
    $rsa = new Crypt_RSA();
    $rsa->loadKey($node_private_key);
    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    $signature = $rsa->sign($data_for_sign);
    debug_print('$data_for_sign=' . $data_for_sign . "\n", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    // создаем тр-ию. пишем $block_id, на момент которого были актуальны голоса в табле 'pct'
    $data = dec_binary(ParseData::findType('new_max_other_currencies'), 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($my_user_id) . ParseData::encode_length_plus_data($json_data) . ParseData::encode_length_plus_data($signature);
    $hash = ParseData::dsha256($data);
    insert_tx($data, $db);
    $new_tx_data['data'] = $data;
    $new_tx_data['hash'] = hextobin(md5($data));
    tx_parser($new_tx_data, true);
}
main_unlock();
Exemple #2
0
    }
    $need_tx .= hextobin($new_data['tx_hash']);
} while ($binary_data);
if (!$need_tx) {
    exit;
}
// получился список нужных нам тр-ий, теперь его пошлем тому ноду, у которого они есть
$data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT `host`,\n\t\t\t\t\t\t `node_public_key`\n\t\t\tFROM `" . DB_PREFIX . "miners_data`\n\t\t\tWHERE `user_id` = {$new_data['user_id']}\n\t\t\t", 'fetch_array');
debug_print($data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
$host = $data['host'];
$node_public_key = $data['node_public_key'];
debug_print($new_data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
// шифруем данные. ключ $key будем использовать для расшифровки ответа
$encrypted_data = encrypt_data($need_tx, $node_public_key, $db, $my_key);
// user_id получателя (нужно для пулов)
$encrypted_data = dec_binary($new_data['user_id'], 5) . $encrypted_data;
debug_print('$encrypted_data=' . bin2hex($encrypted_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
$url = "{$host}/get_tx.php";
debug_print($url, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
// загружаем сами тр-ии
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'data=' . urlencode($encrypted_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$encrypted_tx_set = curl_exec($ch);
curl_close($ch);
debug_print('$encrypted_tx_set=' . $encrypted_tx_set, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
debug_print('$my_key=' . $my_key, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    debug_print($max_promised_amount_votes, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    $new_max_promised_amounts = array();
    foreach ($max_promised_amount_votes as $currency_id => $amounts_and_votes) {
        //$valid_amounts_and_votes = ParseData::makeMaxPromisedAmount($amounts_and_votes);
        //$key = get_max_vote($valid_amounts_and_votes, 0, 1000, 100);
        //$new_max_promised_amounts[$currency_id] =  ParseData::getPctValue($key);
        $new_max_promised_amounts[$currency_id] = get_max_vote($amounts_and_votes, 0, 165, 10);
    }
    if (get_community_users($db)) {
        $my_prefix = $testBlock->user_id . '_';
    } else {
        $my_prefix = '';
    }
    $node_private_key = get_node_private_key($db, $my_prefix);
    $json_data = json_encode($new_max_promised_amounts);
    // подписываем нашим нод-ключем данные транзакции
    $data_for_sign = ParseData::findType('new_max_promised_amounts') . ",{$time},{$my_user_id},{$json_data}";
    $rsa = new Crypt_RSA();
    $rsa->loadKey($node_private_key);
    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    $signature = $rsa->sign($data_for_sign);
    debug_print('$data_for_sign=' . $data_for_sign . "\n", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    // создаем тр-ию. пишем $block_id, на момент которого были актуальны голоса в табле 'pct'
    $data = dec_binary(ParseData::findType('new_max_promised_amounts'), 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($my_user_id) . ParseData::encode_length_plus_data($json_data) . ParseData::encode_length_plus_data($signature);
    $hash = ParseData::dsha256($data);
    insert_tx($data, $db);
    $new_tx_data['data'] = $data;
    $new_tx_data['hash'] = hextobin(md5($data));
    tx_parser($new_tx_data, true);
}
main_unlock();
<?php

/*
 * Получаем тр-ии, которые есть у юзера, в ответ выдаем те, что недостают и
 * их порядок следования, чтобы получить валидный блок
 */
define('DC', TRUE);
define('ABSPATH', dirname(__FILE__) . '/');
set_time_limit(0);
require_once ABSPATH . 'db_config.php';
require_once ABSPATH . 'includes/autoload.php';
require_once ABSPATH . 'includes/errors.php';
$db = new MySQLidb(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT);
$data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT *\n\t\t\tFROM `" . DB_PREFIX . "testblock`\n\t\t\tLIMIT 1\n\t\t\t", 'fetch_array');
$response_binary_data = dec_binary($data['block_id'], 4) . dec_binary($data['time'], 4) . dec_binary($data['user_id'], 5) . encode_length(strlen($data['signature'])) . $data['signature'];
// разбираем присланные данные
$binary_data = $_POST['data'];
$add_sql = '';
if ($binary_data) {
    $tr_array = array();
    // получим хэши тр-ий, которые надо исключить
    do {
        list(, $tr) = unpack("H*", ParseData::string_shift($binary_data, 16));
        // проверим
        if (!check_input_data($tr, 'md5')) {
            die('error md5 (' . $tr . ')');
        }
        $add_sql .= $tr . ',';
    } while ($binary_data);
    $add_sql = substr($add_sql, 0, -1);
    $add_sql = "WHERE `id` NOT IN ({$add_sql})";
        continue;
    }
    //print "id майнеров, которые на нашем уровне\n";
    debug_print($nodes_ids, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    $add_sql = '';
    for ($i = 0; $i < sizeof($nodes_ids); $i++) {
        $add_sql .= "{$nodes_ids[$i]},";
    }
    $add_sql = substr($add_sql, 0, strlen($add_sql) - 1);
    if (!$add_sql) {
        debug_print("continue", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        sleep(1);
        continue;
    }
    // получим хосты майнеров, которые на нашем уровне
    $res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tSELECT `host`\n\t\t\t\t\tFROM `" . DB_PREFIX . "miners_data`\n\t\t\t\t\tWHERE `user_id` IN ({$add_sql})\n\t\t\t\t\t");
    while ($row = $db->fetchArray($res)) {
        $urls[]['url'] = $row['host'] . 'gate_testblock.php';
    }
    // шлем block_id, user_id, mrkl_root, signature
    $data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT `block_id`,  `time`, `user_id`, `mrkl_root`, `signature`\n\t\t\tFROM `" . DB_PREFIX . "testblock`\n\t\t\tWHERE `status` = 'active'\n\t\t\t", 'fetch_array');
    //print_r($data);
    //print_R($urls);
    if ($data) {
        $data_binary = dec_binary($data['block_id'], 4) . dec_binary($data['time'], 4) . dec_binary($data['user_id'], 5) . $data['mrkl_root'] . ParseData::encode_length_plus_data($data['signature']);
        m_curl($urls, $data_binary, '', 'data', 30);
    }
    //else
    debug_print("END", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    sleep(1);
} while (true);
main_lock();
$my_user_id = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tSELECT `user_id`\n\t\t\t\t\tFROM `" . DB_PREFIX . MY_PREFIX . "my_table`\n\t\t\t\t\t", 'fetch_one');
$node_private_key = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tSELECT `private_key`\n\t\t\t\t\tFROM `" . DB_PREFIX . MY_PREFIX . "my_node_keys`\n\t\t\t\t\tWHERE `block_id` = (SELECT max(`block_id`) FROM `" . DB_PREFIX . MY_PREFIX . "my_node_keys` )\n\t\t\t\t\t", 'fetch_one');
if (!$my_user_id || !$node_private_key) {
    main_unlock();
    exit;
}
require_once ABSPATH . 'phpseclib/Math/BigInteger.php';
require_once ABSPATH . 'phpseclib/Crypt/Random.php';
require_once ABSPATH . 'phpseclib/Crypt/Hash.php';
require_once ABSPATH . 'phpseclib/Crypt/RSA.php';
$rsa = new Crypt_RSA();
extract($rsa->createKey(1024));
$publickey = clear_public_key($publickey);
$db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tINSERT INTO  `" . DB_PREFIX . MY_PREFIX . "my_node_keys` (\n\t\t\t\t`public_key`,\n\t\t\t\t`private_key`\n\t\t\t)\n\t\t\tVALUES (\n\t\t\t\t0x{$publickey},\n\t\t\t\t'{$privatekey}'\n\t\t\t)");
$time = time();
// подписываем нашим нод-ключем данные транзакции
$data_for_sign = ParseData::findType('change_node_key') . ",{$time},{$my_user_id},{$publickey}";
$rsa = new Crypt_RSA();
$rsa->loadKey($node_private_key);
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$signature = $rsa->sign($data_for_sign);
print '$node_private_key=' . $node_private_key . "\n";
print '$data_for_sign=' . $data_for_sign . "\n";
print 'strlen($signature)=' . strlen($signature) . "\n";
print 'strlen($publickey)=' . strlen($publickey) . "\n";
// создаем новую транзакцию
$bin_public_key = hextobin($publickey);
$data = dec_binary(ParseData::findType('change_node_key'), 1) . dec_binary($time, 4) . encode_length(strlen($my_user_id)) . $my_user_id . encode_length(strlen($bin_public_key)) . $bin_public_key . encode_length(strlen($signature)) . $signature;
insert_tx($data, $db);
main_unlock();
Exemple #7
0
    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'];
    $time_binary = dec_binary($new_testblock['time'], 4);
    $user_id_binary = dec_binary($new_testblock['user_id'], 5);
    $level_binary = dec_binary($testBlock->level, 1);
    $new_block_header = dec_binary(0, 1) . $new_block_id_binary . $time_binary . $user_id_binary . $level_binary . ParseData::encode_length_plus_data($new_testblock['signature']);
    $new_block = $new_block_header . $transactions;
    list(, $new_block_hex) = unpack("H*", $new_block);
    //testblock_lock();
    // и передаем блок для обратотки через скрипт queue_parser_testblock.php
    // т.к. есть запросы к log_time_, а их можно выполнять только по очереди
    $file = save_tmp_644('FQT', "{$new_header_hash}\t{$new_block_hex}");
    $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\tLOAD DATA LOCAL INFILE  '{$file}'\n\t\t\t\t\tREPLACE INTO TABLE `" . DB_PREFIX . "queue_testblock`\n\t\t\t\t\tFIELDS TERMINATED BY '\t'\n\t\t\t\t\t(@head_hash, @data)\n\t\t\t\t\tSET `head_hash` = UNHEX(@head_hash),\n\t\t\t\t\t\t   `data` = UNHEX(@data)\n\t\t\t\t\t");
    unlink($file);
    //debug_print($db->printsql()."\nAffectedRows=".$db->getAffectedRows() , __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__);
    //main_unlock();
} else {
    //testblock_lock();
    // если всё нормально, то пишем в таблу testblock новые данные
    $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tUPDATE `" . DB_PREFIX . "testblock`\n\t\t\tSET\n\t\t\t\t\t`time` = {$new_testblock['time']},\n\t\t\t\t\t`user_id` = {$new_testblock['user_id']},\n\t\t\t\t\t`header_hash`= 0x{$new_header_hash},\n\t\t\t\t\t`signature` = 0x{$new_testblock['signature_hex']}\n\t\t\t\t");
    //debug_print($db->printsql()."\nAffectedRows=".$db->getAffectedRows() , __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__);
Exemple #8
0
 /**
 	Обработка данных (блоков или транзакций), пришедших с гейта. Только проверка.
 */
 public function ParseData_gate($only_tx = false)
 {
     $count_transactions = 0;
     $this->DataPre();
     $this->global_variables = self::get_variables($this->db, array('max_tx_size', 'max_tx_count', 'error_time', 'max_block_user_transactions', 'max_user_transactions'));
     $transaction_binary_data = $this->binary_data;
     // если это транзакции (type>0), а не блок (type==0)
     if ($this->type > 0) {
         // проверим, есть ли такой тип тр-ий
         $error = $this->checkTxType($this->type);
         if ($error) {
             return $error;
         }
         debug_print('TX', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
         $transaction_binary_data = dec_binary($this->type, 1) . $transaction_binary_data;
         $transaction_binary_data_full = $transaction_binary_data;
         // нет ли хэша этой тр-ии у нас в БД?
         $error = $this->checkLogTx($transaction_binary_data_full);
         if ($error) {
             return $error;
         }
         $this->tx_hash = md5($transaction_binary_data);
         // преобразуем бинарные данные транзакции в массив
         $this->transaction_array = $this->parse_transaction($transaction_binary_data);
         if (!is_array($this->transaction_array)) {
             return $this->transaction_array;
         }
         debug_print($this->transaction_array, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
         // время транзакции может быть немного больше, чем время на ноде.
         // у нода может быть просто не настроено время.
         // время транзакции используется только для борьбы с атаками вчерашними транзакциями.
         // А т.к. мы храним хэши в log_transaction за 36 часов, то боятся нечего.
         $my_time = time();
         if ($this->transaction_array[2] - MAX_TX_FORW > $my_time || $this->transaction_array[2] < $my_time - MAX_TX_BACK) {
             debug_print("tr_time={$this->transaction_array[2]}\nmy_time={$my_time}\nMAX_TX_FORW=" . MAX_TX_FORW . "\nMAX_TX_BACK=" . MAX_TX_BACK . "", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
             return "error tx time ({$this->transaction_array[2]})";
         }
         // $this->transaction_array[3] могут подсунуть пустой
         $user_id = @$this->transaction_array[3];
         if (!check_input_data($user_id, 'bigint')) {
             return 'bad user_id';
         }
         /*// от 1 юзера не может быть более X запросов за 1 минуту. Для борьбы с досами.
         			$count = $this->db->query( __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__, "
         					SELECT `count`
         					FROM `".DB_PREFIX."log_minute`
         					WHERE `user_id` = {$user_id}
         					", 'fetch_one');
         			if (!$count)
         				$this->db->query( __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__, "
         						INSERT INTO `".DB_PREFIX."log_minute` (
         								`user_id`, `count`
         							)
         							VALUES (
         								{$user_id}, 1)
         							");
         			else
         				$this->db->query( __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__, "
         						UPDATE `".DB_PREFIX."log_minute`
         						SET `count` = count+1
         						WHERE `user_id` = {$user_id}
         						");
         
         			if ( $count > $this->global_variables['max_user_transactions'] )
         				return 'max_user_transactions';
         			*/
     }
     // если это блок
     if ($this->type == 0) {
         $count_transactions = array();
         debug_print('BLOCK', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
         $rate = 1;
         // если есть $only_tx=true, то значит идет восстановление уже проверенного блока и заголовок не требуется
         if (!$only_tx) {
             $error = $this->ParseBlock();
             if ($error) {
                 debug_print("[error] " . $error, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                 return $error;
             }
             // проверим данные, указанные в заголовке блока
             debug_print("CheckBlockHeader", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
             $error = $this->CheckBlockHeader();
             if ($error) {
                 return $error;
             }
         } else {
             debug_print('<$only_tx>', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
         }
         // если в ходе проверки тр-ий возникает ошибка, то вызываем откатчик всех занесенных тр-ий. Эта переменная для него
         $this->full_tx_binary_data = $this->binary_data;
         $i = 0;
         $tx_for_RollbackTo = '';
         if ($this->binary_data) {
             do {
                 // обработка тр-ий может занять много времени, нужно отметиться
                 upd_deamon_time($this->db);
                 $transaction_size = $this->decode_length($this->binary_data);
                 if (!$this->binary_data) {
                     debug_print("transaction_size = {$transaction_size}\nthis->full_tx_binary_data = {$this->full_tx_binary_data}", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                     return 'null $this->binary_data TX';
                 }
                 // отчекрыжим одну транзакцию от списка транзакций
                 $transaction_binary_data = $this->string_shift($this->binary_data, $transaction_size);
                 $transaction_binary_data_full = $transaction_binary_data;
                 // добавляем взятую тр-ию в набор тр-ий для RollbackTo, в котором пойдем в обратном порядке
                 $tx_for_RollbackTo .= $this->encode_length_plus_data($transaction_binary_data);
                 // нет ли хэша этой тр-ии у нас в БД?
                 $error = $this->checkLogTx($transaction_binary_data);
                 if ($error) {
                     debug_print('[error]' . $error, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                     $this->RollbackTo($tx_for_RollbackTo, true, true);
                     return $error;
                 }
                 $this->tx_hash = md5($transaction_binary_data);
                 $this->transaction_array = $this->parse_transaction($transaction_binary_data);
                 if (!is_array($this->transaction_array)) {
                     return $this->transaction_array;
                 }
                 // $this->transaction_array[3] могут подсунуть пустой
                 $user_id = @$this->transaction_array[3];
                 if (!check_input_data($user_id, 'bigint')) {
                     return 'bad user_id';
                 }
                 // считаем по каждому юзеру, сколько в блоке от него транзакций
                 $count_transactions[$user_id]++;
                 // чтобы 1 юзер не смог прислать дос-блок размером в 10гб, который заполнит своими же транзакциями
                 if ($count_transactions[$user_id] > $this->global_variables['max_block_user_transactions']) {
                     debug_print($count_transactions, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                     debug_print($user_id, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                     debug_print($this->global_variables, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                     $this->RollbackTo($tx_for_RollbackTo, true, true);
                     return 'max_block_user_transactions';
                 }
                 // проверим, есть ли такой тип тр-ий
                 $error = $this->checkTxType($this->transaction_array[1]);
                 if ($error) {
                     return $error;
                 }
                 $fns_name = self::$MainArray[$this->transaction_array[1]];
                 //print '$fns_name='.$fns_name;
                 $fns_name_init = $fns_name . '_init';
                 $fns_name_front = $fns_name . '_front';
                 debug_print('>>>>>>>>>>>>parsedatagate = ' . $fns_name_front, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                 unset($this->tx_data);
                 $error = $this->{$fns_name_init}();
                 if ($error) {
                     return $error;
                 }
                 debug_print($this->tx_data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                 $error = $this->{$fns_name_front}();
                 if ($error) {
                     debug_print('[error]=>' . $error, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                     //if (substr_count($error, '[limit_requests]')>0)
                     //	$this->RollbackTo ($tx_for_RollbackTo, false, true);
                     //else
                     $this->RollbackTo($tx_for_RollbackTo, true, true);
                     return $error;
                 }
                 // пишем хэш тр-ии в лог
                 $this->insert_in_log_tx($transaction_binary_data_full, $this->tx_data['time']);
                 // ===================>ради эксперимента
                 /*
                 $this->db->query( __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__, "
                 		UPDATE `".DB_PREFIX."transactions`
                 		SET `verified` = 1
                 		WHERE `hash` = 0x".md5($transaction_binary_data_full)."
                 		");
                 */
                 // ====================================
                 $i++;
             } while ($this->binary_data);
         }
     } else {
         debug_print('memory', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
         // / $rate = 10;
         // Оперативные транзакции
         $fns_name = self::$MainArray[$this->type];
         $fns_name_init = $fns_name . '_init';
         $fns_name_front = $fns_name . '_front';
         unset($this->tx_data);
         $error = $this->{$fns_name_init}();
         if ($error) {
             return $error;
         }
         debug_print($this->tx_data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
         $error = $this->{$fns_name_front}();
         if ($error) {
             return $error;
         }
         $this->insert_in_log_tx($transaction_binary_data_full, $this->tx_data['time']);
     }
 }
 // проверим блок, который получился с данными, которые прислал другой нод
 $parsedata = new ParseData($new_block, $db);
 $error = $parsedata->ParseData_gate();
 debug_print("ParseData_gate OK", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 if ($error) {
     unset($parsedata);
     debug_print('------------------[error]' . $error . '-------------------', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     // т.к. мы откатили наши тр-ии из transactions_testblock, то теперь нужно обработать их по новой
     // получим наши транзакции в 1 бинарнике, просто для удобства
     $my_testblock['block_body'] = '';
     $res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT `data`\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)) {
         $my_testblock['block_body'] .= ParseData::encode_length_plus_data($row['data']);
     }
     if ($my_testblock['block_body']) {
         $parsedata = new ParseData(dec_binary(0, 1) . $my_testblock['block_body'], $db);
         $parsedata->ParseData_gate(true);
         unset($parsedata);
     }
     /*if (substr_count($error, '[limit_requests]')>0) {
     			debug_print('----------------[error]'.$error.'-------------------', __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__);
     			// если есть ошибки, то откатим фронтальные измненения от этого блока
     			$parsedata = new ParseData($tx, $db);
     			$parsedata->ParseDataRollbackFront();
     		}
     		else {
     			debug_print('error wo rollback----------------[error]'.$error.'-------------------', __FILE__, __LINE__,  __FUNCTION__,  __CLASS__, __METHOD__);
     		}*/
 } else {
     //main_unlock();
     // т.к. testblock_generator.php пишет в таблы testblock и transactions_testblock нужно локать эти таблы
Exemple #10
0
function m_curl($urls, $_data, $db, $type = 'data', $timeout = 10, $answer = false, $post = true, $remote_node_host = '')
{
    //создаем набор дескрипторов cURL
    $mh = curl_multi_init();
    // при $remote_node_host будет всего 1 url - ip из локальной сети
    for ($i = 0; $i < sizeof($urls); $i++) {
        debug_print('$urls[' . $i . ']: ' . print_r_hex($urls[$i]), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        if ($db) {
            // т.к. на приеме может быть пул, то нужно дописать user_id, чьим нодовским ключем шифруем
            $data = encrypt_data($_data, $urls[$i]['node_public_key'], $db);
            $data = dec_binary($urls[$i]['user_id'], 5) . $data;
        } else {
            $data = $_data;
        }
        if ($remote_node_host) {
            $data = ParseData::encode_length_plus_data($remote_node_host) . $data;
        }
        // создаем ресурс cURL
        $ch[$i] = curl_init();
        curl_setopt($ch[$i], CURLOPT_URL, $urls[$i]['url']);
        //curl_setopt($ch[$i], CURLOPT_FAILONERROR, 1);
        curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT, 10);
        // timeout in seconds
        curl_setopt($ch[$i], CURLOPT_TIMEOUT, $timeout);
        if ($post) {
            curl_setopt($ch[$i], CURLOPT_POST, 1);
            curl_setopt($ch[$i], CURLOPT_POSTFIELDS, $type . '=' . urlencode($data));
        }
        if ($answer) {
            curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 1);
        }
        //$params[] = 'data='.urlencode($data);
        //curl_setopt($ch[$i], CURLOPT_POSTFIELDS, $params);
        //добавляем X дескрипторов
        curl_multi_add_handle($mh, $ch[$i]);
    }
    $active = null;
    //запускаем дескрипторы
    do {
        debug_print('curl_multi_exec', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
        $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    while ($active && $mrc == CURLM_OK) {
        if (curl_multi_select($mh) == -1) {
            usleep(100);
        }
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
    $return = array();
    if ($answer) {
        for ($i = 0; $i < sizeof($urls); $i++) {
            $return[$urls[$i]['user_id']] = curl_multi_getcontent($ch[$i]);
        }
    }
    for ($i = 0; $i < sizeof($urls); $i++) {
        // закрываем все дескрипторы
        curl_multi_remove_handle($mh, $ch[$i]);
    }
    curl_multi_close($mh);
    return $return;
}
Exemple #11
0
upd_deamon_time($db);
// пишем свежие блоки в резервный блокчейн
$end_block_id = get_end_block_id();
$cur_block_id = get_block_id($db);
print $end_block_id . ' / ' . $cur_block_id;
if ($cur_block_id - 30 > $end_block_id) {
    $res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, '
			SELECT `id`, `data`
			FROM `' . DB_PREFIX . 'block_chain`
			WHERE `id` > ' . $end_block_id . ' AND `id` <= ' . ($cur_block_id - 30) . '
			ORDER BY `id`
			');
    while ($row = $db->fetchArray($res)) {
        $data = dec_binary($row['id'], 5) . ParseData::encode_length_plus_data($row['data']);
        $size_and_data = dec_binary(strlen($data), 5) . $data;
        file_put_contents(ABSPATH . 'public/blockchain', $size_and_data . dec_binary(strlen($size_and_data), 5), FILE_APPEND | LOCK_EX);
    }
}
$auto_reload = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tSELECT `auto_reload`\n\t\tFROM `" . DB_PREFIX . "config`\n\t\t", 'fetch_one');
if ($auto_reload < 60) {
    exit;
}
// если main_lock висит более x минут, значит был какой-то сбой
$main_lock = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tSELECT `lock_time`\n\t\tFROM `" . DB_PREFIX . "main_lock`\n\t\tWHERE `script_name` NOT IN ('my_lock', 'cleaning_db')\n\t\t", 'fetch_one');
if ($main_lock && time() - $auto_reload > $main_lock) {
    // на всякий случай пометим, что работаем
    $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tUPDATE `" . DB_PREFIX . "main_lock`\n\t\t\tSET `script_name` = 'cleaning_db'\n\t\t\t");
    $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tUPDATE `" . DB_PREFIX . "config`\n\t\t\tSET `pool_tech_works` = 1\n\t\t\t");
    $tables_array = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSHOW TABLES\n\t\t\t", 'array');
    foreach ($tables_array as $table) {
        //if (!in_array($table, $exceptions))
Exemple #12
0
                debug_print('VOTE = NO', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
            }
            // проходимся по всем нашим майнерам, если это пул и по одному, если это сингл-мод
            foreach ($intersect_my_miners as $my_miner_id) {
                $my_user_id = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\t\tSELECT `user_id`\n\t\t\t\t\t\tFROM `" . DB_PREFIX . "miners_data`\n\t\t\t\t\t\tWHERE `miner_id` = {$my_miner_id}\n\t\t\t\t\t\t", 'fetch_one');
                $community = get_community_users($db);
                if ($community) {
                    $my_prefix = $my_user_id . '_';
                } else {
                    $my_prefix = '';
                }
                $node_private_key = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\t\t\tSELECT `private_key`\n\t\t\t\t\t\tFROM `" . DB_PREFIX . "{$my_prefix}my_node_keys`\n\t\t\t\t\t\tWHERE `block_id` = (SELECT max(`block_id`) FROM `" . DB_PREFIX . "{$my_prefix}my_node_keys` )\n\t\t\t\t\t\t", 'fetch_one');
                $time = time();
                // подписываем нашим нод-ключем данные транзакции
                $data_for_sign = ParseData::findType('votes_node_new_miner') . ",{$time},{$my_user_id},{$row['vote_id']},{$vote}";
                $rsa = new Crypt_RSA();
                $rsa->loadKey($node_private_key);
                $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
                $signature = $rsa->sign($data_for_sign);
                debug_print('$data_for_sign=' . $data_for_sign, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
                // создаем новую транзакцию - подверждение, что фото скопировано и проверено.
                $data = dec_binary(30, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($my_user_id) . ParseData::encode_length_plus_data($row['vote_id']) . ParseData::encode_length_plus_data($vote) . ParseData::encode_length_plus_data($signature);
                insert_tx($data, $db);
            }
        }
        // отмечаем, чтобы больше не брать эту строку
        $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tUPDATE `" . DB_PREFIX . "votes_miners`\n\t\t\t\tSET `cron_checked_time` = " . time() . "\n\t\t\t\tWHERE `id` = {$row['vote_id']}\n\t\t\t\t");
    }
    main_unlock();
    sleep(1);
} while (true);
Exemple #13
0
    }
    if (!$new_admin) {
        main_unlock();
        exit;
    }
    $testBlock = new testblock($db, true);
    if (get_community_users($db)) {
        $my_prefix = $testBlock->user_id . '_';
    } else {
        $my_prefix = '';
    }
    $node_private_key = get_node_private_key($db, $my_prefix);
    // подписываем нашим нод-ключем данные транзакции
    $data_for_sign = ParseData::findType('new_admin') . ",{$time},{$my_user_id},{$new_admin}";
    $rsa = new Crypt_RSA();
    $rsa->loadKey($node_private_key);
    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    $signature = $rsa->sign($data_for_sign);
    debug_print('$data_for_sign=' . $data_for_sign . "\n", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    // создаем тр-ию. пишем $block_id, на момент которого были актуальны голоса в табле 'pct'
    $data = dec_binary(ParseData::findType('new_admin'), 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($my_user_id) . ParseData::encode_length_plus_data($new_admin) . ParseData::encode_length_plus_data($signature);
    $hash = ParseData::dsha256($data);
    insert_tx($data, $db);
    // и не закрывая main_lock переводим нашу тр-ию в verified=1, откатив все несовместимые тр-ии
    // таким образом у нас будут в блоке только актуальные голоса.
    // а если придет другой блок и станет verified=0, то эта тр-ия просто удалится.
    $new_tx_data['data'] = $data;
    $new_tx_data['hash'] = hextobin(md5($data));
    tx_parser($new_tx_data, true);
}
main_unlock();
Exemple #14
0
     // 5 байт = наш user_id. Но они будут не первые, т.к. m_curl допишет вперед user_id получателя (нужно для пулов)
     $to_be_sent = dec_binary($my_user_id, 5);
     if ($data) {
         // блок
         // если 5-й байт = 0, то на приемнике будем читать блок, если = 1 , то сразу хэши тр-ий
         $to_be_sent .= dec_binary(0, 1) . dec_binary($data['block_id'], 3) . $data['hash'] . $data['head_hash'];
         $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "UPDATE `" . DB_PREFIX . "info_block` SET `sent` = 1");
     } else {
         // тр-ии без блока
         $to_be_sent .= dec_binary(1, 1);
     }
     // возьмем хэши тр-ий
     $res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT `hash`, `high_rate`\n\t\t\t\tFROM `" . DB_PREFIX . "transactions`\n\t\t\t\tWHERE `sent` = 0 AND\n\t\t\t\t\t\t\t`for_self_use` = 0\n\t\t\t\t");
     while ($row = $db->fetchArray($res)) {
         list(, $hex_hash) = unpack("H*", $row['hash']);
         $to_be_sent .= dec_binary($row['high_rate'], 1) . $row['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");
     }
     //main_unlock();
     debug_print('$to_be_sent=' . $to_be_sent, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     // отправляем блок и хэши тр-ий, если есть что отправлять
     if (strlen($to_be_sent) > 10) {
         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
Exemple #15
0
        $for_user_id = $_REQUEST['for_user_id'];
        $new_public_key = hextobin($_REQUEST['new_public_key']);
        $data = dec_binary($type, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($user_id) . ParseData::encode_length_plus_data($for_user_id) . ParseData::encode_length_plus_data($new_public_key) . $bin_signatures;
        break;
    case 'change_arbitrator_list':
        $data = dec_binary($type, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($user_id) . ParseData::encode_length_plus_data($_REQUEST['arbitration_trust_list']) . $bin_signatures;
        break;
    case 'money_back_request':
        $data = dec_binary($type, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($user_id) . ParseData::encode_length_plus_data($_REQUEST['order_id']) . ParseData::encode_length_plus_data(hextobin($_REQUEST['arbitrator_enc_text'][0])) . ParseData::encode_length_plus_data(hextobin($_REQUEST['arbitrator_enc_text'][1])) . ParseData::encode_length_plus_data(hextobin($_REQUEST['arbitrator_enc_text'][2])) . ParseData::encode_length_plus_data(hextobin($_REQUEST['arbitrator_enc_text'][3])) . ParseData::encode_length_plus_data(hextobin($_REQUEST['arbitrator_enc_text'][4])) . ParseData::encode_length_plus_data(hextobin($_REQUEST['seller_enc_text'])) . $bin_signatures;
        break;
    case 'change_seller_hold_back':
        $data = dec_binary($type, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($user_id) . ParseData::encode_length_plus_data($_REQUEST['arbitration_days_refund']) . ParseData::encode_length_plus_data($_REQUEST['hold_back_pct']) . $bin_signatures;
        break;
    case 'money_back':
        $data = dec_binary($type, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($user_id) . ParseData::encode_length_plus_data($_REQUEST['order_id']) . ParseData::encode_length_plus_data($_REQUEST['amount']) . $bin_signatures;
        break;
    case 'change_arbitrator_conditions':
        $data = dec_binary($type, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($user_id) . ParseData::encode_length_plus_data($_REQUEST['conditions']) . ParseData::encode_length_plus_data($_REQUEST['url']) . $bin_signatures;
        break;
    case 'change_money_back_time':
        $data = dec_binary($type, 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($user_id) . ParseData::encode_length_plus_data($_REQUEST['order_id']) . ParseData::encode_length_plus_data($_REQUEST['days']) . $bin_signatures;
        break;
}
$hash = md5($data);
if (!in_array($_REQUEST['type'], array('new_pct', 'new_max_promised_amounts', 'new_reduction', 'votes_node_new_miner', 'new_max_other_currencies'))) {
    $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tINSERT INTO `" . DB_PREFIX . "transactions_status` (\n\t\t\t\t`hash`,\n\t\t\t\t`time`,\n\t\t\t\t`type`,\n\t\t\t\t`user_id`\n\t\t\t)\n\t\t\tVALUES (\n\t\t\t\t0x{$hash},\n\t\t\t\t" . time() . ",\n\t\t\t\t{$type},\n\t\t\t\t{$user_id}\n\t\t\t)");
}
$data = bin2hex($data);
$file = save_tmp_644('FSQ', "{$hash}\t{$data}");
$db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tLOAD DATA LOCAL INFILE  '{$file}' IGNORE INTO TABLE `" . DB_PREFIX . "queue_tx`\n\t\tFIELDS TERMINATED BY '\t'\n\t\t(@hash, @data)\n\t\tSET `data` = UNHEX(@data),\n\t\t\t   `hash` = UNHEX(@hash)\n\t\t");
unlink($file);
     continue;
 }
 debug_print('Закончили спать, теперь генерим блок', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
 $block_id = $testBlock->prev_block['block_id'];
 if (!$block_id) {
     debug_print("continue", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     main_unlock();
     unset($testBlock);
     sleep(1);
     continue;
 }
 $my_user_id = $testBlock->user_id;
 $new_block_id = $block_id + 1;
 $new_block_id_binary = dec_binary($new_block_id, 4);
 $user_id_binary = dec_binary($testBlock->cur_user_id, 5);
 $level_binary = dec_binary($testBlock->level, 1);
 if (get_community_users($db)) {
     $my_prefix = $testBlock->user_id . '_';
 } else {
     $my_prefix = '';
 }
 $node_private_key = get_node_private_key($db, $my_prefix);
 $prev_head_hash = $testBlock->prev_block['head_hash'];
 #####################################
 ##		 Формируем блок
 #####################################
 print '$new_block_id=' . $new_block_id . "\n";
 print '$cur_user_id=' . $testBlock->cur_user_id . "\n";
 if (!$testBlock->cur_user_id) {
     debug_print("continue", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
     main_unlock();
//print $reduction_pct."\n";
//print $reduction_type."\n";
//print $reduction_currency_id."\n";
if (isset($reduction_currency_id) && isset($reduction_pct)) {
    if (get_community_users($db)) {
        $my_prefix = $testBlock->user_id . '_';
    } else {
        $my_prefix = '';
    }
    $node_private_key = get_node_private_key($db, $my_prefix);
    print $my_prefix . "\n";
    // подписываем нашим нод-ключем данные транзакции
    $data_for_sign = ParseData::findType('new_reduction') . ",{$time},{$my_user_id},{$reduction_currency_id},{$reduction_pct},{$reduction_type}";
    $rsa = new Crypt_RSA();
    $rsa->loadKey($node_private_key);
    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    $signature = $rsa->sign($data_for_sign);
    debug_print('$data_for_sign=' . $data_for_sign . "\n", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
    print $data_for_sign;
    print $node_private_key;
    // создаем тр-ию. пишем $block_id, на момент которого были актуальны голоса и статусы банкнот
    $reduction_tx_data = dec_binary(ParseData::findType('new_reduction'), 1) . dec_binary($time, 4) . ParseData::encode_length_plus_data($my_user_id) . ParseData::encode_length_plus_data($reduction_currency_id) . ParseData::encode_length_plus_data($reduction_pct) . ParseData::encode_length_plus_data($reduction_type) . ParseData::encode_length_plus_data($signature);
    insert_tx($reduction_tx_data, $db);
    // и не закрывая main_lock переводим нашу тр-ию в verified=1, откатив все несовместимые тр-ии
    // таким образом у нас будут в блоке только актуальные голоса.
    // а если придет другой блок и станет verified=0, то эта тр-ия просто удалится.
    $new_tx_data['data'] = $reduction_tx_data;
    $new_tx_data['hash'] = hextobin(md5($reduction_tx_data));
    tx_parser($new_tx_data, true);
}
main_unlock();