From d45e6309091541e07682705a070a329d6d0a099b Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 16 Dec 2024 15:46:04 +0100 Subject: [PATCH 01/22] Force tags --- src/app/zeko/circuits/bridge_rules.ml | 8 ++++++++ src/app/zeko/circuits/compile_simple.ml | 2 +- src/app/zeko/circuits/folder.ml | 4 ++++ src/app/zeko/circuits/inner_rules.ml | 3 +++ src/app/zeko/circuits/outer_rules.ml | 3 +++ .../circuits/rule_bridge_finalize_cancelled_deposit.ml | 6 ++++++ src/app/zeko/circuits/rule_commit.ml | 3 +++ src/app/zeko/circuits/zeko_transaction_snark.ml | 3 +++ 8 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/app/zeko/circuits/bridge_rules.ml b/src/app/zeko/circuits/bridge_rules.ml index 88bf73d46b..5fb333cd22 100644 --- a/src/app/zeko/circuits/bridge_rules.ml +++ b/src/app/zeko/circuits/bridge_rules.ml @@ -64,6 +64,10 @@ struct ; Rule_bridge_enable.rule ] () ) + + (* FIXME: remove for lazy compilation *) + let () = + Promise.block_on_async_exn (fun () -> Compile_simple.force_tag System.tag) end module Make_custom (Inputs : sig @@ -132,4 +136,8 @@ struct ; Rule_bridge_enable.rule ] () ) + + (* FIXME: remove for lazy compilation *) + let () = + Promise.block_on_async_exn (fun () -> Compile_simple.force_tag System.tag) end diff --git a/src/app/zeko/circuits/compile_simple.ml b/src/app/zeko/circuits/compile_simple.ml index 6de8ce3bc5..7b59730208 100644 --- a/src/app/zeko/circuits/compile_simple.ml +++ b/src/app/zeko/circuits/compile_simple.ml @@ -621,7 +621,7 @@ let compile (type out_t out_var first_input branches n_available_branches) with type out_t = out_t and type out_var = out_var and type branches = (first_input, branches) cons_branch ) = - printf "(compile_simple) called for circuit %s\n" name ; + printf "(compile_simple) called for circuit %s\n%!" name ; assert (Run.in_checked_computation () |> not) ; assert (Run.in_prover () |> not) ; let (Count_branches_result tag_branches) = count_branches branches in diff --git a/src/app/zeko/circuits/folder.ml b/src/app/zeko/circuits/folder.ml index 5988bf7802..64ad8cf90c 100644 --- a/src/app/zeko/circuits/folder.ml +++ b/src/app/zeko/circuits/folder.ml @@ -239,6 +239,10 @@ struct ] ~out_typ:Trans.typ () ) + (* FIXME: remove for lazy compilation *) + let () = + Promise.block_on_async_exn (fun () -> Compile_simple.force_tag System.tag) + type tag_var = System.tag_var type tag_t = System.tag_t diff --git a/src/app/zeko/circuits/inner_rules.ml b/src/app/zeko/circuits/inner_rules.ml index d51bb187a0..97590e1d94 100644 --- a/src/app/zeko/circuits/inner_rules.ml +++ b/src/app/zeko/circuits/inner_rules.ml @@ -3,3 +3,6 @@ include ~out_typ:Snark_params.Tick.Typ.(Mina_base.Zkapp_statement.typ * V.typ) ~name:"Inner_rules" ~override_wrap_domain:`N0 ~branches:[ Rule_inner_sync.rule; Rule_inner_action_witness.rule ] ) + +(* FIXME: remove for lazy compilation *) +let () = Promise.block_on_async_exn (fun () -> Compile_simple.force_tag tag) diff --git a/src/app/zeko/circuits/outer_rules.ml b/src/app/zeko/circuits/outer_rules.ml index 8234bc166f..0c6c87ea44 100644 --- a/src/app/zeko/circuits/outer_rules.ml +++ b/src/app/zeko/circuits/outer_rules.ml @@ -20,3 +20,6 @@ include ~branches: [ Rule_commit_inst.rule; Rule_action_witness.rule; Rule_pause.rule ] ~name:"Outer_rules" ) + +(* FIXME: remove for lazy compilation *) +let () = Promise.block_on_async_exn (fun () -> Compile_simple.force_tag tag) diff --git a/src/app/zeko/circuits/rule_bridge_finalize_cancelled_deposit.ml b/src/app/zeko/circuits/rule_bridge_finalize_cancelled_deposit.ml index a61396e88a..86eeebfd14 100644 --- a/src/app/zeko/circuits/rule_bridge_finalize_cancelled_deposit.ml +++ b/src/app/zeko/circuits/rule_bridge_finalize_cancelled_deposit.ml @@ -92,6 +92,9 @@ struct Typ.( Ase_outer_inst.Stmt.typ * Ase_outer_with_length_inst.Stmt.typ) () ) + + (* FIXME: remove for lazy compilation *) + let () = Promise.block_on_async_exn (fun () -> Compile_simple.force_tag tag) end module Check_accepted_params = struct @@ -133,6 +136,9 @@ struct Check_accepted.Definition.Stmt.typ * Ase_outer_with_length_inst.Stmt.typ) () ) + + (* FIXME: remove for lazy compilation *) + let () = Promise.block_on_async_exn (fun () -> Compile_simple.force_tag tag) end module Witness = struct diff --git a/src/app/zeko/circuits/rule_commit.ml b/src/app/zeko/circuits/rule_commit.ml index 5dc24384e1..10a471e371 100644 --- a/src/app/zeko/circuits/rule_commit.ml +++ b/src/app/zeko/circuits/rule_commit.ml @@ -41,6 +41,9 @@ module Verify_both_ases = struct ( val Compile_simple.compile ~name:"Verify_both_ases" ~branches:[ rule ] ~out_typ:Typ.(Ase_outer_inst.Stmt.typ * Ase_inner_inst.Stmt.typ) () ) + + (* FIXME: remove for lazy compilation *) + let () = Promise.block_on_async_exn (fun () -> Compile_simple.force_tag tag) end module Make (Inputs : sig diff --git a/src/app/zeko/circuits/zeko_transaction_snark.ml b/src/app/zeko/circuits/zeko_transaction_snark.ml index ac8c50756e..c6e38b514f 100644 --- a/src/app/zeko/circuits/zeko_transaction_snark.ml +++ b/src/app/zeko/circuits/zeko_transaction_snark.ml @@ -972,3 +972,6 @@ include ; { branch_name = "merge"; tags = Two_tags_own; main = rule_merge } ] () ) + +(* FIXME: remove for lazy compilation *) +let () = Promise.block_on_async_exn (fun () -> Compile_simple.force_tag tag) From a5c1a28c839e22614b365357d12e18c4a8b813a9 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 16 Dec 2024 15:46:17 +0100 Subject: [PATCH 02/22] Fix wrap domains in ases --- src/app/zeko/circuits/ase.ml | 4 ++-- src/app/zeko/circuits/rule_commit.ml | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/app/zeko/circuits/ase.ml b/src/app/zeko/circuits/ase.ml index c8ef9e4997..bc57f2b613 100644 --- a/src/app/zeko/circuits/ase.ml +++ b/src/app/zeko/circuits/ase.ml @@ -32,7 +32,7 @@ module M_with_length = struct let extend_option_iterations = Int.pow 2 9 - let override_wrap_domain = None + let override_wrap_domain = Some `N1 end module M_without_length = struct @@ -57,7 +57,7 @@ module M_without_length = struct let extend_option_iterations = Int.pow 2 10 - let override_wrap_domain = None + let override_wrap_domain = Some `N1 end module Made_without_length = Folder.Make (M_without_length) () diff --git a/src/app/zeko/circuits/rule_commit.ml b/src/app/zeko/circuits/rule_commit.ml index 10a471e371..ac4f6c362a 100644 --- a/src/app/zeko/circuits/rule_commit.ml +++ b/src/app/zeko/circuits/rule_commit.ml @@ -10,14 +10,14 @@ open Checked.Let_syntax module Ase_outer_inst = Ase.Without_length.Make (struct module Action_state = Outer_action_state - let get_iterations = Int.pow 2 14 + let get_iterations = Int.pow 2 10 end) (** Used to prove the length of the inner action state as stored on the outer account. *) module Ase_inner_inst = Ase.With_length.Make (struct module Action_state = Inner_action_state - let get_iterations = Int.pow 2 14 + let get_iterations = Int.pow 2 10 end) (** Proves both Ase_outer_inst and Ase_inner_inst, to circumvent limitation of two recursive proof verifications per proof. *) @@ -38,7 +38,8 @@ module Verify_both_ases = struct } include - ( val Compile_simple.compile ~name:"Verify_both_ases" ~branches:[ rule ] + ( val Compile_simple.compile ~override_wrap_domain:`N1 + ~name:"Verify_both_ases" ~branches:[ rule ] ~out_typ:Typ.(Ase_outer_inst.Stmt.typ * Ase_inner_inst.Stmt.typ) () ) From 9a4af2642cc74414194816ab0b5632e2b1662580 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Thu, 2 Jan 2025 16:38:30 +0100 Subject: [PATCH 03/22] Add serialization of Account_set.t --- src/app/zeko/circuits/indexed_merkle_tree.ml | 2 +- src/app/zeko/circuits/indexed_merkle_tree.mli | 2 +- src/app/zeko/circuits/zeko_transaction_snark.mli | 2 +- src/app/zeko/circuits/zeko_util.ml | 2 +- src/app/zeko/circuits/zeko_util.mli | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/zeko/circuits/indexed_merkle_tree.ml b/src/app/zeko/circuits/indexed_merkle_tree.ml index ebddca9bdd..9fc8af6908 100644 --- a/src/app/zeko/circuits/indexed_merkle_tree.ml +++ b/src/app/zeko/circuits/indexed_merkle_tree.ml @@ -16,7 +16,7 @@ struct type t = { key : Key.t; next_key : Key.t } [@@deriving snarky] end - type t = F.t + type t = F.t [@@deriving yojson] type var = F.var diff --git a/src/app/zeko/circuits/indexed_merkle_tree.mli b/src/app/zeko/circuits/indexed_merkle_tree.mli index 22ece44a3a..61cf50b108 100644 --- a/src/app/zeko/circuits/indexed_merkle_tree.mli +++ b/src/app/zeko/circuits/indexed_merkle_tree.mli @@ -27,7 +27,7 @@ module Make (Inputs : sig end) : sig open Inputs - type t + type t [@@deriving yojson] type var diff --git a/src/app/zeko/circuits/zeko_transaction_snark.mli b/src/app/zeko/circuits/zeko_transaction_snark.mli index 1ee131d49e..33929ce30b 100644 --- a/src/app/zeko/circuits/zeko_transaction_snark.mli +++ b/src/app/zeko/circuits/zeko_transaction_snark.mli @@ -40,7 +40,7 @@ module Local_state : sig end module Account_set : sig - type t + type t [@@deriving yojson] type var diff --git a/src/app/zeko/circuits/zeko_util.ml b/src/app/zeko/circuits/zeko_util.ml index fd3eab6b6a..dcee9d7040 100644 --- a/src/app/zeko/circuits/zeko_util.ml +++ b/src/app/zeko/circuits/zeko_util.ml @@ -95,7 +95,7 @@ let var_to_app_state_fine = (** To be used with deriving snarky, a simple field *) module F = struct - type t = field + type t = Field.t [@@deriving yojson] type var = Field.Var.t diff --git a/src/app/zeko/circuits/zeko_util.mli b/src/app/zeko/circuits/zeko_util.mli index a864f6f108..93bc7d36fb 100644 --- a/src/app/zeko/circuits/zeko_util.mli +++ b/src/app/zeko/circuits/zeko_util.mli @@ -39,7 +39,7 @@ val var_to_hash : init:string -> ('var, 'value) Typ.t -> 'var -> Field.Var.t Checked.t module F : sig - type t = Pasta_bindings.Fp.t + type t = Pasta_bindings.Fp.t [@@deriving yojson] type var = Field.Var.t From b24821e57a8ed36e83e94f8bfd1652b7c4ab3f86 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 6 Jan 2025 15:32:10 +0100 Subject: [PATCH 04/22] Integrate zeko_transaction_snark into the prover/client --- .../zeko/circuits/zeko_transaction_snark.ml | 4 +- .../zeko/circuits/zeko_transaction_snark.mli | 4 +- src/app/zeko/circuits/zeko_util.ml | 4 +- src/app/zeko/circuits/zeko_util.mli | 4 +- src/app/zeko/sequencer/prover/lib/client.ml | 146 ++++---- src/app/zeko/sequencer/prover/lib/prover.ml | 343 +++++++++++++----- 6 files changed, 331 insertions(+), 174 deletions(-) diff --git a/src/app/zeko/circuits/zeko_transaction_snark.ml b/src/app/zeko/circuits/zeko_transaction_snark.ml index c6e38b514f..352d4e4c65 100644 --- a/src/app/zeko/circuits/zeko_transaction_snark.ml +++ b/src/app/zeko/circuits/zeko_transaction_snark.ml @@ -359,7 +359,7 @@ module Local_state = struct ; excess : Currency.Amount.Signed.t ; account_update_index : Account_update_index.t } - [@@deriving snarky] + [@@deriving snarky, yojson] let to_mina_var ~supply_increase { ledger @@ -410,7 +410,7 @@ module Zeko_stmt = struct ; source_local_state : Local_state.t ; target_local_state : Local_state.t } - [@@deriving snarky] + [@@deriving snarky, yojson] end module T = struct diff --git a/src/app/zeko/circuits/zeko_transaction_snark.mli b/src/app/zeko/circuits/zeko_transaction_snark.mli index 33929ce30b..eba871319b 100644 --- a/src/app/zeko/circuits/zeko_transaction_snark.mli +++ b/src/app/zeko/circuits/zeko_transaction_snark.mli @@ -29,7 +29,7 @@ module Local_state : sig ; excess : Currency.Amount.Signed.t ; account_update_index : Account_update_index.t } - [@@deriving snarky] + [@@deriving snarky, yojson] val to_mina_var : supply_increase:Currency.Amount.Signed.var @@ -71,7 +71,7 @@ module Zeko_stmt : sig ; source_local_state : Local_state.t ; target_local_state : Local_state.t } - [@@deriving snarky] + [@@deriving snarky, yojson] end module T : sig diff --git a/src/app/zeko/circuits/zeko_util.ml b/src/app/zeko/circuits/zeko_util.ml index dcee9d7040..f106ebbfb5 100644 --- a/src/app/zeko/circuits/zeko_util.ml +++ b/src/app/zeko/circuits/zeko_util.ml @@ -248,7 +248,7 @@ module Slot_span = struct end module Slot_range = struct - type t = { lower : Slot.t; upper : Slot.t } [@@deriving snarky] + type t = { lower : Slot.t; upper : Slot.t } [@@deriving snarky, yojson] module Checked = struct let to_valid_while (t : var) : Zkapp_precondition.Valid_while.Checked.t = @@ -390,7 +390,7 @@ let token_owner_id : Account_id.t option -> Token_id.t = function Account_id.derive_token_id ~owner module Even_PC = struct - type t = { public_key : F.t } [@@deriving snarky] + type t = { public_key : F.t } [@@deriving snarky, yojson] let to_pc_var { public_key } : Signature_lib.Public_key.Compressed.var = { x = public_key; is_odd = Boolean.false_ } diff --git a/src/app/zeko/circuits/zeko_util.mli b/src/app/zeko/circuits/zeko_util.mli index 93bc7d36fb..92c4e267c8 100644 --- a/src/app/zeko/circuits/zeko_util.mli +++ b/src/app/zeko/circuits/zeko_util.mli @@ -158,7 +158,7 @@ module Slot_span : sig end module Slot_range : sig - type t = { lower : Slot.t; upper : Slot.t } [@@deriving snarky] + type t = { lower : Slot.t; upper : Slot.t } [@@deriving snarky, yojson] module Checked : sig val to_valid_while : @@ -188,7 +188,7 @@ val push_actions_var : val token_owner_id : Account_id.t option -> Token_id.t module Even_PC : sig - type t = { public_key : F.t } [@@deriving snarky] + type t = { public_key : F.t } [@@deriving snarky, yojson] val to_pc_var : var -> Import.Public_key.Compressed.var end diff --git a/src/app/zeko/sequencer/prover/lib/client.ml b/src/app/zeko/sequencer/prover/lib/client.ml index 849ab4251c..63fb1bb6fe 100644 --- a/src/app/zeko/sequencer/prover/lib/client.ml +++ b/src/app/zeko/sequencer/prover/lib/client.ml @@ -1,5 +1,6 @@ open Async open Core_kernel +open Zeko_circuits let try_connect where_to_connect = match%bind try_with (fun () -> Tcp.connect where_to_connect) with @@ -104,88 +105,97 @@ let rec send ?(proving_timeout = 10.) ?(wait_for_prover_timeout = 600.) send ~proving_timeout ~attempts:(attempts - 1) t input ) else failwith "Timeout while proving" -let wrapper_wrap ?proving_timeout t ~txn_snark = - send ?proving_timeout t (Prover.Input.Wrapper_wrap txn_snark) - >>| function - | Prover.Output.Wrapper_wrap x -> x | _ -> failwith "Unexpected response" - -let wrapper_merge ?proving_timeout t a b = - send ?proving_timeout t (Prover.Input.Wrapper_merge (a, b)) - >>| function - | Prover.Output.Wrapper_merge x -> x | _ -> failwith "Unexpected response" - -let transaction_snark_of_signed_command ?proving_timeout t ~statement - ~user_command_in_block ~sparse_ledger = +let transaction_snark_of_single_signed_command ?proving_timeout t ~source_ledger + ~source_acc_set ~sequencer_pk ~command ~sparse_ledger = send ?proving_timeout t - (Prover.Input.Transaction_snark_of_signed_command - (statement, user_command_in_block, sparse_ledger) ) + (Prover.Input.Txn_snark_single_signed_command + (source_ledger, source_acc_set, sequencer_pk, command, sparse_ledger) ) >>| function - | Prover.Output.Transaction_snark_of_signed_command x -> - x + | Prover.Output.Zeko_transaction_snark (stmt, proof) -> + Zeko_transaction_snark.make_unchecked ~proof stmt | _ -> - failwith "Unexpected response" + failwith "Unexpected response from prover" -let transaction_snark_of_zkapp_command_segment ?proving_timeout t ~statement - ~witness ~spec = +let transaction_snark_of_single_unproved_zkapp_command ?proving_timeout t + ~source_ledger ~target_ledger ~connecting_ledger ~source_local_state + ~target_local_state ~fee_excess ~supply_decrease ~txn_snark_witness + ~sequencer ~source_acc_set ~shift_action_state = send ?proving_timeout t - (Prover.Input.Transaction_snark_of_zkapp_command_segment - (statement, witness, spec) ) + (Prover.Input.Txn_snark_single_unproved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , shift_action_state ) ) >>| function - | Prover.Output.Transaction_snark_of_zkapp_command_segment x -> - x + | Prover.Output.Zeko_transaction_snark (stmt, proof) -> + Zeko_transaction_snark.make_unchecked ~proof stmt | _ -> - failwith "Unexpected response" + failwith "Unexpected response from prover" -let transaction_snark_merge ?proving_timeout t a b = - send ?proving_timeout t (Prover.Input.Transaction_snark_merge (a, b)) - >>| function - | Prover.Output.Transaction_snark_merge x -> - x - | _ -> - failwith "Unexpected response" - -let submit_deposit ?proving_timeout t ~outer_pk ~deposit = - send ?proving_timeout t (Prover.Input.Submit_deposit (outer_pk, deposit)) - >>| function - | Prover.Output.Submit_deposit x -> x | _ -> failwith "Unexpected response" - -let submit_withdrawal ?proving_timeout t ~withdrawal = - send ?proving_timeout t (Prover.Input.Submit_withdrawal withdrawal) - >>| function - | Prover.Output.Submit_withdrawal x -> x | _ -> failwith "Unexpected response" - -let process_deposit ?proving_timeout t ~is_new ~pointer ~before ~after ~deposit - = +let transaction_snark_of_double_unproved_zkapp_command ?proving_timeout t + ~source_ledger ~target_ledger ~connecting_ledger ~source_local_state + ~target_local_state ~fee_excess ~supply_decrease ~txn_snark_witness + ~sequencer ~source_acc_set ~shift_action_state_first + ~shift_action_state_second = send ?proving_timeout t - (Prover.Input.Process_deposit (is_new, pointer, before, after, deposit)) + (Prover.Input.Txn_snark_double_unproved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , shift_action_state_first + , shift_action_state_second ) ) >>| function - | Prover.Output.Process_deposit x -> x | _ -> failwith "Unexpected response" + | Prover.Output.Zeko_transaction_snark (stmt, proof) -> + Zeko_transaction_snark.make_unchecked ~proof stmt + | _ -> + failwith "Unexpected response from prover" -let process_withdrawal ?proving_timeout t ~outer_pk ~is_new ~pointer ~before - ~after ~withdrawal = +let transaction_snark_of_single_proved_zkapp_command ?proving_timeout t + ~source_ledger ~target_ledger ~connecting_ledger ~source_local_state + ~target_local_state ~fee_excess ~supply_decrease ~txn_snark_witness + ~sequencer ~source_acc_set ~zkapp_vk ~zkapp_proof ~shift_action_state = send ?proving_timeout t - (Prover.Input.Process_withdrawal - (outer_pk, is_new, pointer, before, after, withdrawal) ) + (Prover.Input.Txn_snark_single_proved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , zkapp_vk + , zkapp_proof + , shift_action_state ) ) >>| function - | Prover.Output.Process_withdrawal x -> - x + | Prover.Output.Zeko_transaction_snark (stmt, proof) -> + Zeko_transaction_snark.make_unchecked ~proof stmt | _ -> - failwith "Unexpected response" + failwith "Unexpected response from prover" -let outer_step ?proving_timeout t ~last ~outer_public_key ~new_deposits - ~unprocessed_deposits ~old_inner_ledger ~new_inner_ledger = +let transaction_snark_of_merge ?proving_timeout t + ~(left : Zeko_transaction_snark.T.t) ~(right : Zeko_transaction_snark.T.t) = send ?proving_timeout t - (Prover.Input.Outer_step - ( last - , outer_public_key - , new_deposits - , unprocessed_deposits - , old_inner_ledger - , new_inner_ledger ) ) + (Prover.Input.Txn_snark_merge + (left.stmt, left.proof, right.stmt, right.proof) ) >>| function - | Prover.Output.Outer_step x -> x | _ -> failwith "Unexpected response" - -let inner_step ?proving_timeout t ~all_deposits = - send ?proving_timeout t (Prover.Input.Inner_step all_deposits) - >>| function - | Prover.Output.Inner_step x -> x | _ -> failwith "Unexpected response" + | Prover.Output.Zeko_transaction_snark (stmt, proof) -> + Zeko_transaction_snark.make_unchecked ~proof stmt + | _ -> + failwith "Unexpected response from prover" diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index 0d199d0658..dc1a983966 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -3,6 +3,7 @@ open Async open Mina_base open Mina_ledger open Signature_lib +open Zeko_circuits (* Only for yojson serialization of Field *) module Field = Data_hash.Make_full_size (struct @@ -30,117 +31,263 @@ let dummy_sok = (* Unfortunately yojson doesn't support GADTs so it can't be one type, or maybe I'm just bad *) module Input = struct type t = - | Wrapper_wrap of Transaction_snark.t - | Wrapper_merge of (Zkapps_rollup.t * Zkapps_rollup.t) - | Transaction_snark_of_signed_command of - ( Mina_state.Snarked_ledger_state.With_sok.t - * Signed_command.With_valid_signature.t Transaction_protocol_state.t + | Txn_snark_single_signed_command of + ( Ledger_hash.t + * Zeko_transaction_snark.Account_set.t + * Zeko_util.Even_PC.t + * Signed_command.t * Sparse_ledger.t ) - | Transaction_snark_of_zkapp_command_segment of - ( Mina_state.Snarked_ledger_state.With_sok.t - * Transaction_witness.Zkapp_command_segment_witness.t - * Transaction_snark.Zkapp_command_segment.Basic.t ) - | Transaction_snark_merge of (Transaction_snark.t * Transaction_snark.t) - | Submit_deposit of (Public_key.Compressed.t * Zkapps_rollup.TR.t) - | Submit_withdrawal of Zkapps_rollup.TR.t - | Process_deposit of - ( bool - * Field.t - * Zkapps_rollup.TR.t list - * Zkapps_rollup.TR.t list - * Zkapps_rollup.TR.t ) - | Process_withdrawal of - ( Public_key.Compressed.t + | Txn_snark_single_unproved_zkapp_command of + ( Ledger_hash.t + * Ledger_hash.t + * Ledger_hash.t + * Zeko_transaction_snark.Local_state.t + * Zeko_transaction_snark.Local_state.t + * Currency.Fee.Signed.t + * Currency.Amount.t + * Transaction_snark.Zkapp_command_segment.Witness.t + * Zeko_util.Even_PC.t + * Zeko_transaction_snark.Account_set.t + * bool ) + | Txn_snark_double_unproved_zkapp_command of + ( Ledger_hash.t + * Ledger_hash.t + * Ledger_hash.t + * Zeko_transaction_snark.Local_state.t + * Zeko_transaction_snark.Local_state.t + * Currency.Fee.Signed.t + * Currency.Amount.t + * Transaction_snark.Zkapp_command_segment.Witness.t + * Zeko_util.Even_PC.t + * Zeko_transaction_snark.Account_set.t * bool - * Field.t - * Zkapps_rollup.TR.t list - * Zkapps_rollup.TR.t list - * Zkapps_rollup.TR.t ) - | Outer_step of - ( Zkapps_rollup.t - * Public_key.Compressed.t - * Zkapps_rollup.TR.t list - * Zkapps_rollup.TR.t list - * Sparse_ledger.t - * Sparse_ledger.t ) - | Inner_step of Field.t + * bool ) + | Txn_snark_single_proved_zkapp_command of + ( Ledger_hash.t + * Ledger_hash.t + * Ledger_hash.t + * Zeko_transaction_snark.Local_state.t + * Zeko_transaction_snark.Local_state.t + * Currency.Fee.Signed.t + * Currency.Amount.t + * Transaction_snark.Zkapp_command_segment.Witness.t + * Zeko_util.Even_PC.t + * Zeko_transaction_snark.Account_set.t + * Pickles.Side_loaded.Verification_key.t + * Compile_simple.Proof.t + * bool ) + | Txn_snark_merge of + ( Zeko_transaction_snark.Zeko_stmt.t + * Compile_simple.Proof.t + * Zeko_transaction_snark.Zeko_stmt.t + * Compile_simple.Proof.t ) [@@deriving yojson] end -let asd = Ledger_hash.to_yojson - module Output = struct type t = - | Wrapper_wrap of Zkapps_rollup.t - | Wrapper_merge of Zkapps_rollup.t - | Transaction_snark_of_signed_command of Transaction_snark.t - | Transaction_snark_of_zkapp_command_segment of Transaction_snark.t - | Transaction_snark_merge of Transaction_snark.t - | Submit_deposit of Zeko_util.call_forest_tree - | Submit_withdrawal of Zeko_util.call_forest_tree - | Process_deposit of Zeko_util.call_forest - | Process_withdrawal of Zeko_util.call_forest - | Outer_step of Zeko_util.call_forest_tree - | Inner_step of Zeko_util.call_forest_tree + | Zeko_transaction_snark of + (Zeko_transaction_snark.Zeko_stmt.t * Compile_simple.Proof.t) [@@deriving yojson] end module Make (T : Transaction_snark.S) (M : Zkapps_rollup.S) = struct let prove ~logger : Input.t -> Output.t Deferred.t = function - | Wrapper_wrap txn_snark -> - time ~logger "Wrapper.wrap" (M.Wrapper.wrap txn_snark) - >>| fun x -> Output.Wrapper_wrap x - | Wrapper_merge (last, wrapped) -> - time ~logger "Wrapper.merge" (M.Wrapper.merge last wrapped) - >>| fun x -> Output.Wrapper_merge x - | Transaction_snark_of_signed_command - (statement, user_command_in_block, sparse_ledger) -> + | Txn_snark_single_signed_command + (source_ledger, source_acc_set, sequencer, command, sparse_ledger) -> + let open Zeko_transaction_snark in let handler = unstage @@ Sparse_ledger.handler sparse_ledger in - time ~logger "Transaction_snark.of_signed_command" - (T.of_user_command ~init_stack:Mina_base.Pending_coinbase.Stack.empty - ~statement user_command_in_block handler ) - >>| fun x -> Output.Transaction_snark_of_signed_command x - | Transaction_snark_of_zkapp_command_segment (statement, witness, spec) -> - time ~logger "Transaction_snark.of_zkapp_command_segment" - (T.of_zkapp_command_segment_exn ~statement ~witness ~spec) - >>| fun x -> Output.Transaction_snark_of_zkapp_command_segment x - | Transaction_snark_merge (a, b) -> - time ~logger "Transaction_snark.merge" - (T.merge a b ~sok_digest:dummy_sok) - >>| Or_error.ok_exn - >>| fun x -> Output.Transaction_snark_merge x - | Submit_deposit (outer_public_key, deposit) -> - time ~logger "Outer.Submit_deposit" - (M.Outer.submit_deposit ~outer_public_key ~deposit) - >>| fun x -> Output.Submit_deposit x - | Submit_withdrawal withdrawal -> - time ~logger "Inner.Submit_withdrawal" - (M.Inner.submit_withdrawal ~withdrawal) - >>| fun x -> Output.Submit_withdrawal x - | Process_deposit (is_new, pointer, before, after, deposit) -> - time ~logger "Inner.Process_deposit" - (M.Inner.process_deposit ~is_new ~pointer ~before ~after ~deposit) - >>| fun (_, x) -> Output.Process_deposit x - | Process_withdrawal - (outer_public_key, is_new, pointer, before, after, withdrawal) -> - time ~logger "Outer.Process_withdrawal" - (M.Outer.process_withdrawal ~outer_public_key ~is_new ~pointer ~before - ~after ~withdrawal ) - >>| fun (_, x) -> Output.Process_withdrawal x - | Outer_step - ( last - , outer_public_key - , new_deposits - , unprocessed_deposits - , old_inner_ledger - , new_inner_ledger ) -> - time ~logger "Outer.step" - (M.Outer.step last ~outer_public_key ~new_deposits - ~unprocessed_deposits ~old_inner_ledger ~new_inner_ledger ) - >>| fun x -> Output.Outer_step x - | Inner_step all_deposits -> - time ~logger "Inner.step" (M.Inner.step ~all_deposits) - >>| fun x -> Output.Inner_step x + let Compile_simple.[ single_signed_command; _; _; _; _ ] = provers in + let input : Base_input.t = + { source_ledger + ; source_acc_set + ; sequencer + ; transaction = + Mina_transaction.Transaction_union.of_transaction (Command command) + ; witness = + { ledger_path_handler = handler + ; update_acc_set_witness = + { get_account_set_x = (fun () -> failwith "get_account_set_x") + ; get_account_set_z = (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.single_signed_command" + (single_signed_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_single_unproved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , shift_action_state ) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; single_unproved_zkapp_command; _; _; _ ] = + provers + in + let input : Zkapp_single_unproved_input.t = + { base = + { source_ledger + ; target_ledger + ; connecting_ledger + ; source_local_state + ; target_local_state + ; fee_excess + ; supply_decrease + ; witness = + { txn_snark_witness + ; update_acc_set_witness = + { get_account_set_x = + (fun () -> failwith "get_account_set_x") + ; get_account_set_z = + (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + ; sequencer + ; source_acc_set + } + ; shift_action_state + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.single_unproved_zkapp_command" + (single_unproved_zkapp_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_double_unproved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , shift_action_state_first + , shift_action_state_second ) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; _; double_unproved_zkapp_command; _; _ ] = + provers + in + let input : Zkapp_double_unproved_input.t = + { base = + { source_ledger + ; target_ledger + ; connecting_ledger + ; source_local_state + ; target_local_state + ; fee_excess + ; supply_decrease + ; witness = + { txn_snark_witness + ; update_acc_set_witness = + { get_account_set_x = + (fun () -> failwith "get_account_set_x") + ; get_account_set_z = + (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + ; sequencer + ; source_acc_set + } + ; shift_action_state_first + ; shift_action_state_second + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.double_unproved_zkapp_command" + (double_unproved_zkapp_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_single_proved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , zkapp_vk + , zkapp_proof + , shift_action_state ) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; _; _; single_proved_zkapp_command; _ ] = + provers + in + let input : Zkapp_single_proved_input.t = + { base = + { source_ledger + ; target_ledger + ; connecting_ledger + ; source_local_state + ; target_local_state + ; fee_excess + ; supply_decrease + ; witness = + { txn_snark_witness + ; update_acc_set_witness = + { get_account_set_x = + (fun () -> failwith "get_account_set_x") + ; get_account_set_z = + (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + ; sequencer + ; source_acc_set + } + ; zkapp_vk + ; zkapp_proof + ; shift_action_state + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.single_proved_zkapp_command" + (single_proved_zkapp_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_merge (left_stmt, left_proof, right_stmt, right_proof) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; _; _; _; merge ] = provers in + let input : Merge_input.t = + { left = { stmt = left_stmt; proof = left_proof } + ; right = { stmt = right_stmt; proof = right_proof } + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.merge" + (merge input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) let run ~logger ~port = ignore From 55cfdd7f4745d051e40cf4c4b320011a0137e22d Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 6 Jan 2025 15:50:03 +0100 Subject: [PATCH 05/22] Stub all the remaining proving functions --- src/app/zeko/sequencer/prover/lib/client.ml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/app/zeko/sequencer/prover/lib/client.ml b/src/app/zeko/sequencer/prover/lib/client.ml index 63fb1bb6fe..784be56b72 100644 --- a/src/app/zeko/sequencer/prover/lib/client.ml +++ b/src/app/zeko/sequencer/prover/lib/client.ml @@ -199,3 +199,23 @@ let transaction_snark_of_merge ?proving_timeout t Zeko_transaction_snark.make_unchecked ~proof stmt | _ -> failwith "Unexpected response from prover" + +let inner_step ?proving_timeout t ~all_deposits = failwith "Not implemented" + +let outer_step ?proving_timeout t ~last ~outer_public_key:zkapp_pk ~new_deposits + ~unprocessed_deposits ~old_inner_ledger ~new_inner_ledger = + failwith "Not implemented" + +let submit_deposit ?proving_timeout t ~outer_pk ~deposit = + failwith "Not implemented" + +let submit_withdrawal ?proving_timeout t ~withdrawal = + failwith "Not implemented" + +let process_deposit ?proving_timeout t ~is_new ~pointer ~before ~after ~deposit + = + failwith "Not implemented" + +let process_withdrawal ?proving_timeout t ~outer_pk ~is_new ~pointer ~before + ~after ~withdrawal = + failwith "Not implemented" From 108b87717b269499107dbf21f7a176b1865844fc Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Tue, 7 Jan 2025 17:50:46 +0100 Subject: [PATCH 06/22] Integrate zeko_transaction_snark into Merger --- .../zeko/circuits/zeko_transaction_snark.ml | 10 ++ .../zeko/circuits/zeko_transaction_snark.mli | 2 +- src/app/zeko/circuits/zeko_util.ml | 4 + src/app/zeko/circuits/zeko_util.mli | 2 + .../zeko/parallel_merger/parallel_merger.ml | 14 +- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 75 ++------ src/app/zeko/sequencer/prover/lib/client.ml | 166 +++++++++++++++++- 7 files changed, 198 insertions(+), 75 deletions(-) diff --git a/src/app/zeko/circuits/zeko_transaction_snark.ml b/src/app/zeko/circuits/zeko_transaction_snark.ml index 352d4e4c65..de02f6ae97 100644 --- a/src/app/zeko/circuits/zeko_transaction_snark.ml +++ b/src/app/zeko/circuits/zeko_transaction_snark.ml @@ -415,6 +415,16 @@ end module T = struct type t = { stmt : Zeko_stmt.t; proof : Proof_V.t } [@@deriving snarky] + + let to_yojson ({ stmt; proof } : t) = + `Assoc + [ ("stmt", Zeko_stmt.to_yojson stmt); ("proof", Proof.to_yojson proof) ] + + let of_yojson json = + let open Ppx_deriving_yojson_runtime in + let stmt = Zeko_stmt.of_yojson json in + let proof = Proof.of_yojson json in + stmt >>= fun stmt -> proof >>= fun proof -> Ok ({ stmt; proof } : t) end type update_acc_set_witness = diff --git a/src/app/zeko/circuits/zeko_transaction_snark.mli b/src/app/zeko/circuits/zeko_transaction_snark.mli index eba871319b..6a7f76140d 100644 --- a/src/app/zeko/circuits/zeko_transaction_snark.mli +++ b/src/app/zeko/circuits/zeko_transaction_snark.mli @@ -76,7 +76,7 @@ end module T : sig type t = { stmt : Zeko_stmt.t; proof : Zeko_util.Proof_V.t } - [@@deriving snarky] + [@@deriving snarky, yojson] end type update_acc_set_witness = diff --git a/src/app/zeko/circuits/zeko_util.ml b/src/app/zeko/circuits/zeko_util.ml index f106ebbfb5..81a7f412c6 100644 --- a/src/app/zeko/circuits/zeko_util.ml +++ b/src/app/zeko/circuits/zeko_util.ml @@ -392,6 +392,10 @@ let token_owner_id : Account_id.t option -> Token_id.t = function module Even_PC = struct type t = { public_key : F.t } [@@deriving snarky, yojson] + let create_exn (public_key : Signature_lib.Public_key.Compressed.t) = + if public_key.is_odd then failwith "Odd public key" + else ({ public_key = public_key.x } : t) + let to_pc_var { public_key } : Signature_lib.Public_key.Compressed.var = { x = public_key; is_odd = Boolean.false_ } end diff --git a/src/app/zeko/circuits/zeko_util.mli b/src/app/zeko/circuits/zeko_util.mli index 92c4e267c8..4dfa1ae5cb 100644 --- a/src/app/zeko/circuits/zeko_util.mli +++ b/src/app/zeko/circuits/zeko_util.mli @@ -190,5 +190,7 @@ val token_owner_id : Account_id.t option -> Token_id.t module Even_PC : sig type t = { public_key : F.t } [@@deriving snarky, yojson] + val create_exn : Signature_lib.Public_key.Compressed.t -> t + val to_pc_var : var -> Import.Public_key.Compressed.var end diff --git a/src/app/zeko/parallel_merger/parallel_merger.ml b/src/app/zeko/parallel_merger/parallel_merger.ml index 08423b4364..6bcc065042 100644 --- a/src/app/zeko/parallel_merger/parallel_merger.ml +++ b/src/app/zeko/parallel_merger/parallel_merger.ml @@ -6,11 +6,11 @@ let generate_id () = Uuid_unix.create () |> Uuid.to_string module Make (Context : sig type t end) (Merge : sig - type t [@@deriving yojson] + type t val process : Context.t -> t -> t -> t Deferred.t end) (Base : sig - type t [@@deriving yojson] + type t val process : Context.t -> t -> Merge.t Deferred.t end) (Commit : sig @@ -20,17 +20,16 @@ end) (Commit : sig end) = struct module Available_job = struct - type t = Base of Base.t | Merge of Merge.t * Merge.t [@@deriving yojson] + type t = Base of Base.t | Merge of Merge.t * Merge.t end (* Finished job will be always of type `Merge.t` *) module Finished_job = struct - type t = Merge.t [@@deriving yojson] + type t = Merge.t end module Job_status = struct type t = Todo of Available_job.t | Done of Finished_job.t - [@@deriving yojson] end module With_id = struct @@ -54,7 +53,6 @@ struct ; ready_to_commit : unit Ivar.t (** All jobs are done and ready to commit *) } - [@@deriving yojson] let create () = { jobs = [] @@ -167,9 +165,7 @@ struct let is_empty t = List.is_empty t.jobs end - type t = { mutable trees : Tree.t list } [@@deriving yojson] - - let pp t = Core.printf "%s\n%!" (Yojson.Safe.pretty_to_string @@ to_yojson t) + type t = { mutable trees : Tree.t list } let create () = { trees = [] } diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index aedbff9c0a..7f18ad63bd 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -5,6 +5,7 @@ open Async_kernel open Mina_base open Mina_ledger open Signature_lib +open Zeko_circuits module L = Ledger module Field = Snark_params.Tick.Field @@ -154,7 +155,7 @@ module Sequencer = struct type t = | Signed_command of Sparse_ledger.t - * Signed_command.With_valid_signature.t Transaction_protocol_state.t + * Signed_command.t * Transaction_snark.Statement.With_sok.t | Zkapp_command of ( Transaction_witness.Zkapp_command_segment_witness.t @@ -165,49 +166,6 @@ module Sequencer = struct [@@deriving yojson] end - let wrap provers txn_snark = - Zeko_prover.Client.wrapper_wrap provers ~txn_snark - - let merge provers a b = Zeko_prover.Client.wrapper_merge provers a b - - let prove_signed_command provers ~sparse_ledger ~user_command_in_block - ~statement = - let%bind txn_snark = - Utils.print_time "Transaction_snark.of_signed_command" - (Zeko_prover.Client.transaction_snark_of_signed_command provers - ~statement ~user_command_in_block ~sparse_ledger ) - in - wrap provers txn_snark - - let prove_zkapp_command provers ~witnesses ~zkapp_command = - let%bind txn_snark = - match witnesses with - | [] -> - failwith "No witnesses" - | (witness, spec, statement) :: rest -> - let%bind p1 = - Utils.print_time "Transaction_snark.of_zkapp_command_segment" - (Zeko_prover.Client.transaction_snark_of_zkapp_command_segment - provers ~statement ~witness ~spec ) - in - Deferred.List.fold ~init:p1 rest - ~f:(fun acc (witness, spec, statement) -> - let%bind prev = return acc in - let%bind curr = - Utils.print_time "Transaction_snark.of_zkapp_command_segment" - (Zeko_prover.Client - .transaction_snark_of_zkapp_command_segment provers - ~statement ~witness ~spec ) - in - let%bind merged = - Utils.print_time "Transaction_snark.merge" - (Zeko_prover.Client.transaction_snark_merge provers curr - prev ) - in - return merged ) - in - wrap provers txn_snark - module Context = struct module State = struct type t = @@ -288,9 +246,10 @@ module Sequencer = struct end module Merge = struct - type t = Zkapps_rollup.t [@@deriving yojson] + type t = Zeko_transaction_snark.T.t - let process ({ provers; _ } : Context.t) a b = merge provers a b + let process ({ provers; _ } : Context.t) a b = + Zeko_prover.Client.transaction_snark_of_merge provers ~left:a ~right:b end module Base = struct @@ -298,13 +257,17 @@ module Sequencer = struct let process (ctx : Context.t) command_witness = Context.add_command ctx command_witness ; + let sequencer_pk = + Zeko_util.Even_PC.create_exn + @@ Public_key.compress ctx.config.signer.public_key + in match command_witness with - | Command_witness.Signed_command - (sparse_ledger, user_command_in_block, statement) -> - prove_signed_command ctx.provers ~sparse_ledger - ~user_command_in_block ~statement | Command_witness.Zkapp_command (witnesses, zkapp_command) -> - prove_zkapp_command ctx.provers ~witnesses ~zkapp_command + Zeko_prover.Client.transaction_snark_of_zkapp_command ctx.provers + ~witnesses ~sequencer_pk + | Command_witness.Signed_command (l, c, s) -> + Zeko_prover.Client.transaction_snark_of_signed_command ctx.provers + ~sequencer_pk ~witness:(l, c, s) end module Commit = struct @@ -631,14 +594,6 @@ module Sequencer = struct @@ match command with | Signed_command signed_command -> - let user_command_in_block = - { Transaction_protocol_state.Poly.transaction = - Signed_command.check_only_for_signature signed_command - |> Option.value_exn - ; block_data = state_body - ; global_slot - } - in let source_ledger_hash = Sparse_ledger.merkle_root first_pass_ledger in @@ -662,7 +617,7 @@ module Sequencer = struct Result.return ( txn_applied , Merger.Command_witness.Signed_command - (first_pass_ledger, user_command_in_block, statement) ) + (first_pass_ledger, signed_command, statement) ) | Zkapp_command zkapp_command -> let witnesses = Transaction_snark.zkapp_command_witnesses_exn diff --git a/src/app/zeko/sequencer/prover/lib/client.ml b/src/app/zeko/sequencer/prover/lib/client.ml index 784be56b72..775951ec01 100644 --- a/src/app/zeko/sequencer/prover/lib/client.ml +++ b/src/app/zeko/sequencer/prover/lib/client.ml @@ -1,6 +1,7 @@ open Async open Core_kernel open Zeko_circuits +open Mina_base let try_connect where_to_connect = match%bind try_with (fun () -> Tcp.connect where_to_connect) with @@ -112,7 +113,7 @@ let transaction_snark_of_single_signed_command ?proving_timeout t ~source_ledger (source_ledger, source_acc_set, sequencer_pk, command, sparse_ledger) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> - Zeko_transaction_snark.make_unchecked ~proof stmt + ({ stmt; proof } : Zeko_transaction_snark.T.t) | _ -> failwith "Unexpected response from prover" @@ -135,7 +136,7 @@ let transaction_snark_of_single_unproved_zkapp_command ?proving_timeout t , shift_action_state ) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> - Zeko_transaction_snark.make_unchecked ~proof stmt + ({ stmt; proof } : Zeko_transaction_snark.T.t) | _ -> failwith "Unexpected response from prover" @@ -160,7 +161,7 @@ let transaction_snark_of_double_unproved_zkapp_command ?proving_timeout t , shift_action_state_second ) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> - Zeko_transaction_snark.make_unchecked ~proof stmt + ({ stmt; proof } : Zeko_transaction_snark.T.t) | _ -> failwith "Unexpected response from prover" @@ -185,7 +186,7 @@ let transaction_snark_of_single_proved_zkapp_command ?proving_timeout t , shift_action_state ) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> - Zeko_transaction_snark.make_unchecked ~proof stmt + ({ stmt; proof } : Zeko_transaction_snark.T.t) | _ -> failwith "Unexpected response from prover" @@ -196,10 +197,151 @@ let transaction_snark_of_merge ?proving_timeout t (left.stmt, left.proof, right.stmt, right.proof) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> - Zeko_transaction_snark.make_unchecked ~proof stmt + ({ stmt; proof } : Zeko_transaction_snark.T.t) | _ -> failwith "Unexpected response from prover" +let transaction_snark_of_segment ?proving_timeout t ~sequencer_pk + ~(witness : + Transaction_witness.Zkapp_command_segment_witness.t + * Transaction_snark.Zkapp_command_segment.Basic.t + * Mina_state.Snarked_ledger_state.With_sok.t ) = + let mina_local_state_to_zeko + (t : + Mina_transaction_logic.Zkapp_command_logic.Local_state.Value.Stable.V1.t + ) : Zeko_transaction_snark.Local_state.t = + { ledger = t.ledger + ; stack_frame = t.stack_frame + ; call_stack = t.call_stack + ; transaction_commitment = t.transaction_commitment + ; full_transaction_commitment = t.full_transaction_commitment + ; excess = t.excess + ; account_update_index = t.account_update_index + } + in + let first_account_update + (witness : Transaction_witness.Zkapp_command_segment_witness.t) = + match witness.local_state_init.stack_frame.calls with + | [] -> + with_return (fun { return } -> + List.iter witness.start_zkapp_command ~f:(fun s -> + Zkapp_command.Call_forest.iteri + ~f:(fun _i x -> return (Some x)) + s.account_updates.account_updates ) ; + None ) + | xs -> + Zkapp_command.Call_forest.hd_account_update xs + in + let account_update_proof (p : Account_update.t) = + match p.authorization with + | Proof proof -> + Some proof + | Signature _ | None_given -> + None + in + let snapp_proof_data + ~(witness : Transaction_witness.Zkapp_command_segment_witness.t) = + let open Option.Let_syntax in + let%bind p = first_account_update witness in + let%map pi = account_update_proof p in + let vk = + let account_id = Account_id.create p.body.public_key p.body.token_id in + let account : Account.t = + Mina_ledger.Sparse_ledger.( + get_exn witness.local_state_init.ledger + (find_index_exn witness.local_state_init.ledger account_id)) + in + match + Option.value_map ~default:None account.zkapp ~f:(fun s -> + s.verification_key ) + with + | None -> + failwith "No verification key found in the account" + | Some s -> + s + in + (pi, vk) + in + match witness with + | witness, Opt_signed, stmt -> + transaction_snark_of_single_unproved_zkapp_command ?proving_timeout t + ~source_ledger:stmt.source.first_pass_ledger + ~target_ledger:stmt.target.second_pass_ledger + ~connecting_ledger:stmt.connecting_ledger_left (* left or right? *) + ~source_local_state:(mina_local_state_to_zeko stmt.source.local_state) + ~target_local_state:(mina_local_state_to_zeko stmt.target.local_state) + ~fee_excess:stmt.fee_excess.fee_excess_l + ~supply_decrease:stmt.supply_increase.magnitude + ~txn_snark_witness:witness ~sequencer:sequencer_pk + ~source_acc_set:(failwith "Not implemented") + ~shift_action_state:true + | witness, Opt_signed_opt_signed, stmt -> + transaction_snark_of_double_unproved_zkapp_command ?proving_timeout t + ~source_ledger:stmt.source.first_pass_ledger + ~target_ledger:stmt.target.second_pass_ledger + ~connecting_ledger:stmt.connecting_ledger_left (* left or right? *) + ~source_local_state:(mina_local_state_to_zeko stmt.source.local_state) + ~target_local_state:(mina_local_state_to_zeko stmt.target.local_state) + ~fee_excess:stmt.fee_excess.fee_excess_l + ~supply_decrease:stmt.supply_increase.magnitude + ~txn_snark_witness:witness ~sequencer:sequencer_pk + ~source_acc_set:(failwith "Not implemented") + ~shift_action_state_first:true ~shift_action_state_second:true + | witness, Proved, stmt -> ( + match snapp_proof_data ~witness with + | None -> + failwith "of_zkapp_command_segment: Expected exactly one proof" + | Some (p, v) -> + transaction_snark_of_single_proved_zkapp_command ?proving_timeout t + ~source_ledger:stmt.source.first_pass_ledger + ~target_ledger:stmt.target.second_pass_ledger + ~connecting_ledger:stmt.connecting_ledger_left (* left or right? *) + ~source_local_state: + (mina_local_state_to_zeko stmt.source.local_state) + ~target_local_state: + (mina_local_state_to_zeko stmt.target.local_state) + ~fee_excess:stmt.fee_excess.fee_excess_l + ~supply_decrease:stmt.supply_increase.magnitude + ~txn_snark_witness:witness ~sequencer:sequencer_pk + ~source_acc_set:(failwith "Not implemented") + ~zkapp_vk:v.data + ~zkapp_proof:(Compile_simple.Proof.of_pickles p) + ~shift_action_state:true ) + +let transaction_snark_of_zkapp_command ?proving_timeout t ~sequencer_pk + ~(witnesses : + ( Transaction_witness.Zkapp_command_segment_witness.t + * Transaction_snark.Zkapp_command_segment.Basic.t + * Mina_state.Snarked_ledger_state.With_sok.t ) + list ) = + match witnesses with + | [] -> + failwith "Empty zkapp command" + | witness :: rest -> + let%bind p1 = + transaction_snark_of_segment ?proving_timeout t ~sequencer_pk ~witness + in + Deferred.List.fold ~init:p1 rest ~f:(fun prev witness -> + let%bind curr = + transaction_snark_of_segment ?proving_timeout t ~sequencer_pk + ~witness + in + let%bind merged = + transaction_snark_of_merge ?proving_timeout t ~left:curr ~right:prev + in + return merged ) + +let transaction_snark_of_signed_command ?proving_timeout t ~sequencer_pk + ~(witness : + Mina_ledger.Sparse_ledger.t + * Signed_command.t + * Transaction_snark.Statement.With_sok.t ) = + let sparse_ledger, command, stmt = witness in + transaction_snark_of_single_signed_command ?proving_timeout t + ~source_ledger:stmt.source.first_pass_ledger + ~source_acc_set:(failwith "Not implemented") + ~sequencer_pk ~command ~sparse_ledger + let inner_step ?proving_timeout t ~all_deposits = failwith "Not implemented" let outer_step ?proving_timeout t ~last ~outer_public_key:zkapp_pk ~new_deposits @@ -219,3 +361,17 @@ let process_deposit ?proving_timeout t ~is_new ~pointer ~before ~after ~deposit let process_withdrawal ?proving_timeout t ~outer_pk ~is_new ~pointer ~before ~after ~withdrawal = failwith "Not implemented" + +module type S = sig + type t = Zeko_transaction_snark.T.t = + { stmt : Zeko_transaction_snark.Zeko_stmt.t + ; proof : Compile_simple.Proof.t + } + + type var = Zeko_transaction_snark.T.var = + { stmt : Zeko_transaction_snark.Zeko_stmt.var + ; proof : Zeko_circuits.Zeko_util.Proof_V.var + } + + val typ : (var, t) Account_update.Impl.Internal_Basic.Typ.t +end From 7fae6e4cbf8915b3babcb24e9dd88b7395925dd4 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Thu, 9 Jan 2025 15:04:34 +0100 Subject: [PATCH 07/22] Add inner sync to the prover --- src/app/zeko/circuits/compile_simple.ml | 4 + src/app/zeko/circuits/compile_simple.mli | 4 + src/app/zeko/sequencer/prover/cli.ml | 10 +- src/app/zeko/sequencer/prover/lib/client.ml | 22 +- src/app/zeko/sequencer/prover/lib/prover.ml | 494 +++++++++++--------- 5 files changed, 283 insertions(+), 251 deletions(-) diff --git a/src/app/zeko/circuits/compile_simple.ml b/src/app/zeko/circuits/compile_simple.ml index 7b59730208..1df82d17d5 100644 --- a/src/app/zeko/circuits/compile_simple.ml +++ b/src/app/zeko/circuits/compile_simple.ml @@ -7,6 +7,8 @@ type self_width = Pickles_types.Nat.N2.n module Proof = struct include Pickles.Side_loaded.Proof + let to_pickles x = x + let of_pickles x = x end @@ -20,6 +22,8 @@ module Verification_key = struct let of_pickles x = x + let to_pickles x = x + let var_of_pickles x = x let of_tag (Tag tag) = of_compiled_promise tag diff --git a/src/app/zeko/circuits/compile_simple.mli b/src/app/zeko/circuits/compile_simple.mli index d21fc7695a..174b995467 100644 --- a/src/app/zeko/circuits/compile_simple.mli +++ b/src/app/zeko/circuits/compile_simple.mli @@ -1,6 +1,8 @@ module Proof : sig type t [@@deriving yojson] + val to_pickles : t -> Pickles.Side_loaded.Proof.t + val of_pickles : Pickles.Side_loaded.Proof.t -> t end @@ -17,6 +19,8 @@ module Verification_key : sig val of_pickles : Pickles.Side_loaded.Verification_key.t -> t + val to_pickles : t -> Pickles.Side_loaded.Verification_key.t + val var_of_pickles : Pickles.Side_loaded.Verification_key.Checked.t -> var val of_tag : 'tag_var tag -> t Promise.t diff --git a/src/app/zeko/sequencer/prover/cli.ml b/src/app/zeko/sequencer/prover/cli.ml index 7d15e9f863..4cc652189c 100644 --- a/src/app/zeko/sequencer/prover/cli.ml +++ b/src/app/zeko/sequencer/prover/cli.ml @@ -1,7 +1,6 @@ open Core open Async open Signature_lib -module Server = Zeko_prover.Prover let run_server = ( "run-server" @@ -11,14 +10,7 @@ let run_server = in let logger = Logger.create () in [%log info] "Compiling circuits" ; - let module T = Transaction_snark.Make (struct - let constraint_constants = Server.constraint_constants - - let proof_level = Genesis_constants.Proof_level.Full - end) in - let module M = Zkapps_rollup.Make (T) in - let module S = Server.Make (T) (M) in - fun () -> S.run ~logger ~port ) ) + fun () -> Zeko_prover.Prover.run ~logger ~port ) ) let () = Command.group ~summary:"Zeko prover CLI" [ run_server ] |> Command_unix.run diff --git a/src/app/zeko/sequencer/prover/lib/client.ml b/src/app/zeko/sequencer/prover/lib/client.ml index 775951ec01..f1d2da9dc7 100644 --- a/src/app/zeko/sequencer/prover/lib/client.ml +++ b/src/app/zeko/sequencer/prover/lib/client.ml @@ -342,7 +342,13 @@ let transaction_snark_of_signed_command ?proving_timeout t ~sequencer_pk ~source_acc_set:(failwith "Not implemented") ~sequencer_pk ~command ~sparse_ledger -let inner_step ?proving_timeout t ~all_deposits = failwith "Not implemented" +let inner_sync ?proving_timeout t ~public_key ~ase = + send ?proving_timeout t (Prover.Input.Inner_sync (public_key, ase)) + >>| function + | Prover.Output.Inner_sync tree -> + tree + | _ -> + failwith "Unexpected response from prover" let outer_step ?proving_timeout t ~last ~outer_public_key:zkapp_pk ~new_deposits ~unprocessed_deposits ~old_inner_ledger ~new_inner_ledger = @@ -361,17 +367,3 @@ let process_deposit ?proving_timeout t ~is_new ~pointer ~before ~after ~deposit let process_withdrawal ?proving_timeout t ~outer_pk ~is_new ~pointer ~before ~after ~withdrawal = failwith "Not implemented" - -module type S = sig - type t = Zeko_transaction_snark.T.t = - { stmt : Zeko_transaction_snark.Zeko_stmt.t - ; proof : Compile_simple.Proof.t - } - - type var = Zeko_transaction_snark.T.var = - { stmt : Zeko_transaction_snark.Zeko_stmt.var - ; proof : Zeko_circuits.Zeko_util.Proof_V.var - } - - val typ : (var, t) Account_update.Impl.Internal_Basic.Typ.t -end diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index dc1a983966..2fd5d68a6b 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -5,6 +5,27 @@ open Mina_ledger open Signature_lib open Zeko_circuits +type call_forest = + ( Account_update.t + , Zkapp_command.Digest.Account_update.t + , Zkapp_command.Digest.Forest.t ) + Zkapp_command.Call_forest.t +[@@deriving yojson] + +type call_forest_tree = + ( Account_update.t + , Zkapp_command.Digest.Account_update.t + , Zkapp_command.Digest.Forest.t ) + Zkapp_command.Call_forest.Tree.t +[@@deriving yojson] + +let mktree (account_update, account_update_digest, calls) proof = + let account_update : Account_update.t = + { body = account_update; authorization = Proof proof } + in + Zkapp_command.Call_forest.Tree. + { account_update; account_update_digest; calls } + (* Only for yojson serialization of Field *) module Field = Data_hash.Make_full_size (struct let description = "Field" @@ -81,6 +102,7 @@ module Input = struct * Compile_simple.Proof.t * Zeko_transaction_snark.Zeko_stmt.t * Compile_simple.Proof.t ) + | Inner_sync of (Public_key.Compressed.t * Field.t list) [@@deriving yojson] end @@ -88,235 +110,253 @@ module Output = struct type t = | Zeko_transaction_snark of (Zeko_transaction_snark.Zeko_stmt.t * Compile_simple.Proof.t) + | Inner_sync of call_forest_tree [@@deriving yojson] end -module Make (T : Transaction_snark.S) (M : Zkapps_rollup.S) = struct - let prove ~logger : Input.t -> Output.t Deferred.t = function - | Txn_snark_single_signed_command - (source_ledger, source_acc_set, sequencer, command, sparse_ledger) -> - let open Zeko_transaction_snark in - let handler = unstage @@ Sparse_ledger.handler sparse_ledger in - let Compile_simple.[ single_signed_command; _; _; _; _ ] = provers in - let input : Base_input.t = - { source_ledger - ; source_acc_set - ; sequencer - ; transaction = - Mina_transaction.Transaction_union.of_transaction (Command command) - ; witness = - { ledger_path_handler = handler - ; update_acc_set_witness = - { get_account_set_x = (fun () -> failwith "get_account_set_x") - ; get_account_set_z = (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } - } - } - in - let%map stmt, proof = - time ~logger "Zeko_transaction_snark.single_signed_command" - (single_signed_command input |> Promise.to_deferred) - in - Output.Zeko_transaction_snark (stmt, proof) - | Txn_snark_single_unproved_zkapp_command - ( source_ledger - , target_ledger - , connecting_ledger - , source_local_state - , target_local_state - , fee_excess - , supply_decrease - , txn_snark_witness - , sequencer - , source_acc_set - , shift_action_state ) -> - let open Zeko_transaction_snark in - let Compile_simple.[ _; single_unproved_zkapp_command; _; _; _ ] = - provers - in - let input : Zkapp_single_unproved_input.t = - { base = - { source_ledger - ; target_ledger - ; connecting_ledger - ; source_local_state - ; target_local_state - ; fee_excess - ; supply_decrease - ; witness = - { txn_snark_witness - ; update_acc_set_witness = - { get_account_set_x = - (fun () -> failwith "get_account_set_x") - ; get_account_set_z = - (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } - } - ; sequencer - ; source_acc_set - } - ; shift_action_state +let prove ~logger : Input.t -> Output.t Deferred.t = function + | Txn_snark_single_signed_command + (source_ledger, source_acc_set, sequencer, command, sparse_ledger) -> + let open Zeko_transaction_snark in + let handler = unstage @@ Sparse_ledger.handler sparse_ledger in + let Compile_simple.[ single_signed_command; _; _; _; _ ] = provers in + let input : Base_input.t = + { source_ledger + ; source_acc_set + ; sequencer + ; transaction = + Mina_transaction.Transaction_union.of_transaction (Command command) + ; witness = + { ledger_path_handler = handler + ; update_acc_set_witness = + { get_account_set_x = (fun () -> failwith "get_account_set_x") + ; get_account_set_z = (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.single_signed_command" + (single_signed_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_single_unproved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , shift_action_state ) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; single_unproved_zkapp_command; _; _; _ ] = + provers + in + let input : Zkapp_single_unproved_input.t = + { base = + { source_ledger + ; target_ledger + ; connecting_ledger + ; source_local_state + ; target_local_state + ; fee_excess + ; supply_decrease + ; witness = + { txn_snark_witness + ; update_acc_set_witness = + { get_account_set_x = + (fun () -> failwith "get_account_set_x") + ; get_account_set_z = + (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + ; sequencer + ; source_acc_set + } + ; shift_action_state + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.single_unproved_zkapp_command" + (single_unproved_zkapp_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_double_unproved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , shift_action_state_first + , shift_action_state_second ) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; _; double_unproved_zkapp_command; _; _ ] = + provers + in + let input : Zkapp_double_unproved_input.t = + { base = + { source_ledger + ; target_ledger + ; connecting_ledger + ; source_local_state + ; target_local_state + ; fee_excess + ; supply_decrease + ; witness = + { txn_snark_witness + ; update_acc_set_witness = + { get_account_set_x = + (fun () -> failwith "get_account_set_x") + ; get_account_set_z = + (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + ; sequencer + ; source_acc_set + } + ; shift_action_state_first + ; shift_action_state_second + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.double_unproved_zkapp_command" + (double_unproved_zkapp_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_single_proved_zkapp_command + ( source_ledger + , target_ledger + , connecting_ledger + , source_local_state + , target_local_state + , fee_excess + , supply_decrease + , txn_snark_witness + , sequencer + , source_acc_set + , zkapp_vk + , zkapp_proof + , shift_action_state ) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; _; _; single_proved_zkapp_command; _ ] = + provers + in + let input : Zkapp_single_proved_input.t = + { base = + { source_ledger + ; target_ledger + ; connecting_ledger + ; source_local_state + ; target_local_state + ; fee_excess + ; supply_decrease + ; witness = + { txn_snark_witness + ; update_acc_set_witness = + { get_account_set_x = + (fun () -> failwith "get_account_set_x") + ; get_account_set_z = + (fun () -> failwith "get_account_set_z") + ; get_account_set_x_path = + (fun () -> failwith "get_account_set_x_path") + ; get_account_set_y_path = + (fun () -> failwith "get_account_set_y_path") + } + } + ; sequencer + ; source_acc_set + } + ; zkapp_vk + ; zkapp_proof + ; shift_action_state + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.single_proved_zkapp_command" + (single_proved_zkapp_command input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Txn_snark_merge (left_stmt, left_proof, right_stmt, right_proof) -> + let open Zeko_transaction_snark in + let Compile_simple.[ _; _; _; _; merge ] = provers in + let input : Merge_input.t = + { left = { stmt = left_stmt; proof = left_proof } + ; right = { stmt = right_stmt; proof = right_proof } + } + in + let%map stmt, proof = + time ~logger "Zeko_transaction_snark.merge" + (merge input |> Promise.to_deferred) + in + Output.Zeko_transaction_snark (stmt, proof) + | Inner_sync (public_key, ase_fields) -> + let open Inner_rules in + let Compile_simple.[ inner_sync; _ ] = provers in + let%bind vk = + Compile_simple.Verification_key.of_tag Inner_rules.tag + |> Promise.to_deferred + in + let input = + ( { public_key + ; vk_hash = + Zkapp_account.digest_vk + (Compile_simple.Verification_key.to_pickles vk) + ; ase = failwith "Not implemented" } - in - let%map stmt, proof = - time ~logger "Zeko_transaction_snark.single_unproved_zkapp_command" - (single_unproved_zkapp_command input |> Promise.to_deferred) - in - Output.Zeko_transaction_snark (stmt, proof) - | Txn_snark_double_unproved_zkapp_command - ( source_ledger - , target_ledger - , connecting_ledger - , source_local_state - , target_local_state - , fee_excess - , supply_decrease - , txn_snark_witness - , sequencer - , source_acc_set - , shift_action_state_first - , shift_action_state_second ) -> - let open Zeko_transaction_snark in - let Compile_simple.[ _; _; double_unproved_zkapp_command; _; _ ] = - provers - in - let input : Zkapp_double_unproved_input.t = - { base = - { source_ledger - ; target_ledger - ; connecting_ledger - ; source_local_state - ; target_local_state - ; fee_excess - ; supply_decrease - ; witness = - { txn_snark_witness - ; update_acc_set_witness = - { get_account_set_x = - (fun () -> failwith "get_account_set_x") - ; get_account_set_z = - (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } - } - ; sequencer - ; source_acc_set - } - ; shift_action_state_first - ; shift_action_state_second - } - in - let%map stmt, proof = - time ~logger "Zeko_transaction_snark.double_unproved_zkapp_command" - (double_unproved_zkapp_command input |> Promise.to_deferred) - in - Output.Zeko_transaction_snark (stmt, proof) - | Txn_snark_single_proved_zkapp_command - ( source_ledger - , target_ledger - , connecting_ledger - , source_local_state - , target_local_state - , fee_excess - , supply_decrease - , txn_snark_witness - , sequencer - , source_acc_set - , zkapp_vk - , zkapp_proof - , shift_action_state ) -> - let open Zeko_transaction_snark in - let Compile_simple.[ _; _; _; single_proved_zkapp_command; _ ] = - provers - in - let input : Zkapp_single_proved_input.t = - { base = - { source_ledger - ; target_ledger - ; connecting_ledger - ; source_local_state - ; target_local_state - ; fee_excess - ; supply_decrease - ; witness = - { txn_snark_witness - ; update_acc_set_witness = - { get_account_set_x = - (fun () -> failwith "get_account_set_x") - ; get_account_set_z = - (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } - } - ; sequencer - ; source_acc_set - } - ; zkapp_vk - ; zkapp_proof - ; shift_action_state - } - in - let%map stmt, proof = - time ~logger "Zeko_transaction_snark.single_proved_zkapp_command" - (single_proved_zkapp_command input |> Promise.to_deferred) - in - Output.Zeko_transaction_snark (stmt, proof) - | Txn_snark_merge (left_stmt, left_proof, right_stmt, right_proof) -> - let open Zeko_transaction_snark in - let Compile_simple.[ _; _; _; _; merge ] = provers in - let input : Merge_input.t = - { left = { stmt = left_stmt; proof = left_proof } - ; right = { stmt = right_stmt; proof = right_proof } - } - in - let%map stmt, proof = - time ~logger "Zeko_transaction_snark.merge" - (merge input |> Promise.to_deferred) - in - Output.Zeko_transaction_snark (stmt, proof) + : Rule_inner_sync.Witness.t ) + in + let%map (a, au), proof = + time ~logger "Inner_rules.inner_sync" + (inner_sync input |> Promise.to_deferred) + in + Output.Inner_sync (mktree au (Compile_simple.Proof.to_pickles proof)) - let run ~logger ~port = - ignore - @@ Tcp.Server.create (Tcp.Where_to_listen.of_port port) - ~on_handler_error:`Ignore (fun s r w -> - [%log info] "Accepted connection from %s" - (Socket.Address.Inet.to_string s) ; - let%bind () = - Pipe.transfer' ~max_queue_length:1 (Reader.pipe r) (Writer.pipe w) - ~f: - (Deferred.Queue.map ~how:`Sequential ~f:(fun input -> - Yojson.Safe.from_string input - |> Input.of_yojson - |> function - | Ok input -> ( - match%bind - try_with (fun () -> prove ~logger input) - with - | Ok output -> - Output.to_yojson output |> Yojson.Safe.to_string - |> fun s -> String.concat [ s; "\n" ] |> return - | Error e -> - return (Exn.to_string e) ) - | Error e -> - return e ) ) - in - return - ([%log info] "Closed connection from %s" - (Socket.Address.Inet.to_string s) ) ) ; - [%log info] "Listening on port %d\n" port ; - Deferred.never () -end +let run ~logger ~port = + ignore + @@ Tcp.Server.create (Tcp.Where_to_listen.of_port port) + ~on_handler_error:`Ignore (fun s r w -> + [%log info] "Accepted connection from %s" + (Socket.Address.Inet.to_string s) ; + let%bind () = + Pipe.transfer' ~max_queue_length:1 (Reader.pipe r) (Writer.pipe w) + ~f: + (Deferred.Queue.map ~how:`Sequential ~f:(fun input -> + Yojson.Safe.from_string input + |> Input.of_yojson + |> function + | Ok input -> ( + match%bind try_with (fun () -> prove ~logger input) with + | Ok output -> + Output.to_yojson output |> Yojson.Safe.to_string + |> fun s -> String.concat [ s; "\n" ] |> return + | Error e -> + return (Exn.to_string e) ) + | Error e -> + return e ) ) + in + return + ([%log info] "Closed connection from %s" + (Socket.Address.Inet.to_string s) ) ) ; + [%log info] "Listening on port %d\n" port ; + Deferred.never () From 55dbe9d908956d130b11ab92df89e75fe24857d1 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 13 Jan 2025 15:00:17 +0100 Subject: [PATCH 08/22] Add outer commit to the prover --- src/app/zeko/sequencer/prover/lib/client.ml | 25 +++++- src/app/zeko/sequencer/prover/lib/prover.ml | 89 ++++++++++++++++++--- 2 files changed, 102 insertions(+), 12 deletions(-) diff --git a/src/app/zeko/sequencer/prover/lib/client.ml b/src/app/zeko/sequencer/prover/lib/client.ml index f1d2da9dc7..9ad2ee53a6 100644 --- a/src/app/zeko/sequencer/prover/lib/client.ml +++ b/src/app/zeko/sequencer/prover/lib/client.ml @@ -342,10 +342,29 @@ let transaction_snark_of_signed_command ?proving_timeout t ~sequencer_pk ~source_acc_set:(failwith "Not implemented") ~sequencer_pk ~command ~sparse_ledger -let inner_sync ?proving_timeout t ~public_key ~ase = - send ?proving_timeout t (Prover.Input.Inner_sync (public_key, ase)) +let inner_sync ?proving_timeout t ~public_key ~all_actions = + send ?proving_timeout t (Prover.Input.Inner_sync (public_key, all_actions)) >>| function - | Prover.Output.Inner_sync tree -> + | Prover.Output.Call_forest_tree tree -> + tree + | _ -> + failwith "Unexpected response from prover" + +let outer_commit ?proving_timeout t ~txn_snark ~public_key ~new_actions + ~unprocessed_actions ~old_inner_ledger ~new_inner_ledger ~da_signature + ~da_key = + send ?proving_timeout t + (Prover.Input.Outer_commit + ( txn_snark + , public_key + , new_actions + , unprocessed_actions + , old_inner_ledger + , new_inner_ledger + , da_signature + , da_key ) ) + >>| function + | Prover.Output.Call_forest_tree tree -> tree | _ -> failwith "Unexpected response from prover" diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index 2fd5d68a6b..918026818a 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -4,6 +4,7 @@ open Mina_base open Mina_ledger open Signature_lib open Zeko_circuits +module Field = Snark_params.Tick.Field type call_forest = ( Account_update.t @@ -26,13 +27,6 @@ let mktree (account_update, account_update_digest, calls) proof = Zkapp_command.Call_forest.Tree. { account_update; account_update_digest; calls } -(* Only for yojson serialization of Field *) -module Field = Data_hash.Make_full_size (struct - let description = "Field" - - let version_byte = '\x00' -end) - let constraint_constants = Genesis_constants.Compiled.constraint_constants let time ~logger label (d : 'a Deferred.t) = @@ -103,6 +97,15 @@ module Input = struct * Zeko_transaction_snark.Zeko_stmt.t * Compile_simple.Proof.t ) | Inner_sync of (Public_key.Compressed.t * Field.t list) + | Outer_commit of + ( Zeko_transaction_snark.T.t + * Public_key.Compressed.t + * Field.t list + * Field.t list + * Sparse_ledger.t + * Sparse_ledger.t + * Signature.t + * Public_key.Compressed.t ) [@@deriving yojson] end @@ -110,7 +113,7 @@ module Output = struct type t = | Zeko_transaction_snark of (Zeko_transaction_snark.Zeko_stmt.t * Compile_simple.Proof.t) - | Inner_sync of call_forest_tree + | Call_forest_tree of call_forest_tree [@@deriving yojson] end @@ -330,7 +333,75 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function time ~logger "Inner_rules.inner_sync" (inner_sync input |> Promise.to_deferred) in - Output.Inner_sync (mktree au (Compile_simple.Proof.to_pickles proof)) + Output.Call_forest_tree + (mktree au (Compile_simple.Proof.to_pickles proof)) + | Outer_commit + ( txn_snark + , public_key + , _ase1 + , _ase2 + , old_inner_ledger + , new_inner_ledger + , da_signature + , da_key ) -> + let open Outer_rules in + let Compile_simple.[ commit; _; _ ] = provers in + let%bind vk = + Compile_simple.Verification_key.of_tag Outer_rules.tag + |> Promise.to_deferred + in + let inner_account_index = 0 in + let old_inner_acc = + Mina_ledger.Sparse_ledger.get_exn old_inner_ledger inner_account_index + in + let old_inner_acc_path = + List.map ~f:(function + | `Left _ -> + ( { right_side = Field.zero } + : Outer_rules.Rule_commit_inst.PathElt.t ) + | `Right _ -> + ( { right_side = Field.one } + : Outer_rules.Rule_commit_inst.PathElt.t ) ) + @@ Mina_ledger.Sparse_ledger.path_exn old_inner_ledger + inner_account_index + in + let new_inner_acc = + Mina_ledger.Sparse_ledger.get_exn new_inner_ledger inner_account_index + in + let new_inner_acc_path = + List.map ~f:(function + | `Left _ -> + ( { right_side = Field.zero } + : Outer_rules.Rule_commit_inst.PathElt.t ) + | `Right _ -> + ( { right_side = Field.one } + : Outer_rules.Rule_commit_inst.PathElt.t ) ) + @@ Mina_ledger.Sparse_ledger.path_exn new_inner_ledger + inner_account_index + in + let input = + ( { txn_snark = + Zeko_transaction_snark.make_unchecked ~proof:txn_snark.proof + txn_snark.stmt + ; public_key + ; vk_hash = + Zkapp_account.digest_vk + (Compile_simple.Verification_key.to_pickles vk) + ; verify_both_ases = failwith "Not implemented" + ; old_inner_acc + ; old_inner_acc_path + ; new_inner_acc + ; new_inner_acc_path + ; da_signature + ; da_key + } + : Outer_rules.Rule_commit_inst.Witness.t ) + in + let%map (a, au), proof = + time ~logger "Outer_rules.commit" (commit input |> Promise.to_deferred) + in + Output.Call_forest_tree + (mktree au (Compile_simple.Proof.to_pickles proof)) let run ~logger ~port = ignore From 7d874de0d36cac20929d73921e6870f76fd67041 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 13 Jan 2025 17:09:52 +0100 Subject: [PATCH 09/22] Replace ases stubs with short ase implementations --- src/app/zeko/circuits/ase.ml | 35 +++++++++++++++++++- src/app/zeko/circuits/ase.mli | 11 ++++++- src/app/zeko/sequencer/prover/lib/client.ml | 8 ++--- src/app/zeko/sequencer/prover/lib/prover.ml | 36 ++++++++++++++++----- 4 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/app/zeko/circuits/ase.ml b/src/app/zeko/circuits/ase.ml index bc57f2b613..442c1d01f7 100644 --- a/src/app/zeko/circuits/ase.ml +++ b/src/app/zeko/circuits/ase.ml @@ -6,7 +6,8 @@ open Zeko_util module M_with_length = struct module Stmt = struct - type t = { action_state : F.t; length : Checked32.t } [@@deriving snarky] + type t = { action_state : F.t; length : Checked32.t } + [@@deriving snarky, yojson] end module Elem = F @@ -109,6 +110,24 @@ module With_length = struct ~length:target.length in (({ source; target } : Stmt.var), verifier) + + module Init = M_with_length.Stmt + + let prove (init : Init.t) l = + if List.length l > Made_2.get_iterations then + failwith "TODO: Too many actions to prove" + else + let proof_target = + List.fold l ~init ~f:(fun acc action -> + { action_state = + Mina_base.Zkapp_account.Actions.push_hash acc.action_state + action + ; length = Checked32.succ acc.length + } ) + in + let proof = None in + Promise.return + (Made_2.make ?proof ~proof_source:init ~proof_target init l) end end @@ -146,5 +165,19 @@ module Without_length = struct let source = Action_state.unsafe_var_of_field source in let target = Action_state.unsafe_var_of_field target in (({ source; target } : Stmt.var), verifier) + + module Init = M_without_length.Stmt + + let prove (init : Init.t) l = + if List.length l > Made_2.get_iterations then + failwith "TODO: Too many actions to prove" + else + let proof_target = + List.fold l ~init ~f:(fun acc action -> + Mina_base.Zkapp_account.Actions.push_hash acc action ) + in + let proof = None in + Promise.return + (Made_2.make ?proof ~proof_source:init ~proof_target init l) end end diff --git a/src/app/zeko/circuits/ase.mli b/src/app/zeko/circuits/ase.mli index 862a548833..8fb5fc0249 100644 --- a/src/app/zeko/circuits/ase.mli +++ b/src/app/zeko/circuits/ase.mli @@ -5,7 +5,8 @@ open Zeko_util module With_length : sig module Stmt : sig - type t = { action_state : F.t; length : Checked32.t } [@@deriving snarky] + type t = { action_state : F.t; length : Checked32.t } + [@@deriving snarky, yojson] end type trans = { source : Stmt.t; target : Stmt.t } @@ -45,6 +46,8 @@ module With_length : sig val get_iterations : int end) -> sig + module Init = Stmt + module Stmt : sig type t = { source : Inputs.Action_state.With_length.t @@ -69,6 +72,8 @@ module With_length : sig ?check:Zeko_util.Boolean.var -> var -> (Stmt.var * tag_var Compile_simple.prev) Checked.t + + val prove : Init.t -> field list -> t Promise.t end end @@ -112,6 +117,8 @@ module Without_length : sig val get_iterations : int end) -> sig + module Init = Stmt + module Stmt : sig type t = { source : Inputs.Action_state.t; target : Inputs.Action_state.t } @@ -132,5 +139,7 @@ module Without_length : sig ?check:Zeko_util.Boolean.var -> var -> (Stmt.var * tag_var Compile_simple.prev) Checked.t + + val prove : Init.t -> field list -> t Promise.t end end diff --git a/src/app/zeko/sequencer/prover/lib/client.ml b/src/app/zeko/sequencer/prover/lib/client.ml index 9ad2ee53a6..f8a7b0b8cf 100644 --- a/src/app/zeko/sequencer/prover/lib/client.ml +++ b/src/app/zeko/sequencer/prover/lib/client.ml @@ -342,8 +342,8 @@ let transaction_snark_of_signed_command ?proving_timeout t ~sequencer_pk ~source_acc_set:(failwith "Not implemented") ~sequencer_pk ~command ~sparse_ledger -let inner_sync ?proving_timeout t ~public_key ~all_actions = - send ?proving_timeout t (Prover.Input.Inner_sync (public_key, all_actions)) +let inner_sync ?proving_timeout t ~public_key ~ase = + send ?proving_timeout t (Prover.Input.Inner_sync (public_key, ase)) >>| function | Prover.Output.Call_forest_tree tree -> tree @@ -369,10 +369,6 @@ let outer_commit ?proving_timeout t ~txn_snark ~public_key ~new_actions | _ -> failwith "Unexpected response from prover" -let outer_step ?proving_timeout t ~last ~outer_public_key:zkapp_pk ~new_deposits - ~unprocessed_deposits ~old_inner_ledger ~new_inner_ledger = - failwith "Not implemented" - let submit_deposit ?proving_timeout t ~outer_pk ~deposit = failwith "Not implemented" diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index 918026818a..4c6dd6b760 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -96,12 +96,13 @@ module Input = struct * Compile_simple.Proof.t * Zeko_transaction_snark.Zeko_stmt.t * Compile_simple.Proof.t ) - | Inner_sync of (Public_key.Compressed.t * Field.t list) + | Inner_sync of + (Public_key.Compressed.t * (Field.t list * Ase.With_length.Stmt.t)) | Outer_commit of ( Zeko_transaction_snark.T.t * Public_key.Compressed.t - * Field.t list - * Field.t list + * (Field.t list * Field.t) + * (Field.t list * Ase.With_length.Stmt.t) * Sparse_ledger.t * Sparse_ledger.t * Signature.t @@ -313,19 +314,23 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function (merge input |> Promise.to_deferred) in Output.Zeko_transaction_snark (stmt, proof) - | Inner_sync (public_key, ase_fields) -> + | Inner_sync (public_key, ase) -> let open Inner_rules in let Compile_simple.[ inner_sync; _ ] = provers in let%bind vk = Compile_simple.Verification_key.of_tag Inner_rules.tag |> Promise.to_deferred in + let%bind ase = + Rule_inner_sync.Ase_inst.prove (snd ase) (fst ase) + |> Promise.to_deferred + in let input = ( { public_key ; vk_hash = Zkapp_account.digest_vk (Compile_simple.Verification_key.to_pickles vk) - ; ase = failwith "Not implemented" + ; ase } : Rule_inner_sync.Witness.t ) in @@ -338,8 +343,8 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function | Outer_commit ( txn_snark , public_key - , _ase1 - , _ase2 + , outer_ase + , inner_ase , old_inner_ledger , new_inner_ledger , da_signature @@ -379,6 +384,21 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function @@ Mina_ledger.Sparse_ledger.path_exn new_inner_ledger inner_account_index in + let%bind outer_ase = + Rule_commit.Ase_outer_inst.prove (snd outer_ase) (fst outer_ase) + |> Promise.to_deferred + in + let%bind inner_ase = + Rule_commit.Ase_inner_inst.prove (snd inner_ase) (fst inner_ase) + |> Promise.to_deferred + in + let%bind verify_both_ases = + let Compile_simple.[ prove ] = Rule_commit.Verify_both_ases.provers in + let%map out, proof = + prove (outer_ase, inner_ase) |> Promise.to_deferred + in + Rule_commit.Verify_both_ases.make_unchecked ~proof out + in let input = ( { txn_snark = Zeko_transaction_snark.make_unchecked ~proof:txn_snark.proof @@ -387,7 +407,7 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function ; vk_hash = Zkapp_account.digest_vk (Compile_simple.Verification_key.to_pickles vk) - ; verify_both_ases = failwith "Not implemented" + ; verify_both_ases ; old_inner_acc ; old_inner_acc_path ; new_inner_acc From 6310f464fdacea2651a0799432bc3743eec850e8 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Tue, 14 Jan 2025 17:07:57 +0100 Subject: [PATCH 10/22] Implement folding of actions in ase --- src/app/zeko/circuits/ase.ml | 41 +++++------------- src/app/zeko/circuits/ase.mli | 11 +++-- src/app/zeko/circuits/folder.ml | 48 +++++++++++++++++++++ src/app/zeko/circuits/folder.mli | 7 +++ src/app/zeko/sequencer/prover/lib/prover.ml | 7 ++- 5 files changed, 74 insertions(+), 40 deletions(-) diff --git a/src/app/zeko/circuits/ase.ml b/src/app/zeko/circuits/ase.ml index 442c1d01f7..960242b7ef 100644 --- a/src/app/zeko/circuits/ase.ml +++ b/src/app/zeko/circuits/ase.ml @@ -111,23 +111,13 @@ module With_length = struct in (({ source; target } : Stmt.var), verifier) - module Init = M_with_length.Stmt - - let prove (init : Init.t) l = - if List.length l > Made_2.get_iterations then - failwith "TODO: Too many actions to prove" - else - let proof_target = - List.fold l ~init ~f:(fun acc action -> - { action_state = - Mina_base.Zkapp_account.Actions.push_hash acc.action_state - action - ; length = Checked32.succ acc.length - } ) - in - let proof = None in - Promise.return - (Made_2.make ?proof ~proof_source:init ~proof_target init l) + let fold (source : Init.t) actions = + Made_2.fold ~source ~init_arg:source ~elems:actions + ~step_state:(fun acc action -> + { action_state = + Mina_base.Zkapp_account.Actions.push_hash acc.action_state action + ; length = Checked32.succ acc.length + } ) end end @@ -166,18 +156,9 @@ module Without_length = struct let target = Action_state.unsafe_var_of_field target in (({ source; target } : Stmt.var), verifier) - module Init = M_without_length.Stmt - - let prove (init : Init.t) l = - if List.length l > Made_2.get_iterations then - failwith "TODO: Too many actions to prove" - else - let proof_target = - List.fold l ~init ~f:(fun acc action -> - Mina_base.Zkapp_account.Actions.push_hash acc action ) - in - let proof = None in - Promise.return - (Made_2.make ?proof ~proof_source:init ~proof_target init l) + let fold (source : Init.t) actions = + Made_2.fold ~source ~init_arg:source ~elems:actions + ~step_state:(fun acc action -> + Mina_base.Zkapp_account.Actions.push_hash acc action ) end end diff --git a/src/app/zeko/circuits/ase.mli b/src/app/zeko/circuits/ase.mli index 8fb5fc0249..9ac37baef6 100644 --- a/src/app/zeko/circuits/ase.mli +++ b/src/app/zeko/circuits/ase.mli @@ -9,6 +9,8 @@ module With_length : sig [@@deriving snarky, yojson] end + module Init = Stmt + type trans = { source : Stmt.t; target : Stmt.t } val leaf : field list * Stmt.t -> (trans * Proof.t) Promise.t @@ -46,8 +48,6 @@ module With_length : sig val get_iterations : int end) -> sig - module Init = Stmt - module Stmt : sig type t = { source : Inputs.Action_state.With_length.t @@ -73,12 +73,13 @@ module With_length : sig -> var -> (Stmt.var * tag_var Compile_simple.prev) Checked.t - val prove : Init.t -> field list -> t Promise.t + val fold : Init.t -> field list -> t Promise.t end end module Without_length : sig module Stmt = F + module Init = Stmt type trans = { source : field; target : field } @@ -117,8 +118,6 @@ module Without_length : sig val get_iterations : int end) -> sig - module Init = Stmt - module Stmt : sig type t = { source : Inputs.Action_state.t; target : Inputs.Action_state.t } @@ -140,6 +139,6 @@ module Without_length : sig -> var -> (Stmt.var * tag_var Compile_simple.prev) Checked.t - val prove : Init.t -> field list -> t Promise.t + val fold : Init.t -> field list -> t Promise.t end end diff --git a/src/app/zeko/circuits/folder.ml b/src/app/zeko/circuits/folder.ml index 64ad8cf90c..e1287a1389 100644 --- a/src/app/zeko/circuits/folder.ml +++ b/src/app/zeko/circuits/folder.ml @@ -302,5 +302,53 @@ struct { source = proof_source; target = proof_target } in ({ init_arg; t; excess } : t) + + let fold ~source ~init_arg ~elems ~step_state = + let elems_to_prove, excess = + let i = ref 0 in + let l = List.length elems in + List.split_while elems ~f:(fun _ -> + let r = !i < l - get_iterations in + i := !i + 1 ; + r ) + in + match elems_to_prove with + | [] -> + (* No need for folding, everything goes to excess *) + let proof_target = List.fold excess ~init:source ~f:step_state in + Promise.return + (make ?proof:None ~proof_source:source ~proof_target init_arg excess) + | elems_to_prove -> + (* Need to fold *) + let leaf_prover, (leaf_elems, rest) = + match List.length elems_to_prove with + | full_leaf when full_leaf > leaf_iterations -> + (leaf, List.split_n elems_to_prove leaf_iterations) + | _incomplete_leaf -> + (leaf_option, List.split_n elems_to_prove leaf_option_iterations) + in + let%bind.Promise leaf = leaf_prover (leaf_elems, source) in + let rec extend_rest elems_to_prove acc = + match elems_to_prove with + | [] -> + Promise.return acc + | elems_to_prove -> + let extend_prover, (extend_elems, rest) = + match List.length elems_to_prove with + | full_extend when full_extend > extend_iterations -> + (extend, List.split_n elems_to_prove extend_iterations) + | _incomplete_extend -> + ( extend_option + , List.split_n elems_to_prove extend_option_iterations ) + in + let%bind.Promise acc = extend_prover (extend_elems, acc) in + extend_rest rest acc + in + let%bind.Promise trans, proof = extend_rest rest leaf in + let proof_target = + List.fold excess ~init:trans.target ~f:step_state + in + Promise.return + (make ~proof ~proof_source:source ~proof_target init_arg excess) end end diff --git a/src/app/zeko/circuits/folder.mli b/src/app/zeko/circuits/folder.mli index 0de41fea32..212c83671e 100644 --- a/src/app/zeko/circuits/folder.mli +++ b/src/app/zeko/circuits/folder.mli @@ -116,5 +116,12 @@ end) -> t val get_iterations : int + + val fold : + source:Stmt.t + -> init_arg:Init.t + -> elems:Elem.t list + -> step_state:(Stmt.t -> Elem.t -> Stmt.t) + -> t Promise.t end end diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index 4c6dd6b760..88bab3b469 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -322,8 +322,7 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function |> Promise.to_deferred in let%bind ase = - Rule_inner_sync.Ase_inst.prove (snd ase) (fst ase) - |> Promise.to_deferred + Rule_inner_sync.Ase_inst.fold (snd ase) (fst ase) |> Promise.to_deferred in let input = ( { public_key @@ -385,11 +384,11 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function inner_account_index in let%bind outer_ase = - Rule_commit.Ase_outer_inst.prove (snd outer_ase) (fst outer_ase) + Rule_commit.Ase_outer_inst.fold (snd outer_ase) (fst outer_ase) |> Promise.to_deferred in let%bind inner_ase = - Rule_commit.Ase_inner_inst.prove (snd inner_ase) (fst inner_ase) + Rule_commit.Ase_inner_inst.fold (snd inner_ase) (fst inner_ase) |> Promise.to_deferred in let%bind verify_both_ases = From 9546e3b7c8e6a1d843f59ccfa1c5476d9eeb91af Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Wed, 15 Jan 2025 17:53:37 +0100 Subject: [PATCH 11/22] Add outer_commit to the committer --- src/app/zeko/sequencer/lib/committer.ml | 30 ++++++++++----------- src/app/zeko/sequencer/lib/gql_client.ml | 17 +++--------- src/app/zeko/sequencer/prover/lib/prover.ml | 29 +++++++++++++++----- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/app/zeko/sequencer/lib/committer.ml b/src/app/zeko/sequencer/lib/committer.ml index fea73d2130..b96d3145ae 100644 --- a/src/app/zeko/sequencer/lib/committer.ml +++ b/src/app/zeko/sequencer/lib/committer.ml @@ -3,6 +3,7 @@ open Async open Mina_base open Signature_lib open Mina_ledger +open Zeko_circuits module Field = Snark_params.Tick.Field module Commit_witness = struct @@ -12,7 +13,7 @@ module Commit_witness = struct ; old_deposits_pointer : Frozen_ledger_hash.t ; processed_deposits_pointer : Frozen_ledger_hash.t ; signatures : Signature.t list - ; last_snark : Zkapps_rollup.t + ; txn_snark : Zeko_transaction_snark.T.t } [@@deriving yojson] end @@ -111,27 +112,26 @@ let prove_commit ~provers ~(executor : Executor.t) ~zkapp_pk ~archive_uri ; old_deposits_pointer ; processed_deposits_pointer ; signatures - ; last_snark + ; txn_snark } : Commit_witness.t ) = - (* FIXME: pass this check into circuit *) - assert (List.length signatures <> 0) ; - let%bind new_deposits = - Gql_client.fetch_transfers archive_uri - ~from_action_state:old_deposits_pointer + let%bind new_actions = + Gql_client.fetch_actions archive_uri ~from_action_state:old_deposits_pointer ~end_action_state:processed_deposits_pointer zkapp_pk - |> Deferred.map ~f:(List.map ~f:fst) + >>| List.map ~f:fst >>| List.rev + >>| List.map ~f:Account_update.Actions.hash in - let%bind unprocessed_deposits = - Gql_client.fetch_transfers archive_uri + let%bind unprocessed_actions = + Gql_client.fetch_actions archive_uri ~from_action_state:processed_deposits_pointer zkapp_pk - |> Deferred.map ~f:(List.map ~f:fst) + >>| List.map ~f:fst >>| List.rev + >>| List.map ~f:Account_update.Actions.hash in let%bind account_update = - Zeko_prover.Client.outer_step ~proving_timeout:30. provers ~last:last_snark - ~outer_public_key:zkapp_pk ~new_deposits:(List.rev new_deposits) - ~unprocessed_deposits:(List.rev unprocessed_deposits) - ~old_inner_ledger ~new_inner_ledger + Zeko_prover.Client.outer_commit ~proving_timeout:30. provers ~txn_snark + ~public_key:zkapp_pk ~new_actions ~unprocessed_actions ~old_inner_ledger + ~new_inner_ledger ~da_signature:(List.hd_exn signatures) + ~da_key:(failwith "Not implemented") in let command : Zkapp_command.t = { fee_payer = diff --git a/src/app/zeko/sequencer/lib/gql_client.ml b/src/app/zeko/sequencer/lib/gql_client.ml index 8f97e0532c..81b3b86f1d 100644 --- a/src/app/zeko/sequencer/lib/gql_client.ml +++ b/src/app/zeko/sequencer/lib/gql_client.ml @@ -55,7 +55,8 @@ let fetch_action_state uri pk = result |> member "account" |> member "actionState" |> index 0 |> to_string) |> Field.of_string -let fetch_transfers uri ?from_action_state ?end_action_state pk = +let fetch_actions uri ?from_action_state ?end_action_state pk : + (Account_update.Actions.t * int) list Deferred.t = let ok_exn = function | Ppx_deriving_yojson_runtime.Result.Ok x -> x @@ -120,18 +121,8 @@ let fetch_transfers uri ?from_action_state ?end_action_state pk = List.map result.actions ~f:(fun { actionData; blockInfo } -> let block_height = blockInfo.height in List.map actionData ~f:(fun { data } -> - let amount = List.nth_exn data 0 in - let public_key_x = List.nth_exn data 1 in - let is_odd = List.nth_exn data 2 |> Int.of_string in - ( Zkapps_rollup.TR. - { amount = Currency.Amount.of_string amount - ; recipient = - Signature_lib.Public_key.Compressed. - { x = Field.of_string public_key_x - ; is_odd = (match is_odd with 0 -> false | _ -> true) - } - } - , block_height ) ) ) + let fields = List.map data ~f:Field.of_string |> List.to_array in + ([ fields ], block_height) ) ) |> List.join |> (* Drop the first transfer if it's not the initial state *) diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index 88bab3b469..908203af13 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -101,8 +101,8 @@ module Input = struct | Outer_commit of ( Zeko_transaction_snark.T.t * Public_key.Compressed.t - * (Field.t list * Field.t) - * (Field.t list * Ase.With_length.Stmt.t) + * Field.t list + * Field.t list * Sparse_ledger.t * Sparse_ledger.t * Signature.t @@ -342,8 +342,8 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function | Outer_commit ( txn_snark , public_key - , outer_ase - , inner_ase + , outer_ase_fields + , inner_ase_fields , old_inner_ledger , new_inner_ledger , da_signature @@ -384,11 +384,28 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function inner_account_index in let%bind outer_ase = - Rule_commit.Ase_outer_inst.fold (snd outer_ase) (fst outer_ase) + let ({ outer_action_state } : Rollup_state.Inner_state.t) = + Rollup_state.Inner_state.value_of_app_state + (Option.value_exn new_inner_acc.zkapp).app_state + in + let action_state = + Rollup_state.Outer_action_state.With_length.raw outer_action_state + in + Rule_commit.Ase_outer_inst.fold action_state outer_ase_fields |> Promise.to_deferred in let%bind inner_ase = - Rule_commit.Ase_inner_inst.fold (snd inner_ase) (fst inner_ase) + let ({ outer_action_state } : Rollup_state.Inner_state.t) = + Rollup_state.Inner_state.value_of_app_state + (Option.value_exn old_inner_acc.zkapp).app_state + in + let action_state : Ase.With_length.Stmt.t = + Rollup_state.Outer_action_state.With_length. + { action_state = raw outer_action_state + ; length = length outer_action_state + } + in + Rule_commit.Ase_inner_inst.fold action_state inner_ase_fields |> Promise.to_deferred in let%bind verify_both_ases = From 9e318415b7cac555466bacddea7e9914252c8b2e Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Wed, 15 Jan 2025 17:58:39 +0100 Subject: [PATCH 12/22] Remove analytics --- src/app/zeko/sequencer/lib/analytics.ml | 206 ------------------- src/app/zeko/sequencer/lib/gql.ml | 150 -------------- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 21 +- 3 files changed, 6 insertions(+), 371 deletions(-) delete mode 100644 src/app/zeko/sequencer/lib/analytics.ml diff --git a/src/app/zeko/sequencer/lib/analytics.ml b/src/app/zeko/sequencer/lib/analytics.ml deleted file mode 100644 index c572225111..0000000000 --- a/src/app/zeko/sequencer/lib/analytics.ml +++ /dev/null @@ -1,206 +0,0 @@ -open Core_kernel -open Async -open Mina_base -open Signature_lib -open Mina_ledger -module Field = Snark_params.Tick.Field - -module User_activity = struct - type t = - { total_accounts : int; new_accounts_30d : int; active_accounts_30d : int } -end - -module Zkapp_activity = struct - type t = { total_zkapps : int; new_zkapps_30d : int; active_zkapps_30d : int } -end - -module Transaction_activity = struct - type t = - { total_deposits : int - ; total_signed_commands : int - ; total_zkapp_commands : int - } -end - -module Transaction_statistics = struct - type t = { avg_fee : float; avg_pfs : float (* proofs per second *) } -end - -module Top_zkapps = struct - type t = (string * int) list -end - -module Lumina_activity = struct - type t = { total_swaps : int; total_liquidity_pools : int } - - let get ~archive_uri ~zkapp_pk ~lumina_factory = - let%bind lps = - Gql_client.fetch_events archive_uri lumina_factory - >>| List.join - >>| List.filter_map ~f:(function - | _sender_x :: _sender_oddity :: pool_x :: pool_oddity :: _ -> - (* only one event type, so no index *) - (* https://github.com/Lumina-DEX/lumina-mvp/blob/284341acc924bf21ac6947514e23cce7088e68ed/contracts/src/PoolFactory.ts#L39 *) - Some - ( { x = pool_x - ; is_odd = - ( if Field.equal pool_oddity Field.zero then false - else true ) - } - : Public_key.Compressed.t ) - | _ -> - None ) - in - let%bind swaps = - Deferred.List.map ~how:`Parallel lps ~f:(fun lp -> - Gql_client.fetch_events archive_uri lp - >>| List.join - >>| List.filter ~f:(function - | event_type :: _ -> - (* [1] is event type [addLiquidity] *) - (* https://github.com/Lumina-DEX/lumina-mvp/blob/284341acc924bf21ac6947514e23cce7088e68ed/contracts/src/PoolMina.ts#L61 *) - if Field.equal event_type Field.one then true else false - | _ -> - false ) ) - >>| List.length - in - return { total_swaps = swaps; total_liquidity_pools = List.length lps } -end - -module State = struct - type timestamps = { created_at : Time.t; last_active_at : Time.t } - - type avg_fee = { total_fee : int; total_commands : int } - - type t = - { account_map : timestamps Account_id.Map.t - ; zkapp_map : timestamps Account_id.Map.t - ; total_signed_commands : int - ; total_zkapp_commands : int - ; avg_fee : avg_fee - } - - let empty = - { account_map = Account_id.Map.empty - ; zkapp_map = Account_id.Map.empty - ; total_signed_commands = 0 - ; total_zkapp_commands = 0 - ; avg_fee = { total_fee = 0; total_commands = 0 } - } - - let update_with_command t command ledger = - let now = Time.now () in - let accounts = User_command.accounts_accessed command Applied in - let t = - List.fold accounts ~init:t ~f:(fun t (account_id, _) -> - { t with - account_map = - Map.update t.account_map account_id ~f:(function - | None -> - { created_at = now; last_active_at = now } - | Some ts -> - { ts with last_active_at = now } ) - ; zkapp_map = - (let account = - let%bind.Option location = - Ledger.location_of_account ledger account_id - in - Ledger.get ledger location - in - match account with - | Some { zkapp = Some zkapp; _ } -> - Map.update t.zkapp_map account_id ~f:(function - | None -> - { created_at = now; last_active_at = now } - | Some ts -> - { ts with last_active_at = now } ) - | _ -> - t.zkapp_map ) - } ) - in - let t = - { t with - avg_fee = - { total_fee = - t.avg_fee.total_fee - + (Currency.Fee.to_mina_int @@ User_command.fee command) - ; total_commands = t.avg_fee.total_commands + 1 - } - } - in - match command with - | Signed_command _ -> - { t with total_signed_commands = t.total_signed_commands + 1 } - | Zkapp_command _ -> - { t with total_zkapp_commands = t.total_zkapp_commands + 1 } -end - -type t = - { user_activity : User_activity.t - ; zkapp_activity : Zkapp_activity.t - ; transaction_activity : Transaction_activity.t - ; transaction_statistics : Transaction_statistics.t - ; top_zkapps : Top_zkapps.t - ; lumina_activity : Lumina_activity.t - } - -let get (state : State.t) ~archive_uri ~zkapp_pk ~lumina_factory = - let now = Time.now () in - let before_30d = Time.(sub (now ()) (Span.of_day 30.)) in - let user_activity = - User_activity. - { total_accounts = Map.length state.account_map - ; new_accounts_30d = - Map.filter state.account_map ~f:(fun ts -> - Time.between ts.created_at ~low:before_30d ~high:now ) - |> Map.length - ; active_accounts_30d = - Map.filter state.account_map ~f:(fun ts -> - Time.between ts.last_active_at ~low:before_30d ~high:now ) - |> Map.length - } - in - let zkapp_activity = - Zkapp_activity. - { total_zkapps = Map.length state.zkapp_map - ; new_zkapps_30d = - Map.filter state.zkapp_map ~f:(fun ts -> - Time.between ts.created_at ~low:before_30d ~high:now ) - |> Map.length - ; active_zkapps_30d = - Map.filter state.zkapp_map ~f:(fun ts -> - Time.between ts.last_active_at ~low:before_30d ~high:now ) - |> Map.length - } - in - let%bind deposits = - Gql_client.fetch_transfers archive_uri zkapp_pk >>| List.length - in - let transaction_activity = - Transaction_activity. - { total_deposits = deposits - ; total_signed_commands = state.total_signed_commands - ; total_zkapp_commands = state.total_zkapp_commands - } - in - let transaction_statistics = - Transaction_statistics. - { avg_fee = - Float.( / ) - (Int.to_float state.avg_fee.total_fee) - (Int.to_float state.avg_fee.total_commands) - ; avg_pfs = 0. (* TODO: when I do parallel proving will update this *) - } - in - let top_zkapps = Top_zkapps.[] in - let%bind lumina_activity = - Lumina_activity.get ~archive_uri ~zkapp_pk ~lumina_factory - in - return - { user_activity - ; zkapp_activity - ; transaction_activity - ; transaction_statistics - ; top_zkapps - ; lumina_activity - } diff --git a/src/app/zeko/sequencer/lib/gql.ml b/src/app/zeko/sequencer/lib/gql.ml index 05070213ba..0313c93a9b 100644 --- a/src/app/zeko/sequencer/lib/gql.ml +++ b/src/app/zeko/sequencer/lib/gql.ml @@ -1384,140 +1384,6 @@ module Types = struct end end - module Analytics = struct - module User_activity = struct - type t = Analytics.User_activity.t - - let t : ('context, t option) typ = - let open Analytics.User_activity in - obj "UserActivity" ~fields:(fun _ -> - [ field "totalAccounts" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.total_accounts) - ; field "newAccounts30d" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.new_accounts_30d) - ; field "activeAccounts30d" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.active_accounts_30d) - ] ) - end - - module Zkapp_activity = struct - type t = Analytics.Zkapp_activity.t - - let t : ('context, t option) typ = - let open Analytics.Zkapp_activity in - obj "ZkappActivity" ~fields:(fun _ -> - [ field "totalZkapps" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.total_zkapps) - ; field "newZkapps30d" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.new_zkapps_30d) - ; field "activeZkapps30d" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.active_zkapps_30d) - ] ) - end - - module Transaction_activity = struct - type t = Analytics.Transaction_activity.t - - let t : ('context, t option) typ = - let open Analytics.Transaction_activity in - obj "TransactionActivity" ~fields:(fun _ -> - [ field "totalDeposits" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.total_deposits) - ; field "totalSignedCommands" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.total_signed_commands) - ; field "totalZkappCommands" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.total_zkapp_commands) - ; field "totalTransactions" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> - x.total_signed_commands + x.total_zkapp_commands ) - ] ) - end - - module Transaction_statistics = struct - type t = Analytics.Transaction_statistics.t - - let t : ('context, t option) typ = - let open Analytics.Transaction_statistics in - obj "TransactionStatistics" ~fields:(fun _ -> - [ field "averageFee" ~typ:(non_null float) - ~args:Arg.[] - ~resolve:(fun _ x -> x.avg_fee) - ; field "averagePFS" ~typ:(non_null float) - ~args:Arg.[] - ~resolve:(fun _ x -> x.avg_pfs) - ] ) - end - - module Top_zkapps = struct - type t = Analytics.Top_zkapps.t - - let t : ('context, t option) typ = - let open Analytics.Top_zkapps in - list @@ non_null - @@ obj "TopZkapps" ~fields:(fun _ -> - [ field "zkapp" ~typ:(non_null string) - ~args:Arg.[] - ~resolve:(fun _ x -> fst x) - ; field "count" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> snd x) - ] ) - end - - module Lumina_activity = struct - type t = Analytics.Lumina_activity.t - - let t : ('context, t option) typ = - let open Analytics.Lumina_activity in - obj "LuminaActivity" ~fields:(fun _ -> - [ field "totalSwaps" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.total_swaps) - ; field "totalLiquidityPools" ~typ:(non_null int) - ~args:Arg.[] - ~resolve:(fun _ x -> x.total_liquidity_pools) - ] ) - end - - type t = Analytics.t - - let t : ('context, t option) typ = - obj "Analytics" ~fields:(fun _ -> - [ field "userActivity" ~typ:(non_null User_activity.t) - ~args:Arg.[] - ~resolve:(fun _ x -> Analytics.(x.user_activity)) - ; field "zkappActivity" - ~typ:(non_null Zkapp_activity.t) - ~args:Arg.[] - ~resolve:(fun _ x -> Analytics.(x.zkapp_activity)) - ; field "transactionActivity" - ~typ:(non_null Transaction_activity.t) - ~args:Arg.[] - ~resolve:(fun _ x -> Analytics.(x.transaction_activity)) - ; field "transactionStatistics" - ~typ:(non_null Transaction_statistics.t) - ~args:Arg.[] - ~resolve:(fun _ x -> Analytics.(x.transaction_statistics)) - ; field "topZkapps" ~typ:(non_null Top_zkapps.t) - ~args:Arg.[] - ~resolve:(fun _ x -> Analytics.(x.top_zkapps)) - ; field "luminaActivity" - ~typ:(non_null Lumina_activity.t) - ~args:Arg.[] - ~resolve:(fun _ x -> Analytics.(x.lumina_activity)) - ] ) - end - module Archive = struct module BlockInfo = struct type t = Archive.Block_info.t @@ -1969,21 +1835,6 @@ module Queries = struct let%map account_id = Ledger.token_owner l token in Types.AccountObj.get_best_ledger_account l account_id ) - let analytics = - io_field "analytics" - ~typ:(non_null Types.Analytics.t) - ~args: - Arg. - [ arg "luminaFactory" ~typ:(non_null Types.Input.PublicKey.arg_typ) ] - ~resolve:(fun { ctx = sequencer; _ } () lumina_factory -> - let%bind analytics = - let open Zeko_sequencer in - Analytics.get sequencer.analytics_state - ~archive_uri:sequencer.config.archive_uri - ~zkapp_pk:sequencer.config.zkapp_pk ~lumina_factory - in - return (Ok analytics) ) - module Archive = struct let actions = io_field "actions" @@ -2031,7 +1882,6 @@ module Queries = struct ; state_hashes ; token_owner ; network_id - ; analytics ] @ Archive.commands end diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index 7f18ad63bd..426ca76a8b 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -367,7 +367,6 @@ module Sequencer = struct ; apply_q : unit Sequencer.t (* Applying of the user command is async operation, but we need to keep the application synchronous *) ; mutable subscriptions : Subscriptions.t - ; mutable analytics_state : Analytics.State.t } let close t = @@ -411,7 +410,7 @@ module Sequencer = struct (** Apply user command to the ledger without checking the validity of the command *) let apply_user_command_without_check l archive command ~global_slot - ~state_body ~analytics_state = + ~state_body = let accounts_referenced = User_command.accounts_referenced command in let first_pass_ledger = @@ -479,11 +478,7 @@ module Sequencer = struct @@ Account_update.body update } ) )) in - ( first_pass_ledger - , second_pass_ledger - , txn_applied - , target_ledger_hash - , Analytics.State.update_with_command analytics_state command l ) + (first_pass_ledger, second_pass_ledger, txn_applied, target_ledger_hash) (** Apply user command to the sequencer's state, including the check of command validity *) let apply_user_command t ?(skip_validity_check = false) @@ -537,13 +532,11 @@ module Sequencer = struct let%bind.Deferred.Result ( first_pass_ledger , second_pass_ledger , txn_applied - , target_ledger_hash - , new_analytics_state ) = + , target_ledger_hash ) = return (apply_user_command_without_check l t.archive command ~global_slot - ~state_body ~analytics_state:t.analytics_state ) + ~state_body ) in - t.analytics_state <- new_analytics_state ; (* Post transaction to the DA layer *) let changed_accounts = @@ -781,12 +774,11 @@ module Sequencer = struct let state_body = Mina_state.Protocol_state.body compile_time_genesis_state in - let _, _, _, _, analytics_state = + let _, _, _, _ = apply_user_command_without_check mask t.archive command - ~global_slot ~state_body ~analytics_state:t.analytics_state + ~global_slot ~state_body |> Or_error.ok_exn in - t.analytics_state <- analytics_state ; L.Mask.Attached.commit mask ; return () ) in @@ -854,7 +846,6 @@ module Sequencer = struct ; stop = Ivar.create () ; apply_q = Sequencer.create () ; subscriptions = Subscriptions.create () - ; analytics_state = Analytics.State.empty } in let%bind () = From 32820cb26b36fbdf0d0f0e11218a730da230fe97 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Wed, 15 Jan 2025 18:12:10 +0100 Subject: [PATCH 13/22] Make it compile --- src/app/zeko/sequencer/lib/utils.ml | 6 +- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 594 ++++++++++--------- 2 files changed, 305 insertions(+), 295 deletions(-) diff --git a/src/app/zeko/sequencer/lib/utils.ml b/src/app/zeko/sequencer/lib/utils.ml index 45a9ae9b60..63768145df 100644 --- a/src/app/zeko/sequencer/lib/utils.ml +++ b/src/app/zeko/sequencer/lib/utils.ml @@ -53,11 +53,13 @@ let get_state_transition pk command = Some (source, target) let get_inner_deposits_state_exn l = - let (old_deposits_commit :: _) = + let open Zeko_circuits in + let ({ outer_action_state } : Rollup_state.Inner_state.t) = let idx = Mina_ledger.Ledger.index_of_account_exn l Zkapps_rollup.inner_account_id in let inner_acc = Mina_ledger.Ledger.get_at_index_exn l idx in (Option.value_exn inner_acc.zkapp).app_state + |> Rollup_state.Inner_state.value_of_app_state in - old_deposits_commit + outer_action_state diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index 426ca76a8b..709c76db0d 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -289,7 +289,7 @@ module Sequencer = struct ({ da_client; provers; executor; config; kvdb; state } as ctx : Context.t ) { new_inner_ledger; old_deposits_pointer; processed_deposits_pointer } - last_snark = + txn_snark = let%bind signatures = Da_layer.Client.Sequencer.get_signatures da_client ~ledger_hash:(Sparse_ledger.merkle_root new_inner_ledger) @@ -307,7 +307,7 @@ module Sequencer = struct ; old_deposits_pointer ; processed_deposits_pointer ; signatures - ; last_snark + ; txn_snark } in Committer.Store.store_commit kvdb commit_witness @@ -634,30 +634,38 @@ module Sequencer = struct ) ) let update_inner_account t = - let old_deposits_state = - Utils.get_inner_deposits_state_exn (L.of_database t.db) + let old_deposits_state, old_deposits_length = + let s = Utils.get_inner_deposits_state_exn (L.of_database t.db) in + Rollup_state.Outer_action_state.With_length.(raw s, length s) in - let%bind new_deposits = - Gql_client.fetch_transfers t.config.archive_uri + let%bind all_new_actions = + Gql_client.fetch_actions t.config.archive_uri ~from_action_state:old_deposits_state t.config.zkapp_pk in let%bind current_height = Gql_client.fetch_block_height t.config.l1_uri in (* Find pointer for deposits to be processed *) - let processed_pointer = - List.fold new_deposits ~init:old_deposits_state - ~f:(fun curr_state (transfer, block_height) -> + let processed_pointer, processed_new_actions = + List.fold all_new_actions ~init:(old_deposits_state, []) + ~f:(fun (curr_state, curr_actions) (action, block_height) -> if block_height + t.config.deposit_delay_blocks <= current_height then - Zkapp_account.Actions.push_events curr_state - (Zkapps_rollup.TR.to_actions transfer) - else curr_state ) + ( Zkapp_account.Actions.push_events curr_state action + , action :: curr_actions ) + else (curr_state, curr_actions) ) in if Field.equal old_deposits_state processed_pointer then (* In case no new deposits are to process, we don't need to update inner account *) return (old_deposits_state, old_deposits_state) else let%bind inner_account_update = - Zeko_prover.Client.inner_step t.snark_q.provers - ~all_deposits:processed_pointer + Zeko_prover.Client.inner_sync t.snark_q.provers + ~public_key:(failwith "Not implemented: near 123456789?") + ~ase: + ( List.map processed_new_actions ~f:Account_update.Actions.hash + , ( Rollup_state.Outer_action_state.With_length. + { action_state = old_deposits_state + ; length = old_deposits_length + } + : Ase.With_length.Stmt.t ) ) in let fee = Currency.Fee.of_mina_int_exn 0 in let command : Zkapp_command.t = @@ -999,74 +1007,74 @@ let%test_module "Sequencer tests" = { zkapp_keypair; signer; ephemeral_ledger; specs; sequencer } end - let sign_cmd (cmd : Zkapp_command.t) (keys : Keypair.t list) : - Zkapp_command.t = - let full_commitment = - Zkapp_command.Transaction_commitment.create_complete - (Zkapp_command.commitment cmd) - ~memo_hash:(Signed_command_memo.hash cmd.memo) - ~fee_payer_hash: - (Zkapp_command.Digest.Account_update.create - (Account_update.of_fee_payer cmd.fee_payer) ) - in - let sign_raw (pk : Public_key.Compressed.t) msg = - printf "Signing for %s\n" (Public_key.Compressed.to_base58_check pk) ; - let rec go (keys : Keypair.t list) msg = - match keys with - | (kp : Keypair.t) :: keys -> - if - Public_key.Compressed.equal - (Public_key.compress kp.public_key) - pk - then ( - printf "key found\n" ; - Signature_lib.Schnorr.Chunked.sign - ~signature_kind:Mina_signature_kind.Testnet kp.private_key - (Random_oracle.Input.Chunked.field msg) ) - else ( - printf "not equal to %s\n" - Public_key.( - kp.public_key |> compress |> Compressed.to_base58_check) ; - go keys msg ) - | [] -> - failwithf "key not found: %s\n" - (Public_key.Compressed.to_base58_check pk) - () - in - go keys msg - in - let rec sign_tree (tree : Zeko_util.call_forest_tree) : - Zeko_util.call_forest_tree = - { tree with - account_update = - { tree.account_update with - authorization = - ( match tree.account_update.body.authorization_kind with - | Signature -> - assert tree.account_update.body.use_full_commitment ; - Signature - (sign_raw tree.account_update.body.public_key - full_commitment ) - | _ -> - tree.account_update.authorization ) - } - ; calls = sign_forest tree.calls - } - and sign_forest (forest : Zeko_util.call_forest) : Zeko_util.call_forest = - List.map ~f:(fun tree -> { tree with elt = sign_tree tree.elt }) forest - in - { cmd with - fee_payer = - { cmd.fee_payer with - authorization = - ( if - Public_key.Compressed.( - equal empty cmd.fee_payer.body.public_key) - then cmd.fee_payer.authorization - else sign_raw cmd.fee_payer.body.public_key full_commitment ) - } - ; account_updates = sign_forest cmd.account_updates - } + (* let sign_cmd (cmd : Zkapp_command.t) (keys : Keypair.t list) : + Zkapp_command.t = + let full_commitment = + Zkapp_command.Transaction_commitment.create_complete + (Zkapp_command.commitment cmd) + ~memo_hash:(Signed_command_memo.hash cmd.memo) + ~fee_payer_hash: + (Zkapp_command.Digest.Account_update.create + (Account_update.of_fee_payer cmd.fee_payer) ) + in + let sign_raw (pk : Public_key.Compressed.t) msg = + printf "Signing for %s\n" (Public_key.Compressed.to_base58_check pk) ; + let rec go (keys : Keypair.t list) msg = + match keys with + | (kp : Keypair.t) :: keys -> + if + Public_key.Compressed.equal + (Public_key.compress kp.public_key) + pk + then ( + printf "key found\n" ; + Signature_lib.Schnorr.Chunked.sign + ~signature_kind:Mina_signature_kind.Testnet kp.private_key + (Random_oracle.Input.Chunked.field msg) ) + else ( + printf "not equal to %s\n" + Public_key.( + kp.public_key |> compress |> Compressed.to_base58_check) ; + go keys msg ) + | [] -> + failwithf "key not found: %s\n" + (Public_key.Compressed.to_base58_check pk) + () + in + go keys msg + in + let rec sign_tree (tree : Zeko_util.call_forest_tree) : + Zeko_util.call_forest_tree = + { tree with + account_update = + { tree.account_update with + authorization = + ( match tree.account_update.body.authorization_kind with + | Signature -> + assert tree.account_update.body.use_full_commitment ; + Signature + (sign_raw tree.account_update.body.public_key + full_commitment ) + | _ -> + tree.account_update.authorization ) + } + ; calls = sign_forest tree.calls + } + and sign_forest (forest : Zeko_util.call_forest) : Zeko_util.call_forest = + List.map ~f:(fun tree -> { tree with elt = sign_tree tree.elt }) forest + in + { cmd with + fee_payer = + { cmd.fee_payer with + authorization = + ( if + Public_key.Compressed.( + equal empty cmd.fee_payer.body.public_key) + then cmd.fee_payer.authorization + else sign_raw cmd.fee_payer.body.public_key full_commitment ) + } + ; account_updates = sign_forest cmd.account_updates + } *) let%test_unit "apply commands and commit" = print_endline "Started test 'apply commands and commit'" ; @@ -1331,217 +1339,217 @@ let%test_module "Sequencer tests" = | Error unexpected_error -> Error.raise unexpected_error ) - let%test_unit "deposits" = - print_endline "Started test 'deposits'" ; - Quickcheck.test ~trials:1 (Sequencer_test_spec.gen ~delay_deposit:2 ()) - ~f:(fun { zkapp_keypair; signer; ephemeral_ledger; specs; sequencer } -> - (* Create l1 accounts *) - let l1_accounts = - Array.create ~len:5 () - |> Array.map ~f:Signature_lib.Keypair.create - |> Array.to_list - in - Thread_safe.block_on_async_exn (fun () -> - Deferred.List.iter l1_accounts ~f:(fun keypair -> - let%bind _res = - Gql_client.For_tests.create_account gql_uri - (Signature_lib.Public_key.compress keypair.public_key) - in - return () ) ) ; - - (* Send deposits *) - let deposits = - Thread_safe.block_on_async_exn (fun () -> - let submit_deposit ~fee (signer : Keypair.t) deposit = - let%bind nonce = - Gql_client.fetch_nonce gql_uri - (Signature_lib.Public_key.compress signer.public_key) - in - let fee_payer = - Account_update.Fee_payer. - { body = - { public_key = Public_key.compress signer.public_key - ; fee = Currency.Fee.of_mina_int_exn fee - ; valid_until = None - ; nonce = Account.Nonce.of_uint32 nonce - } - ; authorization = Signature.dummy - } - in - let%bind transfer_update = - M.Outer.submit_deposit - ~outer_public_key: - (Public_key.compress zkapp_keypair.public_key) - ~deposit - in - let transferrer_update : Account_update.t = - { body = - { Account_update.Body.dummy with - public_key = Public_key.compress signer.public_key - ; balance_change = - Currency.Amount.Signed.( - negate @@ of_unsigned deposit.amount) - ; use_full_commitment = true - ; authorization_kind = Signature - } - ; authorization = Signature Signature.dummy - } - in - let transfer_cmd : Zkapp_command.t = - { fee_payer - ; account_updates = - Zkapp_command.Call_forest.( - cons_tree transfer_update @@ accumulate_hashes' - @@ of_account_updates - ~account_update_depth:(fun _ -> 0) - [ transferrer_update ]) - ; memo = Signed_command_memo.empty - } - in - return @@ sign_cmd transfer_cmd [ signer ] - in - let account1 = List.nth_exn l1_accounts 0 in - let account2 = List.nth_exn l1_accounts 1 in - let account3 = List.nth_exn l1_accounts 2 in - let account4 = List.nth_exn l1_accounts 3 in - let account5 = List.nth_exn l1_accounts 4 in - - let deposit1 : Zkapps_rollup.TR.t = - { recipient = Public_key.compress account1.public_key - ; amount = Currency.Amount.of_mina_int_exn 10 - } - in - let deposit2 : Zkapps_rollup.TR.t = - { recipient = Public_key.compress account2.public_key - ; amount = Currency.Amount.of_mina_int_exn 20 - } - in - let deposit3 : Zkapps_rollup.TR.t = - { recipient = Public_key.compress account3.public_key - ; amount = Currency.Amount.of_mina_int_exn 30 - } - in - let deposit4 : Zkapps_rollup.TR.t = - { recipient = Public_key.compress account4.public_key - ; amount = Currency.Amount.of_mina_int_exn 40 - } - in - let deposit5 : Zkapps_rollup.TR.t = - { recipient = Public_key.compress account5.public_key - ; amount = Currency.Amount.of_mina_int_exn 50 - } - in - - (* Send deposits for accounts 1 and 2 *) - let%bind _ = - submit_deposit ~fee:5 account1 deposit1 - >>= Gql_client.send_zkapp gql_uri - in - let%bind _ = - submit_deposit ~fee:4 account2 deposit2 - >>= Gql_client.send_zkapp gql_uri - in - - (* Create 2 new blocks for delay *) - let%bind _created = - Gql_client.For_tests.create_new_block gql_uri - in - let%bind _created = - Gql_client.For_tests.create_new_block gql_uri - in - - (* Send deposits for accounts 3, 4 and 5 which won't be processed *) - let%bind _ = - submit_deposit ~fee:3 account3 deposit3 - >>= Gql_client.send_zkapp gql_uri - in - let%bind _ = - submit_deposit ~fee:2 account4 deposit4 - >>= Gql_client.send_zkapp gql_uri - in - let%bind _ = - submit_deposit ~fee:1 account5 deposit5 - >>= Gql_client.send_zkapp gql_uri - in - let%bind _created = - Gql_client.For_tests.create_new_block gql_uri - in - return [ deposit1; deposit2; deposit3; deposit4; deposit5 ] ) - in - - (* Commit should process first 2 deposits *) - Thread_safe.block_on_async_exn (fun () -> - let%bind _ = commit sequencer in - let%bind () = Snark_queue.wait_to_finish sequencer.snark_q in - let%bind () = - Executor.wait_to_finish sequencer.merger_ctx.executor - in - let%bind _created = - Gql_client.For_tests.create_new_block gql_uri - in - let%bind committed_ledger_hash = - Gql_client.fetch_committed_state gql_uri - Signature_lib.Public_key.(compress zkapp_keypair.public_key) - in - let target_ledger_hash = get_root sequencer in - [%test_eq: Ledger_hash.t] committed_ledger_hash target_ledger_hash ; - - return () ) ; - - let deposits_state = - Utils.get_inner_deposits_state_exn (L.of_database sequencer.db) - in - let expected_deposits_state = - (* Expected should be only first 2 deposits *) - List.take deposits 2 - |> List.fold ~init:Zkapp_account.Actions.empty_state_element - ~f:(fun acc transfer -> - Zkapp_account.Actions.push_events acc - (Zkapps_rollup.TR.to_actions transfer) ) - in - [%test_eq: Field.t] deposits_state expected_deposits_state ; - - print_endline "Processing remaining deposits" ; - - (* Create new blocks to process remaining deposits *) - Thread_safe.block_on_async_exn (fun () -> - let%bind _created = - Gql_client.For_tests.create_new_block gql_uri - in - let%bind _created = - Gql_client.For_tests.create_new_block gql_uri - in - return () ) ; - - (* Commit should process remaining deposits *) - Thread_safe.block_on_async_exn (fun () -> - let%bind _ = commit sequencer in - let%bind () = Snark_queue.wait_to_finish sequencer.snark_q in - let%bind () = - Executor.wait_to_finish sequencer.merger_ctx.executor - in - let%bind _created = - Gql_client.For_tests.create_new_block gql_uri - in - let%bind committed_ledger_hash = - Gql_client.fetch_committed_state gql_uri - Signature_lib.Public_key.(compress zkapp_keypair.public_key) - in - let target_ledger_hash = get_root sequencer in - [%test_eq: Ledger_hash.t] committed_ledger_hash target_ledger_hash ; - - return () ) ; - - let deposits_state = - Utils.get_inner_deposits_state_exn (L.of_database sequencer.db) - in - let expected_deposits_state = - List.fold deposits ~init:Zkapp_account.Actions.empty_state_element - ~f:(fun acc transfer -> - Zkapp_account.Actions.push_events acc - (Zkapps_rollup.TR.to_actions transfer) ) - in - [%test_eq: Field.t] deposits_state expected_deposits_state ) + (* let%test_unit "deposits" = + print_endline "Started test 'deposits'" ; + Quickcheck.test ~trials:1 (Sequencer_test_spec.gen ~delay_deposit:2 ()) + ~f:(fun { zkapp_keypair; signer; ephemeral_ledger; specs; sequencer } -> + (* Create l1 accounts *) + let l1_accounts = + Array.create ~len:5 () + |> Array.map ~f:Signature_lib.Keypair.create + |> Array.to_list + in + Thread_safe.block_on_async_exn (fun () -> + Deferred.List.iter l1_accounts ~f:(fun keypair -> + let%bind _res = + Gql_client.For_tests.create_account gql_uri + (Signature_lib.Public_key.compress keypair.public_key) + in + return () ) ) ; + + (* Send deposits *) + let deposits = + Thread_safe.block_on_async_exn (fun () -> + let submit_deposit ~fee (signer : Keypair.t) deposit = + let%bind nonce = + Gql_client.fetch_nonce gql_uri + (Signature_lib.Public_key.compress signer.public_key) + in + let fee_payer = + Account_update.Fee_payer. + { body = + { public_key = Public_key.compress signer.public_key + ; fee = Currency.Fee.of_mina_int_exn fee + ; valid_until = None + ; nonce = Account.Nonce.of_uint32 nonce + } + ; authorization = Signature.dummy + } + in + let%bind transfer_update = + M.Outer.submit_deposit + ~outer_public_key: + (Public_key.compress zkapp_keypair.public_key) + ~deposit + in + let transferrer_update : Account_update.t = + { body = + { Account_update.Body.dummy with + public_key = Public_key.compress signer.public_key + ; balance_change = + Currency.Amount.Signed.( + negate @@ of_unsigned deposit.amount) + ; use_full_commitment = true + ; authorization_kind = Signature + } + ; authorization = Signature Signature.dummy + } + in + let transfer_cmd : Zkapp_command.t = + { fee_payer + ; account_updates = + Zkapp_command.Call_forest.( + cons_tree transfer_update @@ accumulate_hashes' + @@ of_account_updates + ~account_update_depth:(fun _ -> 0) + [ transferrer_update ]) + ; memo = Signed_command_memo.empty + } + in + return @@ sign_cmd transfer_cmd [ signer ] + in + let account1 = List.nth_exn l1_accounts 0 in + let account2 = List.nth_exn l1_accounts 1 in + let account3 = List.nth_exn l1_accounts 2 in + let account4 = List.nth_exn l1_accounts 3 in + let account5 = List.nth_exn l1_accounts 4 in + + let deposit1 : Zkapps_rollup.TR.t = + { recipient = Public_key.compress account1.public_key + ; amount = Currency.Amount.of_mina_int_exn 10 + } + in + let deposit2 : Zkapps_rollup.TR.t = + { recipient = Public_key.compress account2.public_key + ; amount = Currency.Amount.of_mina_int_exn 20 + } + in + let deposit3 : Zkapps_rollup.TR.t = + { recipient = Public_key.compress account3.public_key + ; amount = Currency.Amount.of_mina_int_exn 30 + } + in + let deposit4 : Zkapps_rollup.TR.t = + { recipient = Public_key.compress account4.public_key + ; amount = Currency.Amount.of_mina_int_exn 40 + } + in + let deposit5 : Zkapps_rollup.TR.t = + { recipient = Public_key.compress account5.public_key + ; amount = Currency.Amount.of_mina_int_exn 50 + } + in + + (* Send deposits for accounts 1 and 2 *) + let%bind _ = + submit_deposit ~fee:5 account1 deposit1 + >>= Gql_client.send_zkapp gql_uri + in + let%bind _ = + submit_deposit ~fee:4 account2 deposit2 + >>= Gql_client.send_zkapp gql_uri + in + + (* Create 2 new blocks for delay *) + let%bind _created = + Gql_client.For_tests.create_new_block gql_uri + in + let%bind _created = + Gql_client.For_tests.create_new_block gql_uri + in + + (* Send deposits for accounts 3, 4 and 5 which won't be processed *) + let%bind _ = + submit_deposit ~fee:3 account3 deposit3 + >>= Gql_client.send_zkapp gql_uri + in + let%bind _ = + submit_deposit ~fee:2 account4 deposit4 + >>= Gql_client.send_zkapp gql_uri + in + let%bind _ = + submit_deposit ~fee:1 account5 deposit5 + >>= Gql_client.send_zkapp gql_uri + in + let%bind _created = + Gql_client.For_tests.create_new_block gql_uri + in + return [ deposit1; deposit2; deposit3; deposit4; deposit5 ] ) + in + + (* Commit should process first 2 deposits *) + Thread_safe.block_on_async_exn (fun () -> + let%bind _ = commit sequencer in + let%bind () = Snark_queue.wait_to_finish sequencer.snark_q in + let%bind () = + Executor.wait_to_finish sequencer.merger_ctx.executor + in + let%bind _created = + Gql_client.For_tests.create_new_block gql_uri + in + let%bind committed_ledger_hash = + Gql_client.fetch_committed_state gql_uri + Signature_lib.Public_key.(compress zkapp_keypair.public_key) + in + let target_ledger_hash = get_root sequencer in + [%test_eq: Ledger_hash.t] committed_ledger_hash target_ledger_hash ; + + return () ) ; + + let deposits_state = + Utils.get_inner_deposits_state_exn (L.of_database sequencer.db) + in + let expected_deposits_state = + (* Expected should be only first 2 deposits *) + List.take deposits 2 + |> List.fold ~init:Zkapp_account.Actions.empty_state_element + ~f:(fun acc transfer -> + Zkapp_account.Actions.push_events acc + (Zkapps_rollup.TR.to_actions transfer) ) + in + [%test_eq: Field.t] deposits_state expected_deposits_state ; + + print_endline "Processing remaining deposits" ; + + (* Create new blocks to process remaining deposits *) + Thread_safe.block_on_async_exn (fun () -> + let%bind _created = + Gql_client.For_tests.create_new_block gql_uri + in + let%bind _created = + Gql_client.For_tests.create_new_block gql_uri + in + return () ) ; + + (* Commit should process remaining deposits *) + Thread_safe.block_on_async_exn (fun () -> + let%bind _ = commit sequencer in + let%bind () = Snark_queue.wait_to_finish sequencer.snark_q in + let%bind () = + Executor.wait_to_finish sequencer.merger_ctx.executor + in + let%bind _created = + Gql_client.For_tests.create_new_block gql_uri + in + let%bind committed_ledger_hash = + Gql_client.fetch_committed_state gql_uri + Signature_lib.Public_key.(compress zkapp_keypair.public_key) + in + let target_ledger_hash = get_root sequencer in + [%test_eq: Ledger_hash.t] committed_ledger_hash target_ledger_hash ; + + return () ) ; + + let deposits_state = + Utils.get_inner_deposits_state_exn (L.of_database sequencer.db) + in + let expected_deposits_state = + List.fold deposits ~init:Zkapp_account.Actions.empty_state_element + ~f:(fun acc transfer -> + Zkapp_account.Actions.push_events acc + (Zkapps_rollup.TR.to_actions transfer) ) + in + [%test_eq: Field.t] deposits_state expected_deposits_state ) *) let () = printf "Sequencer tests took %s\n" From ad93605d9e30553beb88e169f106b7e15110ccf4 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Wed, 15 Jan 2025 18:14:32 +0100 Subject: [PATCH 14/22] Remove unused subscriptions --- src/app/zeko/sequencer/lib/gql.ml | 18 +---------------- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 21 -------------------- 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/src/app/zeko/sequencer/lib/gql.ml b/src/app/zeko/sequencer/lib/gql.ml index 0313c93a9b..9b1edb7d56 100644 --- a/src/app/zeko/sequencer/lib/gql.ml +++ b/src/app/zeko/sequencer/lib/gql.ml @@ -1889,23 +1889,7 @@ end module Subscriptions = struct open Schema - let state_hashes_changed = - subscription_field "stateHashesChanged" - ~doc: - "Event that triggers when some of the state hashes are changed. Max \ - once per minute." - ~typ:(non_null Types.State_hashes.t) - ~args:Arg.[] - ~resolve:(fun { ctx = sequencer; _ } -> - let r, w = - Zeko_sequencer.Subscriptions.add_state_hashes_subscriber - sequencer.subscriptions - in - Pipe.write_without_pushback_if_open w - (Zeko_sequencer.get_latest_state sequencer) ; - return (Ok r) ) - - let commands = [ state_hashes_changed ] + let commands = [] end let schema = diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index 709c76db0d..e5d971e5f8 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -342,18 +342,6 @@ module Sequencer = struct } end - module Subscriptions = struct - type t = - { mutable state_hashes_changed : State_hashes.t Pipe.Writer.t list } - - let create () = { state_hashes_changed = [] } - - let add_state_hashes_subscriber t = - let r, w = Pipe.create () in - t.state_hashes_changed <- w :: t.state_hashes_changed ; - (r, w) - end - type t = { db : L.Db.t ; logger : Logger.t @@ -366,7 +354,6 @@ module Sequencer = struct ; da_client : Da_layer.Client.Sequencer.t ; apply_q : unit Sequencer.t (* Applying of the user command is async operation, but we need to keep the application synchronous *) - ; mutable subscriptions : Subscriptions.t } let close t = @@ -403,11 +390,6 @@ module Sequencer = struct ; committed_ledger_hash = Field.zero } - let trigger_state_hashes_changed t = - let state_hashes = get_latest_state t in - List.iter t.subscriptions.state_hashes_changed ~f:(fun w -> - Pipe.write_without_pushback_if_open w state_hashes ) - (** Apply user command to the ledger without checking the validity of the command *) let apply_user_command_without_check l archive command ~global_slot ~state_body = @@ -569,8 +551,6 @@ module Sequencer = struct Da_layer.Client.Sequencer.enqueue_distribute_diff t.da_client ~ledger_openings:first_pass_ledger ~diff ~target_ledger_hash ; - trigger_state_hashes_changed t ; - let pc : Transaction_snark.Pending_coinbase_stack_state.t = (* No coinbase to add to the stack. *) let stack_with_state global_slot = @@ -853,7 +833,6 @@ module Sequencer = struct } ; stop = Ivar.create () ; apply_q = Sequencer.create () - ; subscriptions = Subscriptions.create () } in let%bind () = From 8f7532a38136f4c11506dba2028d55781b2b67c9 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Wed, 15 Jan 2025 18:15:51 +0100 Subject: [PATCH 15/22] Remove unused stop functino --- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index e5d971e5f8..06994f2c95 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -350,17 +350,11 @@ module Sequencer = struct ; snark_q : Snark_queue.t ; merger : Merger.P.t ; merger_ctx : Merger.Context.t - ; stop : unit Ivar.t ; da_client : Da_layer.Client.Sequencer.t ; apply_q : unit Sequencer.t (* Applying of the user command is async operation, but we need to keep the application synchronous *) } - let close t = - L.Db.close t.db ; - Ivar.fill_if_empty t.stop () ; - Throttle.kill t.snark_q.q - let add_account t account_id account = ( L.Db.get_or_create_account t.db account_id account |> Or_error.ok_exn : [ `Added | `Existed ] * L.Db.Location.t ) @@ -716,7 +710,7 @@ module Sequencer = struct if Float.(t.config.commitment_period_sec <= 0.) then () else let period = Time_ns.Span.of_sec t.config.commitment_period_sec in - every ~start:(after period) ~stop:(Ivar.read t.stop) period (fun () -> + every ~start:(after period) period (fun () -> don't_wait_for @@ Deferred.ignore_m @@ commit t ) let bootstrap ~logger ({ config; _ } as t) da_config = @@ -831,7 +825,6 @@ module Sequencer = struct ; kvdb ; state = Merger.Context.load_state kvdb } - ; stop = Ivar.create () ; apply_q = Sequencer.create () } in From 20371eee129f0d670162fbb159fab60673b4f5e2 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Wed, 15 Jan 2025 18:25:23 +0100 Subject: [PATCH 16/22] Clean up snark queue into separate file --- src/app/zeko/sequencer/lib/gql.ml | 31 ++--- src/app/zeko/sequencer/lib/snark_queue.ml | 85 ++++++++++++++ .../lib/{transfers_memory.ml => transfer.ml} | 23 +++- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 106 ------------------ 4 files changed, 119 insertions(+), 126 deletions(-) create mode 100644 src/app/zeko/sequencer/lib/snark_queue.ml rename src/app/zeko/sequencer/lib/{transfers_memory.ml => transfer.ml} (79%) diff --git a/src/app/zeko/sequencer/lib/gql.ml b/src/app/zeko/sequencer/lib/gql.ml index 9b1edb7d56..3c069ba41b 100644 --- a/src/app/zeko/sequencer/lib/gql.ml +++ b/src/app/zeko/sequencer/lib/gql.ml @@ -1273,12 +1273,12 @@ module Types = struct let arg_typ = enum "TransferDirection" ~values: - [ enum_value "DEPOSIT" ~value:Zeko_sequencer.Transfer.Deposit - ; enum_value "WITHDRAW" ~value:Zeko_sequencer.Transfer.Withdraw + [ enum_value "DEPOSIT" ~value:Transfer.Deposit + ; enum_value "WITHDRAW" ~value:Transfer.Withdraw ] end - module Transfer = struct + module Transfer_input = struct type input = Zkapps_rollup.TR.t let arg_typ = @@ -1295,16 +1295,15 @@ module Types = struct end module Request = struct - type input = Zeko_sequencer.Transfer.t + type input = Transfer.t let arg_typ = obj "TransferRequestInput" - ~coerce:(fun transfer direction -> - Zeko_sequencer.Transfer.{ transfer; direction } ) + ~coerce:(fun transfer direction -> Transfer.{ transfer; direction }) ~split:(fun f ({ transfer; direction } : input) -> f transfer direction ) ~fields: - [ arg "transfer" ~typ:(non_null Transfer.arg_typ) + [ arg "transfer" ~typ:(non_null Transfer_input.arg_typ) ; arg "direction" ~typ:(non_null @@ Direction.arg_typ) ] end @@ -1312,12 +1311,12 @@ module Types = struct module Claim = struct open Snark_params.Tick - type input = Zeko_sequencer.Transfer.claim + type input = Transfer.claim let arg_typ = obj "TransferClaimInput" ~coerce:(fun is_new pointer before after transfer -> - Zeko_sequencer.Transfer. + Transfer. { is_new ; pointer = Field.of_string pointer ; before @@ -1330,8 +1329,10 @@ module Types = struct ~fields: [ arg "isNew" ~typ:(non_null bool) ; arg "pointer" ~typ:(non_null string) - ; arg "before" ~typ:(non_null (list @@ non_null Transfer.arg_typ)) - ; arg "after" ~typ:(non_null (list @@ non_null Transfer.arg_typ)) + ; arg "before" + ~typ:(non_null (list @@ non_null Transfer_input.arg_typ)) + ; arg "after" + ~typ:(non_null (list @@ non_null Transfer_input.arg_typ)) ; arg "transfer" ~typ:(non_null Request.arg_typ) ] end @@ -1680,8 +1681,9 @@ module Mutations = struct ~resolve:(fun { ctx = sequencer; _ } () transfer -> let key = Int.to_string @@ Random.int Int.max_value in don't_wait_for - @@ Zeko_sequencer.Snark_queue.enqueue_prove_transfer_request + @@ Snark_queue.enqueue_prove_transfer_request Zeko_sequencer.(sequencer.snark_q) + ~zkapp_pk:Zeko_sequencer.(sequencer.config.zkapp_pk) ~key ~transfer ; return (Ok key) ) @@ -1692,8 +1694,9 @@ module Mutations = struct ~resolve:(fun { ctx = sequencer; _ } () claim -> let key = Int.to_string @@ Random.int Int.max_value in don't_wait_for - @@ Zeko_sequencer.Snark_queue.enqueue_prove_transfer_claim + @@ Snark_queue.enqueue_prove_transfer_claim Zeko_sequencer.(sequencer.snark_q) + ~zkapp_pk:Zeko_sequencer.(sequencer.config.zkapp_pk) ~key ~claim ; return (Ok key) ) @@ -1801,7 +1804,7 @@ module Queries = struct ~args:Arg.[ arg "key" ~typ:(non_null string) ] ~resolve:(fun { ctx = sequencer; _ } () key -> match - Transfers_memory.get + Transfer.Transfers_memory.get Zeko_sequencer.(sequencer.snark_q.transfers_memory) key with diff --git a/src/app/zeko/sequencer/lib/snark_queue.ml b/src/app/zeko/sequencer/lib/snark_queue.ml new file mode 100644 index 0000000000..8ae0482dd1 --- /dev/null +++ b/src/app/zeko/sequencer/lib/snark_queue.ml @@ -0,0 +1,85 @@ +open Core_kernel +open Async +open Mina_base + +type t = + { q : unit Throttle.t + ; transfers_memory : Transfer.Transfers_memory.t + ; provers : Zeko_prover.Client.State.t + } + +let create ~config ~provers = + { q = Throttle.create ~continue_on_error:false ~max_concurrent_jobs:1 + ; transfers_memory = + Transfer.Transfers_memory.create ~lifetime:Float.(60. * 10.) + ; provers + } + +let queue_size t = Throttle.num_jobs_waiting_to_start t.q + +let enqueue t f = + Throttle.enqueue t.q (fun () -> + let%map result = f () in + result ) + +let enqueue_prove_transfer_request t ~key ~zkapp_pk ~(transfer : Transfer.t) = + Throttle.enqueue t.q (fun () -> + let%bind result = + try_with (fun () -> + match transfer with + | { direction = Deposit; transfer } -> + Zeko_prover.Client.submit_deposit t.provers ~outer_pk:zkapp_pk + ~deposit:transfer + | { direction = Withdraw; transfer } -> + Zeko_prover.Client.submit_withdrawal t.provers + ~withdrawal:transfer ) + in + let () = + match result with + | Ok tree -> + Transfer.Transfers_memory.add t.transfers_memory key + (Ok (Zkapp_command.Call_forest.cons_tree tree [])) + | Error e -> + printf "Warning: prove_transfer_request failed %s\n%!" + (Exn.to_string e) ; + Transfer.Transfers_memory.add t.transfers_memory key + (Error (Exn.to_string e)) + in + return () ) + +let enqueue_prove_transfer_claim t ~key ~zkapp_pk ~(claim : Transfer.claim) = + Throttle.enqueue t.q (fun () -> + let%bind result = + try_with (fun () -> + match claim with + | { transfer = { direction = Deposit; transfer } + ; is_new + ; pointer + ; before + ; after + } -> + Zeko_prover.Client.process_deposit t.provers ~is_new ~pointer + ~before ~after ~deposit:transfer + | { transfer = { direction = Withdraw; transfer } + ; is_new + ; pointer + ; before + ; after + } -> + Zeko_prover.Client.process_withdrawal t.provers + ~outer_pk:zkapp_pk ~is_new ~pointer ~before ~after + ~withdrawal:transfer ) + in + let () = + match result with + | Ok forest -> + Transfer.Transfers_memory.add t.transfers_memory key (Ok forest) + | Error e -> + printf "Warning: prove_transfer_claim failed %s\n%!" + (Exn.to_string e) ; + Transfer.Transfers_memory.add t.transfers_memory key + (Error (Exn.to_string e)) + in + return () ) + +let wait_to_finish t = Throttle.capacity_available t.q diff --git a/src/app/zeko/sequencer/lib/transfers_memory.ml b/src/app/zeko/sequencer/lib/transfer.ml similarity index 79% rename from src/app/zeko/sequencer/lib/transfers_memory.ml rename to src/app/zeko/sequencer/lib/transfer.ml index 548ef1e8c2..c46ae579f8 100644 --- a/src/app/zeko/sequencer/lib/transfers_memory.ml +++ b/src/app/zeko/sequencer/lib/transfer.ml @@ -1,12 +1,25 @@ +open Mina_base +module Field = Snark_params.Tick.Field + +type direction = Deposit | Withdraw + +type t = { transfer : Zkapps_rollup.TR.t; direction : direction } + +type claim = + { is_new : bool + ; pointer : Field.t + ; before : Zkapps_rollup.TR.t list + ; after : Zkapps_rollup.TR.t list + ; transfer : t + } + (** Hash table that holds the item only for the specified lifetime. Used to store proved transfer requested by users. *) - -open Base -open Mina_base - module Transfers_memory = struct + open Base + type t_ = ( ( Account_update.t , Zkapp_command.Digest.Account_update.t @@ -48,5 +61,3 @@ module Transfers_memory = struct let get t key = Hashtbl.find t.table key end - -include Transfers_memory diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index 06994f2c95..f93066b053 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -28,20 +28,6 @@ module Sequencer = struct } end - module Transfer = struct - type direction = Deposit | Withdraw - - type t = { transfer : Zkapps_rollup.TR.t; direction : direction } - - type claim = - { is_new : bool - ; pointer : Field.t - ; before : Zkapps_rollup.TR.t list - ; after : Zkapps_rollup.TR.t list - ; transfer : t - } - end - let genesis_constants = Genesis_constants.Compiled.genesis_constants let compile_time_genesis_state = @@ -65,91 +51,6 @@ module Sequencer = struct @@ Sok_message.create ~fee:Currency.Fee.zero ~prover:(Public_key.compress keypair.public_key) - module Snark_queue = struct - type t = - { q : unit Throttle.t - ; config : Config.t - ; transfers_memory : Transfers_memory.t - ; provers : Zeko_prover.Client.State.t - } - - let create ~config ~provers = - { q = Throttle.create ~continue_on_error:false ~max_concurrent_jobs:1 - ; config - ; transfers_memory = Transfers_memory.create ~lifetime:Float.(60. * 10.) - ; provers - } - - let queue_size t = Throttle.num_jobs_waiting_to_start t.q - - let enqueue t f = - Throttle.enqueue t.q (fun () -> - let%map result = f () in - result ) - - let enqueue_prove_transfer_request t ~key ~(transfer : Transfer.t) = - Throttle.enqueue t.q (fun () -> - let%bind result = - try_with (fun () -> - match transfer with - | { direction = Deposit; transfer } -> - Zeko_prover.Client.submit_deposit t.provers - ~outer_pk:t.config.zkapp_pk ~deposit:transfer - | { direction = Withdraw; transfer } -> - Zeko_prover.Client.submit_withdrawal t.provers - ~withdrawal:transfer ) - in - let () = - match result with - | Ok tree -> - Transfers_memory.add t.transfers_memory key - (Ok (Zkapp_command.Call_forest.cons_tree tree [])) - | Error e -> - printf "Warning: prove_transfer_request failed %s\n%!" - (Exn.to_string e) ; - Transfers_memory.add t.transfers_memory key - (Error (Exn.to_string e)) - in - return () ) - - let enqueue_prove_transfer_claim t ~key ~(claim : Transfer.claim) = - Throttle.enqueue t.q (fun () -> - let%bind result = - try_with (fun () -> - match claim with - | { transfer = { direction = Deposit; transfer } - ; is_new - ; pointer - ; before - ; after - } -> - Zeko_prover.Client.process_deposit t.provers ~is_new - ~pointer ~before ~after ~deposit:transfer - | { transfer = { direction = Withdraw; transfer } - ; is_new - ; pointer - ; before - ; after - } -> - Zeko_prover.Client.process_withdrawal t.provers - ~outer_pk:t.config.zkapp_pk ~is_new ~pointer ~before - ~after ~withdrawal:transfer ) - in - let () = - match result with - | Ok forest -> - Transfers_memory.add t.transfers_memory key (Ok forest) - | Error e -> - printf "Warning: prove_transfer_claim failed %s\n%!" - (Exn.to_string e) ; - Transfers_memory.add t.transfers_memory key - (Error (Exn.to_string e)) - in - return () ) - - let wait_to_finish t = Throttle.capacity_available t.q - end - module Merger = struct module Command_witness = struct type t = @@ -271,13 +172,6 @@ module Sequencer = struct end module Commit = struct - (* Only for yojson serialization of Field *) - module Field = Data_hash.Make_full_size (struct - let description = "Field" - - let version_byte = '\x00' - end) - type t = { new_inner_ledger : Sparse_ledger.t ; old_deposits_pointer : Field.t From 2b8ce547b9e23e1a48d1bde2c1b887f8cddd0fa0 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Wed, 15 Jan 2025 18:50:41 +0100 Subject: [PATCH 17/22] Remove old zkapps_rollup stubs and add zeko_constants --- src/app/zeko/da_layer/lib/dune | 2 +- src/app/zeko/da_layer/lib/node.ml | 4 +- src/app/zeko/dune | 32 ++-- src/app/zeko/sequencer/archive_relay/dune | 1 + src/app/zeko/sequencer/archive_relay/run.ml | 19 +-- src/app/zeko/sequencer/dune | 1 - src/app/zeko/sequencer/lib/deploy.ml | 4 +- src/app/zeko/sequencer/lib/dune | 2 +- src/app/zeko/sequencer/lib/utils.ml | 2 +- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 47 +++--- src/app/zeko/sequencer/prover/dune | 1 - src/app/zeko/sequencer/prover/lib/dune | 3 +- src/app/zeko/sequencer/prover/lib/prover.ml | 11 +- .../zeko/sequencer/tests/testing_ledger/dune | 1 - src/app/zeko/zeko_constants.ml | 33 +++++ src/app/zeko/zeko_util.ml | 15 -- src/app/zeko/zkapps_rollup.ml | 137 ------------------ 17 files changed, 83 insertions(+), 232 deletions(-) create mode 100644 src/app/zeko/zeko_constants.ml delete mode 100644 src/app/zeko/zeko_util.ml delete mode 100644 src/app/zeko/zkapps_rollup.ml diff --git a/src/app/zeko/da_layer/lib/dune b/src/app/zeko/da_layer/lib/dune index 340324e590..35d93a34e2 100644 --- a/src/app/zeko/da_layer/lib/dune +++ b/src/app/zeko/da_layer/lib/dune @@ -3,7 +3,7 @@ (inline_tests) (libraries kvdb_base - zkapps_rollup + zeko_constants ;; mina ;; mina_base mina_base.import diff --git a/src/app/zeko/da_layer/lib/node.ml b/src/app/zeko/da_layer/lib/node.ml index d9e7d79fd7..b7bf2b8b58 100644 --- a/src/app/zeko/da_layer/lib/node.ml +++ b/src/app/zeko/da_layer/lib/node.ml @@ -3,7 +3,7 @@ open Mina_base open Mina_ledger open Signature_lib -let constraint_constants = Genesis_constants.Compiled.constraint_constants +let constraint_constants = Zeko_constants.constraint_constants type t = { db : Db.t; signer : Keypair.t; logger : Logger.t } @@ -141,7 +141,7 @@ let post_diff t ~ledger_openings ~diff = let account_id = let aid = Account_update.account_id account_update in if Public_key.Compressed.(Account_id.public_key aid = empty) - then Zkapps_rollup.inner_account_id + then Zeko_constants.inner_account_id else aid in let%bind.Result old_receipt_chain_hash = diff --git a/src/app/zeko/dune b/src/app/zeko/dune index 81cf00035f..f7f86e454d 100644 --- a/src/app/zeko/dune +++ b/src/app/zeko/dune @@ -1,23 +1,19 @@ -(env (_ (flags (:standard -w @a-42-40-44-70-45-41)))) +(env + (_ + (flags + (:standard -w @a-42-40-44-70-45-41)))) (library - (name zeko_util) - (libraries zeko_circuits) + (name zeko_constants) + (libraries + mina_base + snark_params + signature_lib + consensus + mina_state + genesis_ledger + staged_ledger_diff) (inline_tests) (instrumentation (backend bisect_ppx)) - (preprocess - (pps ppx_deriving.show ppx_deriving_snarky ppx_snarky ppx_mina ppx_version ppx_jane ppx_compare h_list.ppx)) - (modules zeko_util) - ) - -(library - (name zkapps_rollup) - (libraries zeko_util) - (inline_tests) - (instrumentation - (backend bisect_ppx)) - (preprocess - (pps ppx_deriving.show ppx_deriving_snarky ppx_snarky ppx_mina ppx_version ppx_jane ppx_compare h_list.ppx)) - (modules zkapps_rollup) - ) + (modules zeko_constants)) diff --git a/src/app/zeko/sequencer/archive_relay/dune b/src/app/zeko/sequencer/archive_relay/dune index 2bd53d550c..9a0828f576 100644 --- a/src/app/zeko/sequencer/archive_relay/dune +++ b/src/app/zeko/sequencer/archive_relay/dune @@ -1,6 +1,7 @@ (executable (name run) (libraries + zeko_constants da_layer mina_lib mina_ledger diff --git a/src/app/zeko/sequencer/archive_relay/run.ml b/src/app/zeko/sequencer/archive_relay/run.ml index 60997e6795..ce68347dcc 100644 --- a/src/app/zeko/sequencer/archive_relay/run.ml +++ b/src/app/zeko/sequencer/archive_relay/run.ml @@ -4,7 +4,7 @@ open Mina_base open Mina_lib open Mina_ledger -let constraint_constants = Genesis_constants.Compiled.constraint_constants +let constraint_constants = Zeko_constants.constraint_constants let rec rmrf path = match Sys.is_directory path with @@ -15,20 +15,7 @@ let rec rmrf path = | false -> Sys.remove path -let compile_time_genesis_state = - let genesis_constants = Genesis_constants.Compiled.genesis_constants in - let consensus_constants = - Consensus.Constants.create ~constraint_constants - ~protocol_constants:genesis_constants.protocol - in - let compile_time_genesis = - Mina_state.Genesis_protocol_state.t - ~genesis_ledger:Genesis_ledger.(Packed.t for_unit_tests) - ~genesis_epoch_data:Consensus.Genesis_epoch_data.for_unit_tests - ~constraint_constants ~consensus_constants - ~genesis_body_reference:Staged_ledger_diff.genesis_body_reference - in - compile_time_genesis.data +let compile_time_genesis_state = Zeko_constants.compile_time_genesis_state let time ~logger label (d : 'a Deferred.t) = let start = Time.now () in @@ -122,7 +109,7 @@ let sync_archive ~(state : State.t) ~hash = ~txn: (Mina_transaction_logic.Transaction_applied .transaction_with_status txn_applied ) - ~dummy_fee_payer:Zkapps_rollup.inner_public_key + ~dummy_fee_payer:Zeko_constants.inner_public_key ~timestamp:(Da_layer.Diff.Stable.Latest.timestamp diff) in protocol_state := new_protocol_state ; diff --git a/src/app/zeko/sequencer/dune b/src/app/zeko/sequencer/dune index 3a43ca3b06..01779c1487 100644 --- a/src/app/zeko/sequencer/dune +++ b/src/app/zeko/sequencer/dune @@ -30,7 +30,6 @@ (name deploy) (libraries sequencer_lib - zkapps_rollup ;; mina ;; mina_base mina_numbers diff --git a/src/app/zeko/sequencer/lib/deploy.ml b/src/app/zeko/sequencer/lib/deploy.ml index 8594e9b147..efbd81ddeb 100644 --- a/src/app/zeko/sequencer/lib/deploy.ml +++ b/src/app/zeko/sequencer/lib/deploy.ml @@ -5,8 +5,8 @@ module L = Mina_ledger.Ledger let deploy_command_exn ~(signer : Keypair.t) ~(fee : Currency.Fee.t) ~(nonce : Account.Nonce.t) ~(zkapp : Keypair.t) ~(initial_ledger : L.t) - ~(constraint_constants : Genesis_constants.Constraint_constants.t) - (module Z : Zkapps_rollup.S) : Zkapp_command.t = + ~(constraint_constants : Genesis_constants.Constraint_constants.t) : + Zkapp_command.t = let zkapp_update = { body = { Body.dummy with diff --git a/src/app/zeko/sequencer/lib/dune b/src/app/zeko/sequencer/lib/dune index f4b15c4652..41f313e8f2 100644 --- a/src/app/zeko/sequencer/lib/dune +++ b/src/app/zeko/sequencer/lib/dune @@ -2,11 +2,11 @@ (name sequencer_lib) (inline_tests) (libraries - zkapps_rollup kvdb_base da_layer zeko_prover parallel_merger + zeko_constants ;; mina ;; mina_base mina_base.import diff --git a/src/app/zeko/sequencer/lib/utils.ml b/src/app/zeko/sequencer/lib/utils.ml index 63768145df..bf39f4a415 100644 --- a/src/app/zeko/sequencer/lib/utils.ml +++ b/src/app/zeko/sequencer/lib/utils.ml @@ -56,7 +56,7 @@ let get_inner_deposits_state_exn l = let open Zeko_circuits in let ({ outer_action_state } : Rollup_state.Inner_state.t) = let idx = - Mina_ledger.Ledger.index_of_account_exn l Zkapps_rollup.inner_account_id + Mina_ledger.Ledger.index_of_account_exn l Zeko_constants.inner_account_id in let inner_acc = Mina_ledger.Ledger.get_at_index_exn l idx in (Option.value_exn inner_acc.zkapp).app_state diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index f93066b053..cbcd55c054 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -9,10 +9,8 @@ open Zeko_circuits module L = Ledger module Field = Snark_params.Tick.Field -let constraint_constants = Genesis_constants.Compiled.constraint_constants - module Sequencer = struct - let constraint_constants = constraint_constants + let constraint_constants = Zeko_constants.constraint_constants module Config = struct type t = @@ -28,22 +26,6 @@ module Sequencer = struct } end - let genesis_constants = Genesis_constants.Compiled.genesis_constants - - let compile_time_genesis_state = - let consensus_constants = - Consensus.Constants.create ~constraint_constants - ~protocol_constants:genesis_constants.protocol - in - let compile_time_genesis = - Mina_state.Genesis_protocol_state.t - ~genesis_ledger:Genesis_ledger.(Packed.t for_unit_tests) - ~genesis_epoch_data:Consensus.Genesis_epoch_data.for_unit_tests - ~constraint_constants ~consensus_constants - ~genesis_body_reference:Staged_ledger_diff.genesis_body_reference - in - compile_time_genesis.data - let keypair = Keypair.create () let sok_digest = @@ -370,7 +352,8 @@ module Sequencer = struct (* the protocol state from sequencer has dummy values which wouldn't pass the txn snark *) let global_slot = Mina_numbers.Global_slot_since_genesis.zero in let state_body = - Mina_state.Protocol_state.body compile_time_genesis_state + Mina_state.Protocol_state.body + Zeko_constants.compile_time_genesis_state in let l = L.of_database t.db in @@ -414,7 +397,7 @@ module Sequencer = struct User_command.accounts_referenced command |> List.map ~f:(fun id -> if Public_key.Compressed.(Account_id.public_key id = empty) - then Zkapps_rollup.inner_account_id + then Zeko_constants.inner_account_id else id ) |> List.stable_dedup in @@ -584,7 +567,7 @@ module Sequencer = struct let target_ledger = Sparse_ledger.of_ledger_subset_exn L.(of_database t.db) - [ Zkapps_rollup.inner_account_id ] + [ Zeko_constants.inner_account_id ] in if Merger.P.current_tree t.merger @@ -648,7 +631,8 @@ module Sequencer = struct let mask = L.of_database t.db in let global_slot = Mina_numbers.Global_slot_since_genesis.zero in let state_body = - Mina_state.Protocol_state.body compile_time_genesis_state + Mina_state.Protocol_state.body + Zeko_constants.compile_time_genesis_state in let _, _, _, _ = apply_user_command_without_check mask t.archive command @@ -668,7 +652,7 @@ module Sequencer = struct let sparse_ledger = Sparse_ledger.of_ledger_subset_exn L.(of_database t.db) - [ Zkapps_rollup.inner_account_id ] + [ Zeko_constants.inner_account_id ] in Merger.Context.reset_state t.merger_ctx sparse_ledger ; return () @@ -754,12 +738,11 @@ let%test_module "Sequencer tests" = let logger = Logger.create () module T = Transaction_snark.Make (struct - let constraint_constants = constraint_constants + let constraint_constants = Zeko_constants.constraint_constants let proof_level = Genesis_constants.Proof_level.Full end) - module M = Zkapps_rollup.Make (T) open Sequencer let number_of_transactions = 5 @@ -804,7 +787,7 @@ let%test_module "Sequencer tests" = in let genesis_accounts = - (M.Inner.account_id, M.Inner.initial_account) + (Zeko_constants.inner_account_id, M.Inner.initial_account) :: ( Array.map init_ledger ~f:(fun (keypair, balance) -> let pk = Signature_lib.Public_key.compress keypair.public_key @@ -851,7 +834,6 @@ let%test_module "Sequencer tests" = Deploy.deploy_command_exn ~signer ~zkapp:zkapp_keypair ~fee:(Currency.Fee.of_mina_int_exn 1) ~nonce ~initial_ledger:ephemeral_ledger ~constraint_constants - (module M) in let%bind _ = Gql_client.send_zkapp gql_uri command in let%bind _created = Gql_client.For_tests.create_new_block gql_uri in @@ -975,7 +957,9 @@ let%test_module "Sequencer tests" = ~state_view: Mina_state.Protocol_state.( Body.view - @@ body compile_time_genesis_state) + @@ body + Zeko_constants + .compile_time_genesis_state) with | Ok (applied, _) -> [%test_eq: Transaction_status.t] @@ -1077,7 +1061,10 @@ let%test_module "Sequencer tests" = Mina_numbers.Global_slot_since_genesis.zero ~state_view: Mina_state.Protocol_state.( - Body.view @@ body compile_time_genesis_state) + Body.view + @@ body + Zeko_constants + .compile_time_genesis_state) with | Ok _ -> () diff --git a/src/app/zeko/sequencer/prover/dune b/src/app/zeko/sequencer/prover/dune index 028ba95451..700eafd3ab 100644 --- a/src/app/zeko/sequencer/prover/dune +++ b/src/app/zeko/sequencer/prover/dune @@ -2,7 +2,6 @@ (name cli) (libraries zeko_prover - zkapps_rollup mina_lib mina_ledger core_unix.command_unix diff --git a/src/app/zeko/sequencer/prover/lib/dune b/src/app/zeko/sequencer/prover/lib/dune index 8ef9fb3da3..39231440c1 100644 --- a/src/app/zeko/sequencer/prover/lib/dune +++ b/src/app/zeko/sequencer/prover/lib/dune @@ -1,7 +1,8 @@ (library (name zeko_prover) (libraries - zkapps_rollup + zeko_circuits + zeko_constants mina_lib mina_ledger yojson diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index 908203af13..f35d7321ca 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -354,9 +354,9 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function Compile_simple.Verification_key.of_tag Outer_rules.tag |> Promise.to_deferred in - let inner_account_index = 0 in let old_inner_acc = - Mina_ledger.Sparse_ledger.get_exn old_inner_ledger inner_account_index + Mina_ledger.Sparse_ledger.get_exn old_inner_ledger + Zeko_constants.inner_account_index in let old_inner_acc_path = List.map ~f:(function @@ -367,10 +367,11 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function ( { right_side = Field.one } : Outer_rules.Rule_commit_inst.PathElt.t ) ) @@ Mina_ledger.Sparse_ledger.path_exn old_inner_ledger - inner_account_index + Zeko_constants.inner_account_index in let new_inner_acc = - Mina_ledger.Sparse_ledger.get_exn new_inner_ledger inner_account_index + Mina_ledger.Sparse_ledger.get_exn new_inner_ledger + Zeko_constants.inner_account_index in let new_inner_acc_path = List.map ~f:(function @@ -381,7 +382,7 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function ( { right_side = Field.one } : Outer_rules.Rule_commit_inst.PathElt.t ) ) @@ Mina_ledger.Sparse_ledger.path_exn new_inner_ledger - inner_account_index + Zeko_constants.inner_account_index in let%bind outer_ase = let ({ outer_action_state } : Rollup_state.Inner_state.t) = diff --git a/src/app/zeko/sequencer/tests/testing_ledger/dune b/src/app/zeko/sequencer/tests/testing_ledger/dune index 979a32e861..a78e746a01 100644 --- a/src/app/zeko/sequencer/tests/testing_ledger/dune +++ b/src/app/zeko/sequencer/tests/testing_ledger/dune @@ -1,7 +1,6 @@ (executable (name run) (libraries - zkapps_rollup sequencer_lib ;; mina ;; mina_base diff --git a/src/app/zeko/zeko_constants.ml b/src/app/zeko/zeko_constants.ml new file mode 100644 index 0000000000..587e48d2cc --- /dev/null +++ b/src/app/zeko/zeko_constants.ml @@ -0,0 +1,33 @@ +open Mina_base +open Signature_lib +module Field = Snark_params.Tick.Run.Field + +let constraint_constants = Genesis_constants.Compiled.constraint_constants + +let genesis_constants = Genesis_constants.Compiled.genesis_constants + +let compile_time_genesis_state = + let consensus_constants = + Consensus.Constants.create ~constraint_constants + ~protocol_constants:genesis_constants.protocol + in + let compile_time_genesis = + Mina_state.Genesis_protocol_state.t + ~genesis_ledger:Genesis_ledger.(Packed.t for_unit_tests) + ~genesis_epoch_data:Consensus.Genesis_epoch_data.for_unit_tests + ~constraint_constants ~consensus_constants + ~genesis_body_reference:Staged_ledger_diff.genesis_body_reference + in + compile_time_genesis.data + +let inner_public_key = + let pk = + Snark_params.Tick.Inner_curve.( + to_affine_exn @@ point_near_x @@ Field.Constant.of_int 123456789) + in + Public_key.compress pk + +let inner_account_id = + Account_id.of_public_key (Public_key.decompress_exn inner_public_key) + +let inner_account_index = 0 diff --git a/src/app/zeko/zeko_util.ml b/src/app/zeko/zeko_util.ml deleted file mode 100644 index 860f986cff..0000000000 --- a/src/app/zeko/zeko_util.ml +++ /dev/null @@ -1,15 +0,0 @@ -open Mina_base - -type call_forest = - ( Account_update.t - , Zkapp_command.Digest.Account_update.t - , Zkapp_command.Digest.Forest.t ) - Zkapp_command.Call_forest.t -[@@deriving yojson] - -type call_forest_tree = - ( Account_update.t - , Zkapp_command.Digest.Account_update.t - , Zkapp_command.Digest.Forest.t ) - Zkapp_command.Call_forest.Tree.t -[@@deriving yojson] diff --git a/src/app/zeko/zkapps_rollup.ml b/src/app/zeko/zkapps_rollup.ml deleted file mode 100644 index bd6e3cf9e7..0000000000 --- a/src/app/zeko/zkapps_rollup.ml +++ /dev/null @@ -1,137 +0,0 @@ -open Mina_base -open Zeko_util -open Snark_params.Tick -open Signature_lib - -let inner_public_key = Zeko_circuits.Outer_rules.Inputs.inner_public_key - -let inner_account_id = Account_id.create inner_public_key Token_id.default - -type t = unit - -let to_yojson _ = failwith "FIXME" - -let of_yojson _ = failwith "FIXME" - -module TR = struct - type t = - { amount : Currency.Amount.t - ; recipient : Signature_lib.Public_key.Compressed.t - } - - let to_yojson = to_yojson - - let of_yojson = of_yojson - - let to_actions _ = failwith "FIXME" -end - -module type S = sig - open Async - - module Wrapper : sig - (** Wrap a ledger transition. - - The wrapped transition must be "whole", and must be made using - inner_pending_coinbase and inner_pending_coinbase_init, - such that the pc target and source are equal. - The connecting ledger must be the ledger between the two passes, - i.e., the end of the first pass, and the beginning of the second pass, - and as such, the passes must be connected. - You can not wrap a single zkapp command segment either, - you can only wrap at least a whole zkapp command. - *) - val wrap : Transaction_snark.t -> t Deferred.t - - (** Merge two wrapped ledger transitions, they must connect or this will fail. *) - val merge : t -> t -> t Deferred.t - end - - module Inner : sig - (** Account update for withdrawing *) - val submit_withdrawal : withdrawal:TR.t -> call_forest_tree Deferred.t - - val process_deposit : - is_new:bool (** Has this recipient been deposited to before? *) - -> pointer:field - -> before:TR.t list (** deposits before last recorded from new to old *) - -> after:TR.t list (** deposits after last recorded from new to old *) - -> deposit:TR.t - -> ([ `Pointer of field ] * call_forest) Deferred.t - - val step : all_deposits:field -> call_forest_tree Deferred.t - - (** Account ID using public key *) - val account_id : Account_id.t - - (** Initial state of inner account in new rollup *) - val initial_account : Account.t - end - - module Outer : sig - (** Account update for depositing *) - val submit_deposit : - outer_public_key:Public_key.Compressed.t - -> deposit:TR.t - -> call_forest_tree Deferred.t - - val process_withdrawal : - is_new:bool (** Has this recipient been withdrawn to before? *) - -> outer_public_key:Public_key.Compressed.t - -> pointer:field - -> before:TR.t list - -> after:TR.t list - -> withdrawal:TR.t - -> ([ `Pointer of field ] * call_forest) Deferred.t - - val step : - t (** The transition, must include Inner.step account update *) - -> outer_public_key:Public_key.Compressed.t - -> new_deposits:TR.t list (** new deposits from new to old *) - -> unprocessed_deposits:TR.t list - (** from new deposits to the current action state *) - -> old_inner_ledger:Mina_ledger.Sparse_ledger.t - (** Old sparse inner ledger including inner account *) - -> new_inner_ledger:Mina_ledger.Sparse_ledger.t - (** New sparse inner ledger including inner account *) - -> call_forest_tree Deferred.t - - (** Create an account update update for deploying the zkapp, given a valid ledger for it. *) - val deploy_exn : Mina_ledger.Ledger.t -> Account_update.Update.t - end -end - -module Make (_ : sig end) : S = struct - module Wrapper = struct - let wrap _ = failwith "FIXME" - - let merge _ _ = failwith "FIXME" - end - - module Outer = struct - let submit_deposit ~outer_public_key:_ ~deposit:_ = failwith "FIXME" - - let process_withdrawal ~is_new:_ ~outer_public_key:_ ~pointer:_ ~before:_ - ~after:_ ~withdrawal:_ = - failwith "FIXME" - - let step _ ~outer_public_key:_ ~new_deposits:_ ~unprocessed_deposits:_ - ~old_inner_ledger:_ ~new_inner_ledger:_ = - failwith "FIXME" - - let deploy_exn _ = failwith "FIXME" - end - - module Inner = struct - let submit_withdrawal ~withdrawal:_ = failwith "FIXME" - - let process_deposit ~is_new:_ ~pointer:_ ~before:_ ~after:_ ~deposit:_ = - failwith "FIXME" - - let step ~all_deposits:_ = failwith "FIXME" - - let account_id = inner_account_id - - let initial_account = Account.empty - end -end From 185f876cedd8dab99c0198e5ea92f0833d95969f Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 20 Jan 2025 15:52:34 +0100 Subject: [PATCH 18/22] Make it compile --- src/app/zeko/sequencer/deploy.ml | 12 ++---------- src/app/zeko/sequencer/lib/deploy.ml | 10 ++++++++++ src/app/zeko/sequencer/lib/gql.ml | 5 ++--- src/app/zeko/sequencer/lib/transfer.ml | 15 ++++++++++++--- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 2 +- 5 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/app/zeko/sequencer/deploy.ml b/src/app/zeko/sequencer/deploy.ml index 301ecf93b6..d679e9e1b7 100644 --- a/src/app/zeko/sequencer/deploy.ml +++ b/src/app/zeko/sequencer/deploy.ml @@ -34,14 +34,6 @@ module Test_accounts = struct (account_id, account) ) end -module T = Transaction_snark.Make (struct - let constraint_constants = constraint_constants - - let proof_level = Genesis_constants.Proof_level.Full -end) - -module M = Zkapps_rollup.Make (T) - let run ~l1_uri ~sk ~initial_state ~da_nodes () = let logger = Logger.create () in let sender_keypair = @@ -65,7 +57,8 @@ let run ~l1_uri ~sk ~initial_state ~da_nodes () = let ledger = L.create_ephemeral ~depth:constraint_constants.ledger_depth () in - L.create_new_account_exn ledger M.Inner.account_id M.Inner.initial_account ; + L.create_new_account_exn ledger Zeko_constants.inner_account_id + Sequencer_lib.Deploy.Z.Inner.initial_account ; match initial_state with | `None -> ledger @@ -85,7 +78,6 @@ let run ~l1_uri ~sk ~initial_state ~da_nodes () = ~zkapp:zkapp_keypair ~fee:(Currency.Fee.of_mina_int_exn 1) ~nonce ~constraint_constants ~initial_ledger:ledger - (module M) in (* Post genesis batch *) diff --git a/src/app/zeko/sequencer/lib/deploy.ml b/src/app/zeko/sequencer/lib/deploy.ml index efbd81ddeb..45bf621225 100644 --- a/src/app/zeko/sequencer/lib/deploy.ml +++ b/src/app/zeko/sequencer/lib/deploy.ml @@ -3,6 +3,16 @@ open Account_update open Signature_lib module L = Mina_ledger.Ledger +module Z = struct + module Inner = struct + let initial_account = failwith "not implemented" + end + + module Outer = struct + let deploy_exn _ledger = failwith "not implemented" + end +end + let deploy_command_exn ~(signer : Keypair.t) ~(fee : Currency.Fee.t) ~(nonce : Account.Nonce.t) ~(zkapp : Keypair.t) ~(initial_ledger : L.t) ~(constraint_constants : Genesis_constants.Constraint_constants.t) : diff --git a/src/app/zeko/sequencer/lib/gql.ml b/src/app/zeko/sequencer/lib/gql.ml index 3c069ba41b..07cb8a3ff5 100644 --- a/src/app/zeko/sequencer/lib/gql.ml +++ b/src/app/zeko/sequencer/lib/gql.ml @@ -1279,13 +1279,12 @@ module Types = struct end module Transfer_input = struct - type input = Zkapps_rollup.TR.t + type input = Transfer.TR.t let arg_typ = obj "TransferInput" ~coerce:(fun amount recipient -> - Zkapps_rollup.TR.{ amount = Amount.of_uint64 amount; recipient } - ) + Transfer.TR.{ amount = Amount.of_uint64 amount; recipient } ) ~split:(fun f (x : input) -> f (Currency.Amount.to_uint64 x.amount) x.recipient ) ~fields: diff --git a/src/app/zeko/sequencer/lib/transfer.ml b/src/app/zeko/sequencer/lib/transfer.ml index c46ae579f8..b96610ba73 100644 --- a/src/app/zeko/sequencer/lib/transfer.ml +++ b/src/app/zeko/sequencer/lib/transfer.ml @@ -3,13 +3,22 @@ module Field = Snark_params.Tick.Field type direction = Deposit | Withdraw -type t = { transfer : Zkapps_rollup.TR.t; direction : direction } +module TR = struct + (* FIXME *) + type t = + { amount : Currency.Amount.t + ; recipient : Signature_lib.Public_key.Compressed.t + } + [@@deriving yojson] +end + +type t = { transfer : TR.t; direction : direction } type claim = { is_new : bool ; pointer : Field.t - ; before : Zkapps_rollup.TR.t list - ; after : Zkapps_rollup.TR.t list + ; before : TR.t list + ; after : TR.t list ; transfer : t } diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index cbcd55c054..159b27908f 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -787,7 +787,7 @@ let%test_module "Sequencer tests" = in let genesis_accounts = - (Zeko_constants.inner_account_id, M.Inner.initial_account) + (Zeko_constants.inner_account_id, Deploy.Z.Inner.initial_account) :: ( Array.map init_ledger ~f:(fun (keypair, balance) -> let pk = Signature_lib.Public_key.compress keypair.public_key From bf6ff5230373958c6e955fce17d8d826004a16c6 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Fri, 24 Jan 2025 16:47:09 +0100 Subject: [PATCH 19/22] Add database for indexed merkle tree --- src/app/zeko/circuits/dune | 1 + src/app/zeko/circuits/indexed_merkle_tree.ml | 3 +- src/app/zeko/dune | 5 - src/app/zeko/indexed_merkle_tree/dune | 22 ++ .../indexed_merkle_tree.ml | 258 ++++++++++++++++++ src/app/zeko/sequencer/lib/dune | 1 + src/app/zeko/zeko_constants.ml | 2 + src/lib/merkle_ledger/intf.ml | 2 + src/lib/rocksdb/database.ml | 6 + src/lib/rocksdb/database.mli | 2 + 10 files changed, 296 insertions(+), 6 deletions(-) create mode 100644 src/app/zeko/indexed_merkle_tree/dune create mode 100644 src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml diff --git a/src/app/zeko/circuits/dune b/src/app/zeko/circuits/dune index 4f2221cf98..a2ad0cc520 100644 --- a/src/app/zeko/circuits/dune +++ b/src/app/zeko/circuits/dune @@ -7,6 +7,7 @@ core_kernel transaction_snark staged_ledger_diff + zeko_constants ) (inline_tests) (instrumentation diff --git a/src/app/zeko/circuits/indexed_merkle_tree.ml b/src/app/zeko/circuits/indexed_merkle_tree.ml index 9fc8af6908..556a628277 100644 --- a/src/app/zeko/circuits/indexed_merkle_tree.ml +++ b/src/app/zeko/circuits/indexed_merkle_tree.ml @@ -33,7 +33,8 @@ struct let length = height end) - let hash_entry = var_to_hash ~init:"indexed merkle tree entry hash" Entry.typ + let hash_entry = + var_to_hash ~init:Zeko_constants.indexed_merkle_tree_salt Entry.typ let implied_root_raw (init : F.var) (path : Path.var) : F.var Checked.t = Checked.List.fold path ~init ~f:(fun acc { hash; is_left } -> diff --git a/src/app/zeko/dune b/src/app/zeko/dune index f7f86e454d..e402068729 100644 --- a/src/app/zeko/dune +++ b/src/app/zeko/dune @@ -1,8 +1,3 @@ -(env - (_ - (flags - (:standard -w @a-42-40-44-70-45-41)))) - (library (name zeko_constants) (libraries diff --git a/src/app/zeko/indexed_merkle_tree/dune b/src/app/zeko/indexed_merkle_tree/dune new file mode 100644 index 0000000000..250a319d22 --- /dev/null +++ b/src/app/zeko/indexed_merkle_tree/dune @@ -0,0 +1,22 @@ +(library + (name indexed_merkle_tree) + (inline_tests) + (libraries + zeko_constants + ;; mina ;; + mina_base + mina_base.import + mina_ledger + merkle_ledger + rocksdb + ;; opam libraries ;; + core_kernel) + (preprocess + (pps + ppx_version + ppx_let + ppx_custom_printf + ppx_base + ppx_deriving_yojson + ppx_inline_test + ppx_assert))) diff --git a/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml b/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml new file mode 100644 index 0000000000..7b3dcf02f2 --- /dev/null +++ b/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml @@ -0,0 +1,258 @@ +open Core +open Signature_lib +open Merkle_ledger +open Mina_base +module Field = Snark_params.Tick.Field + +module Location_at_depth : Merkle_ledger.Location_intf.S = + Merkle_ledger.Location.T + +module Location_binable = struct + module Arg = struct + type t = Location_at_depth.t = + | Generic of Location.Bigstring.Stable.Latest.t + | Account of Location_at_depth.Addr.Stable.Latest.t + | Hash of Location_at_depth.Addr.Stable.Latest.t + [@@deriving bin_io_unversioned, hash, sexp, compare] + end + + type t = Arg.t = + | Generic of Location.Bigstring.t + | Account of Location_at_depth.Addr.t + | Hash of Location_at_depth.Addr.t + [@@deriving hash, sexp, compare] + + include Comparable.Make_binable (Arg) + include Hashable.Make_binable (Arg) [@@deriving sexp, compare, hash, yojson] +end + +module Kvdb : Intf.Key_value_database with type config := string = + Rocksdb.Database + +module Storage_locations : Intf.Storage_locations = struct + let key_value_db_dir = "mina_key_value_db" +end + +module Account_id = struct + include Account_id + + let with_empty_key tid = create Public_key.Compressed.empty tid +end + +module Entry = struct + [%%versioned + module Stable = struct + module V2 = struct + type t = + { value : Token_id.Stable.V2.t; value_next : Token_id.Stable.V2.t } + [@@deriving equal, compare, sexp] + + let to_latest = Fn.id + + let identifier { value; _ } = Account_id.with_empty_key value + + let balance _ = Currency.Balance.zero + + let empty = + { value = Token_id.of_field Field.zero + ; value_next = Token_id.of_field Field.zero + } + + let token { value; _ } = value + end + end] +end + +module Hash = struct + module Arg = struct + type t = Ledger_hash.Stable.Latest.t + [@@deriving sexp, compare, hash, bin_io_unversioned] + end + + [%%versioned + module Stable = struct + module V1 = struct + type t = Ledger_hash.Stable.V1.t + [@@deriving sexp, compare, hash, equal, yojson] + + let (_ : (t, Arg.t) Type_equal.t) = Type_equal.T + + let to_latest = Fn.id + + include Hashable.Make_binable (Arg) + + let to_base58_check = Ledger_hash.to_base58_check + + let merge = Ledger_hash.merge + + let hash_account Entry.{ value; value_next } = + Random_oracle.hash + ~init: + (Hash_prefix_create.salt Zeko_constants.indexed_merkle_tree_salt) + [| Token_id.to_field_unsafe value + ; Token_id.to_field_unsafe value_next + |] + + let empty_account = + Ledger_hash.of_digest (Lazy.force Account.empty_digest) + end + end] +end + +module Inputs = struct + module Key = Public_key.Compressed + module Token_id = Token_id + module Account_id = Account_id + + module Balance = struct + include Currency.Balance + + let to_int = to_nanomina_int + end + + module Account = Entry.Stable.Latest + module Hash = Hash.Stable.Latest + module Kvdb = Kvdb + module Location = Location_at_depth + module Location_binable = Location_binable + module Storage_locations = Storage_locations +end + +module type Indexed_merkle_tree_intf = sig + include + Merkle_ledger.Intf.Ledger.DATABASE + with module Location = Location_at_depth + with module Addr = Location_at_depth.Addr + with type root_hash := Ledger_hash.t + and type hash := Ledger_hash.t + and type key := Public_key.Compressed.t + and type token_id := Token_id.t + and type token_id_set := Token_id.Set.t + and type account := Entry.t + and type account_id_set := Account_id.Set.t + and type account_id := Account_id.t + and type zeko_kvdb := Kvdb.t + + val get_or_create_entry_exn : + t + -> Token_id.t + -> [> `Added | `Existed ] + * [> `X of Token_id.t ] + * [> `X_path of path ] + * [> `Y of Token_id.t ] + * [> `Y_path of path ] + * [> `Z of Token_id.t ] +end + +module Db : Indexed_merkle_tree_intf = struct + include Database.Make (Inputs) + + module Db_error = struct + [@@@warning "-4"] (* due to deriving sexp below *) + + type t = + | Account_location_not_found + | Out_of_leaves + | Malformed_database of string + [@@deriving sexp] + + let ok_exn = function + | Ok x -> + x + | Error e -> + raise (Exn.create_s ([%sexp_of: t] e)) + end + + let lowest_key = Token_id.of_field Field.zero + + let highest_key = + Token_id.of_field + (Field.of_string Bigint.(Field.size - of_int 1 |> to_string)) + + let get_raw t location = + Kvdb.get (zeko_kvdb t) + ~key:(Location.serialize ~ledger_depth:(depth t) location) + + let get_generic t location = + assert (Location.is_generic location) ; + get_raw t location + + module Account_location = struct + let build_location account_id = + Location.build_generic + (Bigstring.of_string + ( "$" + ^ Format.sprintf + !"%{sexp: Public_key.Compressed.t}!%{sexp: Token_id.t}" + (Account_id.public_key account_id) + (Account_id.token_id account_id) ) ) + end + + let find_lower_entry_location_exn t tid = + if Token_id.equal lowest_key tid then + failwith "There is no lower key than the 0" ; + let location_key = + Account_location.build_location (Account_id.with_empty_key tid) + in + let prev_location_key = + Kvdb.prev_key (zeko_kvdb t) + ~key:(Location.serialize ~ledger_depth:(depth t) location_key) + |> Location.parse ~ledger_depth:(depth t) + |> Result.map_error ~f:(fun () -> + Db_error.Malformed_database "Failed to parse prev location key" ) + |> Db_error.ok_exn + in + get_generic t prev_location_key + |> Option.value_exn ~message:"Failed to find prev location" + |> Location.parse ~ledger_depth:(depth t) + |> Result.map_error ~f:(fun _ -> + Db_error.Malformed_database "Failed to parse prev location" ) + |> Db_error.ok_exn + + let create ?directory_name ~depth () = + let db = create ?directory_name ~depth () in + let (_ : [ `Added | `Existed ] * Location_at_depth.t) = + get_or_create_account db + (Account_id.with_empty_key lowest_key) + { Entry.value = lowest_key; value_next = highest_key } + |> Or_error.ok_exn + in + let (_ : [ `Added | `Existed ] * Location_at_depth.t) = + get_or_create_account db + (Account_id.with_empty_key highest_key) + { Entry.value = highest_key; value_next = highest_key } + |> Or_error.ok_exn + in + db + + let get_or_create_entry_exn t tid = + let lower_entry_location = find_lower_entry_location_exn t tid in + let lower_entry = + get t lower_entry_location + |> Result.of_option + ~error:(Db_error.Malformed_database "Could not find lower entry") + |> Db_error.ok_exn + in + let new_entry = + { Entry.value = tid; value_next = lower_entry.value_next } + in + match get_or_create_account t (Account_id.with_empty_key tid) new_entry with + | Ok (`Existed, new_location) -> + ( `Existed + , `X lower_entry.value + , `X_path (merkle_path t lower_entry_location) + , `Y new_entry.value + , `Y_path (merkle_path t new_location) + , `Z new_entry.value_next ) + | Ok (`Added, new_location) -> + let lower_entry = { lower_entry with value_next = tid } in + set t lower_entry_location lower_entry ; + ( `Added + , `X lower_entry.value + , `X_path (merkle_path t lower_entry_location) + , `Y new_entry.value + , `Y_path (merkle_path t new_location) + , `Z new_entry.value_next ) + | Error e -> + Error.raise e +end diff --git a/src/app/zeko/sequencer/lib/dune b/src/app/zeko/sequencer/lib/dune index 41f313e8f2..cb16d5d1ca 100644 --- a/src/app/zeko/sequencer/lib/dune +++ b/src/app/zeko/sequencer/lib/dune @@ -7,6 +7,7 @@ zeko_prover parallel_merger zeko_constants + indexed_merkle_tree ;; mina ;; mina_base mina_base.import diff --git a/src/app/zeko/zeko_constants.ml b/src/app/zeko/zeko_constants.ml index 587e48d2cc..c546562fb8 100644 --- a/src/app/zeko/zeko_constants.ml +++ b/src/app/zeko/zeko_constants.ml @@ -31,3 +31,5 @@ let inner_account_id = Account_id.of_public_key (Public_key.decompress_exn inner_public_key) let inner_account_index = 0 + +let indexed_merkle_tree_salt = "indexed merkle tree entry hash" diff --git a/src/lib/merkle_ledger/intf.ml b/src/lib/merkle_ledger/intf.ml index 0f8391af23..b3da87c1fd 100644 --- a/src/lib/merkle_ledger/intf.ml +++ b/src/lib/merkle_ledger/intf.ml @@ -201,6 +201,8 @@ module type Key_value_database = sig -> ('a, 'b) Continue_or_stop.t ) -> finish:('a -> 'b) -> 'b + + val prev_key : t -> key:Bigstring.t -> Bigstring.t end module type Storage_locations = sig diff --git a/src/lib/rocksdb/database.ml b/src/lib/rocksdb/database.ml index 1621df8a10..14f2abdc98 100644 --- a/src/lib/rocksdb/database.ml +++ b/src/lib/rocksdb/database.ml @@ -119,6 +119,12 @@ let fold_until : in finish @@ loop init +let prev_key t ~(key : Bigstring.t) : Bigstring.t = + let iterator = Rocks.Iterator.create t.db in + Rocks.Iterator.seek iterator key ; + Rocks.Iterator.prev iterator ; + Rocks.Iterator.get_key iterator + let to_bigstring = Bigstring.of_string let%test_unit "get_batch" = diff --git a/src/lib/rocksdb/database.mli b/src/lib/rocksdb/database.mli index 8b66cf176d..9d4daf7cad 100644 --- a/src/lib/rocksdb/database.mli +++ b/src/lib/rocksdb/database.mli @@ -53,6 +53,8 @@ val fold_until : -> finish:('a -> 'b) -> 'b +val prev_key : t -> key:Bigstring.t -> Bigstring.t + module Batch : sig type t = Rocks.WriteBatch.t From 2f220fb656e6dc45855f1973177af9f6524abe35 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 27 Jan 2025 15:29:16 +0100 Subject: [PATCH 20/22] Add imt db to the sequencer --- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 42 +++++++++++++++----- src/app/zeko/sequencer/run.ml | 20 ++++++---- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index 159b27908f..c9148ef13a 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -5,6 +5,7 @@ open Async_kernel open Mina_base open Mina_ledger open Signature_lib +module Imt_db = Indexed_merkle_tree.Db open Zeko_circuits module L = Ledger module Field = Snark_params.Tick.Field @@ -17,6 +18,7 @@ module Sequencer = struct { max_pool_size : int ; commitment_period_sec : float ; db_dir : string option + ; imt_dir : string option ; zkapp_pk : Public_key.Compressed.t ; signer : Keypair.t ; l1_uri : Uri.t Cli_lib.Flag.Types.with_name @@ -220,6 +222,7 @@ module Sequencer = struct type t = { db : L.Db.t + ; imt : Imt_db.t ; logger : Logger.t ; archive : Archive.t ; config : Config.t @@ -261,7 +264,7 @@ module Sequencer = struct } (** Apply user command to the ledger without checking the validity of the command *) - let apply_user_command_without_check l archive command ~global_slot + let apply_user_command_without_check l imt archive command ~global_slot ~state_body = let accounts_referenced = User_command.accounts_referenced command in @@ -297,6 +300,20 @@ module Sequencer = struct L.Mask.Attached.commit l ; + (* Create entires in Indexed Merkle Tree *) + Mina_transaction_logic.Transaction_applied.new_accounts txn_applied + |> List.iter ~f:(fun aid -> + match + Imt_db.get_or_create_entry_exn imt + (Account_id.derive_token_id ~owner:aid) + with + | `Existed, _, _, _, _, _ -> + printf + !"Warning: Account %{sexp: Account_id.t} already existed\n%!" + aid + | `Added, _, _, _, _, _ -> + () ) ; + (* Add events and actions to the memory *) let () = match command with @@ -387,8 +404,8 @@ module Sequencer = struct , txn_applied , target_ledger_hash ) = return - (apply_user_command_without_check l t.archive command ~global_slot - ~state_body ) + (apply_user_command_without_check l t.imt t.archive command + ~global_slot ~state_body ) in (* Post transaction to the DA layer *) @@ -635,7 +652,7 @@ module Sequencer = struct Zeko_constants.compile_time_genesis_state in let _, _, _, _ = - apply_user_command_without_check mask t.archive command + apply_user_command_without_check mask t.imt t.archive command ~global_slot ~state_body |> Or_error.ok_exn in @@ -658,17 +675,22 @@ module Sequencer = struct return () let create ~logger ~zkapp_pk ~max_pool_size ~commitment_period_sec ~da_config - ~da_quorum ~db_dir ~l1_uri ~archive_uri ~signer ~network_id + ~da_quorum ~db_dir ~imt_dir ~l1_uri ~archive_uri ~signer ~network_id ~deposit_delay_blocks ~provers = let db = L.Db.create ?directory_name:db_dir ~depth:constraint_constants.ledger_depth () in + let imt = + Imt_db.create ?directory_name:imt_dir + ~depth:constraint_constants.ledger_depth () + in let config = Config. { max_pool_size ; commitment_period_sec ; db_dir + ; imt_dir ; l1_uri ; archive_uri ; zkapp_pk @@ -689,6 +711,7 @@ module Sequencer = struct let executor = Executor.create ~l1_uri:config.l1_uri ~signer ~kvdb () in let t = { db + ; imt ; logger ; archive = Archive.create ~kvdb:(L.Db.zeko_kvdb db) ; config @@ -846,8 +869,8 @@ let%test_module "Sequencer tests" = ~zkapp_pk: Signature_lib.Public_key.(compress zkapp_keypair.public_key) ~max_pool_size:10 ~commitment_period_sec:0. ~da_config - ~da_quorum:1 ~db_dir:None ~l1_uri:gql_uri ~archive_uri:gql_uri - ~signer ~network_id:"testnet" + ~da_quorum:1 ~db_dir:None ~imt_dir:None ~l1_uri:gql_uri + ~archive_uri:gql_uri ~signer ~network_id:"testnet" ~deposit_delay_blocks:delay_deposit ~provers ) in @@ -1148,8 +1171,9 @@ let%test_module "Sequencer tests" = ~zkapp_pk: Signature_lib.Public_key.(compress zkapp_keypair.public_key) ~max_pool_size:10 ~commitment_period_sec:0. ~da_config - ~da_quorum:1 ~db_dir:None ~l1_uri:gql_uri ~archive_uri:gql_uri - ~signer ~network_id:"testnet" ~deposit_delay_blocks:0 ~provers + ~da_quorum:1 ~db_dir:None ~imt_dir:None ~l1_uri:gql_uri + ~archive_uri:gql_uri ~signer ~network_id:"testnet" + ~deposit_delay_blocks:0 ~provers in return @@ [%test_eq: Frozen_ledger_hash.t] (get_root new_sequencer) diff --git a/src/app/zeko/sequencer/run.ml b/src/app/zeko/sequencer/run.ml index 61cb7d3d11..9abd922442 100644 --- a/src/app/zeko/sequencer/run.ml +++ b/src/app/zeko/sequencer/run.ml @@ -7,8 +7,8 @@ module Graphql_cohttp_async = module Sequencer = Zeko_sequencer.Sequencer let run ~port ~zkapp_pk ~max_pool_size ~commitment_period ~da_config ~da_quorum - ~db_dir ~l1_uri ~archive_uri ~signer ~network_id ~deposit_delay_blocks - ~provers () = + ~db_dir ~imt_dir ~l1_uri ~archive_uri ~signer ~network_id + ~deposit_delay_blocks ~provers () = let zkapp_pk = Option.( value ~default:Signature_lib.Public_key.Compressed.empty @@ -17,9 +17,9 @@ let run ~port ~zkapp_pk ~max_pool_size ~commitment_period ~da_config ~da_quorum let sequencer = Thread_safe.block_on_async_exn (fun () -> Sequencer.create ~logger:(Logger.create ()) ~zkapp_pk ~max_pool_size - ~da_config ~da_quorum ~db_dir:(Some db_dir) ~l1_uri ~archive_uri - ~commitment_period_sec:commitment_period ~network_id - ~deposit_delay_blocks + ~da_config ~da_quorum ~db_dir:(Some db_dir) ~imt_dir:(Some imt_dir) + ~l1_uri ~archive_uri ~commitment_period_sec:commitment_period + ~network_id ~deposit_delay_blocks ~signer: Signature_lib.( Keypair.of_private_key_exn @@ -78,7 +78,11 @@ let () = and db_dir = flag "--db-dir" (optional_with_default "db" string) - ~doc:"string Directory to store the database" + ~doc:"string Directory to store the Ledger database" + and imt_dir = + flag "--imt-dir" + (optional_with_default "db" string) + ~doc:"string Directory to store the Indexed Merkle Tree database" and network_id = flag "--network-id" (optional_with_default "testnet" string) @@ -99,6 +103,6 @@ let () = in let provers = List.map provers ~f:Host_and_port.of_string in run ~port ~zkapp_pk ~max_pool_size ~commitment_period ~da_config ~da_quorum - ~db_dir ~l1_uri ~archive_uri ~signer ~network_id ~deposit_delay_blocks - ~provers ) + ~db_dir ~imt_dir ~l1_uri ~archive_uri ~signer ~network_id + ~deposit_delay_blocks ~provers ) |> Command_unix.run From 76bccb79a40c5e1ce590a641ab2347c29c62c884 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 3 Feb 2025 15:13:58 +0100 Subject: [PATCH 21/22] Generate witnesses for Indexed Merkle Tree --- src/app/zeko/circuits/indexed_merkle_tree.ml | 2 +- src/app/zeko/circuits/indexed_merkle_tree.mli | 2 +- .../zeko/circuits/zeko_transaction_snark.mli | 2 +- src/app/zeko/circuits/zeko_util.ml | 2 +- src/app/zeko/circuits/zeko_util.mli | 2 +- src/app/zeko/indexed_merkle_tree/dune | 1 + .../indexed_merkle_tree.ml | 166 +++++++++++++++--- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 87 +++++++-- src/app/zeko/sequencer/prover/lib/client.ml | 58 +++--- src/app/zeko/sequencer/prover/lib/dune | 1 + src/app/zeko/sequencer/prover/lib/prover.ml | 141 +++++++++------ 11 files changed, 344 insertions(+), 120 deletions(-) diff --git a/src/app/zeko/circuits/indexed_merkle_tree.ml b/src/app/zeko/circuits/indexed_merkle_tree.ml index 556a628277..8175e5e42c 100644 --- a/src/app/zeko/circuits/indexed_merkle_tree.ml +++ b/src/app/zeko/circuits/indexed_merkle_tree.ml @@ -16,7 +16,7 @@ struct type t = { key : Key.t; next_key : Key.t } [@@deriving snarky] end - type t = F.t [@@deriving yojson] + type t = F.t [@@deriving yojson, sexp] type var = F.var diff --git a/src/app/zeko/circuits/indexed_merkle_tree.mli b/src/app/zeko/circuits/indexed_merkle_tree.mli index 61cf50b108..12e929006f 100644 --- a/src/app/zeko/circuits/indexed_merkle_tree.mli +++ b/src/app/zeko/circuits/indexed_merkle_tree.mli @@ -27,7 +27,7 @@ module Make (Inputs : sig end) : sig open Inputs - type t [@@deriving yojson] + type t = F.t [@@deriving yojson, sexp] type var diff --git a/src/app/zeko/circuits/zeko_transaction_snark.mli b/src/app/zeko/circuits/zeko_transaction_snark.mli index 6a7f76140d..0d7247e54b 100644 --- a/src/app/zeko/circuits/zeko_transaction_snark.mli +++ b/src/app/zeko/circuits/zeko_transaction_snark.mli @@ -40,7 +40,7 @@ module Local_state : sig end module Account_set : sig - type t [@@deriving yojson] + type t = F.t [@@deriving yojson, sexp] type var diff --git a/src/app/zeko/circuits/zeko_util.ml b/src/app/zeko/circuits/zeko_util.ml index 81a7f412c6..ddbc70f2e6 100644 --- a/src/app/zeko/circuits/zeko_util.ml +++ b/src/app/zeko/circuits/zeko_util.ml @@ -95,7 +95,7 @@ let var_to_app_state_fine = (** To be used with deriving snarky, a simple field *) module F = struct - type t = Field.t [@@deriving yojson] + type t = Field.t [@@deriving yojson, sexp] type var = Field.Var.t diff --git a/src/app/zeko/circuits/zeko_util.mli b/src/app/zeko/circuits/zeko_util.mli index 4dfa1ae5cb..3865680831 100644 --- a/src/app/zeko/circuits/zeko_util.mli +++ b/src/app/zeko/circuits/zeko_util.mli @@ -39,7 +39,7 @@ val var_to_hash : init:string -> ('var, 'value) Typ.t -> 'var -> Field.Var.t Checked.t module F : sig - type t = Pasta_bindings.Fp.t [@@deriving yojson] + type t = Pasta_bindings.Fp.t [@@deriving yojson, sexp] type var = Field.Var.t diff --git a/src/app/zeko/indexed_merkle_tree/dune b/src/app/zeko/indexed_merkle_tree/dune index 250a319d22..9525b82b19 100644 --- a/src/app/zeko/indexed_merkle_tree/dune +++ b/src/app/zeko/indexed_merkle_tree/dune @@ -9,6 +9,7 @@ mina_ledger merkle_ledger rocksdb + sparse_ledger_lib ;; opam libraries ;; core_kernel) (preprocess diff --git a/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml b/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml index 7b3dcf02f2..d307854b32 100644 --- a/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml +++ b/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml @@ -45,7 +45,7 @@ module Entry = struct module V2 = struct type t = { value : Token_id.Stable.V2.t; value_next : Token_id.Stable.V2.t } - [@@deriving equal, compare, sexp] + [@@deriving equal, compare, sexp, yojson] let to_latest = Fn.id @@ -61,6 +61,11 @@ module Entry = struct let token { value; _ } = value end end] + + let data_hash { value; value_next } = + Random_oracle.hash + ~init:(Hash_prefix_create.salt Zeko_constants.indexed_merkle_tree_salt) + [| Token_id.to_field_unsafe value; Token_id.to_field_unsafe value_next |] end module Hash = struct @@ -85,18 +90,14 @@ module Hash = struct let merge = Ledger_hash.merge - let hash_account Entry.{ value; value_next } = - Random_oracle.hash - ~init: - (Hash_prefix_create.salt Zeko_constants.indexed_merkle_tree_salt) - [| Token_id.to_field_unsafe value - ; Token_id.to_field_unsafe value_next - |] + let hash_account = Entry.data_hash let empty_account = Ledger_hash.of_digest (Lazy.force Account.empty_digest) end end] + + let merge = Ledger_hash.merge end module Inputs = struct @@ -137,11 +138,13 @@ module type Indexed_merkle_tree_intf = sig t -> Token_id.t -> [> `Added | `Existed ] - * [> `X of Token_id.t ] - * [> `X_path of path ] - * [> `Y of Token_id.t ] - * [> `Y_path of path ] - * [> `Z of Token_id.t ] + * ( [> `X of Token_id.t ] + * [> `X_path of path ] + * [> `Y of Token_id.t ] + * [> `Y_path of path ] + * [> `Z of Token_id.t ] ) + + val find_lower_entry_aid_exn : t -> Token_id.t -> Token_id.t end module Db : Indexed_merkle_tree_intf = struct @@ -209,6 +212,14 @@ module Db : Indexed_merkle_tree_intf = struct Db_error.Malformed_database "Failed to parse prev location" ) |> Db_error.ok_exn + let find_lower_entry_aid_exn t tid = + let lower_entry_location = find_lower_entry_location_exn t tid in + get t lower_entry_location + |> Result.of_option + ~error:(Db_error.Malformed_database "Could not find lower entry") + |> Db_error.ok_exn + |> fun entry -> entry.value + let create ?directory_name ~depth () = let db = create ?directory_name ~depth () in let (_ : [ `Added | `Existed ] * Location_at_depth.t) = @@ -239,20 +250,129 @@ module Db : Indexed_merkle_tree_intf = struct match get_or_create_account t (Account_id.with_empty_key tid) new_entry with | Ok (`Existed, new_location) -> ( `Existed - , `X lower_entry.value - , `X_path (merkle_path t lower_entry_location) - , `Y new_entry.value - , `Y_path (merkle_path t new_location) - , `Z new_entry.value_next ) + , ( `X lower_entry.value + , `X_path (merkle_path t lower_entry_location) + , `Y new_entry.value + , `Y_path (merkle_path t new_location) + , `Z new_entry.value_next ) ) | Ok (`Added, new_location) -> let lower_entry = { lower_entry with value_next = tid } in set t lower_entry_location lower_entry ; ( `Added - , `X lower_entry.value - , `X_path (merkle_path t lower_entry_location) - , `Y new_entry.value - , `Y_path (merkle_path t new_location) - , `Z new_entry.value_next ) + , ( `X lower_entry.value + , `X_path (merkle_path t lower_entry_location) + , `Y new_entry.value + , `Y_path (merkle_path t new_location) + , `Z new_entry.value_next ) ) | Error e -> Error.raise e end + +module Sparse_indexed_merkle_tree = struct + include Sparse_ledger_lib.Sparse_ledger.Make (Hash) (Account_id) (Entry) + + let of_db_root (db : Db.t) = of_hash ~depth:(Db.depth db) (Db.merkle_root db) + + let of_db_subset_exn_impl ~path_query ~path_add (db : Db.t) + (tids : Token_id.t list) = + (*** [iterate_n ~f init n] returns [[f init, f (f init), ..]] of size [n] *) + let iterate_n ~f = + let rec impl prev = function + | 0 -> + [] + | n -> + let r = f prev in + r :: impl r (n - 1) + in + impl + in + let lower_entries = + List.map tids ~f:(fun tid -> Db.find_lower_entry_aid_exn db tid) + in + let tids = List.concat [ lower_entries; tids ] in + let locations = + Db.location_of_account_batch db + (List.map tids ~f:Account_id.with_empty_key) + in + let non_empty_locations = List.filter_map locations ~f:snd in + let num_new_accounts = + List.length locations - List.length non_empty_locations + in + let entries = Db.get_batch db non_empty_locations in + let empty_paths, non_empty_paths = + let next_location_exn loc = Option.value_exn (Db.Location.next loc) in + let empty_address = + Db.Addr.of_directions + @@ List.init (Db.depth db) ~f:(Fn.const Direction.Left) + in + let empty_locations = + if num_new_accounts = 0 then [] + else + let first_loc = + Option.value_map ~f:next_location_exn + ~default:(Db.Location.Account empty_address) (Db.last_filled db) + in + first_loc + :: iterate_n ~f:next_location_exn first_loc (num_new_accounts - 1) + in + let paths = path_query db (empty_locations @ non_empty_locations) in + List.split_n paths num_new_accounts + in + let process_location sl key = function + | Some _, (_, Some entry) :: accs, path :: ne_paths, epaths -> + (path_add sl path key entry, accs, ne_paths, epaths) + | None, accs, ne_paths, path :: epaths -> + ( path_add sl path key Entry.Stable.Latest.empty + , accs + , ne_paths + , epaths ) + | Some _, (_, None) :: _, _, _ -> + failwith + "of_ledger_subset_exn: account not found for location returned by \ + location_of_account_batch" + | _ -> + failwith "of_ledger_subset_exn: mismatched lengths" + in + let sl, _, _, _ = + List.fold locations + ~init:(of_db_root db, entries, non_empty_paths, empty_paths) + ~f:(fun (sl, accs, ne_paths, epaths) (key, mloc) -> + process_location sl key (mloc, accs, ne_paths, epaths) ) + in + Debug_assert.debug_assert (fun () -> + [%test_eq: Ledger_hash.t] (Db.merkle_root db) + ((merkle_root sl :> Random_oracle.Digest.t) |> Ledger_hash.of_hash) ) ; + sl + + let of_db_subset_exn = + of_db_subset_exn_impl ~path_query:Db.wide_merkle_path_batch + ~path_add:add_wide_path_unsafe + + let find_lower_entry t tid = + let result = ref None in + iteri t ~f:(fun i entry -> + if + Token_id.equal entry.value_next tid + && not + (Hash.equal (Entry.data_hash entry) + (Entry.data_hash Entry.Stable.Latest.empty) ) + then result := Some (i, entry) ) ; + !result + + let get_or_create_entry_exn t tid = + let lower_entry_location, lower_entry = + find_lower_entry t tid |> Option.value_exn + in + let lower_entry = { lower_entry with value_next = tid } in + let t = set_exn t lower_entry_location lower_entry in + let new_entry_location = find_index_exn t (Account_id.with_empty_key tid) in + let new_entry = + { Entry.value = tid; value_next = lower_entry.value_next } + in + ( set_exn t new_entry_location new_entry + , ( `X lower_entry.value + , `X_path (path_exn t lower_entry_location) + , `Y new_entry.value + , `Y_path (path_exn t new_entry_location) + , `Z new_entry.value_next ) ) +end diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index c9148ef13a..c660802aea 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -6,6 +6,7 @@ open Mina_base open Mina_ledger open Signature_lib module Imt_db = Indexed_merkle_tree.Db +module Sparse_imt = Indexed_merkle_tree.Sparse_indexed_merkle_tree open Zeko_circuits module L = Ledger module Field = Snark_params.Tick.Field @@ -42,10 +43,12 @@ module Sequencer = struct Sparse_ledger.t * Signed_command.t * Transaction_snark.Statement.With_sok.t + * Zeko_prover.Prover.Account_set_witness.t | Zkapp_command of ( Transaction_witness.Zkapp_command_segment_witness.t * Transaction_snark.Zkapp_command_segment.Basic.t - * Mina_state.Snarked_ledger_state.With_sok.t ) + * Mina_state.Snarked_ledger_state.With_sok.t + * Zeko_prover.Prover.Account_set_witness.t ) list * Zkapp_command.t [@@deriving yojson] @@ -150,9 +153,9 @@ module Sequencer = struct | Command_witness.Zkapp_command (witnesses, zkapp_command) -> Zeko_prover.Client.transaction_snark_of_zkapp_command ctx.provers ~witnesses ~sequencer_pk - | Command_witness.Signed_command (l, c, s) -> + | Command_witness.Signed_command (l, c, s, imt) -> Zeko_prover.Client.transaction_snark_of_signed_command ctx.provers - ~sequencer_pk ~witness:(l, c, s) + ~sequencer_pk ~witness:(l, c, s, imt) end module Commit = struct @@ -268,6 +271,11 @@ module Sequencer = struct ~state_body = let accounts_referenced = User_command.accounts_referenced command in + let source_imt = + List.map accounts_referenced ~f:(fun id -> + Account_id.derive_token_id ~owner:id ) + |> Sparse_imt.of_db_subset_exn imt + in let first_pass_ledger = Sparse_ledger.of_ledger_subset_exn l accounts_referenced in @@ -300,18 +308,18 @@ module Sequencer = struct L.Mask.Attached.commit l ; - (* Create entires in Indexed Merkle Tree *) + (* Create entries in Indexed Merkle Tree *) Mina_transaction_logic.Transaction_applied.new_accounts txn_applied |> List.iter ~f:(fun aid -> match Imt_db.get_or_create_entry_exn imt (Account_id.derive_token_id ~owner:aid) with - | `Existed, _, _, _, _, _ -> + | `Existed, _ -> printf !"Warning: Account %{sexp: Account_id.t} already existed\n%!" aid - | `Added, _, _, _, _, _ -> + | `Added, _ -> () ) ; (* Add events and actions to the memory *) @@ -347,7 +355,11 @@ module Sequencer = struct @@ Account_update.body update } ) )) in - (first_pass_ledger, second_pass_ledger, txn_applied, target_ledger_hash) + ( first_pass_ledger + , second_pass_ledger + , txn_applied + , target_ledger_hash + , source_imt ) (** Apply user command to the sequencer's state, including the check of command validity *) let apply_user_command t ?(skip_validity_check = false) @@ -402,7 +414,8 @@ module Sequencer = struct let%bind.Deferred.Result ( first_pass_ledger , second_pass_ledger , txn_applied - , target_ledger_hash ) = + , target_ledger_hash + , source_imt ) = return (apply_user_command_without_check l t.imt t.archive command ~global_slot ~state_body ) @@ -475,10 +488,30 @@ module Sequencer = struct |> Or_error.ok_exn ) ~pending_coinbase_stack_state:pc in + let _, account_set_witness = + Mina_transaction_logic.Transaction_applied.new_accounts + txn_applied + |> List.fold + ~init: + ( source_imt + , Zeko_prover.Prover.Account_set_witness.empty source_imt + ) + ~f:(fun (imt, witness) aid -> + let imt, w = + Sparse_imt.get_or_create_entry_exn imt + (Account_id.derive_token_id ~owner:aid) + in + ( imt + , Zeko_prover.Prover.Account_set_witness.add witness w ) + ) + in Result.return ( txn_applied , Merger.Command_witness.Signed_command - (first_pass_ledger, signed_command, statement) ) + ( first_pass_ledger + , signed_command + , statement + , account_set_witness ) ) | Zkapp_command zkapp_command -> let witnesses = Transaction_snark.zkapp_command_witnesses_exn @@ -496,6 +529,40 @@ module Sequencer = struct , zkapp_command ) ] in + let witnesses = + List.map witnesses ~f:(fun (witness, spec, txn_snark) -> + let account_updates = + Zkapp_command.Call_forest.to_account_updates + witness.local_state_init.stack_frame.calls + in + let aids = + match (spec, account_updates) with + | Proved, first :: _ | Opt_signed, first :: _ -> + [ Account_update.account_id first ] + | Opt_signed_opt_signed, first :: second :: _ -> + [ Account_update.account_id first + ; Account_update.account_id second + ] + | _ -> + failwith "Failed to pop stack frame based on spec" + in + let _, account_set_witness = + List.fold aids + ~init: + ( source_imt + , Zeko_prover.Prover.Account_set_witness.empty + source_imt ) + ~f:(fun (imt, witness) aid -> + let imt, w = + Sparse_imt.get_or_create_entry_exn imt + (Account_id.derive_token_id ~owner:aid) + in + ( imt + , Zeko_prover.Prover.Account_set_witness.add witness w + ) ) + in + (witness, spec, txn_snark, account_set_witness) ) + in Result.return ( txn_applied , Merger.Command_witness.Zkapp_command (witnesses, zkapp_command) @@ -651,7 +718,7 @@ module Sequencer = struct Mina_state.Protocol_state.body Zeko_constants.compile_time_genesis_state in - let _, _, _, _ = + let _, _, _, _, _ = apply_user_command_without_check mask t.imt t.archive command ~global_slot ~state_body |> Or_error.ok_exn diff --git a/src/app/zeko/sequencer/prover/lib/client.ml b/src/app/zeko/sequencer/prover/lib/client.ml index f8a7b0b8cf..6666d75c72 100644 --- a/src/app/zeko/sequencer/prover/lib/client.ml +++ b/src/app/zeko/sequencer/prover/lib/client.ml @@ -107,10 +107,11 @@ let rec send ?(proving_timeout = 10.) ?(wait_for_prover_timeout = 600.) else failwith "Timeout while proving" let transaction_snark_of_single_signed_command ?proving_timeout t ~source_ledger - ~source_acc_set ~sequencer_pk ~command ~sparse_ledger = + ~sequencer_pk ~command ~sparse_ledger ~account_set_witness = send ?proving_timeout t (Prover.Input.Txn_snark_single_signed_command - (source_ledger, source_acc_set, sequencer_pk, command, sparse_ledger) ) + (source_ledger, sequencer_pk, command, sparse_ledger, account_set_witness) + ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> ({ stmt; proof } : Zeko_transaction_snark.T.t) @@ -120,7 +121,7 @@ let transaction_snark_of_single_signed_command ?proving_timeout t ~source_ledger let transaction_snark_of_single_unproved_zkapp_command ?proving_timeout t ~source_ledger ~target_ledger ~connecting_ledger ~source_local_state ~target_local_state ~fee_excess ~supply_decrease ~txn_snark_witness - ~sequencer ~source_acc_set ~shift_action_state = + ~sequencer ~account_set_witness ~shift_action_state = send ?proving_timeout t (Prover.Input.Txn_snark_single_unproved_zkapp_command ( source_ledger @@ -132,8 +133,8 @@ let transaction_snark_of_single_unproved_zkapp_command ?proving_timeout t , supply_decrease , txn_snark_witness , sequencer - , source_acc_set - , shift_action_state ) ) + , shift_action_state + , account_set_witness ) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> ({ stmt; proof } : Zeko_transaction_snark.T.t) @@ -143,8 +144,8 @@ let transaction_snark_of_single_unproved_zkapp_command ?proving_timeout t let transaction_snark_of_double_unproved_zkapp_command ?proving_timeout t ~source_ledger ~target_ledger ~connecting_ledger ~source_local_state ~target_local_state ~fee_excess ~supply_decrease ~txn_snark_witness - ~sequencer ~source_acc_set ~shift_action_state_first - ~shift_action_state_second = + ~sequencer ~shift_action_state_first ~shift_action_state_second + ~account_set_witness = send ?proving_timeout t (Prover.Input.Txn_snark_double_unproved_zkapp_command ( source_ledger @@ -156,9 +157,9 @@ let transaction_snark_of_double_unproved_zkapp_command ?proving_timeout t , supply_decrease , txn_snark_witness , sequencer - , source_acc_set , shift_action_state_first - , shift_action_state_second ) ) + , shift_action_state_second + , account_set_witness ) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> ({ stmt; proof } : Zeko_transaction_snark.T.t) @@ -168,7 +169,7 @@ let transaction_snark_of_double_unproved_zkapp_command ?proving_timeout t let transaction_snark_of_single_proved_zkapp_command ?proving_timeout t ~source_ledger ~target_ledger ~connecting_ledger ~source_local_state ~target_local_state ~fee_excess ~supply_decrease ~txn_snark_witness - ~sequencer ~source_acc_set ~zkapp_vk ~zkapp_proof ~shift_action_state = + ~sequencer ~zkapp_vk ~zkapp_proof ~shift_action_state ~account_set_witness = send ?proving_timeout t (Prover.Input.Txn_snark_single_proved_zkapp_command ( source_ledger @@ -180,10 +181,10 @@ let transaction_snark_of_single_proved_zkapp_command ?proving_timeout t , supply_decrease , txn_snark_witness , sequencer - , source_acc_set , zkapp_vk , zkapp_proof - , shift_action_state ) ) + , shift_action_state + , account_set_witness ) ) >>| function | Prover.Output.Zeko_transaction_snark (stmt, proof) -> ({ stmt; proof } : Zeko_transaction_snark.T.t) @@ -205,7 +206,8 @@ let transaction_snark_of_segment ?proving_timeout t ~sequencer_pk ~(witness : Transaction_witness.Zkapp_command_segment_witness.t * Transaction_snark.Zkapp_command_segment.Basic.t - * Mina_state.Snarked_ledger_state.With_sok.t ) = + * Mina_state.Snarked_ledger_state.With_sok.t + * Prover.Account_set_witness.t ) = let mina_local_state_to_zeko (t : Mina_transaction_logic.Zkapp_command_logic.Local_state.Value.Stable.V1.t @@ -263,7 +265,7 @@ let transaction_snark_of_segment ?proving_timeout t ~sequencer_pk (pi, vk) in match witness with - | witness, Opt_signed, stmt -> + | witness, Opt_signed, stmt, account_set_witness -> transaction_snark_of_single_unproved_zkapp_command ?proving_timeout t ~source_ledger:stmt.source.first_pass_ledger ~target_ledger:stmt.target.second_pass_ledger @@ -273,9 +275,8 @@ let transaction_snark_of_segment ?proving_timeout t ~sequencer_pk ~fee_excess:stmt.fee_excess.fee_excess_l ~supply_decrease:stmt.supply_increase.magnitude ~txn_snark_witness:witness ~sequencer:sequencer_pk - ~source_acc_set:(failwith "Not implemented") - ~shift_action_state:true - | witness, Opt_signed_opt_signed, stmt -> + ~shift_action_state:true ~account_set_witness + | witness, Opt_signed_opt_signed, stmt, account_set_witness -> transaction_snark_of_double_unproved_zkapp_command ?proving_timeout t ~source_ledger:stmt.source.first_pass_ledger ~target_ledger:stmt.target.second_pass_ledger @@ -285,9 +286,9 @@ let transaction_snark_of_segment ?proving_timeout t ~sequencer_pk ~fee_excess:stmt.fee_excess.fee_excess_l ~supply_decrease:stmt.supply_increase.magnitude ~txn_snark_witness:witness ~sequencer:sequencer_pk - ~source_acc_set:(failwith "Not implemented") ~shift_action_state_first:true ~shift_action_state_second:true - | witness, Proved, stmt -> ( + ~account_set_witness + | witness, Proved, stmt, account_set_witness -> ( match snapp_proof_data ~witness with | None -> failwith "of_zkapp_command_segment: Expected exactly one proof" @@ -302,17 +303,16 @@ let transaction_snark_of_segment ?proving_timeout t ~sequencer_pk (mina_local_state_to_zeko stmt.target.local_state) ~fee_excess:stmt.fee_excess.fee_excess_l ~supply_decrease:stmt.supply_increase.magnitude - ~txn_snark_witness:witness ~sequencer:sequencer_pk - ~source_acc_set:(failwith "Not implemented") - ~zkapp_vk:v.data + ~txn_snark_witness:witness ~sequencer:sequencer_pk ~zkapp_vk:v.data ~zkapp_proof:(Compile_simple.Proof.of_pickles p) - ~shift_action_state:true ) + ~shift_action_state:true ~account_set_witness ) let transaction_snark_of_zkapp_command ?proving_timeout t ~sequencer_pk ~(witnesses : ( Transaction_witness.Zkapp_command_segment_witness.t * Transaction_snark.Zkapp_command_segment.Basic.t - * Mina_state.Snarked_ledger_state.With_sok.t ) + * Mina_state.Snarked_ledger_state.With_sok.t + * Prover.Account_set_witness.t ) list ) = match witnesses with | [] -> @@ -335,12 +335,12 @@ let transaction_snark_of_signed_command ?proving_timeout t ~sequencer_pk ~(witness : Mina_ledger.Sparse_ledger.t * Signed_command.t - * Transaction_snark.Statement.With_sok.t ) = - let sparse_ledger, command, stmt = witness in + * Transaction_snark.Statement.With_sok.t + * Prover.Account_set_witness.t ) = + let sparse_ledger, command, stmt, account_set_witness = witness in transaction_snark_of_single_signed_command ?proving_timeout t - ~source_ledger:stmt.source.first_pass_ledger - ~source_acc_set:(failwith "Not implemented") - ~sequencer_pk ~command ~sparse_ledger + ~source_ledger:stmt.source.first_pass_ledger ~sequencer_pk ~command + ~sparse_ledger ~account_set_witness let inner_sync ?proving_timeout t ~public_key ~ase = send ?proving_timeout t (Prover.Input.Inner_sync (public_key, ase)) diff --git a/src/app/zeko/sequencer/prover/lib/dune b/src/app/zeko/sequencer/prover/lib/dune index 39231440c1..8cfe80c7fa 100644 --- a/src/app/zeko/sequencer/prover/lib/dune +++ b/src/app/zeko/sequencer/prover/lib/dune @@ -2,6 +2,7 @@ (name zeko_prover) (libraries zeko_circuits + indexed_merkle_tree zeko_constants mina_lib mina_ledger diff --git a/src/app/zeko/sequencer/prover/lib/prover.ml b/src/app/zeko/sequencer/prover/lib/prover.ml index f35d7321ca..cdb7499bbe 100644 --- a/src/app/zeko/sequencer/prover/lib/prover.ml +++ b/src/app/zeko/sequencer/prover/lib/prover.ml @@ -3,6 +3,7 @@ open Async open Mina_base open Mina_ledger open Signature_lib +module Sparse_imt = Indexed_merkle_tree.Sparse_indexed_merkle_tree open Zeko_circuits module Field = Snark_params.Tick.Field @@ -43,15 +44,79 @@ let dummy_sok = @@ Sok_message.create ~fee:Currency.Fee.zero ~prover:(Public_key.compress (Keypair.create ()).public_key) +module Account_set_witness = struct + type t = + { hash : Zeko_transaction_snark.Account_set.t + ; x : Token_id.t list + ; x_path : Ledger.Path.t list + ; y_path : Ledger.Path.t list + ; z : Token_id.t list + } + [@@deriving sexp, fields] + + let empty imt = + { hash = Sparse_imt.merkle_root imt + ; x = [] + ; x_path = [] + ; y_path = [] + ; z = [] + } + + let add t + ((x, x_path, y, y_path, z) : + [ `X of Token_id.t ] + * [ `X_path of Ledger.Path.t ] + * [ `Y of Token_id.t ] + * [ `Y_path of [ `Left of Field.t | `Right of Field.t ] list ] + * [ `Z of Token_id.t ] ) = + let x = match x with `X x -> x in + let x_path = match x_path with `X_path path -> path in + let y_path = match y_path with `Y_path path -> path in + let z = match z with `Z z -> z in + { t with + x = x :: t.x + ; x_path = x_path :: t.x_path + ; y_path = y_path :: t.y_path + ; z = z :: t.z + } + + let to_yojson t = `String (Sexp.to_string @@ sexp_of_t t) + + let of_yojson = function + | `String s -> ( + try Ok (t_of_sexp @@ Sexp.of_string s) + with _ -> Error "Account_set_witness.of_yojson" ) + | _ -> + Error "Account_set_witness.of_yojson" + + let to_functions t : Zeko_transaction_snark.update_acc_set_witness = + let mina_path_to_zeko_path path = + let open Zeko_transaction_snark.Account_set in + List.map path ~f:(function + | `Left hash -> + ({ PathStep.hash; is_left = true } : PathStep.t) + | `Right hash -> + ({ PathStep.hash; is_left = false } : PathStep.t) ) + in + let i = ref 0 in + { get_account_set_x = (fun () -> List.nth_exn t.x !i) + ; get_account_set_z = (fun () -> List.nth_exn t.z !i) + ; get_account_set_x_path = + (fun () -> List.nth_exn t.x_path !i |> mina_path_to_zeko_path) + ; get_account_set_y_path = + (fun () -> List.nth_exn t.y_path !i |> mina_path_to_zeko_path) + } +end + (* Unfortunately yojson doesn't support GADTs so it can't be one type, or maybe I'm just bad *) module Input = struct type t = | Txn_snark_single_signed_command of ( Ledger_hash.t - * Zeko_transaction_snark.Account_set.t * Zeko_util.Even_PC.t * Signed_command.t - * Sparse_ledger.t ) + * Sparse_ledger.t + * Account_set_witness.t ) | Txn_snark_single_unproved_zkapp_command of ( Ledger_hash.t * Ledger_hash.t @@ -62,8 +127,8 @@ module Input = struct * Currency.Amount.t * Transaction_snark.Zkapp_command_segment.Witness.t * Zeko_util.Even_PC.t - * Zeko_transaction_snark.Account_set.t - * bool ) + * bool + * Account_set_witness.t ) | Txn_snark_double_unproved_zkapp_command of ( Ledger_hash.t * Ledger_hash.t @@ -74,9 +139,9 @@ module Input = struct * Currency.Amount.t * Transaction_snark.Zkapp_command_segment.Witness.t * Zeko_util.Even_PC.t - * Zeko_transaction_snark.Account_set.t * bool - * bool ) + * bool + * Account_set_witness.t ) | Txn_snark_single_proved_zkapp_command of ( Ledger_hash.t * Ledger_hash.t @@ -87,10 +152,10 @@ module Input = struct * Currency.Amount.t * Transaction_snark.Zkapp_command_segment.Witness.t * Zeko_util.Even_PC.t - * Zeko_transaction_snark.Account_set.t * Pickles.Side_loaded.Verification_key.t * Compile_simple.Proof.t - * bool ) + * bool + * Account_set_witness.t ) | Txn_snark_merge of ( Zeko_transaction_snark.Zeko_stmt.t * Compile_simple.Proof.t @@ -120,26 +185,20 @@ end let prove ~logger : Input.t -> Output.t Deferred.t = function | Txn_snark_single_signed_command - (source_ledger, source_acc_set, sequencer, command, sparse_ledger) -> + (source_ledger, sequencer, command, sparse_ledger, account_set_witness) -> let open Zeko_transaction_snark in let handler = unstage @@ Sparse_ledger.handler sparse_ledger in let Compile_simple.[ single_signed_command; _; _; _; _ ] = provers in let input : Base_input.t = { source_ledger - ; source_acc_set + ; source_acc_set = Account_set_witness.hash account_set_witness ; sequencer ; transaction = Mina_transaction.Transaction_union.of_transaction (Command command) ; witness = { ledger_path_handler = handler ; update_acc_set_witness = - { get_account_set_x = (fun () -> failwith "get_account_set_x") - ; get_account_set_z = (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } + Account_set_witness.to_functions account_set_witness } } in @@ -158,8 +217,8 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function , supply_decrease , txn_snark_witness , sequencer - , source_acc_set - , shift_action_state ) -> + , shift_action_state + , account_set_witness ) -> let open Zeko_transaction_snark in let Compile_simple.[ _; single_unproved_zkapp_command; _; _; _ ] = provers @@ -176,18 +235,10 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function ; witness = { txn_snark_witness ; update_acc_set_witness = - { get_account_set_x = - (fun () -> failwith "get_account_set_x") - ; get_account_set_z = - (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } + Account_set_witness.to_functions account_set_witness } ; sequencer - ; source_acc_set + ; source_acc_set = Account_set_witness.hash account_set_witness } ; shift_action_state } @@ -207,9 +258,9 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function , supply_decrease , txn_snark_witness , sequencer - , source_acc_set , shift_action_state_first - , shift_action_state_second ) -> + , shift_action_state_second + , account_set_witness ) -> let open Zeko_transaction_snark in let Compile_simple.[ _; _; double_unproved_zkapp_command; _; _ ] = provers @@ -226,18 +277,10 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function ; witness = { txn_snark_witness ; update_acc_set_witness = - { get_account_set_x = - (fun () -> failwith "get_account_set_x") - ; get_account_set_z = - (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } + Account_set_witness.to_functions account_set_witness } ; sequencer - ; source_acc_set + ; source_acc_set = Account_set_witness.hash account_set_witness } ; shift_action_state_first ; shift_action_state_second @@ -258,10 +301,10 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function , supply_decrease , txn_snark_witness , sequencer - , source_acc_set , zkapp_vk , zkapp_proof - , shift_action_state ) -> + , shift_action_state + , account_set_witness ) -> let open Zeko_transaction_snark in let Compile_simple.[ _; _; _; single_proved_zkapp_command; _ ] = provers @@ -278,18 +321,10 @@ let prove ~logger : Input.t -> Output.t Deferred.t = function ; witness = { txn_snark_witness ; update_acc_set_witness = - { get_account_set_x = - (fun () -> failwith "get_account_set_x") - ; get_account_set_z = - (fun () -> failwith "get_account_set_z") - ; get_account_set_x_path = - (fun () -> failwith "get_account_set_x_path") - ; get_account_set_y_path = - (fun () -> failwith "get_account_set_y_path") - } + Account_set_witness.to_functions account_set_witness } ; sequencer - ; source_acc_set + ; source_acc_set = Account_set_witness.hash account_set_witness } ; zkapp_vk ; zkapp_proof From 9eb6cffe79283e9d34150f8ecf2cb2760f977ee3 Mon Sep 17 00:00:00 2001 From: Martin Ondejka Date: Mon, 3 Feb 2025 17:17:07 +0100 Subject: [PATCH 22/22] Fix deployment --- src/app/zeko/circuits/rollup_state.ml | 4 + src/app/zeko/circuits/zeko_util.ml | 16 ++ src/app/zeko/circuits/zeko_util.mli | 5 + .../indexed_merkle_tree.ml | 115 ++++++++++-- src/app/zeko/sequencer/deploy.ml | 166 +++++++++++------- src/app/zeko/sequencer/lib/deploy.ml | 121 ++++++++++--- src/app/zeko/sequencer/lib/zeko_sequencer.ml | 40 ++++- 7 files changed, 365 insertions(+), 102 deletions(-) diff --git a/src/app/zeko/circuits/rollup_state.ml b/src/app/zeko/circuits/rollup_state.ml index 2da4bbcaed..aeb3d2521e 100644 --- a/src/app/zeko/circuits/rollup_state.ml +++ b/src/app/zeko/circuits/rollup_state.ml @@ -141,6 +141,8 @@ module Inner_state = struct Outer_action_state.With_length.unsafe_value_of_fields ~state ~length } + let value_to_init_state t = Zeko_util.value_to_init_state typ t + type fine = { outer_action_state : Outer_action_state.With_length.fine } (* NB! This will warn you if add a field to `t` without fixing it here. @@ -234,6 +236,8 @@ module Outer_state = struct ; Whole (Even_PC.typ, da_key) ; Whole (Zeko_transaction_snark.Account_set.typ, acc_set) ] + + let value_to_app_state t = Zeko_util.value_to_app_state typ t end module Outer_action = struct diff --git a/src/app/zeko/circuits/zeko_util.ml b/src/app/zeko/circuits/zeko_util.ml index ddbc70f2e6..134c45fc59 100644 --- a/src/app/zeko/circuits/zeko_util.ml +++ b/src/app/zeko/circuits/zeko_util.ml @@ -73,6 +73,22 @@ let var_to_state_generic_fine : in Zkapp_state.V.of_list_exn r' +let value_to_state (some : field -> 'option) (none : 'option) + (typ : ('var, 'value) Typ.t) (x : 'value) : 'option Zkapp_state.V.t = + let (Typ typ) = typ in + let fields, _aux = typ.value_to_fields x in + assert (Array.length fields <= 8) ; + let missing = 8 - Array.length fields in + Zkapp_state.V.of_list_exn + @@ List.append + (List.map ~f:(fun f -> some f) @@ Array.to_list fields) + (List.init missing ~f:(fun _ -> none)) + +let value_to_init_state typ x = value_to_state (fun f -> f) Field.zero typ x + +let value_to_app_state typ x = + value_to_state (fun f -> Set_or_keep.Set f) Set_or_keep.Keep typ x + let var_to_precondition_fine = var_to_state_generic_fine ( module struct diff --git a/src/app/zeko/circuits/zeko_util.mli b/src/app/zeko/circuits/zeko_util.mli index 3865680831..13584a0642 100644 --- a/src/app/zeko/circuits/zeko_util.mli +++ b/src/app/zeko/circuits/zeko_util.mli @@ -32,6 +32,11 @@ val var_to_app_state_fine : -> Field.Var.t Zkapp_basic.Set_or_keep.Checked.t Pickles_types.Vector.Vector_8.t +val value_to_init_state : ('a, 'b) Typ.t -> 'b -> field Zkapp_state.V.t + +val value_to_app_state : + ('a, 'b) Typ.t -> 'b -> field Zkapp_basic.Set_or_keep.t Zkapp_state.V.t + val var_to_actions : ('var, 'value) Typ.t -> 'var -> Mina_base.Zkapp_account.Actions.var Checked.t diff --git a/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml b/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml index d307854b32..244e4b478f 100644 --- a/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml +++ b/src/app/zeko/indexed_merkle_tree/indexed_merkle_tree.ml @@ -144,9 +144,24 @@ module type Indexed_merkle_tree_intf = sig * [> `Y_path of path ] * [> `Z of Token_id.t ] ) - val find_lower_entry_aid_exn : t -> Token_id.t -> Token_id.t + val find_lower_entry_aid : t -> Token_id.t -> Token_id.t option end +let lowest_key = Token_id.of_field Field.zero + +let highest_key = + Token_id.of_field + (Field.of_string Bigint.(Field.size - of_int 1 |> to_string)) + +let lowest_entry = { Entry.value = lowest_key; value_next = highest_key } + +let highest_entry = { Entry.value = highest_key; value_next = highest_key } + +let base_entries = + [ (Account_id.with_empty_key lowest_key, lowest_entry) + ; (Account_id.with_empty_key highest_key, highest_entry) + ] + module Db : Indexed_merkle_tree_intf = struct include Database.Make (Inputs) @@ -166,12 +181,6 @@ module Db : Indexed_merkle_tree_intf = struct raise (Exn.create_s ([%sexp_of: t] e)) end - let lowest_key = Token_id.of_field Field.zero - - let highest_key = - Token_id.of_field - (Field.of_string Bigint.(Field.size - of_int 1 |> to_string)) - let get_raw t location = Kvdb.get (zeko_kvdb t) ~key:(Location.serialize ~ledger_depth:(depth t) location) @@ -212,26 +221,23 @@ module Db : Indexed_merkle_tree_intf = struct Db_error.Malformed_database "Failed to parse prev location" ) |> Db_error.ok_exn - let find_lower_entry_aid_exn t tid = + let find_lower_entry_aid t tid = let lower_entry_location = find_lower_entry_location_exn t tid in get t lower_entry_location - |> Result.of_option - ~error:(Db_error.Malformed_database "Could not find lower entry") - |> Db_error.ok_exn - |> fun entry -> entry.value + |> Option.map ~f:(fun entry -> Entry.(entry.value)) let create ?directory_name ~depth () = let db = create ?directory_name ~depth () in let (_ : [ `Added | `Existed ] * Location_at_depth.t) = get_or_create_account db (Account_id.with_empty_key lowest_key) - { Entry.value = lowest_key; value_next = highest_key } + lowest_entry |> Or_error.ok_exn in let (_ : [ `Added | `Existed ] * Location_at_depth.t) = get_or_create_account db (Account_id.with_empty_key highest_key) - { Entry.value = highest_key; value_next = highest_key } + highest_entry |> Or_error.ok_exn in db @@ -268,6 +274,77 @@ module Db : Indexed_merkle_tree_intf = struct Error.raise e end +module Null = Null_ledger.Make (Inputs) + +module Any_ledger : + Merkle_ledger.Intf.Ledger.ANY + with module Location = Location_at_depth + with type account := Entry.t + and type key := Public_key.Compressed.t + and type token_id := Token_id.t + and type token_id_set := Token_id.Set.t + and type account_id := Account_id.t + and type account_id_set := Account_id.Set.t + and type hash := Hash.t = + Merkle_ledger.Any_ledger.Make_base (Inputs) + +module Mask : + Merkle_mask.Masking_merkle_tree_intf.S + with module Location = Location_at_depth + and module Attached.Addr = Location_at_depth.Addr + with type account := Entry.t + and type key := Public_key.Compressed.t + and type token_id := Token_id.t + and type token_id_set := Token_id.Set.t + and type account_id := Account_id.t + and type account_id_set := Account_id.Set.t + and type hash := Hash.t + and type location := Location_at_depth.t + and type parent := Any_ledger.M.t = +Merkle_mask.Masking_merkle_tree.Make (struct + include Inputs + module Base = Any_ledger.M +end) + +module Maskable : + Merkle_mask.Maskable_merkle_tree_intf.S + with module Location = Location_at_depth + with module Addr = Location_at_depth.Addr + with type account := Entry.t + and type key := Public_key.Compressed.t + and type token_id := Token_id.t + and type token_id_set := Token_id.Set.t + and type account_id := Account_id.t + and type account_id_set := Account_id.Set.t + and type hash := Hash.t + and type root_hash := Hash.t + and type unattached_mask := Mask.t + and type attached_mask := Mask.Attached.t + and type accumulated_t := Mask.accumulated_t + and type t := Any_ledger.M.t = +Merkle_mask.Maskable_merkle_tree.Make (struct + include Inputs + module Base = Any_ledger.M + module Mask = Mask + + let mask_to_base m = Any_ledger.cast (module Mask.Attached) m +end) + +include Mask.Attached + +let create_ephemeral_with_base ~depth () = + let maskable = Null.create ~depth () in + let casted = Any_ledger.cast (module Null) maskable in + let mask = Mask.create ~depth () in + (casted, Maskable.register_mask casted mask) + +let create_ephemeral ~depth () = + let _base, mask = create_ephemeral_with_base ~depth () in + List.iter base_entries ~f:(fun (aid, entry) -> + let _ignore = get_or_create_account mask aid entry |> Or_error.ok_exn in + () ) ; + mask + module Sparse_indexed_merkle_tree = struct include Sparse_ledger_lib.Sparse_ledger.Make (Hash) (Account_id) (Entry) @@ -287,7 +364,8 @@ module Sparse_indexed_merkle_tree = struct impl in let lower_entries = - List.map tids ~f:(fun tid -> Db.find_lower_entry_aid_exn db tid) + List.map tids ~f:(fun tid -> Db.find_lower_entry_aid db tid) + |> List.filter_opt in let tids = List.concat [ lower_entries; tids ] in let locations = @@ -375,4 +453,11 @@ module Sparse_indexed_merkle_tree = struct , `Y new_entry.value , `Y_path (path_exn t new_entry_location) , `Z new_entry.value_next ) ) + + let create_from_tids ~depth tids = + let db = Db.create ~depth () in + let sparse = of_db_subset_exn db tids in + List.fold tids ~init:sparse ~f:(fun sparse tid -> + let sparse, _ = get_or_create_entry_exn sparse tid in + sparse ) end diff --git a/src/app/zeko/sequencer/deploy.ml b/src/app/zeko/sequencer/deploy.ml index d679e9e1b7..30f1a91e21 100644 --- a/src/app/zeko/sequencer/deploy.ml +++ b/src/app/zeko/sequencer/deploy.ml @@ -2,6 +2,7 @@ open Core open Mina_base open Async open Mina_ledger +open Signature_lib module L = Ledger let constraint_constants = Genesis_constants.Compiled.constraint_constants @@ -24,7 +25,7 @@ module Test_accounts = struct List.map accounts ~f:(fun { pk; balance } -> let account_id = Account_id.create - (Signature_lib.Public_key.Compressed.of_base58_check_exn pk) + (Public_key.Compressed.of_base58_check_exn pk) Token_id.default in let account = @@ -34,65 +35,93 @@ module Test_accounts = struct (account_id, account) ) end -let run ~l1_uri ~sk ~initial_state ~da_nodes () = +let run ~l1_uri ~sk ~initial_state ~da_nodes ~pause_key ~sequencer_key ~da_key + () = let logger = Logger.create () in let sender_keypair = - Signature_lib.( - Keypair.of_private_key_exn @@ Private_key.of_base58_check_exn sk) + Keypair.of_private_key_exn @@ Private_key.of_base58_check_exn sk in - let zkapp_keypair = Signature_lib.Keypair.create () in + let zkapp_keypair = Keypair.create () in printf "zkapp secret key: %s\n%!" - (Signature_lib.Private_key.to_base58_check zkapp_keypair.private_key) ; + (Private_key.to_base58_check zkapp_keypair.private_key) ; printf "zkapp public key: %s\n%!" - Signature_lib.Public_key.( - Compressed.to_base58_check @@ compress zkapp_keypair.public_key) ; + Public_key.(Compressed.to_base58_check @@ compress zkapp_keypair.public_key) ; - let nonce = - Thread_safe.block_on_async_exn (fun () -> + Thread_safe.block_on_async_exn (fun () -> + let%bind nonce = Sequencer_lib.Gql_client.infer_nonce l1_uri - (Signature_lib.Public_key.compress sender_keypair.public_key) ) - in - - let ledger = - let ledger = - L.create_ephemeral ~depth:constraint_constants.ledger_depth () - in - L.create_new_account_exn ledger Zeko_constants.inner_account_id - Sequencer_lib.Deploy.Z.Inner.initial_account ; - match initial_state with - | `None -> - ledger - | `Test_accounts test_accounts_path -> - List.fold ~init:ledger - (Test_accounts.parse_accounts_exn ~test_accounts_path) - ~f:(fun ledger (account_id, account) -> - L.create_new_account_exn ledger account_id account ; - ledger ) - | `Db_dir db_dir -> - L.of_database - @@ L.Db.create ~directory_name:db_dir - ~depth:constraint_constants.ledger_depth () - in - let command = - Sequencer_lib.Deploy.deploy_command_exn ~signer:sender_keypair - ~zkapp:zkapp_keypair - ~fee:(Currency.Fee.of_mina_int_exn 1) - ~nonce ~constraint_constants ~initial_ledger:ledger - in + (Public_key.compress sender_keypair.public_key) + in + let%bind initial_inner_account = + Sequencer_lib.Deploy.Z.Inner.initial_account () + in + let ledger, imt_hash = + let ledger = + L.create_ephemeral ~depth:constraint_constants.ledger_depth () + in + L.create_new_account_exn ledger Zeko_constants.inner_account_id + initial_inner_account ; + match initial_state with + | `None -> + ( ledger + , Indexed_merkle_tree.Sparse_indexed_merkle_tree.( + create_from_tids ~depth:constraint_constants.ledger_depth [] + |> merkle_root) ) + | `Test_accounts test_accounts_path -> + let accounts = + Test_accounts.parse_accounts_exn ~test_accounts_path + in + let tids = + List.map accounts ~f:(fun (aid, _) -> + Account_id.derive_token_id ~owner:aid ) + in + let imt_hash = + Indexed_merkle_tree.Sparse_indexed_merkle_tree.( + create_from_tids ~depth:constraint_constants.ledger_depth tids + |> merkle_root) + in + let ledger = + List.fold ~init:ledger accounts + ~f:(fun ledger (account_id, account) -> + L.create_new_account_exn ledger account_id account ; + ledger ) + in + (ledger, imt_hash) + | `Db_dir (db_dir, imt_dir) -> + let imt_hash = + Indexed_merkle_tree.Db.( + create ~directory_name:imt_dir + ~depth:constraint_constants.ledger_depth () + |> merkle_root) + in + let db = + L.of_database + @@ L.Db.create ~directory_name:db_dir + ~depth:constraint_constants.ledger_depth () + in + (db, imt_hash) + in + let%bind command = + Sequencer_lib.Deploy.deploy_command_exn ~signer:sender_keypair + ~zkapp:zkapp_keypair + ~fee:(Currency.Fee.of_mina_int_exn 1) + ~nonce ~constraint_constants ~initial_ledger:ledger + ~account_set_hash:imt_hash ~pause_key ~sequencer:sequencer_key ~da_key + in - (* Post genesis batch *) - Thread_safe.block_on_async_exn (fun () -> - let config = Da_layer.Client.Config.{ nodes = da_nodes } in - match%bind - Da_layer.Client.distribute_genesis_diff ~logger ~config ~ledger - with - | Ok _ -> - return () - | Error e -> - Error.raise e ) ; + (* Post genesis batch *) + let%bind () = + let config = Da_layer.Client.Config.{ nodes = da_nodes } in + match%bind + Da_layer.Client.distribute_genesis_diff ~logger ~config ~ledger + with + | Ok _ -> + return () + | Error e -> + Error.raise e + in - (* Deploy contract *) - Thread_safe.block_on_async_exn (fun () -> + (* Deploy contract *) match%bind Sequencer_lib.Gql_client.send_zkapp l1_uri command with | Ok _ -> Deferred.unit @@ -114,10 +143,17 @@ let () = and init_db_dir = flag "--init-db-dir" (optional string) ~doc:"string Path to the initial db" + and init_imt_dir = + flag "--init-imt-dir" (optional string) + ~doc:"string Path to the initial imt" and da_nodes = flag "--da-node" (listed string) ~doc:"string Address of the DA node, can be supplied multiple times" - in + and pause_key = + flag "--pause-key" (required string) ~doc:"string Pause key" + and sequencer_key = + flag "--sequencer-key" (required string) ~doc:"string Sequencer key" + and da_key = flag "--da-key" (required string) ~doc:"string Da key" in let sk = Sys.getenv_exn "MINA_PRIVATE_KEY" in let da_nodes = List.mapi da_nodes ~f:(fun i uri -> @@ -127,17 +163,29 @@ let () = } ) in let initial_state = - match (test_accounts_path, init_db_dir) with - | Some _, Some _ -> + match (test_accounts_path, init_db_dir, init_imt_dir) with + | Some _, Some _, _ | Some _, _, Some _ -> failwith "Cannot specify both test accounts and initial db" - | Some test_accounts_path, None -> + | None, Some _, None | None, None, Some _ -> + failwith "Cannot specify only one of db and imt" + | Some test_accounts_path, None, None -> `Test_accounts test_accounts_path - | None, Some init_db_dir -> - `Db_dir init_db_dir - | None, None -> + | None, Some init_db_dir, Some init_imt_dir -> + `Db_dir (init_db_dir, init_imt_dir) + | None, None, None -> `None in + + let string_to_even_pc x = + Public_key.Compressed.of_base58_check_exn x + |> Zeko_circuits.Zeko_util.Even_PC.create_exn + in + let pause_key = string_to_even_pc pause_key in + let sequencer_key = string_to_even_pc sequencer_key in + let da_key = string_to_even_pc da_key in + let l1_uri : Uri.t Cli_lib.Flag.Types.with_name = Cli_lib.Flag.Types.{ value = Uri.of_string l1_uri; name = "l1-uri" } in - run ~l1_uri ~sk ~initial_state ~da_nodes ) + run ~l1_uri ~sk ~initial_state ~da_nodes ~pause_key ~sequencer_key + ~da_key ) diff --git a/src/app/zeko/sequencer/lib/deploy.ml b/src/app/zeko/sequencer/lib/deploy.ml index 45bf621225..ab6f2013ca 100644 --- a/src/app/zeko/sequencer/lib/deploy.ml +++ b/src/app/zeko/sequencer/lib/deploy.ml @@ -1,28 +1,107 @@ +open Async open Mina_base open Account_update open Signature_lib module L = Mina_ledger.Ledger module Z = struct + open Zeko_circuits + + let proof_permissions : Permissions.t = + { edit_state = Proof + ; send = Proof + ; receive = None + ; set_delegate = Proof + ; set_permissions = Proof + ; set_verification_key = (Either, Mina_numbers.Txn_version.current) + ; set_zkapp_uri = Proof + ; edit_action_state = Proof + ; set_token_symbol = Proof + ; increment_nonce = None + ; set_voting_for = Proof + ; set_timing = Proof + ; access = Proof + } + module Inner = struct - let initial_account = failwith "not implemented" + let initial_account () = + let%bind vk = + Compile_simple.Verification_key.of_tag Inner_rules.tag + |> Promise.to_deferred + in + return + { Account.empty with + public_key = Zeko_constants.inner_public_key + ; balance = Currency.Balance.max_int + ; permissions = + { proof_permissions with access = Permissions.Auth_required.None } + ; zkapp = + Some + { Zkapp_account.default with + app_state = + Rollup_state.Inner_state.(value_to_init_state default) + ; verification_key = + Some + (Verification_key_wire.Stable.Latest.M.of_binable + (Compile_simple.Verification_key.to_pickles vk) ) + } + } end module Outer = struct - let deploy_exn _ledger = failwith "not implemented" + let unsafe_deploy ~pause_key ~ledger_hash ~sequencer ~da_key ~acc_set = + let%bind vk = + Compile_simple.Verification_key.of_tag Outer_rules.tag + |> Promise.to_deferred + in + return + { Update.dummy with + app_state = + Rollup_state.Outer_state.( + value_to_app_state + ( { pause_key + ; paused = false + ; ledger_hash + ; inner_action_state = + Rollup_state.Inner_action_state.With_length.empty + ; sequencer + ; da_key + ; acc_set + } + : t )) + ; verification_key = + Set + (Verification_key_wire.Stable.Latest.M.of_binable + (Compile_simple.Verification_key.to_pickles vk) ) + ; permissions = Set proof_permissions + } + + let deploy_exn (l : L.t) = + if + not + (Public_key.Compressed.equal Zeko_constants.inner_public_key + (L.get_at_index_exn l 0).public_key ) + then failwith "zeko outer deploy: ledger invalid" + else () ; + unsafe_deploy ~ledger_hash:(L.merkle_root l) end end let deploy_command_exn ~(signer : Keypair.t) ~(fee : Currency.Fee.t) ~(nonce : Account.Nonce.t) ~(zkapp : Keypair.t) ~(initial_ledger : L.t) - ~(constraint_constants : Genesis_constants.Constraint_constants.t) : - Zkapp_command.t = + ~account_set_hash + ~(constraint_constants : Genesis_constants.Constraint_constants.t) + ~pause_key ~sequencer ~da_key = + let%bind update = + Z.Outer.deploy_exn ~pause_key ~sequencer ~da_key ~acc_set:account_set_hash + initial_ledger + in let zkapp_update = { body = { Body.dummy with public_key = Public_key.compress zkapp.public_key ; implicit_account_creation_fee = false - ; update = Z.Outer.deploy_exn initial_ledger + ; update ; use_full_commitment = true ; authorization_kind = Signature } @@ -79,18 +158,20 @@ let deploy_command_exn ~(signer : Keypair.t) ~(fee : Currency.Fee.t) zkapp.private_key (Random_oracle.Input.Chunked.field full_commitment) in - { command with - fee_payer = { command.fee_payer with authorization = sender_signature } - ; account_updates = - Zkapp_command.Call_forest.accumulate_hashes ~hash_account_update:(fun p -> - Zkapp_command.Digest.Account_update.create p ) - @@ Zkapp_command.Call_forest.of_account_updates - ~account_update_depth:(fun _ -> 0) - [ { zkapp_update with - authorization = Control.Signature zkapp_signature - } - ; { sender_update with - authorization = Control.Signature sender_signature - } - ] - } + return + { command with + fee_payer = { command.fee_payer with authorization = sender_signature } + ; account_updates = + Zkapp_command.Call_forest.accumulate_hashes + ~hash_account_update:(fun p -> + Zkapp_command.Digest.Account_update.create p ) + @@ Zkapp_command.Call_forest.of_account_updates + ~account_update_depth:(fun _ -> 0) + [ { zkapp_update with + authorization = Control.Signature zkapp_signature + } + ; { sender_update with + authorization = Control.Signature sender_signature + } + ] + } diff --git a/src/app/zeko/sequencer/lib/zeko_sequencer.ml b/src/app/zeko/sequencer/lib/zeko_sequencer.ml index c660802aea..abae8f7d57 100644 --- a/src/app/zeko/sequencer/lib/zeko_sequencer.ml +++ b/src/app/zeko/sequencer/lib/zeko_sequencer.ml @@ -7,7 +7,7 @@ open Mina_ledger open Signature_lib module Imt_db = Indexed_merkle_tree.Db module Sparse_imt = Indexed_merkle_tree.Sparse_indexed_merkle_tree -open Zeko_circuits +module C = Zeko_circuits module L = Ledger module Field = Snark_params.Tick.Field @@ -134,7 +134,7 @@ module Sequencer = struct end module Merge = struct - type t = Zeko_transaction_snark.T.t + type t = C.Zeko_transaction_snark.T.t let process ({ provers; _ } : Context.t) a b = Zeko_prover.Client.transaction_snark_of_merge provers ~left:a ~right:b @@ -146,7 +146,7 @@ module Sequencer = struct let process (ctx : Context.t) command_witness = Context.add_command ctx command_witness ; let sequencer_pk = - Zeko_util.Even_PC.create_exn + C.Zeko_util.Even_PC.create_exn @@ Public_key.compress ctx.config.signer.public_key in match command_witness with @@ -571,7 +571,7 @@ module Sequencer = struct let update_inner_account t = let old_deposits_state, old_deposits_length = let s = Utils.get_inner_deposits_state_exn (L.of_database t.db) in - Rollup_state.Outer_action_state.With_length.(raw s, length s) + C.Rollup_state.Outer_action_state.With_length.(raw s, length s) in let%bind all_new_actions = Gql_client.fetch_actions t.config.archive_uri @@ -596,11 +596,11 @@ module Sequencer = struct ~public_key:(failwith "Not implemented: near 123456789?") ~ase: ( List.map processed_new_actions ~f:Account_update.Actions.hash - , ( Rollup_state.Outer_action_state.With_length. + , ( C.Rollup_state.Outer_action_state.With_length. { action_state = old_deposits_state ; length = old_deposits_length } - : Ase.With_length.Stmt.t ) ) + : C.Ase.With_length.Stmt.t ) ) in let fee = Currency.Fee.of_mina_int_exn 0 in let command : Zkapp_command.t = @@ -709,6 +709,14 @@ module Sequencer = struct List.iter changed_accounts ~f:(fun (index, account) -> L.set_at_index_exn mask index account ) ; L.Mask.Attached.commit mask ; + (* Add to Indexed Merkle Tree *) + List.iter changed_accounts ~f:(fun (_, account) -> + let aid = Account.identifier account in + let _w = + Imt_db.get_or_create_entry_exn t.imt + (Account_id.derive_token_id ~owner:aid) + in + () ) ; return () | Some (command, _) -> (* Apply command *) @@ -876,8 +884,11 @@ let%test_module "Sequencer tests" = ~num_transactions:number_of_transactions () in + let initial_inner_account = + Thread_safe.block_on_async_exn Deploy.Z.Inner.initial_account + in let genesis_accounts = - (Zeko_constants.inner_account_id, Deploy.Z.Inner.initial_account) + (Zeko_constants.inner_account_id, initial_inner_account) :: ( Array.map init_ledger ~f:(fun (keypair, balance) -> let pk = Signature_lib.Public_key.compress keypair.public_key @@ -898,6 +909,12 @@ let%test_module "Sequencer tests" = in List.iter genesis_accounts ~f:(fun (aid, acc) -> L.create_new_account_exn ephemeral_ledger aid acc ) ; + let account_set_hash = + Sparse_imt.create_from_tids ~depth:constraint_constants.ledger_depth + (List.map genesis_accounts ~f:(fun (aid, _) -> + Account_id.derive_token_id ~owner:aid ) ) + |> Sparse_imt.merkle_root + in (* Post genesis batch *) Thread_safe.block_on_async_exn (fun () -> @@ -910,6 +927,11 @@ let%test_module "Sequencer tests" = | Error e -> Error.raise e ) ; + let stub_pk = + Public_key.compress signer.public_key + |> C.Zeko_util.Even_PC.create_exn + in + (* Deploy *) Thread_safe.block_on_async_exn (fun () -> ( print_endline @@ -920,10 +942,12 @@ let%test_module "Sequencer tests" = Gql_client.infer_nonce gql_uri (Public_key.compress signer.public_key) in - let command = + let%bind command = Deploy.deploy_command_exn ~signer ~zkapp:zkapp_keypair ~fee:(Currency.Fee.of_mina_int_exn 1) ~nonce ~initial_ledger:ephemeral_ledger ~constraint_constants + ~account_set_hash ~pause_key:stub_pk ~sequencer:stub_pk + ~da_key:stub_pk in let%bind _ = Gql_client.send_zkapp gql_uri command in let%bind _created = Gql_client.For_tests.create_new_block gql_uri in