Substrate Validator に立候補、、、がうまくいかない

## 背景と目的

[Polkadot/Substrate Portal](https://polkadot.js.org/apps/#/staking) で Validator 権限を得ようと必要な操作を行ったが、Era が更新されても next up のリストから validators リストに移動することはなく、ノードを起動したコンソールに出力されるログをみてもブロックの生成が行われることはなかった。

Validator を chain spec の初期値から他のアドレスに変更できるように操作手順を整理する。必要があればソースコードの修正を行う。

## 前提

### Substrate バージョン

[github](https://github.com/bdevux/substrate)
[commit d90e092d0734c652f5720071ae0c4f85f2d9457a](https://github.com/bdevux/substrate/tree/d90e092d0734c652f5720071ae0c4f85f2d9457a)

```bash
$ substrate --version
substrate 1.0.0-d90e092d-x86_64-linux-gnu
```

### OS

Amazon Workspace を使用しているので、OS は Amazon Linux2

```bash
$ $ uname -srvmpio
Linux 4.14.106-97.85.amzn2.x86_64 #1 SMP Fri Mar 15 17:07:54 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
```

### Node

ローカル環境（Amazon Workspace)で2つのノードを起動
[Polkadot/Substrate Portal](https://polkadot.js.org/apps/#/staking) から Alice ノードに接続する

Node1: Alice

```bash
cargo run --release \-- \
  --base-path /tmp/alice \
  --chain=dev \
  --alice \
  --node-key 0000000000000000000000000000000000000000000000000000000000000001 \
  --telemetry-url ws://telemetry.polkadot.io:1024 \
  --validator \
```

Node2: Bob

```bash
cargo run --release \-- \
 --base-path /tmp/bob \
 --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN \
 --chain=dev \
 --bob \
 --port 30334 \
 --telemetry-url ws://telemetry.polkadot.io:1024 \
 --validator
```

### Accounts

[Polkadot/Substrate Portal](https://polkadot.js.org/apps/#/staking) の画面で Account を追加

Alice, Bob はすでに追加されている。
初期 Balance が設定されているアカウントを設定したいので下記のようにした。
session は Node 起動時に指定したものにする

1. STASH ALICE
  1.1. create from the following mnemonic seed, raw seed >> //Alice
  1.2. keypair crypto type >> Schnorrkel(sr25519)
  1.3. secret derivation path >> //stash
2. SESSION ALICE
  2.1. create from the following mnemonic seed, raw seed >> //Alice
  2.2. keypair crypto type >> Edwards(ed25519)
3. STASH BOB
  3.1. create from the following mnemonic seed, raw seed >> //Bob
  3.2. keypair crypto type >> Schnorrkel(sr25519)
  3.3. secret derivation path >> //stash
4. SESSION BOB
  4.1. create from the following mnemonic seed, raw seed >> //Bob
  4.2. keypair crypto type >> Edwards(ed25519)

### Staking

Alice は最初から Validator になっている

BOB
1. STASH BOB >> Bond Funds
  1.1 controller account >> BOB
  1.2 value bonded >> ほぼ持っている全額（手数料が払えるように少し少な目）
  1.3 payment destination >> Stash account(increase the amount of stake)
2. BOB >> set session
  2.1 SESSION BOB
3. BOB >> validate

BOB のボタンが赤くなり Validating となる。

Staking overview タブでは validators に STASH ALICE、next up に STASH BOB がリストにある状態となる。

画面右上の session, era の値がインクリメントされ、era が 0 になると STASH BOB が validators に移動するのが期待する挙動だが、変わらないままだった。
画面左上の validators の数字は 1/3 となっているので席には余裕がある。


## 原因の想定

1. 操作手順
  とくに難しい手順ではなく、Controller, Stash, Session を間違えなければ問題無し
2. ソースコード
  Substrate に実装されていないのでは？ Emberic Elm では動いているので実装されている
3. chain
  ノード起動時に --chain=dev を指定したからだろうか？ 
  Chain spec を作るためのものなので、chain_spec.rs を見ることにする
4. アカウント
  Alice, Bob だからなのか？ わざわざデフォルトアカウントだからとかいう分岐処理を書くだろうか
5. Bond Funds
  設定する金額に最低金額が設定されているとか？ 初期資産が1.048M Unit で、全額使っているが、、、、この学でも少ないのかもしれない。

あやしいのは 3, 5 くらいだろうか、4 も一応確認してみる。
本番リリースではデフォルトアカウントをつかいたくないので、目的からはとおくなるが 4 から調べてみる。

## 試行錯誤してみる（1）

一番簡単な 5 の金額については後で、、、、まずはアカウントをデフォルト以外のものにする。

### NODE1 起動 Alice

最初のノードは chain spec で定義されているものを使う必要がある。それ以外のものをつかうとブロックが生成されない。ブロックが生成されないというのは、トランザクションを送る操作はなにも実行されないということなので validator になる以前に、controller の設定もできない。

```bash
cargo run --release \-- \
  --base-path /tmp/alice \
  --chain=dev \
  --alice \
  --node-key 0000000000000000000000000000000000000000000000000000000000000001 \
  --telemetry-url ws://telemetry.polkadot.io:1024 \
  --port=31333 \
  --validator
```
### アカウント作成

Controller, Stash, Session の3つのアカウントを作成する
Session は ed25519 で作る必要がある。これは ノードプラグラムの仕様

1. Controller MTDK1
  1.1. create from the following mnemonic seed, raw seed >> //MTDK1
  1.2. keypair crypto type >> Schnorrkel(sr25519)
  1.3. >> 5FUMxg1uSC7yerqEKnrwrfVWhf9HhUAQE6kh1WBWDZoUgy9q
1. Stash MTDK1
  1.1. create from the following mnemonic seed, raw seed >> //MTDK1
  1.2. keypair crypto type >> Schnorrkel(sr25519)
  1.3. secret derivation path >> //stash
  1.4. >> 5E4MiUD98EB9cz4PsYL8oa5StSYTNM19DZhHDeE8azCAgS4q
2. SESSION MTDK1
  2.1. create from the following mnemonic seed, raw seed >> //MTDK1
  2.2. keypair crypto type >> Edwards(ed25519)
  2.3. >> 5E6RGG1RH3vLSE6CemnD1MBxrCtcero4FX4k5KeRAwLXzQ4R

### 送金 transfer

作成したアカウントは資産をもっていないので、他のアカウントから送金する。
資産がないと bond, set session, validate などなにもできない

Eve から Controller MTDK1 へ 1M
Dave から Stash MTDK1 へ 1M
Session は資産を持つ必要がないので何もしない

### Validator に 立候補

Stash MTDK1 >> Bond Funds >> Controller MTDK1 >> 0.8M
Controller MTDK1 >> Set Session Key >> Session MTDK1
Controller MTDK1 >> Validate

Controller MTDK1 のボタンが赤くなり Stop Validating となる。
Staking Overview で next up に表示される

この段階で MTDK1 ノードを起動しておくべきだが、軌道せずに Era が新しくなるのを待つ。
--->>>> Era が 0 になったが validators リストに追加されることはなかった。

NODE MTDK1 起動

```bash
cargo run --release \-- \
 --base-path /tmp/bob \
 --bootnodes /ip4/127.0.0.1/tcp/31333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN \
 --name=MTDK1 \
 --key=//MTDK1 \
 --chain=dev \
 --port 31334 \
 --telemetry-url ws://telemetry.polkadot.io:1024 \
 --validator
```

Local node address is: /ip4/0.0.0.0/tcp/31334/p2p/QmQsrjxCGTsD8XRLyA1iRqXq6xqqKyoG4ntM9FnFj1PgAh

Web 画面 >> Explore >> Node info
authority	QmQsrjxCGTsD8XRLyA1iRqXq6xqqKyoG4ntM9FnFj1PgAh	610	0x79a274e3d593af926cb0a36d110da5ffdbdcd4c9bd2e77d26b42972a33156749

--->>> Alice ノードが接続している Peer に MTDK1 ノードがある

Roles: AUTHORITY
--->>> ブロック生成する

Using authority key 5E6RGG1RH3vLSE6CemnD1MBxrCtcero4FX4k5KeRAwLXzQ4R
--->>> 作成した Session MTDK1 と同じアドレスになっている

--->>>> Era が 0 になったが validators リストに追加されることはなかった。
Controller MTDK1 >> Stop Validating
Controller MTDK1 >> Validate
--->>>> Era が 0 になったが validators リストに追加されることはなかった。


## 試行錯誤してみる（2）

Alice node もアカウントを変更してみる。

Alice は chain spec に書かれているのでソースコードを書き換えるか json ファイルを作成する。
ソースコードの修正は今回はおこなわずに json を修正する

dev の chain spec を json ファイルに出力する

```
cargo run --release \-- \
  build-spec \
  --chain=dev > dev.json
```

Alice

```bash
$ subkey inspect //Alice
Secret Key URI `//Alice` is account:
  Public key (hex): 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
  Address (SS58): 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY

$ subkey inspect //Alice//stash
Secret Key URI `//Alice//stash` is account:
  Public key (hex): 0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f
  Address (SS58): 5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY

$ subkey -e inspect //Alice
Secret Key URI `//Alice` is account:
  Seed: 0xabf8e5bdbe30c65656c0a3cbd181ff8a56294a69dfedd27982aace4a76909115
  Public key (hex): 0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee
  Address (SS58): 5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TTpu
```

置き換えるアドレス

```bash
$ subkey inspect //Aletta
Secret Key URI `//Aletta` is account:
  Public key (hex): 0xa652fc7a3fbde2158c6d4a381a1b9e1c2c640c59c4d61daa643aeda6300c584f
  Address (SS58): 5FpnTXFLrDx81cPeRwTnGToTtDdTgfs6ekTGuPR9TUZtV9VX

$ subkey inspect //Aletta//stash
Secret Key URI `//Aletta//stash` is account:
  Public key (hex): 0xe89e04724e90b41dab3787ce1ab03e7dd7e3bc2405b79eea8fdae73674f9d463
  Address (SS58): 5HKhuafVLTmGv2DwBz2iWvdAckfk2RFypftRYY4gTchTksXH

$ subkey -e inspect //Aletta
Secret Key URI `//Aletta` is account:
  Seed: 0x770c20c2137238c5b07801520b0f6ba55e2168d1429e56f0bf86cb98c03008d1
  Public key (hex): 0x86ee56c970b191e73e85272fef63f5a295b6a6e8b6d6978325dfac354675fa19
  Address (SS58): 5F7d5KBLwtEoGQQyrZh4N29RrwTEyozWoEeXJ89ZkVeM4YTR
```

dev.json を修正（置換）

Controller
5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
--> 5FpnTXFLrDx81cPeRwTnGToTtDdTgfs6ekTGuPR9TUZtV9VX

Stash
5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY
--> 5HKhuafVLTmGv2DwBz2iWvdAckfk2RFypftRYY4gTchTksXH

Session
5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TTpu
--> 5F7d5KBLwtEoGQQyrZh4N29RrwTEyozWoEeXJ89ZkVeM4YTR

```bash
cargo run --release \-- purge-chain --chain=dev --base-path /tmp/alice
```

```bash
cargo run --release \-- \
  --base-path /tmp/alice \
  --chain=./dev.json \
  --key=//Aletta \
  --name=Aletta \
  --node-key 0000000000000000000000000000000000000000000000000000000000000021 \
  --telemetry-url ws://telemetry.polkadot.io:1024 \
  --port=31333 \
  --validator
```
Node name: Aletta
Roles: AUTHORITY
Using authority key 5F7d5KBLwtEoGQQyrZh4N29RrwTEyozWoEeXJ89ZkVeM4YTR

期待どおりの表示

バリデータへの立候補までは先述のとおり


Node MTDK1 起動

```bash
cargo run --release \-- purge-chain --chain=dev --base-path /tmp/bob
```

```bash
cargo run --release \-- \
 --base-path /tmp/bob \
 --bootnodes /ip4/127.0.0.1/tcp/31333/p2p/QmRx1jhvKeXKpKkraUxxQp4r4vPdajqbbHPJSFyTA97R8P \
 --name=MTDK1 \
 --key=//MTDK1 \
 --chain=./dev.json \
 --port 31334 \
 --telemetry-url ws://telemetry.polkadot.io:1024 \
 --validator

```

--->>> Era が 0 になっても変化なし

raw フラグをつけて spec json を出力


```bash
cargo run --release \-- \
  build-spec \
  --chain=./dev.json --raw > dev_raw.json
```

```bash
cargo run --release \-- \
  --base-path /tmp/alice \
  --chain=./dev_raw.json \
  --key=//Aletta \
  --name=Aletta \
  --node-key 0000000000000000000000000000000000000000000000000000000000000021 \
  --telemetry-url ws://telemetry.polkadot.io:1024 \
  --port=31333 \
  --validator
```

```bash
cargo run --release \-- \
 --base-path /tmp/bob \
 --bootnodes /ip4/127.0.0.1/tcp/31333/p2p/QmRx1jhvKeXKpKkraUxxQp4r4vPdajqbbHPJSFyTA97R8P \
 --name=MTDK1 \
 --key=//MTDK1 \
 --chain=./dev_raw.json \
 --port 31334 \
 --telemetry-url ws://telemetry.polkadot.io:1024 \
 --validator

```
```bash
cargo run --release \-- \
 --base-path /tmp/dave \
 --bootnodes /ip4/127.0.0.1/tcp/31333/p2p/QmRx1jhvKeXKpKkraUxxQp4r4vPdajqbbHPJSFyTA97R8P \
 --dave \
 --chain=./dev_raw.json \
 --port 31335 \
 --telemetry-url ws://telemetry.polkadot.io:1024 \
 --validator

```

とくに変化なし

## 試行錯誤（3）

これが一番簡単だから最初にやっておけばいいことなんだけれど、、、
公式ページのどこかにも書かれていた記憶もあるので、これだろうけど、、、
これを先にやってしまうと書くことが無くなるので後回しにしました。

chain=dev ではアカウントが持つ初期資産は 1.048M Uniti です。
これでなんとかなるんだと思ってましたが、、、、もしかしたら額が少ないからかも？

というわけで balance.setBlance で資産残高を増やします
増やすべき額がわからないので 1T Unit 増やしました。

Ectrinsics > democracy.propose > balance.setBalance 

Democracy 画面で Aye を押してしばらく待てば指定したアカウントの資産が増えます。

Adding Funds 
Staking Overview 画面で Era が更新されるのを待つ

はい！ Validator が交代しました。
あれ？交代？ Aletta が next up に移動しました。
Validator は 3 になっているので、交代することはないはずです。
Bond Funds の額でしょうか？ 1.048M では少ないのかもしれませんね
これはコードをみればわかるかもしれません。


## 結論

Bond Funds が多ければ Validator になれる（かもしれない）