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); } }
// сразу можно удалять данные из таблы-очереди $db->query(__FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__, "\n\t\t\tDELETE FROM `" . DB_PREFIX . "queue_testblock`\n\t\t\tWHERE `head_hash` = 0x{$new_header_hash}\n\t\t\t"); ////debug_print($db->printsql(), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); // прежде всего нужно проверить, а нет ли в этом блоке ошибок с несовметимыми тр-ми // при полной проверке, а не только фронтальной проблем с несовместимыми тр-ми не будет, т.к. там даные сразу пишутся в таблицы // а тут у нас данные пишутся только в log_time_ // и сами тр-ии пишем в отдельную таблу if ($tx) { do { debug_print('$tx=' . $tx, __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); debug_print('$tx hex=' . bin2hex($tx), __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); $tx_size = ParseData::decode_length($tx); // отчекрыжим одну транзакцию от списка транзакций $tx_binary_data = ParseData::string_shift($tx, $tx_size); // проверим, нет ли несовместимых тр-ий list($fatal_error, $wait_error) = clear_incompatible_tx($tx_binary_data, $type, $user_id, $to_user_id, $db, false); if ($fatal_error || $wait_error) { debug_print('[incompatible_tx] continue', __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); testblock_unlock(); sleep(1); continue 2; } } while ($tx); } // откатим тр-ии тестблока, но не удаляя их, т.к. далее еще можем их вернуть rollback_transactions_testblock($db); debug_print("ParseDataRollbackFront OK", __FILE__, __LINE__, __FUNCTION__, __CLASS__, __METHOD__); //ob_save(); // проверим блок, который получился с данными, которые прислал другой нод $parsedata = new ParseData($new_block, $db); $error = $parsedata->ParseData_gate();