こんにちは。ALIS CTOの石井(@sot528)です。
ALISブロックチェーンブログ、今回はALISが実運用するプライベートチェーンについての第二回目の記事です。前回はミドルウェアとしてのEthereum PoAプライベートチェーンの有用性と、界隈の技術動向、私達の非中央集権への考え方、ALISのプライベートチェーン概要と3ヶ月運用した評価について書きました。
この記事は上記エントリが前提なので、よろしければご一読ください。
FYI: 2018年9月現在はEthereumプライベート・コンソーシアムチェーン構築の選択肢としてAzureやAWSが提供するサービスが利用可能です。GCPも2018年末にはEthereumをサポートするようです。プライベートチェーンの運用を検討されている方はこちらもチェックしてみると良いかもしれません。
ALISはMicrosoftと共同検証を実施中で、今後AzureのEthereum Proof-of-Authority Consortiumの評価や検証内容もこのブログに書く予定です。
目次:
・設計思想
・インフラストラクチャ概要
・JSON-RPCとVPC integration
・NLB, Multi AZ, EC2インスタンス
・Bastion
・etc
・備考
ALISのプライベートチェーンは堅牢性を最優先として以下の設計思想で作られています。
・開く必要のない箇所は閉じる
・必要な処理以外は実装しない
・可能な限りシンプルに
前回の記事で詳細を書きましたので割愛しますが、この設計思想の理由はあらゆる意味で堅牢なシステムが求められるからです。そうでなければ私達のプロダクトが頓挫するだけでなく、業界が社会の信用を失い界隈の発展が阻害されることに繋がります。堅牢なシステムが必要なのです。
ALISのインフラ全体について、以前エンジニアの冨樫(@keillera)が記事を書きました。
主にステートを持たないserverlessアーキテクチャで構成されACID特性の無いDynamoDBをDBMSとして利用するALISのシステムにおいて、プライベートチェーンの役割はミッションクリティカルな領域(=金銭が絡む部分)の責任を担うことです。上図の赤線部分がプライベートチェーンです。こちらをより詳細に見てみましょう。
多少、省略していますがMulti AZを意図した割とよくあるシンプルなEC2の構成です。
各パートごとに見てゆきましょう。
ALISのプライベートチェーンはAPI Gateway経由で利用しますが、IAM認証で外部に対して閉じておりALISサブシステムからのリクエストからしか受け付けません。本来ならParityノードをグローバルに公開してフロントエンドからWeb3.js経由で利用したいところですが、開く必要のない箇所は閉じるという設計思想で必要な箇所をのぞきVPCに閉じています。これにより、万一ParityのバグやOS・ミドルウェアレイヤーの脆弱性が存在しても堅牢性を維持できます。
batch処理を除くサブシステムからのプライベートチェーン利用には現状すべてJSON-RPCリクエストを用います。素直に考えるとAPI Gateway -> Lambda上のWeb3 -> プライベートチェーンの設計になるのですが、AWSが2017年11月に公開したAPI Gateway VPC integrationを利用することでLambdaの層を除却できます。これにより以下のメリットを享受できます。
システムにおいてシンプルさは重要です。システムはその複雑度が増すたび指数関数的にバグの混入確率が上がります。こと堅牢性が重要なシステムにおいては、真に必要な実装以外はすなわちリスクと捉えるべきです。Parityはその機能をほぼRPC経由で利用できるため、VPC Integrationを導入しAPI Gatewayから直にRPCリクエストを飛ばせます。これによりLambdaやその上のWeb3ライブラリが不要となり、構成がシンプルに保てます。
VPC内でLambdaを利用する場合、いくつか問題点があります。もっとも大きな問題はLambdaの初回の実行がかなり遅い点です。
参考: [AWS]LambdaからVPC内のリソースにアクセスした際のレイテンシーについて
UX観点でこのタイムラグは許容できません。この問題の解決には少々面倒な構成が必要であり、システムの複雑度も増します。VPC Integrationを利用することで、そもそもLambdaを利用しないことによりこの問題を回避できます。
ALISではVPC Integrationを導入し、プライベートチェーンへのリクエストをすべてJSON-RPCとしました。その実体はAPI GatewayのMessage Templateです(コードの該当箇所)。これによりLambdaでも相当に堅牢な実装がさらに明示的・限定的でよりConstantとなり、その帰結として堅牢性の向上に寄与します。
API GatewayをVPC LinkでNLBに統合し、RPCリクエストはEthereumのParity PoAプライベートチェーンが稼働するEC2の各インスタンスに分散されます。NLBは各インスタンスの死活監視も行います。
Parity PoAノードは2つのAZ(Availavility Zone)にそれぞれ2インスタンスごと稼働するいわゆるMulti AZのスタンダードな構成です。
Tips: ブロックチェーンのシステムを構築する場合はネットワークの構成にコンセンサスアルゴリズムの観点が必要です。つまり、もし51%のノードが悪意を持った場合に問題が発生するアルゴリズムであればそれを意識したネットワークの分散を指向すべきです。この観点は適切にネットワークが分散していれば一部が攻撃を受けた場合でも堅牢性を保てるという意味で、プライベートチェーンやコンソーシアムチェーンにおいても有効です
EC2ではParityがPoAで稼働しており、ブロックチェーンなので当然ですが全ノードが同期しています。NLB経由のRPCリクエストがトランザクションを発行する処理であれば、そのトランザクションは1ブロック/1秒で生成されるブロックに取り込まれ、ノード間で同期されます。EC2の構成管理はPackerとAnsibleで行っています。
※ParityとEC2の構成についてはは別途詳細な記事を書く予定です。
ここは特筆することの無い、いわゆる踏み台(Bastion)サーバです。コントラクトのデプロイ等のチェーンへの操作をここから実施します。しいて言えば一般的なAZごとにBastionを立てる構成ではない点が特徴です。チェーンに直接関わる箇所であり、宿命的に一定のステートを持つので意図的にシンプルな構成としました。SG(Security Group)により繋げるIPアドレスを厳密に(/32)制御し、パスに265bitのハッシュを設定した公開鍵暗号による認証が二重に必要とすることで堅牢性を担保しています。
・監視基盤はシステム全体を通してCloudWatchに集約しています(使いにくいですが...)。Parityノードを含む各EC2インスタンスにもCloudWatch Logs エージェントが導入されており不測の事態にはSlackにAlertが飛びます。
・プライベートチェーンにおいて各ALISユーザは一意のEOAを持ち、そのアドレスは各自のCognito User Poolに格納されています。
API GatewayのMessage Templateにそのアドレスやパラメータが渡されることでリクエストが完成します。
・ALISのシステムはコード化されたインフラを含め、ほぼ全てGitHubで公開しています。
この記事で言及しているプライベートチェーンのリポジトリはこちらです。
※この記事はβ0.21.0(7b10f41)を元に記載しました。
今回はALISのプライベートチェーンのインフラ部分について書きました。次回はEC2インスタンスの内部、Parityのチェーン設計や運用などについて書く予定です。
異論・反論・誤りの指摘・マサカリ大歓迎です。
・ALIS CTO 石井(@sot528)
・この記事は、運営による記事のためいいねによるトークン配布はありません
・この記事への投げ銭はBurnされます
・ALISではエンジニア・R&Dメンバー絶賛募集中です 😉