Develop with pleasure!

福岡でCloudとかBlockchainとか。

提案中のソフトフォークをテストできるようにするBitcoin InquisitionのHeretical Deployment

Bitcoinに現在ソフトフォークによる導入が提案されている機能について、Bitcoinにデプロイする前に(testnetでの導入も何も決まっていない状態で)テストできる環境を提供しているのがBitcoin Inquisition

Bitcoin Inquisitionは、Bitcoin Coreをフォークしたノード実装で、デフォルトsignetで各提案の変更をデプロイしてテストできるようになっている。

Inquisitionで利用可能な機能は、getdeploymentinfo RPCで確認できる。Bitcoin Inquisition v29.1で実行した結果は↓

$ bitcoin-cli getdeploymentinfo
...
  "deployments": {
    ...
    "anyprevout": {
      "type": "heretical",
      "height": 106704,
      "active": true,
      "heretical": {
        "binana-id": "BIN-2016-0118-000",
        "start_time": 1625875200,
        "timeout": 1941408000,
        "period": 432,
        "status": "active",
        "since": 106704,
        "status_next": "active",
        "signal_abandon": "40007600",
        "signals": [
        ]
      }
    },
    "checktemplateverify": {
      "type": "heretical",
      "height": 106704,
      "active": true,
      "heretical": {
        "binana-id": "BIN-2016-0119-000",
        "start_time": 1654041600,
        "timeout": 1969660800,
        "period": 432,
        "status": "active",
        "since": 106704,
        "status_next": "active",
        "signal_abandon": "40007700",
        "signals": [
        ]
      }
    },
    "op_cat": {
      "type": "heretical",
      "height": 193536,
      "active": true,
      "heretical": {
        "binana-id": "BIN-2024-0001-000",
        "start_time": 1704067200,
        "timeout": 2019686400,
        "period": 432,
        "status": "active",
        "since": 193536,
        "status_next": "active",
        "signal_abandon": "42000100",
        "signals": [
        ]
      }
    },
    "checksigfromstack": {
      "type": "heretical",
      "height": 272592,
      "active": true,
      "heretical": {
        "binana-id": "BIN-2024-0003-002",
        "start_time": 1704067200,
        "timeout": 2019686400,
        "period": 432,
        "status": "active",
        "since": 272592,
        "status_next": "active",
        "signal_abandon": "42000302",
        "signals": [
        ]
      }
    },
    "internalkey": {
      "type": "heretical",
      "height": 272592,
      "active": true,
      "heretical": {
        "binana-id": "BIN-2024-0004-000",
        "start_time": 1704067200,
        "timeout": 2019686400,
        "period": 432,
        "status": "active",
        "since": 272592,
        "status_next": "active",
        "signal_abandon": "42000400",
        "signals": [
        ]
      }
...

typehereticalになっているのがHeretical Deploymentによりデプロイされているソフトフォークの提案。各提案の詳細はBINANA(Bitcoin Inquisition Numbers And Names Authority)のリポジトリで確認できる。

Heretical Deploymentの仕組み

各機能は、ソフトフォークでInquisitionに導入されるため、新しい機能を使って作られたトランザクションやブロックは、Inquisition以外の通常のBitcoin Coreなどから見ても有効なものになる(新ルールを評価することはないけど)。そしてInquisitionノードを使っている場合は、Heretical Deploymentによってデプロイされた機能がアクティベートされると、そのルールに従ってトランザクションやブロックを検証するようになる。デフォルトsignetで新機能を試せるのはデフォルトsignetのマイナー(=署名者)*1がInquisitionを実行しているから。

ソフトフォークのデプロイ方法は、これまでのBIP-9などのデプロイとは少し異なる。まず、新しいソフトフォークをセットアップする際は、以下のパラメーターを設定する。

  • bip:割り当てられているBIP番号(BIP番号が割り当てられていない場合、BINANAで振られている番号)
  • bip_version:デプロイするこの提案のバージョン番号(用途については後述)
  • start_time:シグナリングが開始できるUNIX時間
  • timeout:タイムアウトにより自動的に無効化されるUNIX時間。通常start_timeから10年後を設定。

これらはsrc/binana以下のファイルに定義されている。CHECKTEMPLATEVERIFYの場合、以下のようになっている

{
    "binana": [2016, 119, 0],  // 年, BIP/BINANA番号, バージョン
    "deployment": "CHECKTEMPLATEVERIFY",
    "start": 1654041600,
    "timeout": 1969660800,
    "scriptverify": true,
    "scriptverify_discourage": true,
    "opcodes": {
        "CHECKTEMPLATEVERIFY": "0xb3"
    }
}

デプロイされた提案がとり得る状態は、

  • DEFINED:初期状態
  • STARTED:初期状態からMTP時刻がstart_timeを迎えると次の期間で遷移。この状態はシグナルを待ち受ける。
  • LOCKED_IN:シグナル(signal_activate)が観測されると、次の期間にソフトフォークがロックインされる。
  • ACTIVE:ロックイン後、次の期間でソフトフォークが有効になる。
  • DEACTIVATING:アクティブになっている状態で、放棄のシグナル(signal_abandon)が観測されると、その次の期間に遷移する状態。その後ABANDONEDに遷移する。
  • ABANDONED:ソフトフォークが放棄される終端状態。

mainnetの挙動と異なる点としては、

有効化するためのシグナルが、

signal_activate = 0x6000_0000 | (((int32_t)bip)<<8) | (bip_version & 0xFF)

無効化するためのシグナルが、

signal_abandon = 0x4000_0000 | (((int32_t)bip)<<8) | (bip_version & 0xFF)

として定義され、ブロックヘッダーのversionで上記のシグナルが観測されると、次の期間で状態遷移(STARTED -> LOCKED_INおよびACTIVE -> DEACTIVATING)する。signetの場合はPoAなので、BIP-9のような一定期間内の投票ではなく、1つのシグナルブロックだけで処理される。

DEACTIVATINGの仕組みやversionが定義されているのは、テスト中に見つかった課題や改善などでソフトフォークの仕様自体を変更する必要が出た場合に備えるため。その場合、現在デプロイされているソフトフォークについて、signal_abandonシグナルを送り無効化した上で、バージョンをインクリメントして更新した*2ソフトフォークを新たにデプロイする。

その他異なるのは、

  • 状態の更新は、mainnetではretarget period(2016ブロック=約2週間)毎に判定されるけど、Heretical Deploymentでは432ブロック(約3日)毎に判定される。
  • 新しい状態DEACTIVATINGABANDONEDの導入。
    • DEACTIVATING期間は、そのソフトフォークでロックされている資金を回収するための猶予期間。
  • timeoutについては、指定した時刻を迎えた場合、アクティベートされていても無効化(ABANDONEDに遷移)される。

*1:マイナーはKalle AlmとAJ Towns

*2:シグナルの衝突を避けるため