Spine-цепочка
Каждый узел ZooBC ведёт две цепочки. Основная цепочка создаёт блок каждые 15 секунд и несёт транзакции. Рядом с ней работает spine-цепочка: один блок в сутки в mainnet, без каких-либо транзакций. Spine-блок записывает то, за что ручается реестр в целом, — контрольную точку основной цепочки, ключи узлов, которые вошли или вышли, и манифесты последних снимков, — и требует подписей двух третей мест. Поэтому spine-цепочка — якорь финальности и отправная точка каждого нового узла.
Что содержит spine-блок
- Контрольную точку. Каждый spine-блок называет опорный блок основной цепочки, достаточно глубокий, чтобы считаться устоявшимся: на 760 блоков (3 часа 10 минут) ниже вершины основной цепочки в момент создания spine-блока и никогда не ниже опорного блока предыдущего spine-блока. Он копирует корень Меркла этого блока, а его хеш полезной нагрузки фиксирует собственный хеш опорного блока и его накопленную сложность, так что контрольная точка закрепляет один конкретный блок, а не просто высоту.
- Изменения публичных ключей. Ключи узлов, добавленные в реестр или удалённые из него со времени предыдущего spine-блока.
- Манифесты снимков. Для каждого недавнего снимка состояния основной цепочки: хеш всего файла, хеш каждого чанка, опорная высота, срок действия и хеш генезиса основной цепочки (см. Снимки и быстрая синхронизация).
Spine-цепочка создаёт один блок за spine_smithing_period: 86 400 секунд, один в сутки, в mainnet и testnet и 3 600 секунд, один в час, в devnet, где глубина контрольной точки — 80 блоков (20 минут).
Соподписан двумя третями мест
Spine-блок несёт агрегированную подпись: 4-байтовое число, за которым для каждого подписанта следуют его 32-байтовый ключ узла и 64-байтовая подпись Ed25519, все над одними и теми же 204 байтами заголовка. Хеш блока — SHA3-256 от байтов заголовка и всего поля подписей.
Требуемое число подписей:
required = max(spine_min_signatures, ceil(n × 67 / 100))
где n — размер списка подписантов. При 11 местах 11 × 67 / 100 = 7,37, с округлением вверх — 8. Округление вверх намеренное: 7 было бы меньше двух третей от 11.
Spine-цепочка учитывает каждое место в своём списке подписантов, приостановлено оно или нет. Это единственный подсчёт двух третей, в котором приостановленные места всё ещё учитываются, поэтому контрольная точка всегда говорит от имени двух третей всех мест (см. Правила двух третей).
Если слишком много мест выбыло и spine-цепочка останавливается, планка снижается за один шаг: после 3 периодов spine-цепочки без сохранённого spine-блока (3 дня в mainnet) достаточно больше половины — 6 из 11. Ни одна из планок не может опуститься ниже spine_min_signatures, который во всех цепочках равен 5. Если бы требовались все 11 подписей, одно-единственное выбывшее место могло бы остановить spine-цепочку.
Подписанты проверяют, прежде чем подписать
Место никогда не подписывает вслепую. Прежде чем соподписать предложение, каждый подписант проверяет, что:
- изменения ключей совпадают с изменениями в его собственном реестре за тот же диапазон;
- каждый манифест для его цепочки совпадает с его собственным снимком хеш в хеш; подписант без такого снимка воздерживается;
- опорный блок достаточно глубок и не сдвигается назад;
- он ещё не соподписал другой блок на этой высоте spine-цепочки.
Когда узел сохраняет spine-блок, он снова проверяет содержимое, а также жеребьёвку производителя и сложность блока.
Кто предлагает и когда
Производитель spine-блока выбирается жеребьёвкой из списка подписантов: подписант с индексом LE64(SHA3-256(seed ‖ "spine" ‖ round)) mod n, где seed — сид основного блока на опорной высоте предыдущего spine-блока, так что каждый валидатор может повторить жеребьёвку. В mainnet раунд spine-цепочки длится 100 секунд, окно создания — 300 секунд, допуск — 150 секунд; подписант отклоняет предложение старше своего 60-секундного окна сбора. Spine-блок, пришедший раньше, чем предыдущий плюс период минус допуск, отклоняется.
Spine-блоки никогда не бывают пустыми. Из конкурирующих spine-цепочек побеждает та, у которой больше подписей. Узел взвешивает конкурирующую spine-цепочку, прежде чем что-либо откатывать, никогда не откатывает свою spine-цепочку ниже пина релиза и восстанавливает собственную spine-цепочку, если другую не удаётся применить.
Для чего нужна spine-цепочка
- Финальность. Ни один узел не реорганизует основную цепочку ниже последней сохранённой контрольной точки spine-цепочки (см. Финальность и откат).
- Быстрая синхронизация. Новый узел сначала синхронизирует spine-цепочку: её манифесты говорят, какой снимок загрузить, а её изменения ключей — каким ключам узлов доверять (см. Снимки и быстрая синхронизация).
- Архив. Каждый снимок начиная с нулевого блока хранит децентрализованное хранилище, а не каждый узел, поэтому любой может пройти по spine-цепочке назад до любого прошлого снимка и восстановить состояние того времени (см. Архив и чтение прошлого).
Spine-цепочку ведёт каждый узел, а не Foundation, и на ней ничем не торгуют.