# オペレータノード
###### 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: 実行したコントラクトの関数の返り値