Skip to content

Dcoin блокчейн

c-darwin edited this page Apr 19, 2016 · 5 revisions

Каждый раз после создания нового блока происходит распределение майнеров по уровням.

Предположим, что на 0-м уровне оказался майнер с ID 1056. Тогда распределение по уровням будет выглядеть так: 0: 1056 1: 1057, 1058 2: 1059, 1060, 1061, 1062 N: 1056+(2^N)-1 -> 1056+((2^N)-1)*2

Каждый майнер создает специальную пару ключей для работы ноды, публичный ключ записывается в блокчейн, а приватный ключ хранится на ноде и используется для подписания блоков.

Демон testblock_generator

генерирует блоки

  1. Лочит main_lock
  2. Получает номер текщуего блока в info_block
  3. Проверяет, какой блок в testblock, если уже есть info_block.block_id + 1, то начинаем с начала
  4. Генерить могут только майнеры
  5. Узнаем, сколько нам нужно спать через метод GetGenSleep

4.1. variables.sleep.is_ready[prev_block.level](узнаем время, которые было затрачено в ожидании is_ready предыдущим блоком) + variables.sleep.generator[current.level](cколько сек должен ждать нод, перед тем, как начать генерить блок, если нашел себя в одном из уровней.) + ariables.sleep.is_ready[current.level](сумма is_ready всех предыдущих уровней, которые не успели сгенерить блок) 4.2 учтем, сколько уже прошле времени с момента генерации предыдущего блока. и спим остаток. 4.3 Если случится откат или придет новый блок, то генератор блоков нужно запускать с начала, т.к. изменится max_miner_id. О том, что изенился текущий блок узнаем из info_block.head_hash 4.4 Пока спим разлочиваем main_lock. Но в момент запроса head_hash снова лочим.

  1. После того как поспали лочим main_lock
  2. Т.к. во время попытки локнуть main_lock (может занять несколько секунд) уже могло что-то измениться, то еще раз проверим время для сна и хэш текущего блока. Если что-то изменилось, то начинаем всё с начала.
  3. Откатываем transactions_testblock и заново их поместим в таблу transactions
  4. Берем все тр-ии из transactions
  5. Пишем тр-ии в transactions_testblock.
  6. Получаем меркель рут, чтобы нельзя было потом дописать тр-ии
  7. Подписываем нашим нод-ключем заголовок блока newBlockId, prevBlock.Hash, Time, myUserId, level, mrklRoot
  8. Удалим из testblock данные по такому же номеру блока
  9. Запишем в testblock новые данные. С headerHash по которому будем сравнивать с другими блоками на таком же уровне.
  10. Отмечаем used=1 транзакции в transactions, которые попали в transactions_testblock. если не отмечать, то получается, что и в transactions_testblock и в transactions будут провернные тр-ии, которые откатятся дважды
  11. Разлочиваем main_lock

Демон testblock_is_ready

Демон, который отсчитывает время, которые необходимо ждать после того, как началось одноуровневое соревнование, у кого хэш меньше. Когда время прошло, то берется блок из таблы testblock и заносится в queue и queue_front для занесение данных к себе и отправки другим

  1. Определяем, сколько нужно спать.

1.1. Берем “is_ready”:[0,5,10,15,20,40,80,128,256,512,1024,2048,4096,8192] и Level из текущего блока в info_block. Получаем is_ready[level] 1.2. Спим, локая на время получения head_hash для проверки, не сменился ли блок в info_block. Если сменился, то начинаем всё с начала.

  1. После того как поспали лочим main_lock
  2. Т.к. во время попытки локнуть main_lock (может занять несколько секунд) уже могло что-то измениться, то еще раз проверим время для сна и хэш текущего блока. Если что-то изменилось, то начинаем всё с начала.
  3. в промежутке межде тем, как блок был сгенерирован и запуском данного демона может измениться текущий блок поэтому нужно проверять подпись блока из тестблока
  4. Собираем блок из таблиц testBlockData и transactions_testblock
  5. Теперь нужно разнести блок по таблицам и после этого мы будем его слать всем нодам демоном disseminator
  6. Удаляем данные из transactions_testblock и testblock, т.к. они перешли в нормальный блок

Демон queue_parser_blocks

Данные пишет tcpserver.type1 Берем блок. Если блок имеет лучший хэш, то ищем, в каком блоке у нас пошла вилка

  • Если вилка пошла менее чем variables->rollback_blocks блоков назад, то
  • - получаем всю цепочку блоков,
  • - откатываем фронтальные данные от наших блоков,
  • - заносим фронт. данные из новой цепочки
  • - если нет ошибок, то откатываем наши данные из блоков
  • - и заносим новые данные
  • - если где-то есть ошибки, то откатываемся к нашим прежним данным
  • Если вилка была давно, то ничего не трогаем, и оставлеяем скрипту blocks_collection.php
  • Ограничение variables->rollback_blocks нужно для защиты от подставных блоков

tcpserver.type6 (возможны проблема из-за работы без лока)

Получает данные от testblockDisseminator

  • проверяем, находится ли отправитель на одном с нами уровне
  • получаем block_id, user_id, mrkl_root, signature
  • если хэш блока меньше того, что есть у нас в табле testblock, то смотртим, есть ли такой же хэш тр-ий,
  • если отличается, то загружаем блок от отправителя
  • если не отличается, то просто обновляем хэш блока у себя
Clone this wiki locally