From 08e64bba830defaab32659aaeec3104e844e800f Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:17:56 +0900 Subject: [PATCH] add spec docs --- README.md | 65 +++++++++- specs/architecture.png | Bin 0 -> 105149 bytes specs/l1_bridge.md | 73 +++++++++++ specs/l2_bridge.md | 52 ++++++++ specs/l2_output_oracle.md | 32 +++++ specs/minitia.md | 237 ++++++++++++++++++++++++++++++++++++ specs/withdrawal_proving.md | 64 ++++++++++ 7 files changed, 519 insertions(+), 4 deletions(-) create mode 100644 specs/architecture.png create mode 100644 specs/l1_bridge.md create mode 100644 specs/l2_bridge.md create mode 100644 specs/l2_output_oracle.md create mode 100644 specs/minitia.md create mode 100644 specs/withdrawal_proving.md diff --git a/README.md b/README.md index 5f5b5d7b..46f956db 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,66 @@ # OPinit CosmosSDK Modules -This repository provides CosmosSDK modules for OPinit. Any app chain can use these modules to integrate OPinit. +Initia Layer 2 solution with Optimistic Rollup. -## How to Integrate +## Optimistic Rollup Architecture -### Host(L1) Chain +![architecture](./specs/architecture.png) -### Child(L2) Chain +### L1 Components + +#### [Bridge Module](./specs/l1_bridge.md) + +The bridge module triggers the deposit event for the bridge executor, which acts as a relayer between L1 and L2. It has two interfaces: `initialize_deposit` for users and `finalize_withdrawal` for the bridge executor. Both interfaces can be executed by anyone who wants to move the tokens between L1 and L2. + +A deposit does not require any proving or confirmation period, but a withdrawal requires [withdrawal proving](./specs/withdrawal_proving.md) and a finalized output root which contains the withdrawal transaction. + +#### BatchInbox Module + +The batch inbox is the data availability (DA) layer, which can be replaced by other solutions like `Celestia`. The rollup chain can be deterministically derived using the data from the DA layer. This ability to derive the entire rollup chain based on the DA layer is what makes Minitia a rollup. + +To reduce gas costs, the batch inbox only exposes an empty function interface that receives arbitrary bytes as an argument. This trick ensures that L2 data is not a part of the state but instead resides in tx db (= calldata). + +#### [L2OutputOracle Module](./specs/l2_output_oracle.md) + +The L2 output oracle is the component to store the L2 output root for block finalization. The users who withdraw the tokens from L2 to L1 also need to use this output root to prove the withdraw transaction is in the finalized L2 output root. + +The challenger always monitor the oracle output and do challenge when the output is different from the value computed from challenger side. + +### L2 Components + +#### BridgeExecutor + +The bridge executor is the core component in minitia rollup, which is charge of following operations via [L2 Bridge Module](./specs/l2_bridge.md): + +* Finalize L1 deposit transaction to L2. +* Construct withdraw tx storage Merkle Tree. +* Compute L2 output root. +* Provide the withdrawal proofs (Merkle Proofs) to users. + +#### [Minitia](./specs/minitia.md) + +The L2 app chain implementation provides rollup-specific interfaces for a bridge executor. The minitia is a minimized version of the initia app chain, so it does not include staking-related modules such as `staking`, `distribution`, `crisis`, and `evidence`. Instead, it has a new module called `rollup`, which provides a permissioned interface for adding and removing validators, as well as executing [bridge messages](./specs/l2_bridge.md) that can be executed by the bridge executor. + +#### BatchSubmitter + +A background process that submits transaction batches to the `BatchInbox` module of L1. + +#### Challenger + +A challenger is an entity capable of deleting invalid output proposals from the output oracle. It mimics the output root generation process that a bridge executor does to check the validity of the proposed output root on the oracle module. This process confirms that the proposed output root contains a valid app hash, and all withdrawal transactions are properly relayed to L1. + +Additionally, a challenger monitors deposit transactions from L1 to L2 to ensure censorship resistance. If the transactions are not properly relayed to L2 within the timeout (L2 block numbers), the challenger deletes the output root. + +In the initia optimistic rollup spec, a challenger is supposed to run an IBC relayer between L1 and L2 to support instant bridge operation. It is the entity that can monitor an invalid state first, so it can prevent invalid IBC operation by stopping the relayer process. To accomplish this, initia is using [a new ibc middleware](https://github.com/initia-labs/initia/pull/86) on the L1 side to restrict the relayer permission to a specific address for each channel. + +### Dispute Process + +Initia's optimistic rollup uses a simplified version of the dispute mechanism with L1 governance security. This approach is very similar to Cosmos's shared security, but it does not require all validators to run a whole L2 node. Instead, the validators are only required to run an L2 node to decide the valid entity between the `proposer` and `challenger` when a dispute is opened. They do not need to run whole L2 blocks but only need to run a dispute block with the last L2 state on L1. + +The dispute process works as follows: + +1. A `challenger` deletes the invalid output root from the output oracle module. +2. Both a `challenger` and a `proposer` make a governance proposal to update invalid operator addresses: + * The `challenger` make a governance proposal to change the `proposer` to another address if the `proposer` keeps submitting an invalid output root. + * The `proposer` make a governance proposal to change the `challenger` to another address if the `challenger` keeps deleting a valid output root. +3. L1 validators make a validity decision by running an L2 node with L2 state and data inputs. diff --git a/specs/architecture.png b/specs/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..951e4687e7328446a1e391b46bdbc3c394cffb07 GIT binary patch literal 105149 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, // sha3_256(type_name(`L2ID`) || type_name(`l1_token`)) +} +``` + +### `TokenBridgeInitiatedEvent` + +The event is emitted when a user executes `deposit_token` function to move a token from L1 to L2. + +* The bridge module maintain `sequence` number to give an unique identifier for each relaying operation. +* In v1, `l2_id` + `l1_sequence` is the unique identifier. + +```rust +/// Emitted when a token bridge is initiated to the l2 chain. +struct TokenBridgeInitiatedEvent has drop, store { + from: address, // l1 address + to: address, // l2 address + l2_id: String, + l1_token: String, + l2_token: vector, + amount: u64, + l1_sequence: u64, +} +``` + +### `TokenBridgeFinalizedEvent` + +The event is emitted when a withdrawal transaction is proved and finalized. + +* In v1, `sha3(bcs(l2_sequence) + bcs(from) + bcs(to) + bcs(amount) + bytes(l1_token))` is the unique identifier for each withdrawal operation. + +```rust +/// Emitted when a token bridge is finalized on l1 chain. +struct TokenBridgeFinalizedEvent has drop, store { + from: address, // l2 address + to: address, // l1 address + l2_id: String, + l1_token: String, + l2_token: vector, + amount: u64, + l2_sequence: u64, // the sequence number which is assigned from the l2 bridge +} +``` + +## Operations + +### Register Token + +This function is for the bridge executor, who controls the bridge relaying operations. In version 1, only the bridge executor can add support for a new token type. After registration, the `TokenRegisteredEvent` event is emitted to deploy a new coin type module on L2. + +The bridge executor should monitor the `TokenRegisteredEvent` and deploy a new coin type module on L2. They should also execute the L2 bridge's `/minitia.rollup.v1.MsgCreateToken` function for initialization. + +### Initiate Token Bridge + +This function enables a user to transfer their asset from L1 to L2. The deposited token will be locked in the bridge's `DepositStore` and can only be released using the `withdraw` operation in L2. When executed, this operation emits a `TokenBridgeInitiatedEvent`. A bridge executor should subscribe to this event and transfer the token to L2 by executing the `finalize_token_bridge` function in the L2 bridge. + +### Finalize Token Bridge + +This function is used to prove and finalize the withdrawal transaction from L2. The proving process is described [here](https://www.notion.so/Withdrawal-Proving-a49f7c26467044489731048f68ed584b?pvs=21). Once the proving is complete, the deposited tokens are withdrawn to the recipient address, and the `TokenBridgeFinalizedEvent` event is emitted. To prevent duplicate withdrawal attempts, the bridge uses a unique identifier calculated as `sha3(bcs(l2_sequence) + bcs(from) + bcs(to) + bcs(amount) + bytes(l1_token))`. diff --git a/specs/l2_bridge.md b/specs/l2_bridge.md new file mode 100644 index 00000000..571342f5 --- /dev/null +++ b/specs/l2_bridge.md @@ -0,0 +1,52 @@ +# L2 Bridge + +## Events + +### `TokenBridgeFinalizedEvent` + +The event is emitted when a executor finalized the token transfer from the L1 to L2. + +```rust +// Emitted when a token bridge is finalized on l2 chain. +struct TokenBridgeFinalizedEvent has drop, store { + from: address, // l1 address + to: address, // l2 address + l2_token: vector, + amount: u64, + l1_sequence: u64, // the sequence number which is assigned from the l1 bridge +} +``` + +### `TokenBridgeInitiatedEvent` + +The event is emitted when a user executes `withdraw_token` function to move token from L2 to L1. + +- The bridge module maintain `sequence` number to give unique identifier to each relay operation. +- In v1, `l2_sequence` is the unique identifier. + +```rust +// Emitted when a token bridge is initiated to the l1 chain. +struct TokenBridgeInitiatedEvent has drop, store { + from: address, // l2 address + to: address, // l1 address + l2_token: vector, + amount: u64, + l2_sequence: u64, // the operation sequence number +} +``` + +## Operations + +### Register Token + +This function allows the block executor to initialize a new token type with registration on the bridge module. The name of the newly deployed module should follow the L1 bridge contract’s event message `l2_token`, such as `01::l2_${l2_token}::Coin`. + +### Finalize Token Bridge + +This function finalizes the token transfer from L1 to L2. Only the block executor is allowed to execute this operation. + +### Initiate Token Bridge + +This function initiates the token bridge from L2 to L1. Users can execute `withdraw_token` to send tokens from L2 to L1. This operation emits the `TokenBridgeInitiatedEvent` with an `l2_sequence` number to prevent duplicate execution on L1. + +The block executor should monitor this event to build withdraw storage for withdrawal proofs. diff --git a/specs/l2_output_oracle.md b/specs/l2_output_oracle.md new file mode 100644 index 00000000..332a232f --- /dev/null +++ b/specs/l2_output_oracle.md @@ -0,0 +1,32 @@ +# L2 Output Oracle + +In version 1, output oracle maintain `proposer` and `challenger` addresses on its config store. The `proposer` can submit the `output_proposal` and the `challenger` can delete the output when the proposed output state is wrong. + +The first version of the implementation does not include a dispute system, but uses permissioned propose and challenge mechanisms. In version 2, anyone can propose the output with a certain amount of `stake`, and disputes will be resolved based on the governance of L1. + +## Operations + +### Propose L2 Output + +L2 output oracle receives `output_root` with L2 block number to check the checkpoint of L2. The checkpoints are the multiple of `submission_interval`. A proposer must submit the `output_root` at the every checkpoints. + +The followings are the components of `output_root`. + +- `version`: the version of output root +- `state_root`: l2 state root +- `storage_root`: withdrawal storage root +- `latest_block_hash`: l2 latest block hash + +To build the `output_root`, concatenate all the components in sequence and apply `sha3_256`. + +### Delete L2 Output + +A challenger can delete the output without dispute in version 1 with output index. + +### Update Proposer + +The operation is to update proposer to another address when a proposer keeps submitting a invalid output root. The operation is supposed to be executed by `0x1` via L1 governance. + +### Update Challenger + +The operation is to update challenger to another address when a challenger keeps deleting a valid output root. The operation is supposed to be executed by `0x1` via L1 governance. diff --git a/specs/minitia.md b/specs/minitia.md new file mode 100644 index 00000000..5c45358d --- /dev/null +++ b/specs/minitia.md @@ -0,0 +1,237 @@ +# Minitia + +## Messages + +There are three categories of message in `x/rollup`` module. + +* Bridge Executor messages + * [`MsgCreateToken`](#msgcreatetoken) + * [`MsgDeposit`](#msgdeposit) +* Validator messages + * [`MsgExecuteMessages`](#msgexecutemessages) + * [`MsgExecuteLegacyContents`](#msgexecutelegacycontents) +* Authority messages + * [`MsgAddValidator`](#msgaddvalidator) + * [`MsgRemoveValidator`](#msgremovevalidator) + * [`MsgUpdateParams`](#msgupdateparams) + * [`MsgWhitelist`](#msgwhitelist) + * [`MsgSpendFeePool`](#msgspendfeepool) + +### `MsgCreateToken` + +The message is for a bridge executor to publish a new coin struct tag `0x1::native_${denom}::Coin` and initialize a new coin with that struct tag. + +```proto +// MsgCreateToken is the message to create a new token from L1 +message MsgCreateToken { + option (cosmos.msg.v1.signer) = "sender"; + option (amino.name) = "rollup/MsgCreateToken"; + + // the sender address + string sender = 1 [ + (gogoproto.moretags) = "yaml:\"sender\"", + (cosmos_proto.scalar) = "cosmos.AddressString" + ]; + + // denom is the denom of the token to create. + string denom = 2; + string name = 3; + string symbol = 4; + int64 decimals = 5; +} +``` + +### `MsgDeposit` + +The message is for a bridge executor to finalize a deposit request from L1. The message handler internally executes [`finalize_token_bridge`](./l2_bridge.md#finalize-token-bridge) of `l2_bridge`. + +```proto +// MsgDeposit is the message to submit deposit funds from upper layer +message MsgDeposit { + option (cosmos.msg.v1.signer) = "sender"; + option (amino.name) = "rollup/MsgDeposit"; + + // the sender address + string sender = 1 [ + (gogoproto.moretags) = "yaml:\"sender\"", + (cosmos_proto.scalar) = "cosmos.AddressString" + ]; + + // from is l1 sender address + string from = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // to is l2 recipient address + string to = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // amount is the coin amount to deposit. + cosmos.base.v1beta1.Coin amount = 4 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false, + (amino.dont_omitempty) = true + ]; + + // sequence is the sequence number of l1 bridge + uint64 sequence = 5; +} +``` + +### `MsgExecuteMessages` + +The message is to execute authority messages with validator permission like `x/gov` module of cosmos-sdk. Any validator can execute the message with various authority messages. + +```proto +// MsgExecuteMessages is the message to execute the given +// authority messages with validator permission. +message MsgExecuteMessages { + option (cosmos.msg.v1.signer) = "sender"; + option (amino.name) = "rollup/MsgExecuteMessages"; + + // Sender is the that actor that signed the messages + string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // messages are the arbitrary messages to be executed. + repeated google.protobuf.Any messages = 2; +} +``` + +### `MsgExecuteLegacyContents` + +The message is also copied from `x/gov` module of cosmos-sdk to support legacy param update of ibc modules. The execution permission is given to validators. + +```proto + +// MsgExecuteLegacyContents is the message to execute legacy +// (gov) contents with validator permission. +message MsgExecuteLegacyContents { + option (cosmos.msg.v1.signer) = "sender"; + option (amino.name) = "rollup/MsgExecuteLegacyContents"; + + // Sender is the that actor that signed the messages + string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // contents are the arbitrary legacy (gov) contents to be executed. + repeated google.protobuf.Any contents = 2; +} +``` + +### `MsgAddValidator` + +The message is to add a new validator to the comet-bft validator set. The execution permission is given to authority, which is `rollup` module account. + +```proto +// MsgAddValidator defines a SDK message for adding a new validator. +message MsgAddValidator { + option (cosmos.msg.v1.signer) = "authority"; + option (amino.name) = "rollup/MsgAddValidator"; + + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // authority is the address that controls the module + // (defaults to x/rollup unless overwritten). + string authority = 1 [ + (gogoproto.moretags) = "yaml:\"authority\"", + (cosmos_proto.scalar) = "cosmos.AddressString" + ]; + + string moniker = 2; + string validator_address = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + google.protobuf.Any pubkey = 4 [(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey"]; +} +``` + +### `MsgRemoveValidator` + +The message is to remove a validator from the comet-bft validator set. The execution permission is given to authority, which is `rollup` module account. + +```proto +// MsgAddValidator is the message to remove a validator from designated list +message MsgRemoveValidator { + option (cosmos.msg.v1.signer) = "authority"; + option (amino.name) = "rollup/MsgRemoveValidator"; + + // authority is the address that controls the module + // (defaults to x/rollup unless overwritten). + string authority = 1 [ + (gogoproto.moretags) = "yaml:\"authority\"", + (cosmos_proto.scalar) = "cosmos.AddressString" + ]; + + // validator is the validator to remove. + string validator_address = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; +} +``` + +### `MsgUpdateParams` + +The message is to update the rollup module params. The execution permission is given to authority, which is `rollup` module account. + +```proto +// MsgUpdateParams is the message to update legacy parameters +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + option (amino.name) = "rollup/MsgUpdateParams"; + + // authority is the address that controls the module + // (defaults to x/rollup unless overwritten). + string authority = 1 [ + (gogoproto.moretags) = "yaml:\"authority\"", + (cosmos_proto.scalar) = "cosmos.AddressString" + ]; + + // params are the arbitrary parameters to be updated. + Params params = 2; +} +``` + +### `MsgWhitelist` + +The message is to add a coin type to whitelist for auto register. The execution permission is given to authority, which is `rollup` module account. + +```proto +// whitelist a coin type to enable auto coin module register. +message MsgWhitelist { + option (cosmos.msg.v1.signer) = "authority"; + option (amino.name) = "rollup/MsgWhitelist"; + + // authority is the address that controls the module + // (defaults to x/rollup unless overwritten). + string authority = 1 [ + (gogoproto.moretags) = "yaml:\"authority\"", + (cosmos_proto.scalar) = "cosmos.AddressString" + ]; + + // coin_type is the struct tag to whitelist. + string coin_type = 2; +} +``` + +### `MsgSpendFeePool` + +The message is to spend collected fee. The execution permission is given to authority, which is `rollup` module account. + +```proto +// MsgSpendFeePool is the message to withdraw collected fees from the module account to the recipient address. +message MsgSpendFeePool { + option (cosmos.msg.v1.signer) = "authority"; + option (amino.name) = "rollup/MsgSpendFeePool"; + + // authority is the address that controls the module + // (defaults to x/rollup unless overwritten). + string authority = 1 [ + (gogoproto.moretags) = "yaml:\"authority\"", + (cosmos_proto.scalar) = "cosmos.AddressString" + ]; + + // recipient is address to receive the coins. + string recipient = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // the coin amount to spend. + repeated cosmos.base.v1beta1.Coin amount = 3 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.nullable) = false, + (amino.dont_omitempty) = true, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" + ]; +} +``` diff --git a/specs/withdrawal_proving.md b/specs/withdrawal_proving.md new file mode 100644 index 00000000..ac8bad79 --- /dev/null +++ b/specs/withdrawal_proving.md @@ -0,0 +1,64 @@ +# Withdrawal Proving + +`ominitia` defines `submission_interval`, which is the L2 block number at which checkpoints must be submitted. At each `submission_interval`, the bridge executor should build the withdraw storage, which is the Merkle Tree for the withdrawal verification process on L1. + +`ominitia` uses a sorted Merkle Tree to reduce verifying cost, and each tree node is referred to as a `withdrawal_hash`. + +The following are the components of `withdrawal_hash`: + +- `sequence`: The L2 bridge sequence assigned to each withdrawal operation. +- `sender`: The address from which the withdrawal operation is made. +- `receiver`: The address to which the withdrawal operation is made. +- `amount`: The token amount of the withdrawal operation. +- `coin_type`: The L1 token struct tag. + +To build the `withdrawal_hash`, concatenate all the components and apply `sha3_256` after serializing the values with `bcs`, except for `coin_type`, because the `coin_type` is already a string that can be converted to bytes. + +```rust +fun verify( + withdrawal_proofs: vector>, + sequence: u64, + sender: address, + receiver: address, + amount: u64, + coin_type: String, +): bool { + let withdrawal_hash = { + let withdraw_tx_data = vector::empty(); + vector::append(&mut withdraw_tx_data, bcs::to_bytes(&sequence)); + vector::append(&mut withdraw_tx_data, bcs::to_bytes(&sender)); + vector::append(&mut withdraw_tx_data, bcs::to_bytes(&receiver)); + vector::append(&mut withdraw_tx_data, bcs::to_bytes(&amount)); + vector::append(&mut withdraw_tx_data, *string::bytes(&type_info::type_name())); + + sha3_256(withdraw_tx_data) + }; + + let i = 0; + let len = vector::length(&withdrawal_proofs); + let root_seed = withdrawal_hash; + while (i < len) { + let proof = vector::borrow(&withdrawal_proofs, i); + let cmp = bytes_cmp(&root_seed, proof); + root_seed = if (cmp == 2 /* less */) { + let tmp = vector::empty(); + vector::append(&mut tmp, root_seed); + vector::append(&mut tmp, *proof); + + sha3_256(tmp) + } else /* greator or equals */ { + let tmp = vector::empty(); + vector::append(&mut tmp, *proof); + vector::append(&mut tmp, root_seed); + + sha3_256(tmp) + }; + i = i + 1; + }; + + let root_hash = root_seed; + assert!(storage_root == root_hash, error::invalid_argument(EINVALID_STORAGE_ROOT_PROOFS)); +} +``` + +The example implementation of building the Merkle Tree can be found [here](https://github.com/initia-labs/op-bridge-executor).