rollback_transactions_testblock($db, true); debug_print("testBlock->prev_block['block_id']={$testBlock->prev_block['block_id']} // new_block_id = {$new_block_id} ", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); $time = time(); // переведем тр-ии в `verified` = 1 all_tx_parser(); $transactions = ''; $mrkl_array = array(); // берем все данные из очереди. Они уже были проверены ранее, и можно их не проверять, а просто брать $res = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT *\n\t\t\tFROM `" . DB_PREFIX . "transactions`\n\t\t\tWHERE `used`=0 AND\n\t\t\t\t\t\t `verified` = 1\n\t\t\t"); $used_transactions = ''; $max_user_id = 0; // т.к. queue_parser_testblock.php пишет в таблы testblock и transactions_testblock нужно локать эти таблы while ($row = $db->fetchArray($res)) { debug_print($row, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); // читаем первый байт, чтобы узнать какого типа транзакция $transaction_type = binary_dec(substr($row['data'], 0, 1)); print 'data=' . $row['data'] . "\n"; print '$transaction_type = ' . $transaction_type . "\n"; // пишем в блок размер транзакции и её саму $length = encode_length(strlen($row['data'])); print '$length=' . $length . "\n"; $transactions .= $length . $row['data']; // заодно получим хэши для общего хэша тр-ий $mrkl_array[] = hash('sha256', hash('sha256', $row['data'])); // все тр-ии блока пишутся в отдельную таблу transaction_testblock. // чтобы другим нодам слать только недостающие тр-ии $md5 = md5($row['data']); list(, $data_hex) = unpack("H*", $row['data']); $file = save_tmp_644('FTT', "{$md5}\t{$data_hex}\t{$row['type']}\t{$row['user_id']}\t{$row['third_var']}"); $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tLOAD DATA LOCAL INFILE '{$file}'\n\t\t\t\tIGNORE INTO TABLE `" . DB_PREFIX . "transactions_testblock`\n\t\t\t\tFIELDS TERMINATED BY '\t'\n\t\t\t\t(@hash, @data, `type`, `user_id`, `third_var`)\n\t\t\t\tSET `hash` = UNHEX(@hash),\n\t\t\t\t\t `data` = UNHEX(@data)\n\t\t\t\t"); unlink($file);
if ($new_data['block_id'] >= $block_id) { // Это хэш для соревнования, у кого меньше хэш list(, $new_data['hash']) = unpack("H*", string_shift($binary_data, 32)); // Для доп. соревнования, если head_hash равны (шалит кто-то из майнеров и позже будет за такое забанен) list(, $new_data['head_hash']) = unpack("H*", string_shift($binary_data, 32)); $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\t\tINSERT IGNORE INTO `" . DB_PREFIX . "queue_blocks` (\n\t\t\t\t\t`hash`,\n\t\t\t\t\t`head_hash`,\n\t\t\t\t\t`user_id`,\n\t\t\t\t\t`block_id`\n\t\t\t\t) VALUES (\n\t\t\t\t\t0x{$new_data['hash']},\n\t\t\t\t\t0x{$new_data['head_hash']},\n\t\t\t\t\t{$new_data['user_id']},\n\t\t\t\t\t{$new_data['block_id']}\n\t\t\t\t)"); //debug_print($db->printsql(), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); } } debug_print($new_data, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); $variables = ParseData::get_variables($db, array('max_tx_size')); $need_tx = ''; // Разбираем список транзакций do { // 1 - это админские тр-ии, 0 - юзерские $new_data['high_rate'] = binary_dec(string_shift($binary_data, 1)); list(, $new_data['tx_hash']) = unpack("H*", string_shift($binary_data, 16)); // тр-ий нету if (!$new_data['tx_hash']) { debug_print('!$new_data[tx_hash]', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); exit; } // проверим, нет ли у нас такой тр-ии $exists = $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tSELECT count(`hash`)\n\t\t\tFROM `" . DB_PREFIX . "log_transactions`\n\t\t\tWHERE `hash` = 0x{$new_data['tx_hash']}\n\t\t\t", 'fetch_one'); if ($exists) { debug_print('!exists! continue', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); continue; } $need_tx .= hextobin($new_data['tx_hash']); } while ($binary_data); if (!$need_tx) {
function get_end_block_id() { if (!file_exists(ABSPATH . 'public/blockchain')) { return 0; } else { $rs = fopen(ABSPATH . 'public/blockchain', 'r'); // размер блока, записанный в 5-и последних байтах файла blockchain fseek($rs, -5, SEEK_END); $size = binary_dec(fread($rs, 5)); // сам блок fseek($rs, -($size + 5), SEEK_END); $data_binary = fread($rs, $size + 5); // размер (id блока + тело блока) $data_length = binary_dec(string_shift($data_binary, 5)); $block_id = binary_dec(string_shift($data_binary, 5)); fclose($rs); return $block_id; } }
$current_block_id = get_block_id($db); if (!$current_block_id) { if ($config['first_load_blockchain'] == 'file') { debug_print('download blockchain', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); downloadFile('http://dcoin.me/blockchain', ABSPATH . 'public/blockchain'); //file_put_contents(ABSPATH . 'public/blockchain', fopen('http://github.com/c-darwin/dcoin_blocks/raw/master/blockchain-27-08-14', 'r')); } $first = true; if (file_exists(ABSPATH . 'public/blockchain') && filesize(ABSPATH . 'public/blockchain') > 52000000) { debug_print('file_exists blockchain', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); $fp = fopen(ABSPATH . 'public/blockchain', 'r'); do { $data_size = binary_dec(fread($fp, 5)); if ($data_size) { $data_binary = fread($fp, $data_size); $block_id = binary_dec(string_shift($data_binary, 5)); $data_length = ParseData::decode_length($data_binary); $block_data_binary = string_shift($data_binary, $data_length); $parsedata = new ParseData($block_data_binary, $db); if ($first) { $parsedata->current_version = trim(file_get_contents(ABSPATH . 'version')); $first = false; } $error = $parsedata->ParseDataFull(); if ($error) { print $error; break; } $parsedata->insert_into_blockchain(); // отметимся в БД, что мы живы. upd_deamon_time($db);
function ParseBlock() { global $global_current_block_id; /* Заголовок (от 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 Далее - тело блока (Тр-ии) */ if (!$this->binary_data) { return 'null $this->binary_data 1'; } $this->block_data['block_id'] = binary_dec($this->string_shift($this->binary_data, 4)); if (!$this->binary_data) { return 'null $this->binary_data 2'; } $global_current_block_id = $this->block_data['block_id']; $this->block_data['time'] = binary_dec($this->string_shift($this->binary_data, 4)); if (!$this->binary_data) { return 'null $this->binary_data 3'; } $this->block_data['user_id'] = binary_dec($this->string_shift($this->binary_data, 5)); if (!$this->binary_data) { return 'null $this->binary_data 4'; } $this->block_data['level'] = binary_dec($this->string_shift($this->binary_data, 1)); if (!$this->binary_data) { return 'null $this->binary_data 5'; } $sign_size = $this->decode_length($this->binary_data); if (!$this->binary_data) { return 'null $this->binary_data 6'; } $this->block_data['sign'] = $this->string_shift($this->binary_data, $sign_size); }