Перейти к основному содержимому

Доказательство работы

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

Три алгоритма

АлгоритмУзкое местоМинимальная сложность
Cuckoo / CuckatooПоиск цикла в графе с ограничением по памяти3
RandomXCPU4,000
ProgPowGPU200,000

Параметры Cuckoo: размер доказательства 42, минимальное количество битов рёбер 19, количество битов рёбер второго доказательства работы 31, базовое количество битов рёбер 24.

Реализации алгоритмов находятся в отдельных крейтах: EpicCash/randomx-rust и EpicCash/progpow-rust.

Сложность отслеживается отдельно для каждого алгоритма, поэтому get_status возвращает tip.total_difficulty как объект с одним u64 на алгоритм, с ключами cuckaroo, cuckatoo, randomx и progpow.

Заголовок блока указывает алгоритм в proof и содержит решение в solution — значении с внешней тегировкой, форма которого зависит от этого алгоритма:

header.proof and header.solution, field shapes
"proof": "Cuckoo" "solution": {"Cuckoo": [<u64>, ...]} 42 nonces
"proof": "RandomX" "solution": {"RandomX": "<decimal string>"} 32-byte hash, base 10
"proof": "ProgPow" "solution": {"ProgPow": [<byte>, ...]} 32-byte mix, one number per byte
"proof": "MD5" "solution": {"MD5": "<string>"} not scheduled on mainnet

Блоки Cuckatoo и Cuckaroo оба сообщают Cuckoo в proof и различаются по количеству битов рёбер. Типы находятся в api/src/types.rs:574.

Политика блоков

Алгоритм, который должен использоваться для следующего блока, определяется детерминированной политикой. Реализация ведёт счётчик для каждого алгоритма и выбирает тот, который больше всего отстаёт от своей доли в текущем окне из 100 блоков, поэтому смесь в пределах окна точная, а не усреднённая.

Доли на 100 блоков:

ЭраRandomXProgPowCuckatooCuckaroo
Эры 1–2603820
Эра 3 и далее484840

Cuckaroo на mainnet получает нулевую долю. Он существует в системе типов и не планируется.

Политика скомпилирована в узел и не настраивается через epic-server.toml на mainnet. Два ключа сужают её в тестовой сети:

epic-server.toml, floonet and usernet only
[server]
only_randomx = true # каждый блок должен быть RandomX
no_progpow = false # или просто исключить ProgPow из смеси

only_randomx = true позволяет одному CPU-майнеру продвигать приватную цепочку: при смешанной политике майнер, работающий только на RandomX, простаивает на каждой высоте ProgPow. Оба ключа изменяют политику блоков, поэтому цепочка, намайненная с одной настройкой, недействительна с другой. Удалите chain_data при изменении любого из них.

Доли mainnet находятся в core/src/core/block/feijoada.rs:249,

next_block_bottles()

продвигает окно и сбрасывает его на 100 блоках, choose_algo() выполняет выбор по PolicyConfig, а get_bottles_default() возвращает обнулённые счётчики, с которых начинается каждое окно. Константы находятся в core/src/consensus.rs.

Сложность

Каждый алгоритм имеет собственный трек сложности, ретаргетируемый независимо через next_difficulty(). Окно корректировки составляет 60 блоков (DIFFICULTY_ADJUST_WINDOW), один час при целевом интервале 60 секунд, и окно проходит только по блокам того же алгоритма, поэтому каждый трек видит свою собственную историю.

Все три трека используют одинаковый коэффициент зажима 2 и коэффициент демпфирования 3.

Изменения консенсуса по высоте блока

Два изменения консенсуса привязаны к высотам блоков mainnet, а не к версионному форку:

ВысотаИзменение
501,160Правило сложности меняется, минимумы RandomX и ProgPow переходят с 5,000 и 100,000 на 4,000 и 200,000
880,000Коэффициент истечения веса графа меняется: с одного года до ста лет блоков

Реализация, учитывающая только объявленные версии форков, расходится на обоих. Первая объявленная высота хард-форка — 9,000,000, что при блоках с интервалом 60 секунд составляет более десяти лет, поэтому более поздние версии заголовков достижимы только в тестовых сетях.

Далее

Майнер подключается через Stratum на порту 3416 — сырой TCP с JSON, разделённым символами новой строки, — или через внешний JSON-RPC интерфейс узла с помощью get_block_template, finalize_block_template и submit_block. EpicCash/epic-miner — эталонный клиент для майнинга.