ビットコイン・インスティテュート

BIP 22 — getblocktemplateの​基礎

  BIP: 22
  Layer: API/RPC
  Title: getblocktemplate - Fundamentals
  Authors: Luke Dashjr <luke+bip22@dashjr.org>
  Status: Deployed
  Type: Specification
  Assigned: 2012-02-28
  License: BSD-2-Clause

概要

本BIPは、「賢い」ビットコインマイナーおよびプロキシ向けの新しいJSON-RPCメソッドを記述する。 ハッシュ計算用の単純なブロックヘッダーを送信する代わりに、ブロック構造全体が送信され、(任意で)カスタマイズおよび組み立てをマイナー側に委ねる。

著作権

本BIPはBSD 2-clauseライセンスの下でライセンスされる。

仕様

ブロックテンプレートリクエスト

「getblocktemplate」と呼ばれるJSON-RPCメソッドが定義される。 このメソッドはちょうど1個の引数を受け取り、それはリクエストパラメーターのオブジェクトでなければならない。 リクエストパラメーターに “mode” キーが含まれる場合、それは既定の “template” リクエストと「proposal」のいずれかを明示的に選択するために用いられる。

ブロックテンプレートの作成は、さまざまなパラメーターによって左右されうる。

template request

キー必須型説明
capabilitiesいいえ文字列の配列クライアントのサポートを示すため、以下の一覧を含むべきである: “longpoll”、“coinbasetxn”、“coinbasevalue”、“proposal”、“serverlist”、“workid”、およびmutationsのいずれか
modeいいえ文字列”template” または省略でなければならない

getblocktemplateは、以下のキーを含むJSONオブジェクトを返さなければならない。

template

キー必須型説明
bitsはい文字列圧縮された難易度(16進表記)
curtimeはい数値サーバーが認識する現在時刻(ブロック時刻として推奨される)。これは必ずしもシステムクロックではなく、mintime/maxtimeのルールの範囲内に収まらなければならない
heightはい数値求めているブロック高
previousblockhashはい文字列直前のブロックのハッシュ(ビッグエンディアン16進表記)
sigoplimitいいえ数値ブロック内で許容されるsigop数
sizelimitいいえ数値ブロック内で許容されるバイト数
transactions推奨オブジェクトの配列ビットコイントランザクションに関する情報を含むオブジェクト(コインベースを除く)
versionはい数値常に1または2(少なくともビットコインでは)。クライアントは使用するバージョンの含意を理解しなければならない(例えばバージョン2ではBIP 0034に準拠する)
coinbaseauxいいえオブジェクトコインベースのscriptSigの内容に含めるべきデータ。このオブジェクトのうち値(バイト単位で16進表記)のみを含めるべきであり、キーは含めない。これにはブロック高は含まれない。ブロック高はBIP 0034によりscriptSigへの含有が要求されている。値は “PUSH” オペコードの中にエンコードすることが望ましい。カウントに含まれるSIGOPを、実行されないにもかかわらず意図せず消費しないようにするためである
coinbasetxnこれか↓オブジェクトコインベーストランザクションに関する情報
coinbasevalueこれか↑数値コインベースに利用可能な総資金(サトシ単位)
workidいいえ文字列提供される場合、結果とともにこの値を返さなければならない(Block Submissionを参照)

transactionsオブジェクトの形式

レスポンスの “transactions” キーに列挙されるオブジェクトは、以下のキーを含む。

template “transactions” element

キー型説明
data文字列16進表記(バイト単位)でエンコードされたトランザクションデータ
depends数値の配列このトランザクションが最終ブロックに含まれる場合に、同じく含まれていなければならない、それより前のトランザクション(“transactions” 一覧中の1始まりのインデックスによる)。キーが存在しない場合、依存関係は不明であり、クライアントは依存関係がないと仮定してはならない
fee数値トランザクションの入力と出力の額の差(サトシ単位)。コインベーストランザクションの場合は、集められたブロック手数料の合計を表す負の数値となる(ブロック補助金は含まない)。キーが存在しない場合、手数料は不明であり、クライアントは手数料がないと仮定してはならない
hash文字列リトルエンディアン16進表記のハッシュ/ID
required真偽値提供されtrueである場合、このトランザクションは最終ブロックに含まれなければならない
sigops数値ブロック上限の算定に用いられるSigOpの総数。キーが存在しない場合、sigop数は不明であり、クライアントはないと仮定してはならない

“data” キーのみが必須であるが、サーバーは既知であれば他のキーも提供すべきである。

ブロックの提出

「submitblock」と呼ばれるJSON-RPCメソッドが定義され、これにより採掘済みのブロック(またはシェア)を提出する。 このメソッドは2個の引数を受け取る。 最初の引数は常に、提出するブロックデータを16進エンコードした文字列である。2番目の引数はパラメーターのオブジェクトであり、パラメーターが不要な場合は省略できる。

submitblock parameters (2nd argument)

キー型説明
workid文字列サーバーがworkidを提供していた場合、提出時に含めなければならない

このメソッドは、シェアが受理された場合にはnullを、シェアが却下された場合はその理由を簡潔に述べる文字列を、あるいはシェアが提出された各マージマイニングチェーンごとにキーを持つオブジェクトを、いずれか返さなければならない。

任意: ロングポーリング

template request

キー型説明
capabilities文字列の配列ロングポーリングをサポートするマイナーは、文字列 “longpoll” を含む一覧を提供すべきである
longpollid文字列期限切れを監視するジョブの “longpollid”。ロングポールリクエストに対してのみ必須かつ有効である

template

キー型説明
longpollid文字列ロングポールリクエストの識別子。サーバーがロングポーリングをサポートしない場合は省略しなければならない
longpolluri文字列提供される場合、ロングポールリクエストに用いる代替のURI
submitold真偽値ロングポールレスポンスにのみ関係する。このレスポンス以前に受け取った作業がなお有効である可能性があり(既定)、そのシェアを提出すべきかどうかを示す。falseの場合、マイナーはシェアキューを破棄したくなるかもしれない

サーバーがロングポーリングをサポートする場合、ブロックテンプレートに “longpollid” キーを含めなければならず、各イベントについて一意でなければならない。 任意の “longpollid” は1つの条件のみを確認すべきであり、再利用すべきではない。 例えば、新しいブロックについてのみロングポールのウェイクアップを行うサーバーは、直前のブロックハッシュを用いてもよい。 ただし、クライアントは “longpollid” に何らかの特定の意味があると仮定すべきではない。 サーバーは “longpolluri” キーを、相対または絶対のURIとして提供してよく、これは元の接続とは(ポート番号を含め)まったく異なるリソースを指定してもよい。 サーバーが “longpolluri” を提供した場合、クライアントはロングポールリクエストにそちらのURIのみを用いなければならない。

クライアントは、標準的なJSON-RPCリクエスト(HTTPトランスポートの場合はデータを伴うPOST)と同じ認証情報を用い、リクエスト中の “longpollid” パラメーターにサーバーから提供された値を設定して、ロングポールリクエストを開始してよい。

このリクエストは、サーバーが “longpollid” によって識別される現在のブロックデータを置き換えたいと考えるまで、処理も応答もされるべきではない。 クライアントは非常に長いリクエストタイムアウトでこのリクエストを行うべきであり、サーバーが(“chunked” Transfer-Encodingを伴うHTTPヘッダーなど)部分的なレスポンスをあらかじめ送り、最終的なJSONレスポンスの完了のみを遅延させる場合、それを受け入れなければならない。

完了したレスポンスを受信した際:

  • “submitold” が提供されかつfalseである場合に限り、クライアントは過去の操作の結果を破棄してよく、直ちに新しい作業に取りかからなければならない。
  • クライアントは、直ちにではないとしても、できるだけ早く受け取った新しい作業に取りかかるべきである。
  • クライアントは、同じロングポーリングURIに対して新しいリクエストを行うべきである。

クライアントが不完全または無効なレスポンスを受信した場合、指数バックオフを用いてリクエストを再試行すべきである。 クライアントはこのバックオフに(最大バックオフ時間などの)制限を設けてもよく、適切と判断する任意のアルゴリズムを用いてもよい。 ただし、複数回の失敗の後に遅延なく直ちに再試行することは禁止される。 「Forbidden」レスポンス(例えばHTTP 403)の場合、クライアントはユーザーの介入なしに再試行を試みるべきではない。

任意: テンプレートの調整

template request

キー型説明
sigoplimit数値または真偽値テンプレートに含めるsigopの最大数
sizelimit数値または真偽値ブロック全体に用いるバイト数の最大値
maxversion数値サポートするブロックバージョン番号の最大値

“sigoplimit” と “sizelimit” については、負の値とゼロはサーバーが定める上限からのオフセットとして扱われる。 真偽値が提供されtrueである場合は既定の上限が用いられ、falseの場合はサーバーに対し、返すテンプレートに一切の上限を用いないよう指示する。 サーバーはこれらの希望する上限を尊重すべきであるが、それは必須ではない。 クライアントは、返されたテンプレートが自身の要件を適切に満たしていることを確認すべきである。

付録: 却下理由の例

シェアが却下されうる理由には、以下を含むがこれに限られない。

share rejection reasons

理由説明
bad-cb-flagサーバーが、許可していない機能を示すフラグを検出した
bad-cb-lengthコインベースが長すぎた(ビットコインの上限は100バイト)
bad-cb-prefixサーバーはコインベースへの追記のみを許可しているが、それを超えて変更されていた
bad-diffbits”bits” が変更されていた
bad-prevblk直前のブロックが、サーバーが構築しようとしているものではない
bad-txnmrklrootブロックヘッダーのマークルルートがトランザクションのマークルツリーと一致しなかった
bad-txnsブロック内のトランザクションについて、サーバーが何らかの点で受け入れなかった
bad-versionバージョンが誤っていた
duplicateサーバーが既にこのブロックデータを処理済みである
high-hashブロックヘッダーが、指定されたターゲットより低い値へハッシュされなかった
rejected詳細のない一般的な却下
stale-prevblk直前のブロックが、もはやサーバーが構築しようとしているものではなくなった
stale-workこのブロックの元になった作業が、もはや受け入れられなくなった
time-invalid時刻が許容されるものでなかった
time-too-new時刻が未来に寄りすぎていた
time-too-old時刻が過去に寄りすぎていた
unknown-userブロックを提出したユーザーが認識されなかった
unknown-workテンプレートまたはworkidを識別できなかった

動機

bitcoindのJSON-RPCサーバーは、ビットコインを生産的にマイニングするために必要な作業を生成する負荷にもはや耐えられず、作業生成に特化した外部ソフトウェアが必要になっている。 同時に、新しい独立したノード実装も成熟しつつあり、いずれマイナーをサポートできるようになる。

フルノードと作業生成ソフトウェアの間の互換性を確保するには、ブロック構築の詳細を伝達するための共通の標準が必要である。

論拠

トランザクションを(txidの)ハッシュとして単純に扱わないのはなぜか。

  • サーバーがトランザクションデータベースにアクセスできない場合や、マイナーがネットワーク全体にブロードキャストされていないトランザクションを含めたい場合がある。
  • マイナーは完全なトランザクション検証を行わないことを選ぶ場合があり、手元のトランザクションデータベースにアクセスできない場合もある。

“workid” の目的は何か。

  • サーバーがすべてのmutationを許容する場合、それがどのジョブに基づくものかを識別するのが難しくなりうる。内容によって提出物を検証することも可能ではあるが、発行されたジョブと比較する方がはるかに容易である。マイナーにとってこれを記録しておくことは非常に容易である。したがって、“workid” を用いることは、より多くのmutationを可能にする非常に安価な解決策である。

トランザクションについて “sigops” を提供すべきなのはなぜか。

  • BIP 0016によるブロックsigopに関するルールの変更のため、トランザクション自体からsigopを数えることは不可能になっている(scriptCheck内のsigopもカウントに含めなければならない)。

リファレンス実装

  • Eloipool(サーバー) (https://gitorious.org/bitcoin/eloipool)
  • libblkmaker(クライアント) (http://gitorious.org/bitcoin/libblkmaker)
  • bitcoind(最小構成のサーバー) (https://github.com/bitcoin/bitcoin/pull/936/files)

関連項目

  • BIP 23: getblocktemplate - プールドマイニング