2018.07.03

PoAのEmpty stepを試す


こんにちは、次世代システム研究室のN.O.です。

PoA(Proof of Authority)はEthereumのテストネットKovanで採用されているコンセンサスアルゴリズムです。もとからあるテストネットRopstenでは、アタックによってサービスが利用できなくなるという問題がありました。そこで安全で高速なテストネットの提供を目的に、PoAを採用したkovanテストネットが提案されました。PoAはブロックの作成元を限定することで安定したブロック生成ができ、高速なブロック生成ができることから、テストネットに限らず独自チェーンのメインネットとしても有力な選択肢となっています。

PoAではブロックを生成するvalidatorというアカウントがあり、validatorは1つのノードに紐付きます。そのため、ネットワークの冗長性を確保するにはvalidatorが紐付いたノードを複数動かす必要があります。このとき、複数のvalidatorが正しくブロックを生成できるようにするため、force sealingというオプションが用意されています。force sealingではトランザクションが無い場合も一定の時間間隔でブロックを生成します。そのため、トランザクションの無い空のブロックが生成されてしまうことになり、ストレージ容量の浪費に繋がってしまいます。
そこで、ストレージ容量を削減する機能としてparity-1.10Empty stepが実装されました。

Empty stepでは、トランザクションが発生しなかった場合、validatorはブロックを作成するのではなく、サインとともにEmptyStepというメッセージをブロードキャストします。EmptyStepメッセージは次に生成されるブロックに入ります。
これによって、今まで空のブロックを作っていたのがEmptyStepメッセージに置き換わりますので、ブロックチェーンのスリム化=ストレージ使用量の削減が期待できます。
早速試してみたいと思います。

chain-specはhttps://github.com/paritytech/parity/blob/master/ethcore/res/authority_round_empty_steps.jsonを参考に作成します。

関連する項目

  • emptyStepsTransition #Empty stepを有効にするブロックナンバー。最初から有効にする場合は1を設定する。
  • maximumEmptySteps #スキップする空のstepの最大値

設定例はこのような形になります。
    "name": "PoAEmptyStepChain", //nameは適当な名前でOKです
    "engine": {
        "authorityRound": {
            "params": {
                ...他のパラメータ...
                "emptyStepsTransition": "1",
                "maximumEmptySteps": "2"
                ...以下略...

Empty stepが無効のブロックと、有効にしたブロックを比較してみます。

Empty stepが無効のブロック
  {
    "author": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
    "difficulty": "0xfffffffffffffffffffffffffffffffe",
    "extraData": "0xd583010a078650617269747986312e32362e31826c69",
    "gasLimit": "0x5c8a71",
    "gasUsed": "0x0",
    "hash": "0xc51901300e22f20a57fb4fe42f10b7460d4574c838ee5c763ade09197bf4401d",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "miner": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
    "number": "0xb",
    "parentHash": "0xd4d99f2600f49e354f94a757d0275768f3725a97ddec60f09c1d7585d1cdcef5",
    "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
    "sealFields": [
      "0x841e674b00",
      "0xb841da17240d445baa1ff983e777baabf1af44ecb47629ff14786bd8f6a82c1baef342af3de5cb752abe22524e62c202e5efc64d7e50d610e4706de3fcbc617c068a00"
    ],
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "signature": "da17240d445baa1ff983e777baabf1af44ecb47629ff14786bd8f6a82c1baef342af3de5cb752abe22524e62c202e5efc64d7e50d610e4706de3fcbc617c068a00",
    "size": "0x240",
    "stateRoot": "0x1afb2c165aeb1d7b9b4b56cd495accf0cdf5a1d85b3b4a58225b3123f3a85fbc",
    "step": "510085888",
    "timestamp": "0x5b35e100",
    "totalDifficulty": "0xaffffffffffffffffffffffffe19ab4f5",
    "transactions": [],
    "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
    "uncles": []
  }

Empty stepが有効のブロック
"emptySteps"ヘッダが追加され、"sealFields"ヘッダが若干大きくなっているのが分かります。
  {
    "author": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
    "difficulty": "0xfffffffffffffffffffffffffffffffe",
    "emptySteps": "[(10eb…3c00, 510085578, 36ee…ce71),(48dd…4a00, 510085579, 36ee…ce71)]",
    "extraData": "0xd583010a078650617269747986312e32362e31826c69",
    "gasLimit": "0x5c8a71",
    "gasUsed": "0x0",
    "hash": "0x6591c3cd752aeee30f0f22ea76ed93cd2a7ad571e11fe6f33bc5b496752801f0",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "miner": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
    "number": "0xb",
    "parentHash": "0x36ee6dbd416b79f838d9687113bc6066d4835e18eaa16d8c83e16ae61f15ce71",
    "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
    "sealFields": [
      "0x841e6749cc",
      "0xb84198d912a20e5fee1e2ad2152fec2716140c1401b1240b3b726641e6174303c2100e188f5abf9fb8edb8f710e7819b3f204ea85b91e70a8d128a32d102c6dab48000",
      "0xf894f848b84110ebf6fd2116a06157765a1f932fdccc57293360d3e71c7a1c6a9913b7d1de4f61c2b1077beba3956eb7c99f525caeed3577ed0c9ef6cadd5be8cb5308463d3c00841e6749caf848b84148ddc50bca73af43c69a821babee0c366bc1b499511395e3102159f1aefe93d46a242d251f2596398620de2ea111b9b64a1e5e0312ad3f019dc74ff9a925434a00841e6749cb"
    ],
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "signature": "98d912a20e5fee1e2ad2152fec2716140c1401b1240b3b726641e6174303c2100e188f5abf9fb8edb8f710e7819b3f204ea85b91e70a8d128a32d102c6dab48000",
    "size": "0x2d6",
    "stateRoot": "0xd7364344c1f98bf3252bf31293401f30d46a1b4b750f9a6277868d8310571b71",
    "step": "510085580",
    "timestamp": "0x5b35dd64",
    "totalDifficulty": "0xaffffffffffffffffffffffffe19ab63f",
    "transactions": [],
    "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
    "uncles": []
  }


100ブロック作った時点でのサイズを比較します。ヘッダが追加された分、Empty stepのほうが10%程増加しています。
root@ubuntu-xenial:~# du -shc ./chains/PoAChain/db/
332K    ./chains/PoAChain/db/

root@ubuntu-xenial:~# du -shc ./chains/PoAEmptyStepChain/db/
360K    ./.parity/chains/PoAEmptyStepChain/db/

15分動かした時点でのサイズを比較します。Empty stepのほうが約50%程度ストレージ使用量を節約できているのが分かります。
root@ubuntu-xenial:~# du -shc ./chains/PoAChain/db/
664K    ./.parity/chains/PoAChain/db/

root@ubuntu-xenial:~# du -shc ./chains/PoAEmptyStepChain/db/
360K    ./.parity/chains/PoAEmptyStepChain/db/

このようにEmpty stepではヘッダの増加が確認できましたので、空のブロックがあまり発生しない、コンスタントにトランザクションが発生するようなネットワークでは逆効果になる可能性があります。ですが、トランザクション数がそこまで多くならないネットワークでは、ストレージの使用量を節約できることが確認できました。IoTデバイスなど、リソースの制約が厳しいデバイスでもフルノードを稼働させたい、といった場合には良い選択肢になるかと考えます。今回は基本的な確認しか行なっておらず、ノード障害時の挙動までは確認しておりませんので、本格的に採用を検討する際は十分な検証をお願いします。

次世代システム研究室では、アプリケーション開発や設計を行うアーキテクト、またはブロックチェーンのエンジニアを募集しています。次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。