package tezos-protocol-013-PtJakart

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

Defines storage for Smart Contract Optimistic Rollups.

Commitments

Commitments are stored directly in the L1 context. Commitments are immutable and content-addressed, and can be indexed by a Commitment_hash.

A commitment represents a claim about the state of a PVM.

We also keep auxiliary state about each commitment, namely:

  • When it was first added.
  • Its current number of stakers.

This auxiliary data is not part of the commitment itself. They represent information that the L1 knows about the claim, not the claim itself.

Predecessors and Boot state

Each commitment contains the hash of its predecessor. Multiple commitments can have the same predecessor. Therefore, commitments form a Merkle tree.

Conceptually the root of this tree is the Commitment_hash.zero. This commitment claims that the PVM (Proof-generating Virtual Machine) is in a pre-boot state and waiting to start booting by interpreting the boot sector with respect to the Machine semantics.

Cemented and Disputable commitments

Commitments accepted as true by the protocol are referred to as Cemented.

Stakers

The Stakers table maps Stakers (implicit accounts) to commitments.

Let Stakers(S) mean "looking up the key S in Stakers".

A staker S is directly staked on C if Stakers(S) = C. A staker S is indirectly staked on C if C is an ancestor of Stakers(S) in the commitment tree.

Dispute

Commitments that have at least one sibling are referred to as Disputed. More formally, a commitment C is disputed if at least one staker is not (directly or indirectly) staked on C.

Dispute resolution

The rollup protocol ensures that all disputes are resolved before cementing a commitment. Therefore, cemented commitments form a list rather than a tree.

In the context we only store the Last Cemented Commitment (LCC), which is by definition a descendant of zero. We also store all Disputable commitments that have at least one Staker.

For example, assuming the full set of commitments for a rollup looks like this:

           LCC  staker1  staker2
            |      |        |
            |      V        |
            V   --c3        |
zero--c1 --c2--/            |
               \            V
                --c4------ c5

then commitments c2..c5 will be stored in the context.

Conflicts

Let Commitments(S) be the set of commitments directly staked on by staker S.

Two stakers A and B are:

  • In total agreement iff Commitments(A) = Commitments(B).
  • In partial agreement iff either Commitments(A) ⊂ Commitments(B), or Commitments(B) ⊂ Commitments(A).
  • In conflict iff they are neither in total or partial agreement.

We can further refine a conflict to note what they are in conflict about, e.g. they may be in conflict about the inbox, about execution, or both. We can resolve conflicts by first resolving the conflict about inbox, then about execution (since execution is irrelevant if the inbox is not correct).

type Tezos_protocol_environment_013_PtJakart.Error_monad.error +=
  1. | Sc_rollup_does_not_exist of Sc_rollup_repr.t
  2. | Sc_rollup_already_staked
  3. | Sc_rollup_not_staked_on_lcc
  4. | Sc_rollup_staker_backtracked
  5. | Sc_rollup_unknown_commitment of Sc_rollup_repr.Commitment_hash.t
  6. | Sc_rollup_parent_not_lcc
  7. | Sc_rollup_too_far_ahead
  8. | Sc_rollup_too_recent
  9. | Sc_rollup_no_stakers
  10. | Sc_rollup_disputed
  11. | Sc_rollup_no_conflict
  12. | Sc_rollup_not_staked
  13. | Sc_rollup_remove_lcc
  14. | Sc_rollup_bad_inbox_level

originate context ~kind ~boot_sector produces an address a for a smart contract rollup using the origination nonce found in context. This function also initializes the storage with a new entry indexed by a to remember the kind of the rollup at address a and also to remember its boot_sector.

Also returns the number of allocated bytes.

kind context address returns Some kind iff address is an existing rollup of some kind. Returns None if address is not the address of an existing rollup.

add_message context rollup msg adds msg to rollup's inbox.

This function returns the updated context as well as the size diff.

May fail with:

  • sc_rollup_max_available_messages if inbox is full

deposit_stake context rollup staker stakes staker at the last cemented commitment, freezing sc_rollup_deposit from staker's account balance.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_already_staked if staker is already staked
  • Sc_rollup_staker_funds_too_low if staker does not have enough funds to cover the deposit

This should usually be followed by refine_stake to stake on a specific commitment.

This function does not authenticate the staker.

withdraw_stake context rollup staker removes staker and returns any deposit previously frozen by deposit_stake.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_not_staked_on_lcc if staker is not staked on the last cemented commitment

Note that it is not possible to be staked on a Cemented commitment other than the Last, because of Cementation Rule #4. See cement_commitment for details.

By design, the operation wrapping this should not be authenticated, as it may be necessary for nodes on the honest branch to refund stakers on the LCC. They must do so by using withdraw_stake as they are implicitly staked on the LCC and can not dispute it.

refine_stake context rollup staker commitment moves the stake of staker to commitment. Because we do not assume any form of coordination between validators, we do not distinguish between adding new commitments and staking on existing commitments. The storage of commitments is content-addressable to minimize storage duplication.

Subsequent calls to refine_stake and cement_commitment must use a context with greater level, or behavior is undefined.

The first time a commitment hash is staked on, it is assigned a deadline, which is counted in Tezos blocks (levels). Further stakes on the block does not affect the deadline. The commitment can not be cemented before the deadline has expired. Note that if a commitment is removed due to disputes and then re-entered, a later deadline may be assigned. Assuming one honest staker is always available, this only affects invalid commitments.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_too_far_ahead if staker would be more than sc_rollup_max_future_commitments ahead of the Last Cemented Commitment
  • Sc_rollup_bad_inbox_level if commitment's predecessor is less than sc_rollup_commitment_frequency blocks ahead
  • Sc_rollup_not_staked if staker is not staked
  • Sc_rollup_staker_backtracked if staker is not staked on an ancestor of commitment
  • Sc_rollup_unknown_commitment if the parent of the given commitment does not exist

Returns the hash of the given commitment.

This function does not authenticate the staker.

This is a wrapper around deposit_stake and refine_stake that deposits a stake and then refines it to the specified commitment, creating that commitment if necessary. Before calling deposit_stake it checks that the staker is not already staked, and if so will skip that step and go straight to calling refine_stake.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_too_far_ahead if staker would be more than sc_rollup_max_future_commitments ahead of the Last Cemented Commitment
  • Sc_rollup_bad_inbox_level if commitment's predecessor is less than sc_rollup_commitment_frequency blocks ahead
  • Sc_rollup_staker_backtracked if staker is not staked on an ancestor of commitment
  • Sc_rollup_unknown_commitment if the parent of the given commitment does not exist
  • Sc_rollup_staker_funds_too_low if staker is not previously a staker, and does not have enough funds to cover the deposit

Returns the hash of the given commitment.

This function does not authenticate the staker.

last_cemented_commitment context rollup returns the last cemented commitment of the rollup.

If no commitments have been cemented, the rollup is said to be in a pre-boot state, and last_cemented_commitment = Commitment_hash.zero.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist

cement_commitment context rollup commitment cements the given commitment.

Subsequent calls to refine_stake and cement_commitment must use a context with greater level, or behavior is undefined.

For cementing to succeed, the following must hold:

  1. The deadline for commitment must have passed.
  2. The predecessor of commitment must be the Last Cemented Commitment.
  3. There must be at least one staker.
  4. All stakers must be indirectly staked on commitment.

If successful, last_cemented_commitment is set to the given commitment and the appropriate amount of inbox messages is consumed.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_unknown_commitment if commitment does not exist
  • Sc_rollup_parent_not_lcc if commitment is not the child of the last cemented commitment
  • Sc_rollup_too_recent if commitment has not passed its deadline
  • Sc_rollup_no_stakers if there are zero stakers
  • Sc_rollup_disputed if at least one staker is not staked on commitment

get_conflict_point context rollup staker1 staker2 returns the first point of disagreement between the given stakers. The returned commitments are distinct, and have the same parent commitment.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_no_conflict if staker1 is staked on an ancestor of the commitment staked on by staker2, or vice versa

get_commitment context rollup commitment_hash returns the commitment with the given hash.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_unknown_commitment if commitment does not exist

remove_staker context rollup staker forcibly removes the given staker and confiscates their frozen deposits.

Any commitments no longer staked on are removed and storage reclaimed by remove_staker. Because of this there is no need to explicitly reject commitments.

May fail with:

  • Sc_rollup_does_not_exist if rollup does not exist
  • Sc_rollup_not_staked if staker is not staked
  • Sc_rollup_remove_lcc if staker is staked on a cemented commitment
OCaml

Innovation. Community. Security.