Develop with pleasure!

福岡でCloudとかBlockchainとか。

Stratum protocol extensionsについて定義したBIP-310

Stratumはプールマイニングをサポートするマイニングプロトコルだが、その拡張の利用については長らく正式な規格を記述するBIPが無かったが、それをBIPとして定義したのがBIP-310↓

github.com

基本的には、Stratumサーバーとマイニングソフトウェアが接続された直後に、mining.configureメッセージを送信してサーバ/クライアント間でサポートしている拡張について認識し、利用する拡張について調整する仕組み。

BIP-310で定義されている拡張は以下の4つ。

  • version-rolling
  • minimum-difficulty
  • subscribe-extranonce
  • info

1つめのバージョンローリングは、こないだ書いたBIP-320の利用を前提としている(まぁ前提というか実際はもうそういう使い方されてる)。

techmedia-think.hatenablog.com

以下BIPに定義されているプロトコルの詳細↓

動機

Stratumプロトコルの拡張のサポートを指定する最初の動機は、マイナーにBitcoinのブロックヘッダの最初のフィールドの値を変更する「バージョンローリング」と呼ばれるものを許可することだった。

オリジナルのStratumプロトコルのバージョンではサーバーに異なるブロックバージョンの値を伝えることができなかったため、バージョンローリングはStratumプロトコル後方互換性がない。同様に、サーバーは安全なbitを使ってマイナーにローリングすることができなかった。したがってマイナーとプールの両方は、バージョンローリングをサポートするためにいつくかのプロトコル拡張を実装する必要がある。

通常、マイナーが未知のメッセージをサーバーに送信すると、サーバーは接続を閉じる(全てのサーバーが閉じるわけではないが、いくつかのサーバー実装ではそうなっている。)。そのため未知のメッセージをサーバーに送信することは安全ではない。

我々はこの機会を利用して、将来複数の拡張をサポートするためにプロトコルに対して後方互換性のない変更を行うことができる。マイナーがその能力を広告すると同時にサーバからいくつかの必要な機能を要求することができる。

機能のネゴシエーションのため同じ仕組みがまだ知られていない機能に対しても使用されることが望ましい。マイニングソフトウェアにも簡単に実装されるべきだ。

標準的な方法で機能の初期設定/ネゴシエーションを処理するstratumプロトコル(mining.configure)への新しいメッセージを1つ導入する。これにより将来、stratumプロトコルに新しいメッセージを追加することなく機能を追加することができる。

各拡張にはextension codeと呼ばれる一意の文字列名がある。

仕様

現在、以下の拡張が定義されている。

  • version-rolling
  • minimum-difficulty
  • subscribe-extranonce

追加のデータタイプ

以下の名称はタイプエイリアスとして使われ、メッセージの定義を簡単にする。

  • TMask
    32bitの符号なし整数([0-9a-fA-F]{8})をエンコードする長さ8の大文字小文字を区別しない16進文字列
  • TExtensionCode
    プロトコル拡張の名前と同じ値の空でない文字列
  • TExtensionResult
    true / false / String
    • true 要求された機能がサポートされ、その設定が理解でき適用される。
    • false この機能はサポートしていないか未知のもの
    • String 何がうまく行かなかったかに関する情報を含む文字列

mining.configure リクエス

このメッセージ(JSON RPCリクエスト)は、サーバーとの接続が確立された後にマイナーが送信する最初のメッセージである必要がある。クライアントはこのメッセージを使って自身がサポートする機能を宣伝し、いくつかのプロトコル拡張を要求/許可する。

最初の理由は、実装と可能な限りやりとりを簡単、シンプルにしたいからだ。拡張は、拡張の繰り返し設定が何を意味するか明示的に定義することができる。

各拡張コードは、その拡張パラメータや拡張の戻り値に対してネームスペースを提供する。慣例により、名称は拡張コードに”.”とパラメータ名を追加することで形成される。同様のことが戻り値にも適用され、result mapにも転送される。例えば「version-rolling.mask」は拡張「version-rolling」の「mask」というパラメータ名だ。

パラメータ
  • extensions(必須。TExtensionCodeのリスト)
    • リスト内の各文字列は有効な拡張コードでなければならない。各コードの意味は、拡張定義の一部として独立して記述される。マイナーは利用可能な全ての機能を広告しなければならない。
  • extension-parameters(必須。String -> 任意のデータのMap)
    • 最初のパラメータから要求/許可された拡張のパラメータ
戻り値
  • String -> 任意のデータのMap
    • 拡張リストの各コードは、定義された戻り値(TExtensionCode -> TExtensionResult)を持たなければならない。こうすることでマイナーは拡張が有効になっているかどうか確認することができる。例えばバージョンローリングをサポートしていない場合は{"version-rolling":false}
    • いくつかの拡張では、追加情報をマイナーに提供する必要がある。戻り値のMapはこのために使われる。

リクエストの例

{"method": "mining.configure",
  "id": 1,
  "params": [["minimum-difficulty", "version-rolling"],
         {"minimum-difficulty.value": 2048,
          "version-rolling.mask": "1fffe000", "version-rolling.min-bit-count": 2}]}

(マイナーは「version-rolling」と「minimum-difficulty」という拡張を要求する。この際、拡張の定義に従ってパラメータをセットする)

結果の例

{"error": null,
  "id": 1,
  "result": {"version-rolling": true,
         "version-rolling.mask": "18000000",
         "minimum-difficulty": true}}

定義された拡張

拡張「version-rolling」

この拡張によりマイナーはブロックヘッダのバージョンフィールドの一部のbitの値を変更できます。現在バージョンローリングに使用される標準bitは存在しないため、マイナーとサーバー間で調整する必要がある。

マイナーはマイナーが変更可能なbitを記述マスクをサーバーに送信する。1 = 変更可能なbit、0 = 変更不可能なbit (miner_mask)とバージョンローリングに必要な最小bit数。

サーバーは通常、version bits(server_mask)の一部のみを変更することができ、残りのversion bitsは固定されている。これは例えばブロックを有効なブロックにするためであったり、何らかのシグナリングに使われている場合があるためだ。

サーバーはコンフィギュレーションメッセージに応答し、マイナーのマスクとサーバーのマスクの共通bit交差を持つマスクを送信する(response = server_mask & miner_mask)。

リクエスト例(16bitのマスクから任意の2 bitを変更できるマイナー)

{"method": "mining.configure", "id": 1, "params": [["version-rolling"], {"version-rolling.mask": "1fffe000", "version-rolling.min-bit-count": 2}]}

結果の例(成功の場合)

{"error": null, "id": 1, "result": {"version-rolling": true, "version-rolling.mask": "18000000"}}

結果の例(未知の拡張の場合)

{"error": null, "id": 1, "result": {"version-rolling": false}}
拡張パラメータ
  • version-rolling.mask (オプション、TMask、デフォルト値は"ffffffff"
    • 1をセットされたbitは、マイナーによって変更することができる。この値はマイニングセッション全体で安定していることが期待される。マイナーはマスクを送信する必要はなく、この場合デフォルトのフルマスクが使用される。
拡張の戻り値
  • version-rolling(必須、TExtensionResult)
    • trueの場合サーバーは新しいパラメータmining.submitを受け取る(後述)。
  • version-rolling.mask(必須、TMask)
    • 1をセットされたbitは、マイナーによって変更することができる。マイナーがマスク値0のbitを変更した場合、サーバーは送信を拒否する。
    • サーバーは可能な限り最大のマスクを返すべきだ(可能な限り多くのbitが1に設定された)。これはプロキシが将来のクライアントに最適なマスクを調整する必要がある場合に、マイニングプロキシの設定に役立つ。利用可能なnVersion bitsについて記述したドラフトがある。サーバーはBIPで指定されたすべてのbitをカバーするマスクを作成するべきだ。
  • version-rolling.min-bit-count(必須、TMask)
    • マイナーはまたハードウェアでの効率的なバージョンローリングに必要な最小bit数も提供する。このパラメータはプールサーバに重要な診断情報を提供することに注意すること。要求されたbit数がプールサーバーの制限を超えた場合、ハッシュパワーを完全に使用することがない、常に劣化モードで動作する可能性がある。この稀なミスマッチが発生した場合、マイナーとの接続を終了してはならない。
「mining.set_version_mask」の通知

サーバーは接続に有効な新しいマスクについてマイナーに通知する。このメッセージは、mining.configureメッセージによりバージョンローリングの拡張が正常にセットアップされた後、いつでも送信できる。新しいマスクはすぐに有効になり、サーバーは次のジョブを待機しない。

パラメータ
  • mask(必須、TMask)
    意味はversion-rolling.mask 戻りパラメータと同じ。

サンプル

{"params":["00003000"], "id":null, "method": "mining.set_version_mask"}
mining.submit 要求の変更

バージョンローリング拡張が正常にアクティベートされた直後に(サーバーによって送信されたmining.configureの結果)、サーバーはメッセージmining.submitの追加パラメータを受け取らなければならない。クライアントは追加のパラメータversion_bitsを1つ送らなければならない(worker_name, job_id, extranonce2, ntime, nonceに続く6つめのパラメータとして)。

追加のパラメータ
  • version_bits(必須、TMask)
    マイナーによってセットされるversion bits。
    • マイナーはmining.configureもしくはmining.set_version_mask通知(last_mask)の応答として、サーバーから最後に受信したマスクの設定bitに対応するbitのみを設定できる。このためversion_bits & ~last_mask == 0となる
    • サーバーは次のように送信するnVersionを計算する。nVersion = (job_version & ~last_mask) | (version_bits & last_mask)job_versionjob_idと共にジョブの一部としてマイナーに送信されたブロックバージョン。

拡張「minimum-difficulty」

この拡張により、マイナーは接続されたマシンに最小難易度の要求をすることができる。これにより、接続されたデバイスのハードリミットを伝える方法がないオリジナルのStratumプロトコルの問題を解決する。

拡張パラメータ
  • minimum-difficulty.value(必須、Integer/Float, >= 0)
    マイナー/接続に許容される最小難易度の値。機能を無効にするには0をセットする。
拡張戻り値
  • minimum-difficulty(必須、TExtensionResult)
    • 最小難易度が受け入れられたかどうか
    • この拡張はminimum-difficultyコードを持つmining.configureを再度呼び出して複数回設定することができる。

拡張「subscribe-extranonce」

パラメータの無い拡張。マイナーはmining.set_extranonceメッセージを受信することができることを広告する(ハッシュレートルーティングシナリオに役立つ)。

拡張「info」

マイナーはテキストベースの追加情報を提供する。

拡張パラメータ
  • info.connection-url(オプション、文字列)
    マイニングソフトウェアがstratumサーバに接続するために使用する正確なURL。
  • info.hw-version(オプション、文字列)
    製造元固有のハードウェアバージョン文字列
  • info.sw-version(オプション、文字列)
    製造元固有のソフトウェアバージョン文字列
  • info.hw-id(オプション、文字列)
    マイニングデバイスの一意の識別子

互換性

現在、さまざまなプロトコル拡張を目的とした同様のプロトコル機能mining.capabilitiesが存在する。しかし、mining.configureは、全ての受け入れらた/調整中の拡張を確認するサーバーの応答を必要とするため、この機能と互換性がない。我々がこれを非互換にしたのは、mining.capabilitiesの要求には関連する応答がないためだ。