Nostr WoT
NostrNIPRelays

NIP-67: подсказка о полноте EOSE

EOSE всегда означал, что релей закончил отправку сохранённых событий, а не то, что он отправил их все. NIP-67 добавляет необязательную подсказку, чтобы клиенты наконец могли отличить одно от другого.

Nostr WoT Newsroom

Статья3 min read

Материал подготовлен редакцией Nostr WoT на основе указанных первоисточников и опубликован автоматически, без индивидуальной проверки человеком.

NIP-67: подсказка о полноте EOSE

NIP-01 определяет EOSE как границу между сохранёнными и реальными событиями для подписки. Чего он никогда не определял, так это того, действительно ли релей отправил всё хранимое, что соответствует фильтру. NIP-67, написанный пользователем mattn и объединённый 6 июня 2026 года, даёт релеям способ сообщить об этом.

Пробел, который оставлял EOSE

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

Это предположение ошибается двумя конкретными способами.

Во-первых, когда ограничение релея оказывается ниже запрошенного клиентом limit, клиент ошибочно решает, что результат полон. Клиент запрашивает последние 500 заметок. Релей ограничивает ответы 300 событиями и отправляет ровно 300. Поскольку 300 меньше 500, клиент делает вывод, что получил всё. Это не так. Остальные подходящие заметки остаются на релее, и клиент никогда не узнаёт об их существовании.

Во-вторых, когда число подходящих событий оказывается в точности равным ограничению релея, клиент не может понять, что получил их все. У него нет выбора, кроме как отправить ещё один REQ со значением until, установленным на метку времени самого старого полученного события, только чтобы убедиться, что следующая порция пуста. Релей с ограничением в 300 событий получает как минимум два запроса для любой подписки, достигающей этого предела, независимо от того, оставались ли ещё данные для получения.

Что добавляет NIP-67

Спецификация добавляет необязательный третий элемент к сообщению EOSE, массив строк-подсказок:

text
["EOSE", <subscription_id>, [<hint>, ...]]

Определены два значения подсказки. "finish" означает, что релей отправил все сохранённые события, соответствующие фильтрам подписки, поэтому клиенту не следует пагинировать дальше. "more" означает, что релей удерживает дополнительные подходящие сохранённые события, которые не отправил, поэтому клиенту следует пагинировать, чтобы их получить. Релей не обязан отправлять "more", даже если это правда, поскольку точное знание о том, что подходящих данных больше, обходится небесплатно не на каждом бэкенде хранения.

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

Совместимость работает в обе стороны. Релей, добавивший этот NIP, отправляет EOSE из трёх элементов каждому клиенту, независимо от того, понимает ли тот подсказку, потому что клиенты без поддержки NIP-67 уже индексируют EOSE по позиции и просто игнорируют лишний элемент, точно так же, как парсер JSON без проблем принимает лишний элемент в конце массива. Клиент, добавивший поддержку подсказки, не получает ничего дополнительного от релеев, которые её ещё не реализовали, и просто продолжает использовать свою текущую логику пагинации.

NIP также затрагивает связанный граничный случай с совпадающими метками времени. Когда релей не отправляет "finish", несколько сохранённых событий могут иметь одинаковое самое старое значение created_at в одном ответе, и пагинация по until рискует незаметно потерять события, разделяющие эту граничную метку времени. Релеям рекомендуется, где это возможно, продвигаться достаточно далеко, чтобы все события с граничной меткой времени попадали в один ответ, и отправлять "finish" только тогда, когда действительно не остаётся ничего более старого.

Ожидается, что релеи, реализующие NIP-67, укажут 67 в своём поле supported_nips согласно NIP-11.

Почему это важно

Незаметное усечение и по-настоящему пустой результат сегодня выглядят для клиента одинаково. Это различие важнее всего там, где отсутствие дальнейших результатов имеет значение: запросы модерации, аудиты, или клиент, пытающийся установить, что у конкретного публичного ключа действительно больше нет событий определённого рода. NIP-67 не меняет способ хранения или доставки событий. Он даёт релеям небольшой необязательный словарь, чтобы честно сообщать, действительно ли история сохранённых событий подписки была исчерпана.

Источники

Каждое утверждение в этом материале ссылается на первоисточник.

  1. NIP-67: EOSE Completeness Hint — nostr-protocol/nips (6 июня 2026 г.)

Ещё от редакции

Stay Updated

Get the latest on new features, trust assertions, and services integration as they ship.

No spam, ever. Unsubscribe anytime.