diff --git a/src/proto_alpha/lib_client/injection.ml b/src/proto_alpha/lib_client/injection.ml index 56832cd849fa1179812e0e13b3ed99312eedd4b5..5006cd403a278676098f3b2fce2ced65b0885a10 100644 --- a/src/proto_alpha/lib_client/injection.ml +++ b/src/proto_alpha/lib_client/injection.ml @@ -393,6 +393,7 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size | Transfer_ticket_result {paid_storage_size_diff; _} -> Ok paid_storage_size_diff | Sc_rollup_originate_result {size; _} -> Ok size + | Zk_rollup_origination_result {storage_size; _} -> Ok storage_size | Transaction_result (Transaction_to_tx_rollup_result _) -> (* TODO: https://gitlab.com/tezos/tezos/-/issues/2339 Storage fees for transaction rollup. @@ -415,8 +416,7 @@ let estimated_storage_single (type kind) ~tx_rollup_origination_size | Sc_rollup_cement_result _ | Sc_rollup_publish_result _ | Sc_rollup_refute_result _ | Sc_rollup_timeout_result _ | Sc_rollup_recover_bond_result _ - | Sc_rollup_dal_slot_subscribe_result _ | Zk_rollup_origination_result _ - -> + | Sc_rollup_dal_slot_subscribe_result _ -> Ok Z.zero) | Skipped _ -> error_with "Cannot estimate storage of skipped operation" diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 635c3da9afdb74a14c5405c708316ee7d4a67e81..b2d2c3fcf8997572c35c30f589a0648cae9d887c 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -791,8 +791,9 @@ let pp_manager_operation_contents_result ppf op_result = in let pp_zk_rollup_origination_result (Zk_rollup_origination_result - {consumed_gas; originated_zk_rollup; size = _; balance_updates}) = + {consumed_gas; originated_zk_rollup; storage_size; balance_updates}) = pp_consumed_gas ppf consumed_gas ; + pp_storage_size ppf storage_size ; Format.fprintf ppf "@,Address: %a" Zk_rollup.Address.pp originated_zk_rollup ; pp_balance_updates ppf balance_updates in diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 3374e097ab2e68e8288d224a3e58e55c9998ffbb..f82c5a2095f8d5552c686c8566990da7cdda68c2 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -1612,7 +1612,7 @@ let burn_manager_storage_fees : ctxt ~storage_limit ~payer - payload.size + payload.storage_size >>=? fun (ctxt, storage_limit, balance_updates) -> let result = Zk_rollup_origination_result {payload with balance_updates} diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index a7c62eba5632943fc5521283e3ec6037bcf1e270..91e72b60892985baecf5c90608baa350bacc6e83 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -180,7 +180,7 @@ type _ successful_manager_operation_result = balance_updates : Receipt.balance_updates; originated_zk_rollup : Zk_rollup.t; consumed_gas : Gas.Arith.fp; - size : Z.t; + storage_size : Z.t; } -> Kind.zk_rollup_origination successful_manager_operation_result @@ -753,10 +753,9 @@ module Manager_result = struct ~op_case:Operation.Encoding.Manager_operations.zk_rollup_origination_case ~encoding: Data_encoding.( - obj5 + obj4 (req "balance_updates" Receipt.balance_updates_encoding) (req "originated_zk_rollup" Zk_rollup.Address.encoding) - (dft "consumed_gas" Gas.Arith.n_integral_encoding Gas.Arith.zero) (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) (req "size" z)) ~select:(function @@ -766,26 +765,13 @@ module Manager_result = struct ~kind:Kind.Zk_rollup_origination_manager_kind ~proj:(function | Zk_rollup_origination_result - {balance_updates; originated_zk_rollup; consumed_gas; size} -> - ( balance_updates, - originated_zk_rollup, - Gas.Arith.ceil consumed_gas, - consumed_gas, - size )) + {balance_updates; originated_zk_rollup; consumed_gas; storage_size} + -> + (balance_updates, originated_zk_rollup, consumed_gas, storage_size)) ~inj: - (fun ( balance_updates, - originated_zk_rollup, - consumed_gas, - consumed_milligas, - size ) -> - assert (Gas.Arith.(equal (ceil consumed_milligas) consumed_gas)) ; + (fun (balance_updates, originated_zk_rollup, consumed_gas, storage_size) -> Zk_rollup_origination_result - { - balance_updates; - originated_zk_rollup; - consumed_gas = consumed_milligas; - size; - }) + {balance_updates; originated_zk_rollup; consumed_gas; storage_size}) let sc_rollup_originate_case = make diff --git a/src/proto_alpha/lib_protocol/apply_results.mli b/src/proto_alpha/lib_protocol/apply_results.mli index 9b70c8eb0166c6ac877c6bb86072a2b9813e838f..6b3903dd929f2bed265f76c57f9a524fadf5460e 100644 --- a/src/proto_alpha/lib_protocol/apply_results.mli +++ b/src/proto_alpha/lib_protocol/apply_results.mli @@ -276,7 +276,9 @@ and _ successful_manager_operation_result = balance_updates : Receipt.balance_updates; originated_zk_rollup : Zk_rollup.t; consumed_gas : Gas.Arith.fp; - size : Z.t; + (* Number of bytes allocated by the ZKRU origination. + Used to burn storage fees. *) + storage_size : Z.t; } -> Kind.zk_rollup_origination successful_manager_operation_result diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 614f47a44e2900dd754ca2ef3eb0cdf7c949b12e..9a33dffa69ab06ab4468eae9e35a116b54d674f4 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -1030,26 +1030,9 @@ module Encoding = struct encoding = obj4 (req "public_parameters" Plonk.public_parameters_encoding) - (let circuits_info_encoding = - conv_with_guard - (fun m -> - List.of_seq @@ Zk_rollup_account_repr.SMap.to_seq m) - (fun l -> - let m = - Zk_rollup_account_repr.SMap.of_seq @@ List.to_seq l - in - if - (* Check that the list has no duplicated keys *) - Compare.List_length_with.( - l <> Zk_rollup_account_repr.SMap.cardinal m) - then - Error - "Zk_rollup_origination: circuits_info has duplicated \ - keys" - else Ok m) - (list (tup2 string bool)) - in - req "circuits_info" circuits_info_encoding) + (req + "circuits_info" + Zk_rollup_account_repr.circuits_info_encoding) (req "init_state" Zk_rollup_state_repr.encoding) (* TODO https://gitlab.com/tezos/tezos/-/issues/3655 Encoding of non-negative [nb_ops] for origination *) diff --git a/src/proto_alpha/lib_protocol/storage.mli b/src/proto_alpha/lib_protocol/storage.mli index 590988c668affbd38dc07404887646508c63959b..ebbf7d61d134eabf6479ec4f35cdbd9a7803007a 100644 --- a/src/proto_alpha/lib_protocol/storage.mli +++ b/src/proto_alpha/lib_protocol/storage.mli @@ -877,7 +877,7 @@ module Dal : sig end module Zk_rollup : sig - (** Zero ZK rollup. + (** ZK rollup. Each ZK rollup is associated to: diff --git a/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml b/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml index b961f894b1286121212e2104d85416f1e302d7f3..cb976864a1c7824480b434826710c37226caea2d 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml @@ -1,6 +1,6 @@ (*****************************************************************************) (* *) -(* MIT License *) +(* Open Source License *) (* Copyright (c) 2022 Nomadic Labs *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) @@ -77,30 +77,32 @@ type op_code module Bound : sig type 'a t = private Z.t - val max_balance : balance t + val bound_balance : balance t - val max_amount : amount t + val bound_amount : amount t - val max_fee : fee t + val bound_fee : fee t - val max_op_code : op_code t + val bound_op_code : op_code t val v : 'a t -> Z.t end = struct type 'a t = Z.t - (** Maximum ticket balance, as found in the price field of an operation's - header *) - let max_balance = Z.(shift_left one 20) + (** These bounds are exclusive. *) - (** Maximum ticket amount, used for fee circuit *) - let max_amount = Z.(shift_left one 20) + (** Upper bound for ticket balance, as found in the price field of an + operation's header *) + let bound_balance = Z.(shift_left one 20) - (** Maximum fee amount for one public operation *) - let max_fee = Z.(shift_left one 10) + (** Upper bound for ticket amount, used for fee circuit *) + let bound_amount = Z.(shift_left one 20) - (** Maximum value for op code *) - let max_op_code = Z.(shift_left one 1) + (** Upper bound for fee amount of one public operation *) + let bound_fee = Z.(shift_left one 10) + + (** Upper bound for op code *) + let bound_op_code = Z.one let v x = x end @@ -138,9 +140,9 @@ module Types = struct (** Dummy values for these types. Useful to get the circuit without having the actual inputs. *) module Dummy = struct - let op_code = Bounded.make ~bound:Bound.max_op_code Z.zero + let op_code = Bounded.make ~bound:Bound.bound_op_code Z.zero - let balance = Bounded.make ~bound:Bound.max_balance Z.zero + let balance = Bounded.make ~bound:Bound.bound_balance Z.zero let tezos_pkh = Environment.Signature.Public_key_hash.zero @@ -182,7 +184,8 @@ module Types = struct open Encodings (L) - let op_code_encoding ~safety = Bounded_e.encoding ~safety Bound.max_op_code + let op_code_encoding ~safety = + Bounded_e.encoding ~safety Bound.bound_op_code let encoding_to_scalar e x = let bs = Data_encoding.Binary.to_bytes_exn e x in @@ -202,9 +205,9 @@ module Types = struct (encoding_of_scalar Signature.Public_key_hash.encoding) scalar_encoding - let amount_encoding ~safety = Bounded_e.encoding ~safety Bound.max_amount + let amount_encoding ~safety = Bounded_e.encoding ~safety Bound.bound_amount - let fee_encoding ~safety = Bounded_e.encoding ~safety Bound.max_fee + let fee_encoding ~safety = Bounded_e.encoding ~safety Bound.bound_fee let ticket_encoding ~safety (bound : 'a Bound.t) : ('a ticket, 'a ticket_u, _) encoding = @@ -216,7 +219,7 @@ module Types = struct (obj2_encoding scalar_encoding (Bounded_e.encoding ~safety bound)) let ticket_balance_encoding ~safety = - ticket_encoding ~safety Bound.max_balance + ticket_encoding ~safety Bound.bound_balance let header_encoding ~safety : (header, header_u, _) encoding = conv @@ -361,8 +364,7 @@ end = struct (* zkr1PxS4vgvBsf6XVHRSB7UJKcrTWee8Dp7Wx *) Hex.to_bytes_exn (`Hex "c9a524d4db6514471775c380231afc10f2ef6ba3") - let dummy_ticket_hash = - Hex.to_bytes_exn (`Hex (String.init (2 * 32) @@ Fun.const '0')) + let dummy_ticket_hash = Bytes.make 32 '0' let _of_proto_state : Zk_rollup.State.t -> Types.P.state = fun s -> Bls12_381.Fr.is_one s.(0) @@ -392,7 +394,7 @@ end = struct VC.predicate_op ~old_state:false ~new_state:true - ~fee:(T.Bounded.make ~bound:Bound.max_fee Z.zero) + ~fee:(T.Bounded.make ~bound:Bound.bound_fee Z.zero) ~exit_validity:false ~rollup_id:Dummy.tezos_pkh dummy_op ); @@ -400,14 +402,14 @@ end = struct VC.predicate_batch ~old_state:false ~new_state:true - ~fees:(T.Bounded.make ~bound:Bound.max_amount Z.zero) + ~fees:(T.Bounded.make ~bound:Bound.bound_amount Z.zero) ~rollup_id:Dummy.tezos_pkh (Stdlib.List.init Params.batch_size (Fun.const dummy_op)) ); ( "fee", VC.predicate_fees ~old_state:false ~new_state:false - ~fees:(T.Bounded.make ~bound:Bound.max_amount Z.zero) ); + ~fees:(T.Bounded.make ~bound:Bound.bound_amount Z.zero) ); ] let circuits = diff --git a/src/proto_alpha/lib_protocol/test/helpers/zk_rollup_l2_helpers.ml b/src/proto_alpha/lib_protocol/test/helpers/zk_rollup_l2_helpers.ml index af6814716a1501b332455134b9dad51c64f05550..eb710552b7cc8a4d493180c80f1b3c9db9df6221 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/zk_rollup_l2_helpers.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/zk_rollup_l2_helpers.ml @@ -1 +1,26 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + module Dummy_zk_rollup = Dummy_zk_rollup diff --git a/src/proto_alpha/lib_protocol/zk_rollup_account_repr.ml b/src/proto_alpha/lib_protocol/zk_rollup_account_repr.ml index 06ed67a39712aa4a84bdc4fb71abda18a9a763ed..d9a6b421bb5ee30c957dc3901a64f3e6fdda5b57 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_account_repr.ml +++ b/src/proto_alpha/lib_protocol/zk_rollup_account_repr.ml @@ -36,12 +36,25 @@ type dynamic = {state : Zk_rollup_state_repr.t} type t = {static : static; dynamic : dynamic} +let circuits_info_encoding : bool SMap.t Data_encoding.t = + let open Data_encoding in + conv_with_guard + (fun m -> List.of_seq @@ SMap.to_seq m) + (fun l -> + let m = SMap.of_seq @@ List.to_seq l in + if + (* Check that the list has no duplicated keys *) + Compare.List_length_with.(l <> SMap.cardinal m) + then Error "Zk_rollup_origination: circuits_info has duplicated keys" + else Ok m) + (list (tup2 string bool)) + let encoding = let open Data_encoding in let static_encoding = let circuits_info_encoding = conv - (fun m -> List.of_seq @@ SMap.to_seq m) + SMap.bindings (fun l -> SMap.of_seq @@ List.to_seq l) (list (tup2 string bool)) in diff --git a/src/proto_alpha/lib_protocol/zk_rollup_account_repr.mli b/src/proto_alpha/lib_protocol/zk_rollup_account_repr.mli index 37b4eae02b04d32b68c00e4be377507f6ea1272d..c84c94746dd2ceeafbd23d646e7d20d92dbfc080 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_account_repr.mli +++ b/src/proto_alpha/lib_protocol/zk_rollup_account_repr.mli @@ -50,3 +50,7 @@ type dynamic = { type t = {static : static; dynamic : dynamic} val encoding : t Data_encoding.t + +(* Encoding for the [circuits_info] field. + Checks that keys are not duplicated in serialized representation. *) +val circuits_info_encoding : bool SMap.t Data_encoding.t diff --git a/src/proto_alpha/lib_protocol/zk_rollup_apply.ml b/src/proto_alpha/lib_protocol/zk_rollup_apply.ml index df361b65d1ba11f4d167f050403bbb9e5ffdb981..2d6704f98221a94229130774d14fb3142bb34c28 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_apply.ml +++ b/src/proto_alpha/lib_protocol/zk_rollup_apply.ml @@ -50,22 +50,24 @@ let () = (fun () -> Zk_rollup_negative_nb_ops) let assert_feature_enabled ctxt = - fail_unless (Constants.zk_rollup_enable ctxt) Zk_rollup_feature_disabled + error_unless (Constants.zk_rollup_enable ctxt) Zk_rollup_feature_disabled let originate ~ctxt_before_op ~ctxt ~public_parameters ~circuits_info ~init_state ~nb_ops = - assert_feature_enabled ctxt >>=? fun () -> - fail_when Compare.Int.(nb_ops < 0) Zk_rollup_negative_nb_ops >>=? fun () -> - Zk_rollup.originate - ctxt - { - public_parameters; - state_length = Array.length init_state; - circuits_info; - nb_ops; - } - ~init_state - >>=? fun (ctxt, originated_zk_rollup, size) -> + let open Lwt_result_syntax in + let*? () = assert_feature_enabled ctxt in + let*? () = error_when Compare.Int.(nb_ops < 0) Zk_rollup_negative_nb_ops in + let+ ctxt, originated_zk_rollup, storage_size = + Zk_rollup.originate + ctxt + { + public_parameters; + state_length = Array.length init_state; + circuits_info; + nb_ops; + } + ~init_state + in let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = Apply_results.Zk_rollup_origination_result @@ -75,7 +77,7 @@ let originate ~ctxt_before_op ~ctxt ~public_parameters ~circuits_info (* TODO https://gitlab.com/tezos/tezos/-/issues/3544 Carbonate ZKRU operations *) consumed_gas; - size; + storage_size; } in - return (ctxt, result, []) + (ctxt, result, []) diff --git a/src/proto_alpha/lib_protocol/zk_rollup_apply.mli b/src/proto_alpha/lib_protocol/zk_rollup_apply.mli index c54761db5e9178d85a2168f97a85f6d19cdaf302..0fd88b7de2b8a6720718730ccea15dc1c6d050df 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_apply.mli +++ b/src/proto_alpha/lib_protocol/zk_rollup_apply.mli @@ -48,7 +48,7 @@ type error += activated.} } *) -val assert_feature_enabled : t -> unit tzresult Lwt.t +val assert_feature_enabled : t -> unit tzresult (** [originate ~ctxt_before_op ~ctxt ~public_parameters ~transcript ~circuits_info ~init_state ~nb_ops] diff --git a/src/proto_alpha/lib_protocol/zk_rollup_operation_repr.ml b/src/proto_alpha/lib_protocol/zk_rollup_operation_repr.ml index f020df556484fedcafaeafd16ed02af05ad0d240..66f4c227c4c9367c1a094398a242e00a94e21b20 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_operation_repr.ml +++ b/src/proto_alpha/lib_protocol/zk_rollup_operation_repr.ml @@ -34,12 +34,12 @@ type t = { let int_to_scalar x = Zk_rollup_scalar.of_z (Z.of_int x) let pkh_to_scalar x = - Zk_rollup_scalar.of_bytes - (Data_encoding.Binary.to_bytes_exn Signature.Public_key_hash.encoding x) + Zk_rollup_scalar.of_bits + (Data_encoding.Binary.to_string_exn Signature.Public_key_hash.encoding x) let ticket_hash_to_scalar ticket_hash = - Zk_rollup_scalar.of_bytes - @@ Data_encoding.Binary.to_bytes_exn Ticket_hash_repr.encoding ticket_hash + Zk_rollup_scalar.of_bits + @@ Data_encoding.Binary.to_string_exn Ticket_hash_repr.encoding ticket_hash let to_scalar_array {op_code; price; l1_dst; rollup_id; payload} = Array.concat diff --git a/src/proto_alpha/lib_protocol/zk_rollup_repr.ml b/src/proto_alpha/lib_protocol/zk_rollup_repr.ml index 35497192cc9a4cfb8733d9b4120008f135270295..f52bda0a2718f01152c25acc443fced9e75b6db4 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_repr.ml +++ b/src/proto_alpha/lib_protocol/zk_rollup_repr.ml @@ -76,8 +76,8 @@ end type t = Address.t let to_scalar x = - Zk_rollup_scalar.of_bytes - (Data_encoding.Binary.to_bytes_exn Address.encoding x) + Zk_rollup_scalar.of_bits + (Data_encoding.Binary.to_string_exn Address.encoding x) type pending_list = | Empty of {next_index : int64} diff --git a/src/proto_alpha/lib_protocol/zk_rollup_scalar.ml b/src/proto_alpha/lib_protocol/zk_rollup_scalar.ml index 1bdc3d01a05e6e9f8e121bf32085fba4d99dc604..8db6c7b68c1c333fc2c688a98fd35cd1fdac0292 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_scalar.ml +++ b/src/proto_alpha/lib_protocol/zk_rollup_scalar.ml @@ -31,7 +31,7 @@ let of_z z = t a field element *) Bls12_381.Fr.of_z z -let of_bytes bs = - (* The bytes are interpreted as a Z integer *) - let z = Z.of_bits @@ Bytes.to_string bs in +let of_bits bs = + (* The bits are interpreted as a Z integer *) + let z = Z.of_bits bs in of_z z diff --git a/src/proto_alpha/lib_protocol/zk_rollup_scalar.mli b/src/proto_alpha/lib_protocol/zk_rollup_scalar.mli index 2cfce7d9ee2f1fe733be15b30ba1a6bc025f0305..0b9307cefe3ff708cda473503f1bb6ca33d992e5 100644 --- a/src/proto_alpha/lib_protocol/zk_rollup_scalar.mli +++ b/src/proto_alpha/lib_protocol/zk_rollup_scalar.mli @@ -34,7 +34,7 @@ type t = Bls12_381.Fr.t is applied. *) val of_z : Z.t -> t -(** Safe conversion from bytes. +(** Safe conversion from bits, represented as a string. If the numerical value is not in the field, modulo reduction is applied. *) -val of_bytes : bytes -> t +val of_bits : string -> t