Перейти к содержанию

IPFS: UnixFS и дерево блоков

CID адресует блок, но учебный выпуск состоит из файлов и каталогов. UnixFS задаёт структуры, позволяющие представить их поверх связанных блоков. В уроке построим небольшое дерево выпуска и проследим, как изменение одного урока влияет на корневую идентичность, не обязательно изменяя каждую соседнюю часть.

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

Файл как части и связи

Импортёр может разделить файл на части, сохранить их как блоки и создать узлы, связывающие части в нужном порядке. При чтении клиент следует структуре и восстанавливает последовательность байтов. Кодек и правила UnixFS объясняют, как интерпретировать эти связи.

Небольшой текст может иметь компактное представление, а большой архив — многоуровневое. Настройки импорта влияют на размер частей и форму дерева. Поэтому корневой CID не обязан быть простым отпечатком исходного файла, как установлено в предыдущем уроке.

Для библиотечного HTML важно, что восстановление возвращает точные исходные байты. Читатель может независимо сравнить SHA-256 файла с манифестом. Проверка структурных блоков и проверка итоговой последовательности дополняют друг друга, но относятся к разным представлениям.

Каталог связывает имена

Каталог содержит связи к дочерним объектам с именами. Выпуск может выглядеть так:

ROOT
 ├─ index.html ─────────→ HTML_ROOT
 ├─ assets ────────────→ ASSETS_ROOT
 │    └─ site.css ─────→ CSS_BLOCK_OR_ROOT
 └─ lessons ───────────→ LESSONS_ROOT
      └─ 01.html ──────→ LESSON_ROOT

Имя 01.html входит в структуру каталога. Если переименовать его в introduction.html, корневое представление каталога изменится, даже когда байты самого файла остаются прежними. Для сайта это ожидаемо: путь является частью выпуска и влияет на относительные ссылки.

Один дочерний объект может быть доступен через несколько связей. Но наличие ссылки в корне не означает, что соответствующий блок сейчас доступен у любого хранителя. Структура сообщает, что требуется для чтения, а доступность определяется наличием всех необходимых данных.

Изменение одного урока

Редакция исправляет предложение в lessons/01.html. Меняются блоки, которые зависят от новых байтов, корень файла и узлы каталога на пути к общему корню. Неизменный site.css может сохранить прежний CID при том же представлении.

Это позволяет повторно использовать одинаковые блоки. Однако нельзя обещать, что любая правка изменит ровно один блок. Разбиение зависит от профиля: вставка в начале при фиксированных частях может сдвинуть последующие границы. Иные стратегии ведут себя по-другому. Сначала определяем импорт, затем анализируем фактическое повторное использование.

Для библиотеки полезно сохранить манифест обоих выпусков. Читатель видит, какие файлы объявлены в новой версии, а архив различает корни. Старый выпуск не изменяется, хотя некоторые блоки могут быть общими у нескольких корней.

Путь и корень

Ссылка /ipfs/ROOT_CID/lessons/01.html задаёт корень и последующий путь. Последний компонент сам по себе не является криптографическим идентификатором. Клиент должен пройти связи от доверенного корня к ожидаемому файлу.

Если приложение проверило только корень каталога, но затем показало файл, полученный независимо с обычного URL, связи проверки нарушаются. Нужно либо следовать проверенному DAG, либо отдельно сверить файл с доверенным манифестом. Наличие CID в адресной строке шлюза не означает, что браузер сам выполнил полную структурную проверку.

При отсутствии файла ожидается предметная ошибка разрешения пути. Её нельзя заменять автоматической выдачей текущей страницы другого выпуска, сохраняя прежний адрес. Такой удобный fallback разрушит обещание содержания и затруднит объяснение пользователю.

Размеры и метаданные

UnixFS может включать предусмотренные метаданные, например режим или время, в зависимости от импортёра и выбранного профиля. Если они входят в блоки, изменение метаданных способно изменить CID без правки текста. Для повторяемого выпуска нужно определить, какие поля сохраняются и какие нормализуются.

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

Большие каталоги могут использовать другие структуры, чем маленький учебный пример. Приложение должно поддерживать предусмотренное представление, а не считать все каталоги коротким плоским списком. Для первого выпуска выбираем ограниченный и документированный набор, затем расширяем профиль осознанно.

Что меняется при правке одного урока

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

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

Теперь переименуем файл второго урока, не меняя его текст. Содержимое файла может сохранить прежнее представление, но связь имени в каталоге изменится. Корень снова будет другим. Для HTTP-ссылок это ещё и изменение маршрута. Совпадение файлового SHA-256 не доказывает, что старый относительный путь продолжает разрешаться в новой структуре. Поэтому манифест связывает имя и байты, а редактор анализирует оба вида изменений.

Наконец, представим частичное хранение: у получателя есть корневой каталог и первый урок, но нет блоков второго. Он способен узнать, какой второй файл ожидается, однако не восстановит недостающий текст из одной ссылки. Для интерфейса полезно показать доступные элементы и точную причину незавершённого получения. Нельзя считать выпуск полностью сохранённым только потому, что удалось прочитать его оглавление. Такая ситуация объясняет, зачем в дальнейшем понадобятся рекурсивное удержание и проверка полноты архива.

Полнота хранения

Хранитель, сохранивший только корневой блок, знает ссылки, но может не иметь ни текста, ни стилей. Поэтому резервирование выпуска должно включать достижимые необходимые блоки. Закрепление корня обычно рассматривается рекурсивно по выбранным правилам, и его завершение нужно подтвердить.

Точно так же архив с корнем в заголовке не обязательно содержит полный DAG. Поздние уроки CAR покажут, как отделить перечисление ожидаемой вершины от наличия всех зависимостей. Сейчас это требование описи: корень, профиль и состав достижимого набора.

Файловая модель объяснена в документации IPFS и спецификации UnixFS. После урока вы можете проследить путь от корня к файлу и объяснить изменение корня при правке текста или имени. Далее закрепим настройки, которые позволят другому импортёру повторить выбранный выпуск.

Оглавление серии