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

IPFS: манифест учебного выпуска

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

Пример является собственным форматом библиотеки. Это не универсальный стандарт IPFS. Реальные отпечатки и CID не вычисляются: пометки TO_BE_COMPUTED показывают незаполненные значения, которые нельзя принять за готовую проверку.

Что объявляет издатель

Манифест содержит идентификатор схемы, номер курса, редакционную версию и список файлов. Для каждого файла полезны точный путь, размер байтов и алгоритм контрольной суммы. CID может дополнительно описывать content-addressed-представление, но не заменяет обычный файловый отпечаток.

{
  "schema": "library-release-v1",
  "courseId": "17",
  "edition": "1",
  "files": [
    {
      "path": "lessons/01-introduction.html",
      "bytes": "TO_BE_COMPUTED",
      "sha256": "TO_BE_COMPUTED"
    }
  ]
}

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

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

Состав не равен каталогу сервера

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

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

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

Манифест описывает себя осторожно

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

В нашей модели SHA-256 точных байтов release.json хранится в доверенном объявлении, например в CourseCatalog. Манифест описывает другие файлы, а его CID сохраняется отдельно как способ адресации. Это разрывает круговую зависимость и делает проверку понятной.

Корневой CID каталога тоже не вставляем в тот же файл внутри каталога наивным способом. Если он зависит от манифеста, добавление корня в манифест изменит корень. Для полного досье выпуска используем внешний редакционный документ или объявление, связывающее эти значения после импорта.

Проверка схемы после целостности

Читатель сначала получает точные байты манифеста и сверяет с доверенным отпечатком. Затем разбирает документ и проверяет допустимую схему. Эти два этапа отвечают на разные вопросы: подлинные ли объявленные байты и поддерживает ли приложение их смысл.

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

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

Изменение выпуска

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

Если исправили только описательное название, байты манифеста тоже меняются. Нужно решить, является ли такое исправление новой редакцией или отдельным внешним описанием. Внутри неизменного объекта «косметическая» правка не исчезает из криптографической идентичности.

Одинаковый путь не может объявлять два файла

Предположим, редактор по ошибке добавил в массив две записи для lessons/01-introduction.html. В первой указан старый отпечаток, во второй — новый. Обычный JSON с массивом остаётся синтаксически допустимым. Однако наша схема отвергает документ: читатель не должен выбирать запись по принципу «последняя победила». Иначе две реализации могут принять разные объявления из одних и тех же байтов, хотя их криптографическая проверка прошла одинаково.

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

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

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

Досье материала

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

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

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