Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/app/zeko/circuits/count_commits.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
open Snark_params.Tick
open Zeko_util

module Definition = struct
module Stmt = struct
type t =
{ source_action_state : Rollup_state.Outer_action_state.t
; target_action_state : Rollup_state.Outer_action_state.t
; n_commits : Checked32.t
}
[@@deriving snarky]
end

module Elem = Rollup_state.Outer_action

let dummy_elem =
Rollup_state.Outer_action.Witness
{ aux = Field.zero
; children_digest = Rollup_state.Zkapp_call_forest.Digest.empty
; slot_range = Slot_range.infinite
}

module Init = struct
type t = { original_action_state : Rollup_state.Outer_action_state.t }
[@@deriving snarky]
end

let init ~check:_ ({ original_action_state } : Init.var) : Stmt.var Checked.t
=
Checked.return
( { source_action_state = original_action_state
; target_action_state = original_action_state
; n_commits = Checked32.Checked.zero
}
: Stmt.var )

let step (action : Rollup_state.Outer_action.var)
({ source_action_state; target_action_state; n_commits } : Stmt.var) =
let* target_action_state =
Rollup_state.Outer_action.push_var action target_action_state
in
let*| n_commits =
let* increment =
if_ ~typ:Checked32.typ action.is_commit
~then_:Checked32.(Checked.constant one)
~else_:Checked32.Checked.zero
in
Checked32.Checked.add n_commits increment
in
Stmt.{ source_action_state; target_action_state; n_commits }

let name = "count_commits"

let leaf_iterations =
Zeko_constants.Folder_iterations.Count_commits.leaf_iterations

let leaf_option_iterations =
Zeko_constants.Folder_iterations.Count_commits.leaf_option_iterations

let extend_iterations =
Zeko_constants.Folder_iterations.Count_commits.extend_iterations

let extend_option_iterations =
Zeko_constants.Folder_iterations.Count_commits.extend_option_iterations

let wrap_domain = Some `N14
end

include Folder.Make (Definition) ()
30 changes: 28 additions & 2 deletions src/app/zeko/circuits/design/rollup-centralized-explanation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ It should be possible to have a stake in the rollup.
And above all, it should be secure.

To that end, here is a summary of what we want from the core protocol:

- The core rollup protocol does not handle transfer of value/MINA.
- There is an associated token called ZEKO, using the fungible
token standard, minted on the L1.
Expand All @@ -25,8 +26,8 @@ To that end, here is a summary of what we want from the core protocol:
to ensure that sequencer does not waste work synchronizing something that
might be rolled back immediately.
- Actions on the outside:
+ Witness (witness arbitrary account update)
+ Commit (sequencer committed)
- Witness (witness arbitrary account update)
- Commit (sequencer committed)
- There is a backup special committee that can pause the rollup.
Being paused is indicated by a field on the outer account.

Expand All @@ -42,6 +43,7 @@ of actions.
Withdrawals happen correspondingly, the other way around.
We also wish to support timeouts on deposits.
We do this by regarding a deposit as having three states:

- Unknown
- Accepted
- Rejected
Expand Down Expand Up @@ -117,6 +119,30 @@ can profit from those deposits being processed.

To prevent this from happening, we also specify a maximum size for the slot range.

## Emergency commit

When the sequencer goes offline, we need a way to unblock the system
without decentralization of sequencing already in place.

An emergency commit may be issued by anyone once enough time has
passed since the upper bound of the last commit slot range.
That upper bound witnesses the latest possible time a commit could
have occurred; if the current slot is past it by a fixed margin,
then no commit has happened since.

Malicious sequencer can not pick a very large upper bound, since the slot range is capped by max_valid_size.

However, we can only certify “no commit happened” relative to one of
the last five outer action states. To make this check viable,
the sequencer must maintain rolling commits over at least five slots
within the max_sequencer_inactivity window. With a sufficiently
large window (e.g., on the order of a month), this obligation is
trivial for a healthy sequencer.

In effect, the emergency commit seals the gap with a bounded slot
range, restores liveness, and lets subsequent sequencers resume
committing under the usual rules.
Comment on lines +142 to +144
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this accurate? It's not clear to me how liveness would be restored. It seems to me that there is no mechanism to update the sequencer on the outer account, so how would we resume committing if that sequencer stays offline? Since a normal commit requires sequencer signature.


## ZEKO token

The ZEKO token will use the
Expand Down
59 changes: 59 additions & 0 deletions src/app/zeko/circuits/design/rollup-centralized-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,65 @@ let do_commit
}
]

let count_commits original_action_state actions =
let f (acc_action_state, n) = function
| (Commit _) as action ->
List.append action acc_action_state, n + 1
| (Witness _) as action ->
List.append action acc_action_state, n
in
List.fold_left ~init:(original_action_state, 0) ~f actions

val max_sequencer_inactivity : nat

(* Emergency commit in case of sequencer's inactivity *)
let do_emergency_commit
~txn_snark
~valid_while
~new_actions
~new_inner_actions
~old_inner_action_state_length
~unsynchronized_actions
~pause_key
~da_key
~outer_action_state_before_last_commit
~last_commit
~actions_since_last_commit
=
let [ commit ] =
do_commit
~txn_snark
~valid_while
~new_actions
~new_inner_actions
~old_inner_action_state_length
~unsynchronized_actions
~pause_key
~da_key
in

(* Count commits since last commit *)
let (target_action_state, n_commits) = count_commits
(List.append last_commit outer_action_state_before_last_commit)
actions_since_last_commit
in

(* Check that there has not been any commit after last commit *)
assert n_commits = 0 ;

(* Check that count_commits is matching the precondition *)
assert target_action_state = commit.preconditions.action_state ;

(* Check that enought time elapsed since last commit *)
assert commit.preconditions.valid_while.lower - last_commit.valid_while.upper >= max_sequencer_inactivity;

(* Remove sequencer preconditions *)
[ { commit with
children = []
; preconditions.app_state.sequencer = Ignore
}
]

let do_witness_outer ~aux ~children ~valid_while =
[ { public_key = zeko_pk
; actions = [ Witness { aux ; children ; valid_while } ]
Expand Down
1 change: 1 addition & 0 deletions src/app/zeko/circuits/dune
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
rule_bridge_outer_token_owner
rule_change_permissions
check_accepted_make
count_commits
bridge_state
outer_rules
inner_rules
Expand Down
3 changes: 3 additions & 0 deletions src/app/zeko/circuits/outer_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ module Make (Inputs : sig
val inner_public_key : Signature_lib.Public_key.Compressed.t

val chain_l1 : Mina_signature_kind.t

val max_sequencer_inactivity : int
end)
() =
struct
Expand All @@ -17,6 +19,7 @@ struct
Snark_params.Tick.Typ.(Mina_base.Zkapp_statement.typ * V.typ)
~branches:
[ Rule_commit_inst.rule
; Rule_commit_inst.Emergency_commit.rule
; Rule_action_witness_inst.rule
; Rule_pause_inst.rule
]
Expand Down
Loading