Beispiel #1
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;
         }
     }
 }