IPFS: выпуск, обновление и откат
Исправление урока создаёт новый выпуск, но читатели могут продолжать пользоваться первой редакцией. В уроке подготовим публикационный процесс, который разделяет построение данных, подтверждение хранения и изменение текущей рекомендации. Он позволит откатить неудачное обновление без ложного обещания удалить распространявшиеся байты.
Сеть, реестр, pinning API и DNS не изменяются. Мы пишем журнал процедуры и ожидаемые состояния. Никакой новой редакции в публичной инфраструктуре этой работой не объявлено.
Стадии выпуска
Сначала редакция получает готовый каталог и манифест. Затем формируются блоки по закреплённому профилю и вычисляются значения. Затем проверяется достаточное хранение. Только после этого возникает основание объявить выпуск текущим.
prepared → imported → replicated → announced → current
Это собственная модель процесса. Некоторые проекты объединяют последние стадии, но их смысл различается: событие реестра может быть объявлено, а DNSLink ещё видеть старый корень. Внутренний журнал должен выразить промежуточное состояние, а не ставить один флаг по первой удачной операции.
Каждая стадия имеет идентичность выпуска. Повторное выполнение не создаёт новую редакцию только оттого, что задача запущена заново. Если байты изменились, это новая версия содержания; если изменилось лишь место хранения, прежний объект остаётся тем же.
Согласование данных
Перед объявлением сверяем SHA-256 точных байтов манифеста, CID манифеста и корень каталога. Все значения должны относиться к одному подготовленному набору. Нельзя взять отпечаток до последней правки, а корень после неё и считать такую пару цельной.
Манифест не включает собственную итоговую контрольную сумму наивным способом. Досье связывает вычисленные значения после подготовки. Запись реестра подтверждает согласованное обязательство приложения, а способы обнаружения сообщают, где получить соответствующие байты.
Если профиль импорта изменился при тех же файлах, сохраняется отдельное объяснение. Новый корень не обязательно означает новую смысловую редакцию текста, но это другой объект представления. Для текущей библиотеки выбираем однозначную версию досье, чтобы читатель мог воспроизвести нужный вариант.
Сбой между действиями
Представим, что реплики готовы, а отправка объявления вернула тайм-аут. Транзакция могла уже попасть в сеть. Прежде чем повторять запись, сервис наблюдает конкретное действие и текущую запись контракта. Неизвестный результат не равен отсутствию операции.
Другой случай: реестр обновлён, DNSLink ещё нет. Клиент старого указателя может получить прежний манифест и увидеть несовпадение с текущим contentHash. Интерфейс сообщает переходное расхождение и предлагает явный путь, если новый объект уже известен. Нельзя молча выключать проверку ради гладкого обновления.
Третий случай: текущий указатель обновлён, но одна реплика не готова. Решение о достаточности зависит от выбранной политики числа копий. Если процедура требовала две, один успех не превращает выпуск в полностью поддержанный.
Откат рекомендации
Во второй редакции обнаружена ошибочная инструкция. Редакция может вернуть текущий указатель на первую, объявить отзыв или подготовить третью исправленную. Выбор отражается в журнале с причиной. deactivate базового контракта меняет активность курса, но не удаляет файлы.
Скачанные материалы остаются у читателей, а независимые хранители могут продолжить их выдачу. Поэтому фраза «мы откатили, значит ошибка исчезла из интернета» неверна. Нужно опубликовать ясное исправление и обозначить, какие редакции оно затрагивает.
Историческая ссылка на второй выпуск может показывать предупреждение через доверенный читатель, если он получает актуальную редакционную информацию. Но сами байты второго объекта не должны неожиданно стать третьими. Неизменность и рекомендация остаются отдельными свойствами.
Версионная история
Базовый CourseCatalog хранит текущую запись, а не полный список редакций в одном поле. Для истории библиотека сохраняет манифесты, события и внешнее досье. Если понадобится контрактный реестр версий, его модель вводится явно как новое расширение, а не предполагается задним числом.
Индексатор событий учитывает сетевую принадлежность и реорганизации. Событие, однажды увиденное в старой ветви, не всегда остаётся объявлением выбранной истории. Журнал публикации сохраняет наблюдения и итоговое основание текущего решения отдельно.
Редакционная версия тоже не равна номеру блока. Один выпуск может быть повторно объявлен в иной сетевой операции, а несколько административных событий относиться к одному содержимому. Внутренний releaseId связывает процедуру, но не заменяет криптографические значения.
Сбой между объявлением и указателем
Представим, что новая редакция полностью подготовлена и сохранена, затем CourseCatalog обновлён, но публикация изменяемого указателя завершилась неизвестным результатом. Процесс имеет частичный успех: новое обязательство уже может быть объявлено, а привычное имя ещё ведёт к старому манифесту. Нельзя исправлять это подменой контрольного значения в клиенте. Оператор продолжает процедуру с сохранёнными идентичностями и выясняет состояние именно незавершённого шага.
Если неизвестен результат транзакции реестра, повтор также требует аккуратности. Подготовленная операция, отправленная транзакция и наблюдённое включение — разные записи. Реорганизация может изменить принадлежность наблюдения выбранной истории. В досье сохраняется контекст объявления, а не только флаг «успешно». Этот курс не реализует индексатор EVM, но его публикационная модель должна оставлять место для такого пересмотра.
Для восстановления удобно иметь журнал стадий выпуска, в котором каждая завершённая стадия связывается с теми же точными байтами, корнями и редакцией. После сбоя процесс не собирает новый HTML случайно поверх уже объявленного обязательства. Если действительно требуется новая подготовка, она оформляется отдельным выпуском. Иначе диагностика перестанет понимать, какой набор хранителей должен содержать объявленные данные.
Откат тоже является новым редакционным решением с собственным наблюдаемым выполнением. Он меняет рекомендации, но не стирает журнальную историю и чужие копии неудачной редакции. Для посетителя библиотека может показать выбранную версию и причину временного возврата. Для оператора сохраняет незавершённые задачи, чтобы отложенный ответ старой операции не вернул указатель обратно после отката. Так последовательность публикации становится управляемой системой состояний, а не набором независимых кнопок с одним общим сообщением «всё готово».
Согласование доступа
Если читатель купил первую редакцию, политика определяет, получает ли он вторую автоматически и сохраняет ли право на первую. Это договор сервиса, а не функция IPFS. При изменении назначения ключей зашифрованного выпуска правила также описываются отдельно.
Нельзя считать, что владелец токена или оплаченного счёта физически не сможет поделиться уже полученным открытым файлом. Сервис контролирует будущую выдачу в своей границе, а не каждое копирование содержания. Этот вопрос подробнее рассматривается в уроке доступа.
Результат — восстановимый журнал выпуска с отдельными стадиями и действиями отката. Основы изменяемых указателей изложены в IPNS-спецификации, а хранения — в документации pinning. Теперь обновление является объяснимой последовательностью, а не одной кнопкой с непроверенным обещанием мгновенного успеха.