generated at
保存済みイベント取得時のリレー間挙動差異

文責: jiftechnify

購読直後( REQ を送ってから EOSE が返ってくるまで)に取得できる「保存済みイベント」の数や順序は、リレー実装の違い・ REQ のフィルタの指定の仕方によって異なる。この挙動の差異について調査した結果をまとめる。

調査対象のリレー実装
いずれも2023/03/14時点の最新版のコードを参照。

フィルタにlimitを指定した場合の挙動
nostr-rs-relay: 該当コード
イベント数: limit
順序: 新しい順
nostream: 該当コード
イベント数: limit (^1)
順序: 新しい順
strfry
イベント数: min(limit, 500) (^2)
順序: 新しい順

^1: limit が5000を超える場合、 REQ を送信した時点でエラーとなり NOTICE メッセージが返ってくる
invalid: \"[2].limit\" must be less than or equal to 5000
^2: 500 という数字はmaxFilterLimitという設定項目のデフォルト値で、変更可能

フィルタにlimitを指定しなかった場合の挙動
nostr-rs-relay: 該当コード
条件にマッチする全イベントを返却
順序: 古い順
nostream: 該当コード
固定で500件のイベントを返却
順序: 古い順
strfry
デフォルト設定では500件のイベントを返却 (^3)
順序: 新しい順

^3: maxFilterLimitを変更することで、件数を変更可能

since/untilを指定した場合の挙動
→ NIP-01で明確に挙動が定義されたため、最新版の実装では以下の差異はなくなっている。ただし、リレー管理者が最新版に更新しているとは限らないため、現実にはまだ差異が残っている可能性がある。(2023/08/22 追記)
nostr-rs-relay: 該当コード
created_at since / until に等しいイベントを含まない
nostream: 該当コード
created_at since / until に等しいイベントを含む
created_at since / until に等しいイベントを含む

備考
strfryの取得イベント順序の証拠となるコードは発見できていないが、READMEのこの部分を読む限り、常に新しい順になると考えてよさそう

TODO
REQ のレートリミットの実装差異、レートリミットに引っかかった際のエラーメッセージ調査

関連
nostr-fetch: 上記の挙動差異を吸収しながらリレーから過去のイベントを漏れなく取得する、JS/TS向けライブラリ
Nostrのリレーから漏れなくすべてのイベントを取ってくる技術: nostr-fetchの実装解説スライド。上記の挙動差異についても触れている