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__); $aes = new Crypt_AES(); $aes->setKey($my_key); // теперь в $binary_tx будут обычные тр-ии $binary_tx = $aes->decrypt($encrypted_tx_set); unset($aes); debug_print('$binary_tx=' . $binary_tx, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); // разберем полученные тр-ии do { $tx_size = ParseData::decode_length($binary_tx); $tx_binary_data = ParseData::string_shift($binary_tx, $tx_size); debug_print('$tx_binary_data=' . $tx_binary_data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); list(, $tx_hex) = unpack("H*", $tx_binary_data); if (!$tx_binary_data) { continue; } // проверим размер if (strlen($tx_binary_data) > $variables['max_tx_size']) { debug_print('strlen($binary_tx) > $variables[max_tx_size]', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); die("error tx size"); } // точно ли выдали то /*if ( md5($tx_binary_data) != $new_data['tx_hash'] ) { debug_print("error tx_hash (".md5($tx_binary_data)."!={$new_data['tx_hash']})", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); die ("error tx_hash (".md5($tx_binary_data)."!={$new_data['tx_hash']})"); }*/
$variables_ = ParseData::get_variables($db, array('alert_error_time')); $my_miner_id = get_my_miner_id($db); // если юзер уже майнер, то у него должно быть настроено точное время if ($my_miner_id) { $diff = intval(ntp_time()); if ($diff > $variables_['alert_error_time']) { $lng['alert_time'] = str_ireplace('[sec]', $diff, $lng['alert_time']); echo "\n\t\t\t\t\t <div class=\"alert alert-danger alert-dismissable\" style='margin-top: 30px'><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button>\n\t\t\t\t <h4>Warning!</h4>\n\t\t\t\t <div>{$lng['alert_time']}</div>\n\t\t\t\t </div>\n\t\t\t\t "; } } } if (empty($_SESSION['restricted'])) { // после обнуления таблиц my_node_key будет пуст // получим время из последнего блока $last_block_bin = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT `data`\n\t\t\tFROM `" . DB_PREFIX . "block_chain`\n\t\t\tORDER BY `id` DESC\n\t\t\tLIMIT 1\n\t\t\t", 'fetch_one'); ParseData::string_shift($last_block_bin, 5); $block_time = ParseData::binary_dec_string_shift($last_block_bin, 4); // дождемся загрузки свежих блоков // if (time() - $block_time < 600) { закомменчено, т.к. при ручном откате до какого-то блока время будет старое $my_node_key = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT `private_key`\n\t\t\t\tFROM `" . DB_PREFIX . MY_PREFIX . "my_node_keys`\n\t\t\t\tWHERE `block_id` > 0\n\t\t\t\tLIMIT 1\n\t\t\t\t", 'fetch_one'); $my_miner_id = get_my_miner_id($db); if (!$my_node_key && $my_miner_id > 0) { echo "\n\t\t\t\t\t <div class=\"alert alert-danger alert-dismissable\" style='margin-top: 30px'><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button>\n\t\t\t\t <h4>Warning!</h4>\n\t\t\t\t <div>{$lng['alert_change_node_key']}</div>\n\t\t\t\t </div>\n\t\t\t\t "; } //} } // просто информируем, что в данном разделе у юзера нет прав $skip_community = array('node_config', 'nulling', 'start_stop'); $skip_restricted_users = array('node_config', 'change_node_key', 'nulling', 'start_stop', 'cash_requests_in', 'cash_requests_out', 'upgrade', 'notifications', 'interface'); if (!node_admin_access($db) && in_array($tpl_name, $skip_community) || !empty($_SESSION['restricted']) && in_array($tpl_name, $skip_restricted_users)) { echo "\n\t\t\t <div class=\"alert alert-danger alert-dismissable\" style='margin-top: 30px'><button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-hidden=\"true\">×</button>\n\t\t\t <h4>Warning!</h4>\n\t\t\t <div>{$lng['permission_denied']}</div>\n\t\t\t </div>\n\t\t\t ";
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})"; } // сами тр-ии $transactions = ''; $res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\tSELECT `data`\n\t\tFROM `" . DB_PREFIX . "transactions_testblock`\n\t\t{$add_sql}\n\t\t"); while ($row = $db->fetchArray($res)) { $length = encode_length(strlen($row['data'])); $transactions .= $length . $row['data'];
debug_print('$encrypted_data=' . $encrypted_data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); debug_print('$encrypted_data=' . bin2hex($encrypted_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); // извлечем ключ, декодируем его и декодируем им данные $binary_tx = decrypt_data($encrypted_data, $db); if (substr($binary_tx, 0, 7) == '[error]') { die($binary_tx); } //debug_print('$binary_tx='.$binary_tx, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); list(, $tx_hex) = unpack("H*", $binary_tx); $tx_hash = md5($binary_tx); $variables = ParseData::get_variables($db, array('max_tx_size')); // проверим размер if (strlen($binary_tx) > $variables['max_tx_size']) { die("error tx size"); } $block_data['type'] = ParseData::binary_dec_string_shift($binary_tx, 1); $block_data['time'] = ParseData::binary_dec_string_shift($binary_tx, 4); $size = ParseData::decode_length($binary_tx); $block_data['user_id'] = ParseData::string_shift($binary_tx, $size); if ($block_data['user_id'] == 1) { $high_rate = 1; } else { $high_rate = 0; } // заливаем тр-ию в БД $data = "{$tx_hash}\t{$high_rate}\t{$tx_hex}"; debug_print("data={$data}", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); $file = save_tmp_644('FTB', $data); $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tLOAD DATA LOCAL INFILE '{$file}'\n\t\t\tIGNORE INTO TABLE `" . DB_PREFIX . "queue_tx`\n\t\t\tFIELDS TERMINATED BY '\t'\n\t\t\t(@hash, `high_rate`, @data)\n\t\t\tSET `hash` = UNHEX(@hash),\n\t\t\t\t `data` = UNHEX(@data)\n\t\t\t"); unlink($file); //debug_print($db->printsql()."\ngetAffectedRows=".$db->getAffectedRows(), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_TIMEOUT, 120); $binary_block = curl_exec($ch); curl_close($ch); debug_print('$block_data:' . $binary_block, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); upd_deamon_time($db); if (!$binary_block) { // баним на 1 час хост, который дал нам пустой блок, хотя должен был дать все до максимального // для тестов убрал, потом вставить. //nodes_ban ($db, $max_block_id_user_id, substr($binary_block, 0, 512)."\n".__FILE__.', '.__LINE__.', '. __FUNCTION__.', '.__CLASS__.', '. __METHOD__); main_unlock(); continue 2; } $binary_block_full = $binary_block; ParseData::string_shift($binary_block, 1); // уберем 1-й байт - тип (блок/тр-я) // распарсим заголовок блока $block_data = parse_block_header($binary_block); debug_print('$block_data:' . print_r_hex($block_data), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); debug_print('$block_id=' . $block_id, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); // если существуют глючная цепочка, тот тут мы её проигнорируем $bad_blocks = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT `bad_blocks` FROM `" . DB_PREFIX . "config`\n\t\t\t\t", 'fetch_one'); $bad_blocks = json_decode($bad_blocks, true); debug_print('$bad_blocks=' . print_r_hex($bad_blocks), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); if (@$bad_blocks[$block_data['block_id']] == bin2hex($block_data['sign'])) { nodes_ban($db, $max_block_id_user_id, "bad_block = {$block_data['block_id']}=>{$bad_blocks[$block_data['block_id']]}\n" . __FILE__ . ', ' . __LINE__ . ', ' . __FUNCTION__ . ', ' . __CLASS__ . ', ' . __METHOD__); main_unlock(); continue 2; } // размер блока не может быть более чем max_block_size
$tr_binary = ParseData::string_shift($binary_data, $length); do { // берем по одной тр-ии $length = ParseData::decode_length($tr_binary); print '$length=' . $length . "\n"; if ($length == 0) { break; } $tr = ParseData::string_shift($tr_binary, $length); $tr_array[md5($tr)] = $tr; } while (true); // порядок тр-ий $order_array = array(); do { if ($binary_data) { $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__);
function get_my_notice_data() { global $db, $lng; if (empty($_SESSION['restricted'])) { $data = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, ' SELECT `user_id`, `miner_id`, `status` FROM `' . DB_PREFIX . MY_PREFIX . 'my_table` ', 'fetch_array'); if (!$data['user_id']) { $tpl['account_status'] = 'searching'; } else { if ($data['status'] == 'bad_key') { $tpl['account_status'] = 'bad_key'; } else { if ($data['miner_id']) { $tpl['account_status'] = 'miner'; } else { if ($data['user_id']) { $tpl['account_status'] = 'user'; } } } } } else { // user_id уже есть, т.к. мы смогли зайти в урезанном режиме по паблик-кею // проверим, может есть что-то в miners_data $user_id = intval($_SESSION['user_id']); $status = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tSELECT `status`\n\t\t\t\tFROM `" . DB_PREFIX . "miners_data`\n\t\t\t\tWHERE `user_id` = {$user_id}\n\t\t\t\tLIMIT 1\n\t\t\t\t", 'fetch_one'); if ($status) { $tpl['account_status'] = $status; } else { $tpl['account_status'] = 'user'; } } $tpl['account_status'] = $lng['status_' . $tpl['account_status']]; $confirmed_block_id = get_confirmed_block_id($db); $confirmed_block_id = $confirmed_block_id ? $confirmed_block_id : 1; // получим время из последнего подвержденного блока $last_block_bin = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT `data`\n\t\t\tFROM `" . DB_PREFIX . "block_chain`\n\t\t\tWHERE `id` = {$confirmed_block_id}\n\t\t\tLIMIT 1\n\t\t\t", 'fetch_one'); ParseData::string_shift($last_block_bin, 1); // уберем тип $block_id = ParseData::binary_dec_string_shift($last_block_bin, 4); $block_time = ParseData::binary_dec_string_shift($last_block_bin, 4); $tpl['time_last_block'] = date('d-m-Y H:i:s', $block_time); $tpl['time_last_block_int'] = $block_time; $tpl['cur_block_id'] = $block_id; $tpl['connections'] = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT count(*)\n\t\t\tFROM `" . DB_PREFIX . "nodes_connection`\n\t\t\t", 'fetch_one'); if (time() - $block_time > 1800) { $tpl['main_status'] = $lng['downloading_blocks']; $tpl['main_status_complete'] = 0; } else { $tpl['main_status'] = $lng['downloading_complete']; $tpl['main_status_complete'] = 1; } return $tpl; }