Cosmos SDK製Proof of StakeのTendermintバリデータ変更の仕組み

はいみなさんこんにちは。

日本初(多分)の実用向けCosmosSDK製Tendermintチェーン

Cosmos SDKの知見共有第一弾です。

Cosmos SDKでつくるProof of StakeのTendermintバリデータ変更はどのように動くかコードベースでご紹介します。

Becoming a Validator
There are two ways to become validator.
They can be pre-established in the genesis state
The ABCI app responds to the EndBlock message with changes to the existing validator set.

https://github.com/tendermint/tendermint/wiki/Validators

バリデータを登録するには2つの方法があるようです。

1.genesis stateで設定する

genesis.jsonに記述してしまう方法です。

https://github.com/lcnem/lcnemint

lcnemintのリポジトリが参考になると思います。

2.EndBlockerで更新する

https://github.com/cosmos/cosmos-sdk

Cosmos SDKリポジトリ内にあるCosmos Hubノード「gaiad」のコードが参考になります。

func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
	tags := gov.EndBlocker(ctx, app.govKeeper)
	validatorUpdates, endBlockerTags := staking.EndBlocker(ctx, app.stakingKeeper)
	tags = append(tags, endBlockerTags...)

	return abci.ResponseEndBlock{
		ValidatorUpdates: validatorUpdates,
		Tags:             tags,
	}
}

validatorUpdatesという変数に、更新されたバリデータリストが代入されます。

代入する値は、staking.EndBlockerの返り値となるわけですが、ここのstakingはまさにProof of Stakeでのステーク量を管理している部分ですね。

このstakingはCosmos SDKのx/stakingに記述されています。

https://github.com/cosmos/cosmos-sdk/tree/develop/x/staking

つまり

  • ステーク量管理はCosmos SDKがやってくれる
  • ステーク量をもとにTendermintバリデータリストを返してくれるメソッド”staking.EndBlocker”もCosmos SDKが提供してくれる
  • TendermintはABCIを経由してバリデータセットを更新する窓口”abci.ResponceEndBlock”を提供してくれる

ということになります。

課題

lcnemintのようにコンソーシアムで動かしたい場合、stakingは必要ありません。しかしgenesis state時点でなく途中でバリデータを追加したいという状況に間違いなく直面します。

“stake”というシンボルのトークンをコンソーシアム参加者に配布してそれをステークさせるという手を使う必要がありそう。ステークの手続きなどによってはあまりスマートではないけど…