ようこそ!このドキュメントは、素晴らしい新機能を追加したいときに、仕様を安全に変更する方法についてのメタディスカッションです。
私たちは皆、物事をより良くしようとしています。尊敬、配慮、親切、ユーモアがこのプロセスを楽しいものにし、報われるものにしてきました。この状態を維持したいと思っています。私たちは親切です!
仕様にはいくつかの拡張メカニズムがあります。これらを利用するか、必要に応じて新しいものを導入してください。
未知の奇数のピア間メッセージは無視されます。つまり、「奇数であることは大丈夫!」ということです。私を知るにつれて、これがより意味を持つようになります。
メッセージが拡張であり、相手がそれをサポートしているかどうかを知る必要がない場合は、奇数を与えるべきです。相手がそれをサポートしていないと壊れる場合(つまり、絶対に起こってはいけない場合)は、偶数を与えてください。ミスは起こりますし、将来のソフトウェアのバージョンは古いバージョンに対してテストされないかもしれません。
新しいメッセージタイプを内部で試したい場合は、32768以上を使用することをお勧めします(偶数を使用し、これらが誤って外部に漏れた場合に壊れるようにします)。
フィーチャービットは、メッセージを送信することが合法であるかどうかを知る方法であり(上記参照)、適切なピアを見つけるためにも使用できます。
フィーチャービットは常にペアで割り当てられます。たとえそれが必須であることが意味をなさない場合でもです。フィーチャービットはPRのタイトルで自己割り当てされ、他の人が自己割り当てしやすくします。PRが仕様にマージされるまで、実験的な実装は提案されたフィーチャービット+100を使用するべきです。マージされたら(プロトコルが変更されない場合)、両方のフィーチャービットを受け入れることができます。
ほとんどの仕様変更には関連するフィーチャービットがあるべきです。過去にはフィーチャービットをグループ化していましたが、実装が壊れたときに単一のフィーチャーを無効にすることができませんでした。
通常、機能ビットは最初に導入されるときは奇数であり、その後、導入がほぼ普遍的になると偶数になることがあります。これにより、レガシーコードを削除できることが多くなります。なぜなら、その機能に対応できないピアと通信することがなくなるからです。
新しい機能ビットを内部で試したい場合は、100以上を使用することをお勧めします。
仕様では、メッセージ内の追加データは無視されるとされており、これも将来的に拡張する方法の一つです。BOLT 1.0では、オプションフィールドが追加され、その存在は機能ビットによって示されました。
現代的な方法は、メッセージの末尾に TLV を追加することです。これにはオプションフィールドが含まれます。再び、偶数は機能ビットがサポートを示す場合にのみ送信し、奇数は古いピアに送信しても問題ないことを意味します(これにより、実装が容易になることが多く、ピアは無条件にそれらを送信できます)。
仕様書はテキスト形式で読みやすく、HTMLに変換された後も読みやすく、[tools/extract-formats.py]によって消化可能であることが求められます。特に、フィールドは正しい型を使用し、可能な限りその構造を明示的に記述する必要があります(100*バイトフィールドは避けてください)。
必要であれば、奇妙なフォーマット変更が必要な場合は、そのツールを修正することができます。
このツールの出力は、いくつかの実装のコードを生成するために使用され、実装が仕様を広範に引用し、その引用が正しいことを自動テストすることも推奨されます。これは、c-lightningが行っているようにです。
新しいものが既存のものを置き換える場合は、既存のものをレガシーのサブセクションに移動することを確認してください。新しい読者は、すぐに最新バージョンにアクセスしたいと思うでしょう。古典的な Linux snprintf 1.27 マンページを模倣しないでください:
RETURN VALUE
If the output was truncated, the return value is -1, otherwise it is the
number of characters stored, not including the terminating null. (Thus
until glibc 2.0.6. Since glibc 2.1 these functions return the number
of characters (excluding the trailing null) which would have been writ‐
ten to the final string if enough space had been available.)
想像してみてください。最初の文だけを読んで、自分が探している答えがそこにあると仮定してしまう人の苦々しさを! 20年経ってもそのことを苦々しく覚えていて、それを引っ張り出して「こう書いてはいけない」という例として使う人がいるとしたら。それは悲しいことですね。
フォーマットの方法を知りたい場合は、詳細なスタイルガイドがあります。また、CIシステムでスペルチェッカーを実行しているので、[.aspell.en.pws]に行を追加する必要があるかもしれません。
要件には明白なものもあれば、微妙なものもあります。これらは実装者が書くべきコードを案内するように設計されているので、あなたが自分の実装を開発する際に書いてください。MUST
/SHOULD
/MAY
およびNOT
を使用してください。詳細はRFC 2119を参照してください。
要件は、実装と同様に、書き手と読み手に分けられます。書き手が何をしなければならないか、そして書き手がそれをしなかった場合に読み手が何をしなければならないかを正確に定義してください。開発者は、書き手の要件から読み手の要件を直感で理解する必要があってはなりません。
データには要件がないことに注意してください。「foo MUST be 0」と言うのではなく、「書き手はfooを0に設定しなければならない」と言い、「fooが0でない場合、読み手は接続を失敗させなければならない」と言ってください。
MUST check
という用語は避けてください。代わりに「接続を失敗させなければならない」や「チャネルを失敗させなければならない」または「エラーメッセージを送信しなければならない」を使用してください。
将来の拡張のための微妙な技術があります。例えば、「書き手はfooを0に設定しなければならない」と言って、読み手の要件には触れないかもしれませんが、「読み手はfooを無視しなければならない」と言う方が良いです。仕様の将来のバージョンでは、書き手がfoo
を1
に設定する場合が定義されるかもしれませんが、古い読み手がそれを無視することがわかっています。
MAY
は何かの目的を示すヒントです。仕様に書かれていないことは何でも実装が行うことができます。MUST
は、何かをしないとプロトコルやセキュリティが破壊される場合に使用します。
要件は曖昧であっても構いません(例:「適時に」)。しかし、それは最後の手段としての敗北の認識としてのみです。もしあなたが知らないのであれば、可哀想な実装者に何の希望があるでしょうか?
新しい低レベルプロトコルの構築には、テストベクトルが必要です。これらは伝統的に仕様書内の行として記載されていましたが、現代のトレンドは JSON と分離されたファイルを使用することです。これにより、実装が機械で読み取れることを意図しています。
新しいピア間メッセージについては、全体の会話をシミュレートするテストフレームワークが開発中です。
大規模な機能の議論には メーリングリスト があり、明確な問題やプルリクエストには GitHub リポジトリ が用意されています。また、Freenode の #lightning-dev で隔週で IRC ミーティングが行われており、現在はアデレード/オーストラリアのタイムゾーンで火曜日の午前 5:30 に開催されています(例:2019 年 7 月 23 日火曜日 05:30 == 7 月 22 日月曜日 20:00 UTC)。
スペルミス、タイプミス、フォーマットの変更は、2 人の貢献者が承認し、反対がなければ受け入れられます。それ以外の変更は IRC ミーティングで承認され、記録されます。プロトコルの変更には、2 つの独立した実装が成功裏に相互運用することが必要です。仕様の変更は後で修正が難しいため、合意に時間がかかることがありますので、忍耐強くお待ちください。
さらに、広範な方向性が確立される招待制の対面サミットが時折開催されます。これらは素晴らしい機会であり、ぜひ一度参加してみてください。
私たちはあなたが参加してくれることを楽しみにしています! 親愛なる Lightning 開発者一同。