diff --git a/src/app/zkapp_limits/zkapp_limits.ml b/src/app/zkapp_limits/zkapp_limits.ml index b2f14cfe18e3..7555b9512649 100644 --- a/src/app/zkapp_limits/zkapp_limits.ml +++ b/src/app/zkapp_limits/zkapp_limits.ml @@ -2,31 +2,35 @@ open Core_kernel let main () = - let genesis_constants = Genesis_constants.Compiled.genesis_constants in - let cost_limit = genesis_constants.zkapp_transaction_cost_limit in - let max_event_elements = genesis_constants.max_event_elements in - let max_action_elements = genesis_constants.max_action_elements in - let values = List.init 20 ~f:Fn.id in + let Genesis_constants. + { max_event_elements + ; max_action_elements + ; max_zkapp_segment_per_transaction + ; _ + } = + Genesis_constants.Compiled.genesis_constants + in + let values = List.init (1 + max_zkapp_segment_per_transaction) ~f:Fn.id in printf "max field elements for events per transaction: %d\n" max_event_elements ; printf "max field elements for actions per transaction: %d\n" max_action_elements ; printf "All possible zkApp account update combinations:\n" ; - List.iter values ~f:(fun proofs -> + List.iter values ~f:(fun proof_segments -> List.iter values ~f:(fun signed_single_segments -> List.iter values ~f:(fun signed_pair_segments -> let cost = - Mina_base.Zkapp_command.zkapp_cost ~proof_segments:proofs + Mina_base.Zkapp_command.zkapp_cost ~proof_segments ~signed_single_segments ~signed_pair_segments - ~genesis_constants () in - if Float.(cost <. cost_limit) then + if cost <= max_zkapp_segment_per_transaction then printf "Proofs updates=%d Signed/None updates=%d Pairs of \ - Signed/None updates=%d: Total account updates: %d Cost: %f \n\ + Signed/None updates=%d: Total account updates: %d Cost: %d \n\ %!" - proofs signed_single_segments signed_pair_segments - (proofs + signed_single_segments + (signed_pair_segments * 2)) + proof_segments signed_single_segments signed_pair_segments + ( proof_segments + signed_single_segments + + (signed_pair_segments * 2) ) cost ) ) ) let () = main () diff --git a/src/lib/genesis_constants/genesis_constants.ml b/src/lib/genesis_constants/genesis_constants.ml index 1f96fda19022..7637f2c1aa7f 100644 --- a/src/lib/genesis_constants/genesis_constants.ml +++ b/src/lib/genesis_constants/genesis_constants.ml @@ -215,10 +215,11 @@ module T = struct { protocol : Protocol.Stable.Latest.t ; txpool_max_size : int ; num_accounts : int option - ; zkapp_proof_update_cost : float - ; zkapp_signed_single_update_cost : float - ; zkapp_signed_pair_update_cost : float - ; zkapp_transaction_cost_limit : float + ; max_zkapp_segment_per_transaction : int + (** The maximum number of segments allowed per zkapp command. A + segment is either: a proof, a signed single update, or a signed + pair update. Transactions with a number of segments equal to this + limit are valid. *) ; max_event_elements : int ; max_action_elements : int ; zkapp_cmd_limit_hardcap : int @@ -425,11 +426,8 @@ module Make (Node_config : Node_config_intf.S) : S = struct } ; txpool_max_size = pool_max_size ; num_accounts = None - ; zkapp_proof_update_cost = Node_config.zkapp_proof_update_cost - ; zkapp_signed_single_update_cost = - Node_config.zkapp_signed_single_update_cost - ; zkapp_signed_pair_update_cost = Node_config.zkapp_signed_pair_update_cost - ; zkapp_transaction_cost_limit = Node_config.zkapp_transaction_cost_limit + ; max_zkapp_segment_per_transaction = + Node_config.max_zkapp_segment_per_transaction ; max_event_elements = Node_config.max_event_elements ; max_action_elements = Node_config.max_action_elements ; zkapp_cmd_limit_hardcap = Node_config.zkapp_cmd_limit_hardcap diff --git a/src/lib/genesis_ledger_helper/lib/genesis_ledger_helper_lib.ml b/src/lib/genesis_ledger_helper/lib/genesis_ledger_helper_lib.ml index ce385ad3acc5..0c7b6ecb9e12 100644 --- a/src/lib/genesis_ledger_helper/lib/genesis_ledger_helper_lib.ml +++ b/src/lib/genesis_ledger_helper/lib/genesis_ledger_helper_lib.ml @@ -563,18 +563,9 @@ let make_genesis_constants ~logger ~(default : Genesis_constants.t) ; txpool_max_size = Option.value ~default:default.txpool_max_size (config.daemon >>= fun cfg -> cfg.txpool_max_size) - ; zkapp_proof_update_cost = - Option.value ~default:default.zkapp_proof_update_cost - (config.daemon >>= fun cfg -> cfg.zkapp_proof_update_cost) - ; zkapp_signed_single_update_cost = - Option.value ~default:default.zkapp_signed_single_update_cost - (config.daemon >>= fun cfg -> cfg.zkapp_signed_single_update_cost) - ; zkapp_signed_pair_update_cost = - Option.value ~default:default.zkapp_signed_pair_update_cost - (config.daemon >>= fun cfg -> cfg.zkapp_signed_pair_update_cost) - ; zkapp_transaction_cost_limit = - Option.value ~default:default.zkapp_transaction_cost_limit - (config.daemon >>= fun cfg -> cfg.zkapp_transaction_cost_limit) + ; max_zkapp_segment_per_transaction = + Option.value ~default:default.max_zkapp_segment_per_transaction + (config.daemon >>= fun cfg -> cfg.max_zkapp_segment_per_transaction) ; max_event_elements = Option.value ~default:default.max_event_elements (config.daemon >>= fun cfg -> cfg.max_event_elements) diff --git a/src/lib/mina_base/zkapp_command.ml b/src/lib/mina_base/zkapp_command.ml index abb9fa913a05..7360628cb3e0 100644 --- a/src/lib/mina_base/zkapp_command.ml +++ b/src/lib/mina_base/zkapp_command.ml @@ -1309,16 +1309,33 @@ module Update_group = Make_update_group (struct failwith "zkapp_segment_of_controls: Unsupported combination" end) -let zkapp_cost ~proof_segments ~signed_single_segments ~signed_pair_segments - ~(genesis_constants : Genesis_constants.t) () = - (*10.26*np + 10.08*n2 + 9.14*n1 < 69.45*) - let proof_cost = genesis_constants.zkapp_proof_update_cost in - let signed_pair_cost = genesis_constants.zkapp_signed_pair_update_cost in - let signed_single_cost = genesis_constants.zkapp_signed_single_update_cost in - Float.( - (proof_cost * of_int proof_segments) - + (signed_pair_cost * of_int signed_pair_segments) - + (signed_single_cost * of_int signed_single_segments)) +(** [zkapp_cost ~proof_segments ~signed_single_segments ~signed_pair_segments] + returns the cost of a zkapp command having such constitution. + + The cost of a zkapp command is defined as the number of segments it have in + the base layer. + + This is because SNARK Coordinator schedules single base proof/merge to each + SNARK worker. These proofs form a B-ary tree, where B is Pickles' branching + factor, i.e. the number of proofs Pickles could be merged at once. Under + current configuration, B is 2. + + The latency before us getting a final proof would be the latency from root + to any leaf node. Given we have sufficient workers available, possible proof + trees would be more or less a balanced binary tree, so with n segments, the + latency would of Theta(log_B n), assuming all kind proofs requires roughly + same time to proof. + + to ensure the latency of receving final proof to be smaller than some cap, + we could equally just restrict number of leave segments. For example, If we + want the tree to have at most [L] layers, we just ensure the cost for any + zkapp_command to be at most [B^L]. + + WARN: this is only relevant after we merged SNARK worker rework PRs, please + remove this warning if we've already done so. +*) +let zkapp_cost ~proof_segments ~signed_single_segments ~signed_pair_segments = + proof_segments + signed_single_segments + signed_pair_segments (* Zkapp_command transactions are filtered using this predicate - when adding to the transaction pool @@ -1361,14 +1378,17 @@ let valid_size (type aux) ~(genesis_constants : Genesis_constants.t) | Signed_pair -> (proof_segments, signed_singles, signed_pairs + 1) ) in - let cost_limit = genesis_constants.zkapp_transaction_cost_limit in - let max_event_elements = genesis_constants.max_event_elements in - let max_action_elements = genesis_constants.max_action_elements in + let Genesis_constants. + { max_event_elements + ; max_action_elements + ; max_zkapp_segment_per_transaction + ; _ + } = + genesis_constants + in let zkapp_cost_within_limit = - Float.( - zkapp_cost ~proof_segments ~signed_single_segments ~signed_pair_segments - ~genesis_constants () - < cost_limit) + zkapp_cost ~proof_segments ~signed_single_segments ~signed_pair_segments + <= max_zkapp_segment_per_transaction in let valid_event_elements = num_event_elements <= max_event_elements in let valid_action_elements = num_action_elements <= max_action_elements in diff --git a/src/lib/mina_compile_config/mina_compile_config.ml b/src/lib/mina_compile_config/mina_compile_config.ml index 72480e9c887b..ba9515834c7f 100644 --- a/src/lib/mina_compile_config/mina_compile_config.ml +++ b/src/lib/mina_compile_config/mina_compile_config.ml @@ -20,10 +20,7 @@ module Inputs = struct ; rpc_handshake_timeout_sec : float ; rpc_heartbeat_timeout_sec : float ; rpc_heartbeat_send_every_sec : float - ; zkapp_proof_update_cost : float - ; zkapp_signed_pair_update_cost : float - ; zkapp_signed_single_update_cost : float - ; zkapp_transaction_cost_limit : float + ; max_zkapp_segment_per_transaction : int ; max_event_elements : int ; max_action_elements : int ; zkapp_cmd_limit_hardcap : int @@ -47,10 +44,7 @@ type t = ; rpc_handshake_timeout : Time.Span.t ; rpc_heartbeat_timeout : Time.Span.t ; rpc_heartbeat_send_every : Time.Span.t - ; zkapp_proof_update_cost : float - ; zkapp_signed_pair_update_cost : float - ; zkapp_signed_single_update_cost : float - ; zkapp_transaction_cost_limit : float + ; max_zkapp_segment_per_transaction : int ; max_event_elements : int ; max_action_elements : int ; zkapp_cmd_limit_hardcap : int @@ -80,10 +74,7 @@ let make (inputs : Inputs.t) = ; rpc_heartbeat_timeout = Time.Span.of_sec inputs.rpc_heartbeat_timeout_sec ; rpc_heartbeat_send_every = Time.Span.of_sec inputs.rpc_heartbeat_send_every_sec - ; zkapp_proof_update_cost = inputs.zkapp_proof_update_cost - ; zkapp_signed_pair_update_cost = inputs.zkapp_signed_pair_update_cost - ; zkapp_signed_single_update_cost = inputs.zkapp_signed_single_update_cost - ; zkapp_transaction_cost_limit = inputs.zkapp_transaction_cost_limit + ; max_zkapp_segment_per_transaction = inputs.max_zkapp_segment_per_transaction ; max_event_elements = inputs.max_event_elements ; max_action_elements = inputs.max_action_elements ; network_id = inputs.network_id @@ -115,11 +106,8 @@ let to_yojson t = , `Float (Time.Span.to_sec t.rpc_heartbeat_timeout) ) ; ( "rpc_heartbeat_send_every" , `Float (Time.Span.to_sec t.rpc_heartbeat_send_every) ) - ; ("zkapp_proof_update_cost", `Float t.zkapp_proof_update_cost) - ; ("zkapp_signed_pair_update_cost", `Float t.zkapp_signed_pair_update_cost) - ; ( "zkapp_signed_single_update_cost" - , `Float t.zkapp_signed_single_update_cost ) - ; ("zkapp_transaction_cost_limit", `Float t.zkapp_transaction_cost_limit) + ; ( "max_zkapp_segment_per_transaction" + , `Int t.max_zkapp_segment_per_transaction ) ; ("max_event_elements", `Int t.max_event_elements) ; ("max_action_elements", `Int t.max_action_elements) ; ("network_id", `String t.network_id) @@ -147,12 +135,8 @@ module Compiled = struct ; rpc_handshake_timeout_sec = Node_config.rpc_handshake_timeout_sec ; rpc_heartbeat_timeout_sec = Node_config.rpc_heartbeat_timeout_sec ; rpc_heartbeat_send_every_sec = Node_config.rpc_heartbeat_send_every_sec - ; zkapp_proof_update_cost = Node_config.zkapp_proof_update_cost - ; zkapp_signed_pair_update_cost = - Node_config.zkapp_signed_pair_update_cost - ; zkapp_signed_single_update_cost = - Node_config.zkapp_signed_single_update_cost - ; zkapp_transaction_cost_limit = Node_config.zkapp_transaction_cost_limit + ; max_zkapp_segment_per_transaction = + Node_config.max_zkapp_segment_per_transaction ; max_event_elements = Node_config.max_event_elements ; max_action_elements = Node_config.max_action_elements ; network_id = Node_config.network @@ -188,14 +172,8 @@ module For_unit_tests = struct Node_config_for_unit_tests.rpc_heartbeat_timeout_sec ; rpc_heartbeat_send_every_sec = Node_config_for_unit_tests.rpc_heartbeat_send_every_sec - ; zkapp_proof_update_cost = - Node_config_for_unit_tests.zkapp_proof_update_cost - ; zkapp_signed_pair_update_cost = - Node_config_for_unit_tests.zkapp_signed_pair_update_cost - ; zkapp_signed_single_update_cost = - Node_config_for_unit_tests.zkapp_signed_single_update_cost - ; zkapp_transaction_cost_limit = - Node_config_for_unit_tests.zkapp_transaction_cost_limit + ; max_zkapp_segment_per_transaction = + Node_config_for_unit_tests.max_zkapp_segment_per_transaction ; max_event_elements = Node_config_for_unit_tests.max_event_elements ; max_action_elements = Node_config_for_unit_tests.max_action_elements ; network_id = Node_config_for_unit_tests.network diff --git a/src/lib/node_config/intf/node_config_intf.mli b/src/lib/node_config/intf/node_config_intf.mli index 66000d83ecc7..a127dcf1e57e 100644 --- a/src/lib/node_config/intf/node_config_intf.mli +++ b/src/lib/node_config/intf/node_config_intf.mli @@ -8,13 +8,7 @@ end (* It's stupid that this exists. TODO: Remove and make configurable. *) module type Unconfigurable_constants = sig - val zkapp_proof_update_cost : float - - val zkapp_signed_pair_update_cost : float - - val zkapp_signed_single_update_cost : float - - val zkapp_transaction_cost_limit : float + val max_zkapp_segment_per_transaction : int val max_event_elements : int diff --git a/src/lib/node_config/unconfigurable_constants/node_config_unconfigurable_constants.ml b/src/lib/node_config/unconfigurable_constants/node_config_unconfigurable_constants.ml index 1097f3486552..21b587184958 100644 --- a/src/lib/node_config/unconfigurable_constants/node_config_unconfigurable_constants.ml +++ b/src/lib/node_config/unconfigurable_constants/node_config_unconfigurable_constants.ml @@ -1,25 +1,6 @@ (* FIXME: These should be configurable. *) -(** limits on Zkapp_command.t size - 10.26*np + 10.08*n2 + 9.14*n1 < 69.45 - where np: number of single proof updates - n2: number of pairs of signed/no-auth update - n1: number of single signed/no-auth update - and their coefficients representing the cost - The formula was generated based on benchmarking data conducted on bare - metal i9 processor with room to include lower spec. - 69.45 was the total time for a combination of updates that was considered - acceptable. - The method used to estimate the cost was linear least squares. -*) - -let zkapp_proof_update_cost = 10.26 - -let zkapp_signed_pair_update_cost = 10.08 - -let zkapp_signed_single_update_cost = 9.14 - -let zkapp_transaction_cost_limit = 69.45 +let max_zkapp_segment_per_transaction = 16 let max_event_elements = 100 diff --git a/src/lib/runtime_config/runtime_config.ml b/src/lib/runtime_config/runtime_config.ml index 928c5543069a..68fda63ec9cb 100644 --- a/src/lib/runtime_config/runtime_config.ml +++ b/src/lib/runtime_config/runtime_config.ml @@ -464,10 +464,7 @@ module Json_layout = struct type t = { txpool_max_size : int option [@default None] ; peer_list_url : string option [@default None] - ; zkapp_proof_update_cost : float option [@default None] - ; zkapp_signed_single_update_cost : float option [@default None] - ; zkapp_signed_pair_update_cost : float option [@default None] - ; zkapp_transaction_cost_limit : float option [@default None] + ; max_zkapp_segment_per_transaction : int option [@default None] ; max_event_elements : int option [@default None] ; max_action_elements : int option [@default None] ; zkapp_cmd_limit_hardcap : int option [@default None] @@ -1271,10 +1268,7 @@ module Daemon = struct type t = Json_layout.Daemon.t = { txpool_max_size : int option ; peer_list_url : string option - ; zkapp_proof_update_cost : float option [@default None] - ; zkapp_signed_single_update_cost : float option [@default None] - ; zkapp_signed_pair_update_cost : float option [@default None] - ; zkapp_transaction_cost_limit : float option [@default None] + ; max_zkapp_segment_per_transaction : int option [@default None] ; max_event_elements : int option [@default None] ; max_action_elements : int option [@default None] ; zkapp_cmd_limit_hardcap : int option [@default None] @@ -1303,18 +1297,9 @@ module Daemon = struct { txpool_max_size = opt_fallthrough ~default:t1.txpool_max_size t2.txpool_max_size ; peer_list_url = opt_fallthrough ~default:t1.peer_list_url t2.peer_list_url - ; zkapp_proof_update_cost = - opt_fallthrough ~default:t1.zkapp_proof_update_cost - t2.zkapp_proof_update_cost - ; zkapp_signed_single_update_cost = - opt_fallthrough ~default:t1.zkapp_signed_single_update_cost - t2.zkapp_signed_single_update_cost - ; zkapp_signed_pair_update_cost = - opt_fallthrough ~default:t1.zkapp_signed_pair_update_cost - t2.zkapp_signed_pair_update_cost - ; zkapp_transaction_cost_limit = - opt_fallthrough ~default:t1.zkapp_transaction_cost_limit - t2.zkapp_transaction_cost_limit + ; max_zkapp_segment_per_transaction = + opt_fallthrough ~default:t1.max_zkapp_segment_per_transaction + t2.max_zkapp_segment_per_transaction ; max_event_elements = opt_fallthrough ~default:t1.max_event_elements t2.max_event_elements ; max_action_elements = @@ -1343,10 +1328,7 @@ module Daemon = struct let gen = let open Quickcheck.Generator.Let_syntax in let%bind txpool_max_size = Int.gen_incl 0 1000 in - let%bind zkapp_proof_update_cost = Float.gen_incl 0.0 100.0 in - let%bind zkapp_signed_single_update_cost = Float.gen_incl 0.0 100.0 in - let%bind zkapp_signed_pair_update_cost = Float.gen_incl 0.0 100.0 in - let%bind zkapp_transaction_cost_limit = Float.gen_incl 0.0 100.0 in + let%bind max_zkapp_segment_per_transaction = Int.gen_incl 0 50 in let%bind max_event_elements = Int.gen_incl 0 100 in let%bind zkapp_cmd_limit_hardcap = Int.gen_incl 0 1000 in let%bind minimum_user_command_fee = @@ -1355,10 +1337,7 @@ module Daemon = struct let%map max_action_elements = Int.gen_incl 0 1000 in { txpool_max_size = Some txpool_max_size ; peer_list_url = None - ; zkapp_proof_update_cost = Some zkapp_proof_update_cost - ; zkapp_signed_single_update_cost = Some zkapp_signed_single_update_cost - ; zkapp_signed_pair_update_cost = Some zkapp_signed_pair_update_cost - ; zkapp_transaction_cost_limit = Some zkapp_transaction_cost_limit + ; max_zkapp_segment_per_transaction = Some max_zkapp_segment_per_transaction ; max_event_elements = Some max_event_elements ; max_action_elements = Some max_action_elements ; zkapp_cmd_limit_hardcap = Some zkapp_cmd_limit_hardcap diff --git a/src/lib/testing/integration_test_lib/runtime_config_builder.ml b/src/lib/testing/integration_test_lib/runtime_config_builder.ml index 72af8cf76fe4..54e01c014b39 100644 --- a/src/lib/testing/integration_test_lib/runtime_config_builder.ml +++ b/src/lib/testing/integration_test_lib/runtime_config_builder.ml @@ -14,10 +14,7 @@ let create ~(test_config : Test_config.t) ~(genesis_ledger : Genesis_ledger.t) = Some { txpool_max_size = Some test_config.txpool_max_size ; peer_list_url = None - ; zkapp_proof_update_cost = None - ; zkapp_signed_single_update_cost = None - ; zkapp_signed_pair_update_cost = None - ; zkapp_transaction_cost_limit = None + ; max_zkapp_segment_per_transaction = None ; max_event_elements = None ; max_action_elements = None ; zkapp_cmd_limit_hardcap = None