# オペレータノード ###### tags: `Yellow paper` `オペレータノード` # 概要 SRUネットワークで動作するオペレータの処理を記載する。 ## Transactionを受け取る オペレータは、ユーザからのSignedTransactionZKPとTxPayloadを受け取る。Transactionの検証後に、Transaction Poolに保存する。 **フロー** 1. オペレータは、Transactionを実行したいユーザからSignedTransactionZKPとTxPayloadを受け取る。 2. オペレータは、受け取ったTransactionの有効性を検証する。 3. オペレータは、Transactionの有効性の検証後にTxPayloadからPending状態のTransactionを作成し、Transaction Poolに保存する。 4. Transaction Poolに保存されたPending状態のTransactionは、オフチェーンコミット時にオペレータに取り出される。 **ユーザが送信したTransactionが不正な場合** ユーザにerrorオブジェクトを返却する。 **SignedTransactionZKPのインターフェイス** > TODO: 他YP参考 ## POST `sru_sendTransaction` 応答時間 100ms ### Example ```bash curl -X POST --data '{"jsonrpc":"1.0","method":"sru_sendTransaction","params":[{see above}],"id":1}' // Result { "id":1, "jsonrpc": "1.0", "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" } ``` **TxPayloadインターフェイス** | Field | Type | Value | | --------------- | --- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | to | address | 実行したいコントラクトアドレスを指定する | | Data | bytes | コントラクトアドレスに呼び出し関数とその引数の情報 | | nonce | uint | メッセージの再送を防ぐための Nonce, トランザクションを実行するたび各ユーザごとに increment する | | from | address | 秘密鍵とnonceから一意に生成されるワンタイムアドレス | | userStateValue | uint256 | [contract address + contract 内で宣言された index] => value となるような [bytes32] | | zkProof | bytes | そのコントラクトを実行するために必要な asset storage の value について、その資産の保有者の名前無しで asset の値が value 以上であることを証明する | **errorオブジェクトのインターフェイス** | Field | Type | Value | | ------- | --- | ------------------------------------------------ | | message | string | エラーメッセージ | | code | int | 発生したエラーに対応するエラーコード | | data | map | それぞれのエラーごとに任意のオブジェクトを入れる | **シーケンス図** ```mermaid sequenceDiagram actor U as User participant O as Operator autonumber U ->> O : sendSignedTransaction(signedTransactionZKP, txPayload) O ->> O : zkVerify(signedTransactionZKP, zkProof) O ->> O : saveToTransactionPool(transaction) O ->> U : Response: transactionHash ``` ## L1コミットするために複数のTransactionをまとめる(Rollup) オペレータは、複数のTransactionをまとめる(Rollupする)。 オペレータは、6時間ごとに前回rollupしたブロックに含まれる最後のブロックナンバーを渡しそれ以降に作成されたブロックのコミットデータを分散ストレージから取得する。 1. オペレータは、Transaction Poolから取得した全てのTransactionを検証する。 3. オペレータは、コミットデータから取得した全てのTransactionの有効性をZKによる検証によって行う。 4. オペレータは、検証後にTransactionをまとめてRollupする。 5. オペレータは、RollupしたTransactionを分散ストレージ上に送信し保存する。 6. 分散ストレージをポーリングしている外部の高い計算リソースを持ったサーバは、新しいRollupしたTransactionが分散ストレージに追加されると、それを取得する。 7. 外部の高い計算リソースを持ったサーバは、Rollupに取り込まれた全てのTransactionの有効性をZKによる検証によって行ったというProofを作成する。 8. 外部の高い計算リソースサーバは続けて、作成したProofと対応するRollup TransactionをL1ブロックチェーンのSRUスマートコントラクトに投げ、Transactionハッシュを受け取る。 9. 外部の高い計算リソースを持ったサーバは、投げたTransactionのstatusのconfirm処理を行う。 **Transactionが不正な場合** - どうする?除いて登録でいいのか。 ```mermaid sequenceDiagram participant O as Operator participant D as Distribute Storage participant P as Proof Server participant L as L1 Contract autonumber O ->> O : fetchCommits(prevBlockNumber) O ->> O : verify(transacitons) O ->> O : zkVerify(trasactions) O ->> O : rollup(transactions) O ->> D : saveRollupTransaction(rollupTransaction) D ->> O : Response: rollupTransaction P ->> D : fetchRollupTransaction() D ->> P : Response : rollupTransaction P ->> P : createProof(rollupTransaction) P ->> L : sendTrancaction(rollupTransaction, zkProof) L ->> P : Response: transctionHash P ->> L : confirmTransaction(transctionHash) ``` **RollupTrasactionのインターフェイス** | Field | Type | Value | | ------------ | --- | -------------------------------- | | transactions | bytes | 対応するTransactionとProofの配列 | # オペレータ間の通信 ``` たぶんDfinity使わないのでコメントアウト **Dfinity使う場合** オペレータは、Dfinity上に1つのみ構築される。このDfinityのオペレータの状態は、分散コンピューティングによって状態が正しく検証維持されている。オペレータは1台のみなので、オペレータ間の通信は特に必要ない。 ``` オペレータは、P2Pで繋がっているオペレータにデータを伝播させる。 1. オペレータは、最新の全てのStateおよび、分散ストレージ上に保存しているデータのCID(コンテンツ識別子)をローカルDBで管理している。 2. オペレータは、自分とP2Pで繋がっているオペレータをサブスクライブする 3. オペレータは、Peer間で同期が必要なデータを変更するイベントが発生するとデータをP2Pで繋がっている全てのオペレータにパブリッシュする。 4. データを受け取ったオペレータは、そのデータが自分が保持していない場合には、正しいデータであるかを確認し、問題なければ保存する。 5. データを受け取ったオペレータは、自分がP2Pで接続しているその他のPeerにも同様の動作を行う。 **送受信するデータ** - 分散ストレージ上に保存しているデータのCID - Transaction PoolのTransaction - 最新の全てのState **伝播方法** - 個別でデータを伝播するケースはないので、データをBroadcastする。 **シーケンス図** ```mermaid sequenceDiagram participant OA as OperatorA participant OB as OperatorB autonumber OB ->> OA : subscribe(event) OA ->> OA : saveState(state) or saveCid(cid) OA ->> OB : publish(data) OB ->> OB : check(data) OB ->> OB : saveState(state) or saveCid(cid) ``` # オペレーターノードの初期の同期 L2の最新のVerified Block高を他のオペレーターノードから取得し、そのBlock高のStateを分散ストレージから取得する。zkRollupではVerifyされたブロックは確定的でReorgが発生しないため、ブロック内のtxを実行することなくStateを同期することができる。Merkle Rootを正しく構成できるだけで、そのStateになることが確かに正しいと検証できる。 ## GET `/latest_verified_block` :::warning RESTじゃない気がする。 ::: 応答時間 100msec以内 ## リクエストパラメータ なし ## レスポンス | name | types | remarks | | -------- | -------- | -------- | | blockNumber | uint |verifyされた一番最新のブロック高| ```mermaid sequenceDiagram participant OA as OperatorA participant OB as OperatorB participant D as Distribute Storage autonumber OA ->> OB : getLatestVerifiedBlock() OA ->> D : getStorage(latestVerifiedBlockNumber) ``` # オフチェーンコミット オペレータは、SRUネットワーク上にブロックを作成する。 **フロー** 1. オペレータは、Transaction Pool上の複数のPending状態のTransactionからブロックに含めるTransactionを取得する。 2. オペレータは、取得した複数のTransactionに無効なTransactionがないかZKPを使わず検証する。 3. オペレータは、取得した複数のTransactionの有効性をZKによって証明する。 4. オペレータは、検証後に取得した複数のTransactionを同時に承認し複数のTransactionをまとめた(Rollupした)ブロックを作成する。 5. オペレータは、Trasaction Poolから今回取得したTransactionを削除する。 6. オペレータは、作成したブロックのコミットデータを分散ストレージに送信し保存する。またProofデータも同様に分散ストレージに送信し保存する。 7. 新規ブロック作成時に、assetの変更があった場合は、stateを更新しデータを分散ストレージに送信し保存する。 **Rollupブロック作成間隔** 1 ~ 2分 **Transaction PoolにPending状態のTransactionが存在しない場合** - オフチェーンコミットは、次回のインターバルまでスキップされる。 **不正なTransactionがあった場合** - 検証したTransactionに不正なTransactionがあった場合は、その不正なTranctionを除き処理を継続する。 **分散ストレージに送信時にエラーが起きた場合** - 3回リトライ処理を行い。もしリトライ時にも送信ができなかった場合は、ErrorStorageHandlerにデータを渡す。 **シーケンス図** ```mermaid sequenceDiagram participant O as Operator participant D as Distribute Storage autonumber O ->> O : fetchTransactionsFromTransactionPool(timestamp) O ->> O : verifyTransactions(trasactions) O ->> O : zkProveTransactions(trasactions) O ->> O : createBlock(trasactions) O ->> D : saveCommit(commit) O ->> D : saveProof(proof) D ->> O : saveOnetimeUserState(onetimeUserState) D ->> O : saveGlobalState(globalState) ``` # コントラクト実行時の返り値を返却する オペレータは、ユーザが実行したSRUネットワーク上にデプロイされたコントラクトの関数の返り値を返却する。 **フロー** - ユーザは、オペレータに実行したいコントラクトの関数を投げる。 - オペレータは、コントラクトの関数を実行する。 - オペレータは、取得した値をユーザに返却する。 ## POST `sru_call` ```bash // Request curl -X POST --data '{"jsonrpc":"1.0","method":"sru_call","params":[{see above}],"id":1}' // Result { "id":1, "jsonrpc": "1.0", "result": "0x" } ``` **Paramsインターフェイス** | Field | Type | Value | | --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | from | address | 呼び出す人のアドレス| | to | address | 実行したいコントラクトアドレスを指定する | | Data | bytes | コントラクトアドレスに呼び出し関数とその引数の情報 | **エラーが発生した場合** コントラクト関数の実行時にエラーが起きた場合は、errorオブジェクトを返却する。 **errorオブジェクトのインターフェイス** | Field | Type | Value | | ------- | --- | ------------------------------------------------ | | message | string | エラーメッセージ | | code | int | 発生したエラーに対応するエラーコード | | data | map | それぞれのエラーごとに任意のオブジェクトを入れる | **シーケンス図** ```mermaid sequenceDiagram actor U as User participant O as Operator autonumber U ->> O : callContractMethod(params) O ->> O : callContractMethod(params) O ->> U : Response: result ``` params: 実行したいコントラクトの関数に渡す引数 result: 実行したコントラクトの関数の返り値