2014年4月にリリースされたBitcoin Core 0.9.0、ネットワークのプロトコルバージョン70002でサポートされたreject
メッセージのBIP↓
bips/bip-0061.mediawiki at master · bitcoin/bips · GitHub
リモートピアとメッセージを交換する際、意図する動作にならないケースにおいて、その原因が何なのかリモートピアに通知するためにreject
メッセージが追加された。
動機
ピアに対しなぜトランザクションやブロックが受け入れられなかったのか、フィードバックすることは異なる実装間の相互運用性を助けることになる。また、SPVクライアントにとっても、優先度や手数料が不十分でトランザクションがリジェクトされた際に、何が悪かったのか判断する助けになる。
仕様
この仕様のデータタイプは以下のWikiで記載されている通り。
Protocol documentation - Bitcoin Wiki
reject
このBIPで新しいメッセージタイプreject
を導入する。
このメッセージはversion
、tx
、block
メッセージのレスポンスとしてピアに送信される。
例えば、2つのピア間の通信で、なんらかの理由でリジェクトされたトランザクションのメッセージフローは以下のようになる。
--> inv <-- getdata --> tx <-- reject
P2Pのプロトコルバージョンが70002以降の実装では、このreject
メッセージをサポートする必要がる。
共通のペイロード
各reject
メッセージは、以下のフィールドで始まる。
(一部のメッセージは、メッセージ固有のデータが追加される。)
サイズ | 名称 | データタイプ | 内容 |
---|---|---|---|
可変 | response-to-msg | var-str | リジェクトの原因となったメッセージ |
1 | reject-code | uint8_t | 0x01から0x4fまでのリジェクトコード(後述) |
可変 | reason | var_string | デバッグのための人が認識できるリジェクトメッセージ |
reason
はデバッグのためのだけに用意されており、特に実装が異なる場合は異なる文字列が使用されることがある。この文字列は問題を診断するためにだけ使い、決してユーザに表示したりしないこと。
reject-code
には以下のカテゴリに分類される。(以下に記述するserver
はreject
メッセージを生成するピアで、client
はreject
メッセージを受信するピア)
範囲 | カテゴリ |
---|---|
0x01-0x0f | プロトコルのシンタックスエラー |
0x10-0x1f | プロトコルのセマンティックエラー |
0x40-0x4f | serverのポリシールール |
全メッセージタイプ共通のreject code
code | 定義 |
---|---|
0x01 | メッセージがデコード出来ませんでした |
reject version code
version
メッセージへのレスポンスとして、初期コネクションを確立する際に生成されるコード
code | 定義 |
---|---|
0x11 | clientでは廃止されサポートされていないバージョンです。 |
0x12 | 重複したversion メッセージを受け取りました。 |
reject tx payload, codes
トランザクションのリジェクトメッセージには、既存のメッセージに加え以下のTXIDが付与される。
サイズ | 名称 | データタイプ | 内容 |
---|---|---|---|
32 | hash | char[32] | リジェクトされたトランザクションのハッシュ |
以下のコードが使用される。
code | 定義 |
---|---|
0x10 | トランザクションが何らかの理由(無効な署名、出力のコインの量が入力のコインの量を超えているなど)で無効です。 |
0x12 | 入力は既に使用されています。 |
0x40 | (serverにとって)非標準なトランザクションなのでマイニング/リレーされません。 |
0x41 | 1つ以上の出力の量がdust の閾値以下です。 |
0x42 | マイニングやリレーをするのい充分なトランザクション手数料/優先度がありません。 |
payload, reject block
ブロックのリジェクトメッセージは、既存のメッセージに加え以下のブロックヘッダのハッシュが付与される。
サイズ | 名称 | データタイプ | 内容 |
---|---|---|---|
32 | hash | char[32] | リジェクトされたブロックヘッダのハッシュ |
以下のコードが使用される。
code | 定義 |
---|---|
0x10 | ブロックが何らかの理由(無効なProof-of-Work、無効な署名など)で無効です。 |
0x11 | サポートされなくなったブロックのバージョンです。 |
0x43 | コンパイルされたチェックポイントが異なるブロックチェーンのブロックです。 |
注意:serverのベストチェーンには含まれていないが、そのブロックが有効なブロックである場合は、rejectメッセージを作成してはいけない。
互換性
reject
メッセージを認識しない古いピアでは、reject
メッセージは無視されるるため、下位互換性がある。
実装上の注意事項
実装者は、攻撃者が有効なトランザクションやブロックに対しreject
メッセージを送信したり、ランダムにreject
メッセージを送信するような攻撃や、DoS攻撃が行われた際に何が起きるか考慮する必要がある。例えば、reject
メッセージを受信した際に全てそれをユーザーに通知するようにしていたら、攻撃者がユーザーへの嫌がらせをする攻撃が可能になる。また、全てのreject
メッセージをログに書き込むだけでも、ユーザーのディスクを溢れさせるような攻撃に繋がる。