Joel Björnson
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # SCORU Communication Layer **Status**: Awaiting feedback This document outlines a design of cross-layer communication, including deposits and withdrawals of assets. We want to provide minimal protocol support on top of which more advanced rollup specific protocols can be built. For more info and a break-down of the work, see the [SCORU Communication Layer](https://gitlab.com/tezos/tezos/-/milestones/76#tab-issues) milestone. ## Requirements We need to support: - L1 contracts (explicit accounts) calling and transferring assets to L2 contracts. - L2 contracts calling and transferring assets to L1 contracts (explicit accounts) ## Overview Message passing from L1 to L2 is ultimately achieved by L1 contracts emitting SCORU operations which are included in a particular SCORU's *inbox*. The operations in the inbox are detected by all SCORU nodes executing the corresponding rollup by monitoring internal operations. Once the inbox has been committed to L1 and the refutation period has passed, all operations that are contained in the cemented state have been processed. Likewise, an L2 contract can send a (asynchronous) message to an L1 contract by emitting an output-effect which may be processed in L1. Once the SCORU state including the effect has been cemented it is available for execution. ## Representing assets An important aspect of cross-layer communication is depositing and withdrawing *assets*. Tickets can be used for representing such assets. Only tickets with a positive amount is permitted as ownership of zero-amount tickets are not tracked. Each SCORU has a unique address which may hold tickets. The SCORU balance for tickets are tracked by the [ticket-balance table](https://gitlab.com/tezos/tezos/-/milestones/38). A smart contract on L1 may deposit tickets to the rollup by a transaction the rollup address. The tickets are contained in the parameters. As far as the L1 protocol is concerned, the SCORU address is the sole owner of the tickets. ## Typed SCORUs Similar to a smart contract, a SCORU needs to be registered with a concrete type. That way smart-contract calls a SCORU can be type checked just like regular contract calls. Allowing any type may be less efficient for rollups that want to restrict their parameter type (typically TORU currently allows only `exists t. ticket t`). Using `bytes` would push pressure on L1 Michelson smart-contracts to encode data for L2. We plan to support a subset of Michelson types — essentially everything that is `passable` except `big_map` and `sapling_state`. We don't support `big_map` because they are references to values that exist in the L1 context and `sapling_state` does not carry any meaning for the rollup. As an extension we also consider to introduce an existential Michelson type for providing more flexibility. For instance, that could be used to allow SCORUs to accept tickets of an arbitrary payload type. Note that it's possible for rollups to design an arbitrary encoding scheme by registering the type as `bytes`. ## Rollup Management Protocol The communication layer between the L1 protocol and any L2 kernel must follow the specification of a Rollup Management Protocol. In particular to describe such actions as: - Sending messages from L1 to L2 (including ticket deposits). - Sending messages from L2 to L1 (including ticket withdrawals). - Minting ticket-tokens in L1 based on kernel authorization — for example to represent a minted L2 asset. - Other effects authorized by the L2 kernel, such as a hardware/ISA upgrade. This protocol is meant to be shared between kernels and PVMs. To enable the L1/L2 communication we need at least specifications for an *L1 to L2 message* and a *L2 to L1 message*. In the L1 protocol we can represent a message from L1 to L2 — as: ```ocaml type inbox_message = Sc_message of { payload : Script_repr.expr; (** A Micheline value containing the parameters passed to the rollup. *) sender : Alpha_context.Contract.t; (** The L1 caller contract. *) source : Signature.public_key_hash; (** The implicit account that originated the transaction. *) } ``` For L2 to L1 we support grouping of multiple L2 to L1 messages in atomic batches: ```ocaml type transaction = { unparsed_parameters_ty : Script_repr.expr; (** The type of the parameters. *) unparsed_parameters : Script_repr.expr; (** The payload. *) destination : Destination.t; (** The recipient contract or rollup. *) entrypoint : Entrypoint.t; (** Entrypoint of the destination. *) } type outbox_message = | Atomic_transaction_batch of { transactions : transaction list} ``` Why support atomic batches? One reason is that it gives the rollup the ability to choose whether or not atomicity is required for multiple withdrawals. Another reaons is it requires fewer L1 transaction to execute. For the protocol layer we will expose functions for encoding values of these types. Further, any rollup needs to be able to emit and consume such values. :::warning The encoding scheme for the the Rollup Management Protocl types is yet to be decided. Can we use the standard data-encoding library and serialize *Micheline* expressions to binary format? ::: ## L1 to L2 messaging An L1 contract is able to call a contract in L2 by emitting a *scoru-transaction-operation* where destination is set to a SCORU contract. A SCORU transaction is similar to a regular (internal) transaction. For technical reasons we may choose factor it out as a separate internal manager operation: ```ocaml and 'kind manager_operation = ... | Sc_rollup_transaction : { destination : Sc_rollup_t.; entrypoint : Entrypoint.t; parameters_ty : 'a ty; parameters : 'a } -> -> Kind.sc_rollup_transaction manager_operation ``` The effect of applying the operation in L1 is: - Transfer ownership of any tickets in the parameters from the callee contract to the SCORU. - Emit a "Deposit" message as defined by the Rollup Management Protocol, and append it to the SCORU's inbox. :::info When a SCORU node processes a transaction from the inbox containing tickets, it may mint a corresponding amount of tickets in L2, in order to represent the asset there. :::: ### Atomicity What happens when an execution succeeds on L1 but fails on L2? Imagine an execution that is successfully submitted to the inbox in L1 but fails to be processed by L2. This could happen if, for example, the callee contract provided insufficient funds. From the Tezos protocol's perspective, this is a valid scenario and we do not intend to protect against it in the protocol layer. :::info It is still possible to build SCORUs that support cancellation/re-try logic. For instance by having L2 emit an output-effect that communicates the failed status of the transaction as well as potential refunds. ::: ### An example Following is an example of the execution of an L1 to L2 transaction. We here assume: - A SCORU with address `SCORU1` - A contract, `KT1` Suppose the contract `KT1` holds some tickets, reflected in the ticket-balance table: | Owner x Ticketer x Content | Amount | | -----------------------------|-------:| | `(KT1, KTX, Unit)` | 200| Consider a call to the `KT1` contract that outputs a transaction operation to `SCORU1`: ```ocaml= Sc_rollup_transaction { destination = Destination.scoru_address "SCORU1"; entrypoint = Entrypoint.default; parameters_ty = pair string (ticket unit); parameters = ("SCORU_ADDRESS_42", {ticketer = KTX; content = (); amount = 50}); } ``` The ticket from the parameter is moved from the `KT1` address to the `SCORU1` address. The new ticket-balance is updated and now contains the following entries: | Owner x Ticketer x Content | Amount | | -------------------------------|-------:| | `(KT1, KTX, Unit)` | 150 | | `(SCORU1, KTX, Unit)` | 50 | L1 emits a message which is appended to the `SCORU1`'s inbox. The message is an encoded version of a Rollup Management Protocol deposit message: ```ocaml let l1_to_l2_message = Sc_mesage { payload = seq ["SCORU_ADDRESS_42", pair KTX unit 50}]; sender = KT1 } ``` An ORU node processes the inbox that includes the deposit message and applies the operation in L2. :::info How the transaction is applied in L2 is opaque to L1. One can imagine the following thing happening on L2 side: - Mint `50 KTX tokens` and credit `SCORU_ADDRESS_42` (internal L2 address). - Execute the transaction using the corresponding `KT1` address in L2 to charge for fees. ::: ## L2 to L1 messaging The way L2 calls L1 is not transparent from the Tezos protocol's point of view. The important thing to note is that a SCORU can emit effects to its *outbox*. As mentioned above, calls to smart contracts on L1 can be batched as described by the `atomic_transaction_batch` Rollup Management Protocol effect. Once a committed state is cemented — that is when the refutation period has ended — any such effect may be executed, within a time window, via a manager operation in L1. For this purpose we will extend the external `manager_operation` as in: ```ocaml type _ manager_operation = | ... | Sc_rollup_atomic_batch { sc_rollup : Sc_rollup.t; lcc_level : Sc_rollup.Commitment.t; outbox_level : int; message_index : int; inclusion_proof : inclusion_proof; atomic_transaction_batch : Rollup_management_protocol.atomic_transaction_batch } ``` The `Sc_atomic_batch` operation contains a batch of transfers which involve executing smart contract calls to the destination contracts. If any of these invocations fail, for instance because they don't type check, or insufficient gas was provided, the whole batch is rejected. Note that anyone can submit rollup withdrawal operation and needs to pay the gas fees for all contract calls that are included in the batch. :::warning Then we need to make sure this is not attackable. E.g. if some limit (gas, burn) is not enough, it should not burn the right to try to withdraw again. The source of the operation cannot be the payer, otherwise it may have a change of semantics! (this reminds me of a proposal for having operations paid by someone else) ::: ### Keeping tracking of processed messages To prevent messages from being processed multiple times we need to keep track of the processed ones. Here, we follow a similar approach to TORU with a storage API for recording messages based on rollup, commitment and index: ```ocaml val record : context -> Sc_rollup.t -> Sc_rollup.Commitment.t -> message_position:int -> context tzresult Lwt.t ``` The underlying implementation should use a `bitset` to minimize overhead. :::warning Because `Bitset.add` is in O(`message_position`) we need to make sure the position is legitimate before we call `record`. ::: Whenever a message has been processed we record it. Since we want to bound the number of recorded messages, we impose: - A maximum number of levels in which rollup withdrawal for a particular commit may be executed. - A cap on the total number of active levels for which we keep an "applied message" record. - A cap on the maximum number of outbox messages per level. The total size of the records for applied messages for a rollup is bounded by: ``` maximum-number-of-active-levels * maximum-number-of-outbox-messages-per-level ``` The maximum storage cost must be paid for upfront when originating the rollup. It's conceivable to make this configurable by the rollup itself. Beyond this deadline, we may safely remove old records. For this purpose we provide an additional manager operation for removing old commitments. It may be called by anyone who care about preventing the rollup from getting stuck due to exceeding the maximum number of recorded messages. We will provide a new manager operation for removing old commitments that involve cleaning up recorded messages: ```ocaml type _ manager_operation = | ... | Sc_rollup_remove_commitment : { sc_rollup : Sc_rollup.t; } ``` ### An example Following is an example workflow, assuming an L2 implementation with accounts and smart contracts: 1) An L2 contract, `SCORU_ADDRESS_42`, emits an L2-to-L1 withdrawal message that transfers 20 `(KTX, Unit)` ticket-tokens to `KT2`. 2) The effect is included in an `atomic_transaction_batch`. 3) The rollup proceeds and a state containing the emitted withdrawal batch in its outbox is committed. 4) The refutation period passes and the new state is cemented. 5) A user executes a `Sc_rollup_withdraw` operation on L1 for the corresponding withdrawal batch by providing an inclusion proof. Upon successful execution of the manager operation, the protocol registers that the outbox message has been processed. Since the withdrawal batch included a ticket transfer to `KT2`, the ticket-table is updated: | Owner x Ticketer x Content | Amount | | -------------------------------|-------:| | `(KT1, KTX, Unit)` | 150 | | `(SCORU1, KTX, Unit)` | 30 | | `(KT2, KTX, Unit)` | 20 |

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully