Плагин архива блоков
block_archive — опциональный, неконсенсусный плагин. Он хранит на диске постоянную копию каждого необратимого блока, разбитую на файлы-диапазоны фиксированного размера. Нужен потому, что dlt_block_log DLT-ноды держит только скользящее окно (dlt-block-log-max-blocks, по умолчанию 100 000 блоков) и выбрасывает старые блоки.
Плагин не меняет консенсус, не требует хардфорка и не влияет на обработку блоков: ноды с ним и без него полностью совместимы.
Исходный код: plugins/block_archive/plugin.cpp
Зависимости
chain::pluginВключение
По умолчанию плагин выключен. Добавьте в config.ini (выше секций [logger.*] — строки, дописанные в конец файла, попадают в последнюю секцию и молча игнорируются):
plugin = block_archive
block-archive-dir = block-archive
block-archive-range = 10000| Опция | По умолчанию | Описание |
|---|---|---|
block-archive-dir | block-archive | Папка архива. Относительный путь считается от data dir ноды. |
block-archive-range | 10000 | Блоков в файле. Минимум 100. Менять для существующего архива нельзя — используйте новую папку. |
При старте плагин пишет в лог свои настройки и курсор:
block_archive: /var/lib/vizd/block-archive, range 10000, last archived block 83792999Как работает
- После каждого применённого блока плагин сравнивает свой курсор (последний заархивированный блок) с последним необратимым блоком (LIB).
- Все блоки от
курсор + 1до LIB читаются из block log ноды и дописываются в файл своего диапазона. Архивируются только необратимые блоки, поэтому в архиве не бывает блока, который может откатиться при смене форка. - Диапазон
kпокрывает блоки[k × N, k × N + N − 1], гдеN—block-archive-range. Текущий диапазон пишется в<dir>/partial/blocks-<начало диапазона>. - Когда записан последний блок диапазона, файл запечатывается: переносится в корень папки под окончательным именем. Файлы в корне полные и больше никогда не меняются.
block-archive/
├── blocks-0083790000-0083799999.log ← запечатан, неизменяем
├── blocks-0083790000-0083799999.log.index
├── blocks-0083800000-0083809999.log
├── blocks-0083800000-0083809999.log.index
└── partial/
├── blocks-0083810000 ← текущий диапазон
└── blocks-0083810000.indexФормат файлов
Каждый диапазон — пара файлов в формате dlt_block_log (см. Лог блоков):
.log— сериализованные записиsigned_block, за каждой — её 8-байтный стартовый offset;.log.index— 8-байтный заголовок с номером первого блока, затем по одному 8-байтному offset на блок.
Блок n читается одним seek: offset = index[8 + (n − first) × 8]. Номера в именах дополнены нулями до 10 знаков, поэтому алфавитный порядок файлов совпадает с порядком блоков.
Первый файл и точка старта
Архив начинается с LIB на момент первого включения плагина — старые блоки не догружаются. <first> в имени файла — первый реально сохранённый блок, поэтому у ноды, запущенной со снапшота, первый файл короче N (например, blocks-0083792402-0083792499).
Рестарты
Курсор восстанавливается с диска: самый старший запечатанный файл плюс голова файла в partial/. После рестарта или падения плагин продолжает со следующего блока, без дыр и дублей. Файл в partial/ для уже запечатанного диапазона удаляется как устаревший.
Ошибки
Архив — побочная копия и не должен ломать ноду:
- любая ошибка записи останавливает архивирование со строкой
elog(block_archive: …, archiving stopped); нода продолжает работать и применять блоки; - если следующий блок уже не читается (нода была выключена дольше окна
dlt_block_logили плагин включили снова после долгой паузы), архивирование останавливается, а не пишет дыру. После рестарта оно тоже остаётся остановленным, потому что курсор лежит на диске. Чтобы продолжить, заполните дыру из другого архива или уберите папку и начните новую.
Следите за строкой archiving stopped в логе ноды.
Чтение архива
Используйте инструменты из programs/util/block-log/ — см. Инструменты лога блоков:
node programs/util/block-log/block-archive.cjs info /var/lib/vizd/block-archive
node programs/util/block-log/block-archive.cjs search /var/lib/vizd/block-archive --op=transfer --account=aliceЗапечатанные файлы неизменяемы, поэтому их можно копировать, сжимать, бэкапить и раздавать на ходу, не останавливая ноду. Файлы в partial/ не читайте и не перемещайте.
Место на диске
Архив растёт вместе с цепью, нода его не чистит. Размер зависит от содержимого блоков: оцените его по размеру вашего dlt_block_log, поделённому на его окно и умноженному на число блоков, которые хотите хранить. Старые запечатанные файлы можно свободно переносить в холодное хранилище — плагин смотрит только на самый старший запечатанный файл и partial/.