用語集 / ノードとソフトウェア
インベントリ
別名はInventoryです。
- インベントリとは?
- インベントリとは、ノードがピアに対して通知するオブジェクト識別子のリストであり、実際にはまだ何も送信せずに、自身が保持しているトランザクションとブロックを伝えるものです。
まず通知し、要求があれば届けます。この方式のおかげで、ネットワークが重複であふれ返ることはありません。各エントリのコストは36バイトで、4バイトのタイプタグと32バイトのハッシュからなり、1つのinvメッセージには最大50,000個まで含めることができます。オブジェクトをすでに保持しているピアは決して要求せず、帯域幅が消費されることもありません。
仕組み
インベントリのエントリは、2つの要素の組です。1つはこれが何の種類のものかを示す番号で、もう1つはそれを識別するハッシュです。
タイプコードは小さな整数です。1はトランザクション、2はブロック、3は旧来のブルームフィルター方式によるフィルタリング済みブロック、4はコンパクトブロック、5はウィットネスハッシュによって識別されるトランザクションです。タイプの上にビット0x40000000を立てるとウィットネス付きの変種であることを示すため、SegWitに対応したピアは、古いピアが通常のブロックを要求する場面でMSG_WITNESS_BLOCKを要求します。
やり取りは3つの手順で進みます。ノードが新しいものを列挙したinvを送信します。ピアはそのリストを走査し、認識できるものはすべて無視して、不足しているものだけを指定したgetdataで応答します。ノードはそれらのオブジェクトを1つにつき1つのメッセージで送信し、その間に破棄されたものについてはnotfoundを返します。50,000という上限の背景にある計算には注目する価値があります。50,000個のエントリは36バイトで1,800,000バイトとなり、単一メッセージの上限である4,000,000バイトに余裕をもって収まります。そしてBitcoin Coreには、これら2つの定数の整合性を保つコンパイル時のアサーションが含まれています。
タイミングは実装の詳細ではなく、プライバシーのための制御です。Bitcoin Coreはトランザクションを把握した瞬間には通知しません。通知はまとめられ、アウトバウンドのピアには平均2秒、インバウンドのピアには平均5秒のランダム化されたタイマーで送信されるため、多くのノードに接続した監視者が到着順から支払いの発生元を突き止めることはできません。ブロックはこの遅延を完全に省略します。隠すものがなく、秒単位の時間がコストになるからです。
すべてのハッシュをすべてのピアに叫ぶのは高コストであり、Erlayはその解決策として提唱されています。ピア同士は識別子を四方八方に氾濫させる代わりに、互いが保持しているものの短いスケッチを定期的に照合します。
どこで見られるか
インベントリはノードのネットワークインターフェース上で最もノイズの多いものであり、最も観察しやすいものです。
getpeerinfo呼び出しはトラフィックをメッセージタイプ別に分解し、invはほぼ常に最大のカウンターの1つに含まれます。接続の良いノードは、結局誰も必要としなかったハッシュの通知に、帯域幅の実に大きな割合を費やしています。ある支払いが一方のブロックエクスプローラーには他方より数秒早く表示されるのも同じ理由です。それらは別々の観察者であり、ネットワークの異なる部分から別々の通知を聞いているのです。
手放したほうがよい習慣が1つあります。invは約束ではありません。ノードはトランザクションを通知した後、mempoolが埋まると数分でそれを追い出すことがあり、誰に対しても訂正を負うことはありません。
インベントリvs mempool
インベントリはメッセージであり、mempoolは保管場所であり、その瞬間を超えて存続するのは両者のうち片方だけです。invはハッシュがどこかに存在することをピアに伝えます。mempoolは、ノードが実際に検証し、メモリ上に保持し、転送またはマイニングする用意のある未承認トランザクションの集合であり、デフォルトで300MBのサイズで、最も安価なものから先に追い出すポリシーを持っています。自分のtxidがinv通知を通じて伝播するのを観察すれば、ネットワークが自分の支払いを聞いたことは分かります。しかし、1時間後にまだ誰かがそれを保持しているかどうかまでは分かりません。