読者です 読者をやめる 読者になる 読者になる

Develop with pleasure!

福岡でCloudとかBlockchainとか。

メッセージが拒否された理由を明確にするBIP-061

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を導入する。
このメッセージはversiontxblockメッセージのレスポンスとしてピアに送信される。

例えば、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には以下のカテゴリに分類される。(以下に記述するserverrejectメッセージを生成するピアで、clientrejectメッセージを受信するピア)

範囲 カテゴリ
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メッセージをログに書き込むだけでも、ユーザーのディスクを溢れさせるような攻撃に繋がる。