From 99264c78a4cb8fcd2f9d5f0c02c8b878724ed7b1 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 18:49:06 +0200 Subject: [PATCH 01/15] Proto/Michelson: remove TODO !4844 actually makes the TODO obsolete Fix #1688 --- src/proto_alpha/lib_protocol/script_interpreter_defs.ml | 3 --- src/proto_alpha/lib_protocol/script_ir_translator.ml | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index d50a1b9e15ad..2e9baf99fb8e 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -588,9 +588,6 @@ let transfer (ctxt, sc) gas amount location parameters_ty parameters destination [credit] (taken to contract being executed), and an initial storage [init] of type [storage_ty]. The type of the new contract argument is [param_ty]. *) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 - Refactor the sharing part of unparse_script and create_contract *) let create_contract (ctxt, sc) gas storage_type code delegate credit init = let ctxt = update_context gas ctxt in collect_lazy_storage ctxt storage_type init >>?= fun (to_duplicate, ctxt) -> diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index bf2dd91fab05..ec5a4f06507c 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5885,8 +5885,6 @@ and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = return (Prim (loc, prim, List.rev items, annot), ctxt) | (Int _ | String _ | Bytes _) as atom -> return (atom, ctxt) -(* TODO: https://gitlab.com/tezos/tezos/-/issues/1688 - Refactor the sharing part of unparse_script and create_contract *) let unparse_script ctxt mode (Ex_script (Script {code; arg_type; storage; storage_type; entrypoints; views; _})) = -- GitLab From c3bc74ea6e7c03ba075a637a2375889f8ea18cd0 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 18:50:39 +0200 Subject: [PATCH 02/15] Proto/Michelson: update docstring for create_contract I forgot to do it in !4844 --- .../lib_protocol/script_interpreter_defs.ml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 2e9baf99fb8e..ef27d1cf2773 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -582,12 +582,10 @@ let transfer (ctxt, sc) gas amount location parameters_ty parameters destination let (gas, ctxt) = local_gas_counter_and_outdated_context ctxt in return (res, ctxt, gas) -(* [create_contract (ctxt, sc) gas storage_ty param_ty code entrypoints - delegate credit init] creates an origination operation for a - contract represented by [code], with some [entrypoints], some initial - [credit] (taken to contract being executed), and an initial storage - [init] of type [storage_ty]. The type of the new contract argument - is [param_ty]. *) +(** [create_contract (ctxt, sc) gas storage_ty code delegate credit init] + creates an origination operation for a contract represented by [code], some + initial [credit] (withdrawn from the contract being executed), and an + initial storage [init] of type [storage_ty]. *) let create_contract (ctxt, sc) gas storage_type code delegate credit init = let ctxt = update_context gas ctxt in collect_lazy_storage ctxt storage_type init >>?= fun (to_duplicate, ctxt) -> -- GitLab From 1eec6a275601738b8f7eecb94a0d3b80922fd795 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 20:25:47 +0200 Subject: [PATCH 03/15] Proto/Michelson: simplify two calls to unparse_script No need for the whole unparse_script machinery when only the storage is needed. --- src/proto_alpha/lib_plugin/plugin.ml | 12 ++++-------- src/proto_alpha/lib_protocol/contract_services.ml | 10 +++------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 3bf22b22044f..7692de7cdd84 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2827,14 +2827,10 @@ module RPC = struct ~legacy:true ~allow_forged_in_storage:true script - >>=? fun (ex_script, ctxt) -> - unparse_script ctxt unparsing_mode ex_script - >>=? fun (script, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - script.storage - >>?= fun (storage, _ctxt) -> return_some storage) ; + >>=? fun (Ex_script (Script {storage; storage_type; _}), ctxt) -> + unparse_data ctxt unparsing_mode storage_type storage + >|=? fun (storage, _ctxt) -> + Some (Micheline.strip_locations storage)) ; (* Patched RPC: get_script *) Registration.register1 ~chunked:true diff --git a/src/proto_alpha/lib_protocol/contract_services.ml b/src/proto_alpha/lib_protocol/contract_services.ml index 080c82530cae..2a4f99760d5c 100644 --- a/src/proto_alpha/lib_protocol/contract_services.ml +++ b/src/proto_alpha/lib_protocol/contract_services.ml @@ -380,13 +380,9 @@ let[@coq_axiom_with_reason "gadt"] register () = let ctxt = Gas.set_unlimited ctxt in let open Script_ir_translator in parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script - >>=? fun (ex_script, ctxt) -> - unparse_script ctxt Readable ex_script >>=? fun (script, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - script.storage - >>?= fun (storage, _ctxt) -> return_some storage) ; + >>=? fun (Ex_script (Script {storage; storage_type; _}), ctxt) -> + unparse_data ctxt Readable storage_type storage + >|=? fun (storage, _ctxt) -> Some (Micheline.strip_locations storage)) ; opt_register2 ~chunked:true S.entrypoint_type -- GitLab From 793c74d656b0be26fe4a1d14d94b25e56c0842fd Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 18:42:04 +0200 Subject: [PATCH 04/15] Proto/Michelson: merge parse_script and unparse_script unparse_script is never used without parse_script. --- src/proto_alpha/lib_plugin/plugin.ml | 6 ++---- .../lib_protocol/contract_services.ml | 12 +++++++----- .../lib_protocol/script_ir_translator.ml | 17 +++++++++++++---- .../lib_protocol/script_ir_translator.mli | 10 ++++++++-- .../integration/michelson/test_typechecking.ml | 12 ++++++------ 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 7692de7cdd84..d5a2704a1926 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2841,14 +2841,12 @@ module RPC = struct | None -> return_none | Some script -> let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script + Script_ir_translator.parse_and_unparse_script_unaccounted ctxt ~legacy:true ~allow_forged_in_storage:true + unparsing_mode script - >>=? fun (ex_script, ctxt) -> - unparse_script ctxt unparsing_mode ex_script >>=? fun (script, _ctxt) -> return_some script) let get_storage_normalized ctxt block ~contract ~unparsing_mode = diff --git a/src/proto_alpha/lib_protocol/contract_services.ml b/src/proto_alpha/lib_protocol/contract_services.ml index 2a4f99760d5c..50ac8966e8f6 100644 --- a/src/proto_alpha/lib_protocol/contract_services.ml +++ b/src/proto_alpha/lib_protocol/contract_services.ml @@ -504,11 +504,13 @@ let[@coq_axiom_with_reason "gadt"] register () = | None -> return (None, ctxt) | Some script -> let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script ctxt ~legacy:true ~allow_forged_in_storage:true script - >>=? fun (ex_script, ctxt) -> - unparse_script ctxt Readable ex_script >|=? fun (script, ctxt) -> - (Some script, ctxt)) + Script_ir_translator.parse_and_unparse_script_unaccounted + ctxt + ~legacy:true + ~allow_forged_in_storage:true + Readable + script + >|=? fun (script, ctxt) -> (Some script, ctxt)) >|=? fun (script, _ctxt) -> {balance; delegate; script; counter}) ; S.Sapling.register () diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index ec5a4f06507c..0e4fb159c05b 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5885,11 +5885,20 @@ and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = return (Prim (loc, prim, List.rev items, annot), ctxt) | (Int _ | String _ | Bytes _) as atom -> return (atom, ctxt) -let unparse_script ctxt mode - (Ex_script - (Script {code; arg_type; storage; storage_type; entrypoints; views; _})) = - let (Lam (_, original_code)) = code in +let parse_and_unparse_script_unaccounted ?type_logger ctxt ~legacy + ~allow_forged_in_storage mode original_script = Gas.consume ctxt Unparse_costs.unparse_script >>?= fun ctxt -> + parse_script + ?type_logger + ctxt + ~legacy + ~allow_forged_in_storage + original_script + >>=? fun ( Ex_script + (Script + {code; arg_type; storage; storage_type; entrypoints; views; _}), + ctxt ) -> + let (Lam (_, original_code)) = code in unparse_code ctxt ~stack_depth:0 mode original_code >>=? fun (code, ctxt) -> unparse_data ctxt ~stack_depth:0 mode storage_type storage >>=? fun (storage, ctxt) -> diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index 2d88ed80ebaf..f1fa196d79db 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -394,8 +394,14 @@ val parse_script : (ex_script * context) tzresult Lwt.t (* Gas accounting may not be perfect in this function, as it is only called by RPCs. *) -val unparse_script : - context -> unparsing_mode -> ex_script -> (Script.t * context) tzresult Lwt.t +val parse_and_unparse_script_unaccounted : + ?type_logger:type_logger -> + context -> + legacy:bool -> + allow_forged_in_storage:bool -> + unparsing_mode -> + Script.t -> + (Script.t * context) tzresult Lwt.t val parse_contract : context -> diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml index 5e9bf5963032..8099deea028d 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml @@ -38,7 +38,8 @@ open Error_monad_operators let wrap_error_lwt x = x >>= fun x -> Lwt.return @@ Environment.wrap_tzresult x -(* Test for Script_ir_translator.unparse_script on a script declaring views. *) +(* Test for Script_ir_translator.parse_and_unparse_script_unaccounted on a + script declaring views. *) let test_unparse_view () = let dummy_contract = "{parameter unit; storage unit; code { CAR; NIL operation; PAIR }; view \ @@ -53,15 +54,14 @@ let test_unparse_view () = Context.init 3 >>=? fun (b, _cs) -> Incremental.begin_construction b >>=? fun v -> let ctx = Incremental.alpha_ctxt v in - Script_ir_translator.parse_script + Script_ir_translator.parse_and_unparse_script_unaccounted ctx ~legacy:true ~allow_forged_in_storage:false + Readable script - >>=?? fun (ex_script, ctx) -> - Script_ir_translator.unparse_script ctx Readable ex_script - >>=?? fun (unparse_script, _ctx) -> - let aft = Data_encoding.force_bytes unparse_script.code in + >>=?? fun (unparsed_script, _ctx) -> + let aft = Data_encoding.force_bytes unparsed_script.code in Alcotest.(check bytes) "didn't match" bef aft |> return let test_context () = -- GitLab From 22e5d89e3c2ad84d9ed75db36ece227eecba3045 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 18:56:35 +0200 Subject: [PATCH 05/15] Proto/Michelson: remove gas accounting of parse_and_unparse_script_unaccounted --- src/proto_alpha/lib_protocol/michelson_v1_gas.ml | 13 ------------- src/proto_alpha/lib_protocol/michelson_v1_gas.mli | 4 ---- .../lib_protocol/script_ir_translator.ml | 14 +++----------- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml index 4631f1b92066..624f3e235363 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.ml +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.ml @@ -955,13 +955,6 @@ module Cost_of = struct (* TODO: Add benchmarked value from [Unparse_comparable_type_benchmark]. *) let cost_UNPARSE_COMPARABLE_TYPE type_size = S.mul (S.safe_int 20) type_size - (* model the unparse_views sub function of unparse_script *) - let cost_UNPARSING_VIEWS number_of_views = - S.mul (S.safe_int 30) (S.safe_int number_of_views) - - (* model unparse_script *) - let cost_UNPARSING_SCRIPT = S.safe_int 460 - (* TODO: benchmark *) let cost_COMPARABLE_TY_OF_TY = S.safe_int 120 @@ -1816,12 +1809,6 @@ module Cost_of = struct let unparse_data_cycle = atomic_step_cost cost_UNPARSING_DATA - let unparse_views (views : Script_typed_ir.view_map) = - let (module Box) = Script_map.get_module views in - atomic_step_cost @@ cost_UNPARSING_VIEWS Box.size - - let unparse_script = atomic_step_cost cost_UNPARSING_SCRIPT - let unit = Gas.free (* Reasonable estimate. *) diff --git a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli index 15a04ef478f3..4628d23b3650 100644 --- a/src/proto_alpha/lib_protocol/michelson_v1_gas.mli +++ b/src/proto_alpha/lib_protocol/michelson_v1_gas.mli @@ -495,10 +495,6 @@ module Cost_of : sig val unparse_data_cycle : Gas.cost - val unparse_views : Script_typed_ir.view_map -> Gas.cost - - val unparse_script : Gas.cost - val unit : Gas.cost val contract : Gas.cost diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 0e4fb159c05b..ca1f557089c5 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5887,7 +5887,6 @@ and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = let parse_and_unparse_script_unaccounted ?type_logger ctxt ~legacy ~allow_forged_in_storage mode original_script = - Gas.consume ctxt Unparse_costs.unparse_script >>?= fun ctxt -> parse_script ?type_logger ctxt @@ -5906,7 +5905,7 @@ let parse_and_unparse_script_unaccounted ?type_logger ctxt ~legacy (let loc = Micheline.dummy_location in unparse_parameter_ty ~loc ctxt arg_type ~entrypoints >>? fun (arg_type, ctxt) -> - unparse_ty ~loc ctxt storage_type >>? fun (storage_type, ctxt) -> + unparse_ty ~loc ctxt storage_type >|? fun (storage_type, ctxt) -> let open Micheline in let unparse_view_unaccounted name {input_ty; output_ty; view_code} views = Prim @@ -5921,14 +5920,9 @@ let parse_and_unparse_script_unaccounted ?type_logger ctxt ~legacy [] ) :: views in - let unparse_views views = - Gas.consume ctxt (Unparse_costs.unparse_views views) >|? fun ctxt -> - let views = - Script_map.fold unparse_view_unaccounted views [] |> List.rev - in - (views, ctxt) + let views = + Script_map.fold unparse_view_unaccounted views [] |> List.rev in - unparse_views views >>? fun (views, ctxt) -> let code = Seq ( loc, @@ -5939,8 +5933,6 @@ let parse_and_unparse_script_unaccounted ?type_logger ctxt ~legacy ] @ views ) in - Gas.consume ctxt (Script.strip_locations_cost code) >>? fun ctxt -> - Gas.consume ctxt (Script.strip_locations_cost storage) >|? fun ctxt -> ( { code = lazy_expr (strip_locations code); storage = lazy_expr (strip_locations storage); -- GitLab From eae14638e08d5838ab5588ed5ce065d11d01881f Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 19:19:25 +0200 Subject: [PATCH 06/15] Proto/Michelson: use type_logger consistently in typecheck_code --- src/proto_alpha/lib_protocol/script_ir_translator.ml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index ca1f557089c5..af78bac6a893 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5559,13 +5559,7 @@ let typecheck_code : in trace (Ill_typed_contract (code, !type_map)) result >>=? fun (Lam _, ctxt) -> let views_result = - typecheck_views - ctxt - ~type_logger:(fun loc ~stack_ty_before ~stack_ty_after -> - type_map := (loc, (stack_ty_before, stack_ty_after)) :: !type_map) - ~legacy - storage_type - views + typecheck_views ctxt ?type_logger ~legacy storage_type views in trace (Ill_typed_contract (code, !type_map)) views_result >|=? fun ctxt -> (!type_map, ctxt) -- GitLab From 81cbe2179a3c1215e34808f0e4b51f8c6bca6843 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 19:24:07 +0200 Subject: [PATCH 07/15] Proto/Michelson: remove type_logger from parse_and_unparse_script_unaccounted --- src/proto_alpha/lib_protocol/script_ir_translator.ml | 11 +++-------- src/proto_alpha/lib_protocol/script_ir_translator.mli | 1 - 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index af78bac6a893..65c873fb8083 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5879,14 +5879,9 @@ and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = return (Prim (loc, prim, List.rev items, annot), ctxt) | (Int _ | String _ | Bytes _) as atom -> return (atom, ctxt) -let parse_and_unparse_script_unaccounted ?type_logger ctxt ~legacy - ~allow_forged_in_storage mode original_script = - parse_script - ?type_logger - ctxt - ~legacy - ~allow_forged_in_storage - original_script +let parse_and_unparse_script_unaccounted ctxt ~legacy ~allow_forged_in_storage + mode original_script = + parse_script ctxt ~legacy ~allow_forged_in_storage original_script >>=? fun ( Ex_script (Script {code; arg_type; storage; storage_type; entrypoints; views; _}), diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index f1fa196d79db..1980c60038b5 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -395,7 +395,6 @@ val parse_script : (* Gas accounting may not be perfect in this function, as it is only called by RPCs. *) val parse_and_unparse_script_unaccounted : - ?type_logger:type_logger -> context -> legacy:bool -> allow_forged_in_storage:bool -> -- GitLab From f88f29e2a0059db6f24e2b1b991e07d538b9e8f0 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 19:44:14 +0200 Subject: [PATCH 08/15] Proto/Michelson: split typecheck_code --- .../lib_protocol/script_ir_translator.ml | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 65c873fb8083..4c98d994b1bd 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5516,17 +5516,27 @@ let[@coq_axiom_with_reason "gadt"] parse_script : {code_size; code; arg_type; storage; storage_type; views; entrypoints}), ctxt ) +type typechecked_code_internal = + | Typechecked_code_internal : { + toplevel : toplevel; + arg_type : ('arg, _) ty; + storage_type : ('storage, _) ty; + entrypoints : 'arg entrypoints; + type_map : type_map; + } + -> typechecked_code_internal + let typecheck_code : legacy:bool -> show_types:bool -> context -> Script.expr -> - (type_map * context) tzresult Lwt.t = + (typechecked_code_internal * context) tzresult Lwt.t = fun ~legacy ~show_types ctxt code -> (* Constants need to be expanded or [parse_toplevel] may fail. *) Global_constants_storage.expand ctxt code >>=? fun (ctxt, code) -> - parse_toplevel ctxt ~legacy code - >>?= fun ({arg_type; storage_type; code_field; views}, ctxt) -> + parse_toplevel ctxt ~legacy code >>?= fun (toplevel, ctxt) -> + let {arg_type; storage_type; code_field; views} = toplevel in let type_map = ref [] in let arg_type_loc = location arg_type in record_trace @@ -5537,7 +5547,8 @@ let typecheck_code : record_trace (Ill_formed_type (Some "storage", code, storage_type_loc)) (parse_storage_ty ctxt ~stack_depth:0 ~legacy storage_type) - >>?= fun (Ex_ty storage_type, ctxt) -> + >>?= fun (ex_storage_type, ctxt) -> + let (Ex_ty storage_type) = ex_storage_type in pair_t storage_type_loc arg_type storage_type >>?= fun (Ty_ex_c arg_type_full) -> pair_t storage_type_loc list_operation_t storage_type @@ -5562,7 +5573,9 @@ let typecheck_code : typecheck_views ctxt ?type_logger ~legacy storage_type views in trace (Ill_typed_contract (code, !type_map)) views_result >|=? fun ctxt -> - (!type_map, ctxt) + ( Typechecked_code_internal + {toplevel; arg_type; storage_type; entrypoints; type_map = !type_map}, + ctxt ) (* Uncarbonated because used only in RPCs *) let list_entrypoints_uncarbonated (type full fullc) (full : (full, fullc) ty) @@ -6491,3 +6504,7 @@ let script_size in let cost = Script_typed_ir_size_costs.nodes_cost ~nodes in (Saturation_repr.(add code_size storage_size |> to_int), cost) + +let typecheck_code ~legacy ~show_types ctxt code = + typecheck_code ~legacy ~show_types ctxt code + >|=? fun (Typechecked_code_internal {type_map; _}, ctxt) -> (type_map, ctxt) -- GitLab From cfb3e3bc258a9a991ca493bdad200ac46c59ce43 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 19:53:44 +0200 Subject: [PATCH 09/15] Proto/Michelson: use typecheck_code in parse_and_unparse_script_unaccounted --- .../lib_protocol/script_ir_translator.ml | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 4c98d994b1bd..24c13b7acb2c 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5893,14 +5893,30 @@ and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = | (Int _ | String _ | Bytes _) as atom -> return (atom, ctxt) let parse_and_unparse_script_unaccounted ctxt ~legacy ~allow_forged_in_storage - mode original_script = - parse_script ctxt ~legacy ~allow_forged_in_storage original_script - >>=? fun ( Ex_script - (Script - {code; arg_type; storage; storage_type; entrypoints; views; _}), + mode {code; storage} = + Script.force_decode_in_context + ~consume_deserialization_gas:When_needed + ctxt + code + >>?= fun (code, ctxt) -> + typecheck_code ~legacy ~show_types:false ctxt code + >>=? fun ( Typechecked_code_internal + { + toplevel = {code_field; arg_type = _; storage_type = _; views}; + arg_type; + storage_type; + entrypoints; + type_map = _; + }, ctxt ) -> - let (Lam (_, original_code)) = code in - unparse_code ctxt ~stack_depth:0 mode original_code >>=? fun (code, ctxt) -> + parse_storage + ctxt + ~legacy + ~allow_forged:allow_forged_in_storage + storage_type + ~storage + >>=? fun (storage, ctxt) -> + unparse_code ctxt ~stack_depth:0 mode code_field >>=? fun (code, ctxt) -> unparse_data ctxt ~stack_depth:0 mode storage_type storage >>=? fun (storage, ctxt) -> Lwt.return -- GitLab From a0aebba22111f03ed5bfe36d7822018f956349b9 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 20:00:35 +0200 Subject: [PATCH 10/15] Proto/Michelson: add normalize_types option to parse_and_unparse_script_unaccounted --- src/proto_alpha/lib_plugin/plugin.ml | 1 + .../lib_protocol/contract_services.ml | 1 + .../lib_protocol/script_ir_translator.ml | 20 ++++++++++++++----- .../lib_protocol/script_ir_translator.mli | 1 + .../michelson/test_typechecking.ml | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index d5a2704a1926..27ae64b1d2ce 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2846,6 +2846,7 @@ module RPC = struct ~legacy:true ~allow_forged_in_storage:true unparsing_mode + ~normalize_types:true script >>=? fun (script, _ctxt) -> return_some script) diff --git a/src/proto_alpha/lib_protocol/contract_services.ml b/src/proto_alpha/lib_protocol/contract_services.ml index 50ac8966e8f6..acc5b78963a5 100644 --- a/src/proto_alpha/lib_protocol/contract_services.ml +++ b/src/proto_alpha/lib_protocol/contract_services.ml @@ -509,6 +509,7 @@ let[@coq_axiom_with_reason "gadt"] register () = ~legacy:true ~allow_forged_in_storage:true Readable + ~normalize_types:true script >|=? fun (script, ctxt) -> (Some script, ctxt)) >|=? fun (script, _ctxt) -> {balance; delegate; script; counter}) ; diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 24c13b7acb2c..68fd39b62595 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -5893,7 +5893,7 @@ and[@coq_axiom_with_reason "gadt"] unparse_code ctxt ~stack_depth mode code = | (Int _ | String _ | Bytes _) as atom -> return (atom, ctxt) let parse_and_unparse_script_unaccounted ctxt ~legacy ~allow_forged_in_storage - mode {code; storage} = + mode ~normalize_types {code; storage} = Script.force_decode_in_context ~consume_deserialization_gas:When_needed ctxt @@ -5902,7 +5902,13 @@ let parse_and_unparse_script_unaccounted ctxt ~legacy ~allow_forged_in_storage typecheck_code ~legacy ~show_types:false ctxt code >>=? fun ( Typechecked_code_internal { - toplevel = {code_field; arg_type = _; storage_type = _; views}; + toplevel = + { + code_field; + arg_type = original_arg_type_expr; + storage_type = original_storage_type_expr; + views; + }; arg_type; storage_type; entrypoints; @@ -5921,9 +5927,13 @@ let parse_and_unparse_script_unaccounted ctxt ~legacy ~allow_forged_in_storage >>=? fun (storage, ctxt) -> Lwt.return (let loc = Micheline.dummy_location in - unparse_parameter_ty ~loc ctxt arg_type ~entrypoints - >>? fun (arg_type, ctxt) -> - unparse_ty ~loc ctxt storage_type >|? fun (storage_type, ctxt) -> + (if normalize_types then + unparse_parameter_ty ~loc ctxt arg_type ~entrypoints + >>? fun (arg_type, ctxt) -> + unparse_ty ~loc ctxt storage_type >|? fun (storage_type, ctxt) -> + (arg_type, storage_type, ctxt) + else ok (original_arg_type_expr, original_storage_type_expr, ctxt)) + >|? fun (arg_type, storage_type, ctxt) -> let open Micheline in let unparse_view_unaccounted name {input_ty; output_ty; view_code} views = Prim diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.mli b/src/proto_alpha/lib_protocol/script_ir_translator.mli index 1980c60038b5..a2504a6d7128 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.mli +++ b/src/proto_alpha/lib_protocol/script_ir_translator.mli @@ -399,6 +399,7 @@ val parse_and_unparse_script_unaccounted : legacy:bool -> allow_forged_in_storage:bool -> unparsing_mode -> + normalize_types:bool -> Script.t -> (Script.t * context) tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml index 8099deea028d..be2a0ae79b15 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_typechecking.ml @@ -59,6 +59,7 @@ let test_unparse_view () = ~legacy:true ~allow_forged_in_storage:false Readable + ~normalize_types:true script >>=?? fun (unparsed_script, _ctx) -> let aft = Data_encoding.force_bytes unparsed_script.code in -- GitLab From 4f5dff7f5c6f14598d2a5c48a291bb4617deab0a Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 20:33:19 +0200 Subject: [PATCH 11/15] Proto/RPCs: add normalize_types flag to contract info --- .../lib_protocol/contract_services.ml | 19 ++++++++++++++----- .../lib_protocol/contract_services.mli | 6 +++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/proto_alpha/lib_protocol/contract_services.ml b/src/proto_alpha/lib_protocol/contract_services.ml index acc5b78963a5..f60675624690 100644 --- a/src/proto_alpha/lib_protocol/contract_services.ml +++ b/src/proto_alpha/lib_protocol/contract_services.ml @@ -226,7 +226,7 @@ module S = struct let info = RPC_service.get_service ~description:"Access the complete status of a contract." - ~query:RPC_query.empty + ~query:normalize_types_query ~output:info_encoding RPC_path.(custom_root /: Contract.rpc_arg) @@ -294,6 +294,12 @@ let[@coq_axiom_with_reason "gadt"] register () = | true -> f ctxt contract >|=? Option.some | false -> return_none) in + let register_field_with_query ~chunked s f = + opt_register1 ~chunked s (fun ctxt contract query () -> + Contract.exists ctxt contract >>=? function + | true -> f ctxt contract query >|=? Option.some + | false -> return_none) + in let register_opt_field ~chunked s f = opt_register1 ~chunked s (fun ctxt contract () () -> Contract.exists ctxt contract >>=? function @@ -490,7 +496,10 @@ let[@coq_axiom_with_reason "gadt"] register () = do_big_map_get ctxt id key) ; register1 ~chunked:true S.big_map_get_all (fun ctxt id {offset; length} () -> do_big_map_get_all ?offset ?length ctxt id) ; - register_field ~chunked:false S.info (fun ctxt contract -> + register_field_with_query + ~chunked:false + S.info + (fun ctxt contract {normalize_types} -> Contract.get_balance ctxt contract >>=? fun balance -> Delegate.find ctxt contract >>=? fun delegate -> (match Contract.is_implicit contract with @@ -509,7 +518,7 @@ let[@coq_axiom_with_reason "gadt"] register () = ~legacy:true ~allow_forged_in_storage:true Readable - ~normalize_types:true + ~normalize_types script >|=? fun (script, ctxt) -> (Some script, ctxt)) >|=? fun (script, _ctxt) -> {balance; delegate; script; counter}) ; @@ -517,8 +526,8 @@ let[@coq_axiom_with_reason "gadt"] register () = let list ctxt block = RPC_context.make_call0 S.list ctxt block () () -let info ctxt block contract = - RPC_context.make_call1 S.info ctxt block contract () () +let info ctxt block contract ~normalize_types = + RPC_context.make_call1 S.info ctxt block contract {normalize_types} () let balance ctxt block contract = RPC_context.make_call1 S.balance ctxt block contract () () diff --git a/src/proto_alpha/lib_protocol/contract_services.mli b/src/proto_alpha/lib_protocol/contract_services.mli index 6f86556cb088..4625b5ea3a50 100644 --- a/src/proto_alpha/lib_protocol/contract_services.mli +++ b/src/proto_alpha/lib_protocol/contract_services.mli @@ -38,7 +38,11 @@ type info = { val info_encoding : info Data_encoding.t val info : - 'a #RPC_context.simple -> 'a -> Contract.t -> info shell_tzresult Lwt.t + 'a #RPC_context.simple -> + 'a -> + Contract.t -> + normalize_types:bool -> + info shell_tzresult Lwt.t val balance : 'a #RPC_context.simple -> 'a -> Contract.t -> Tez.t shell_tzresult Lwt.t -- GitLab From a4e8ad401efeb19e191d534132759bee552a4937 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 20:37:23 +0200 Subject: [PATCH 12/15] Plugin/RPCs: add normalize_types to get_script_normalized --- src/proto_alpha/lib_client/client_proto_context.ml | 1 + .../lib_client/michelson_v1_error_reporter.ml | 1 + src/proto_alpha/lib_plugin/plugin.ml | 14 +++++++++----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 97b98a7f8732..4dbb04f9fb1f 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -61,6 +61,7 @@ let get_script (rpc : #rpc_context) ~chain ~block ~unparsing_mode contract = rpc (chain, block) ~unparsing_mode + ~normalize_types:true ~contract let get_script_hash (rpc : #rpc_context) ~chain ~block contract = diff --git a/src/proto_alpha/lib_client/michelson_v1_error_reporter.ml b/src/proto_alpha/lib_client/michelson_v1_error_reporter.ml index 9510cf87059b..b1b78b40cc4a 100644 --- a/src/proto_alpha/lib_client/michelson_v1_error_reporter.ml +++ b/src/proto_alpha/lib_client/michelson_v1_error_reporter.ml @@ -128,6 +128,7 @@ let fetch_script (cctxt : #Protocol_client_context.rpc_context) ~chain ~block cctxt (chain, block) ~unparsing_mode:Readable + ~normalize_types:true ~contract >>=? function | None -> fail (Fetch_script_not_found_meta_error contract) diff --git a/src/proto_alpha/lib_plugin/plugin.ml b/src/proto_alpha/lib_plugin/plugin.ml index 27ae64b1d2ce..941647e72476 100644 --- a/src/proto_alpha/lib_plugin/plugin.ml +++ b/src/proto_alpha/lib_plugin/plugin.ml @@ -2804,7 +2804,10 @@ module RPC = struct ~description: "Access the script of the contract and normalize it using the \ requested unparsing mode." - ~input:(obj1 (req "unparsing_mode" unparsing_mode_encoding)) + ~input: + (obj2 + (req "unparsing_mode" unparsing_mode_encoding) + (dft "normalize_types" bool false)) ~query:RPC_query.empty ~output:(option Script.encoding) RPC_path.(path /: Contract.rpc_arg / "script" / "normalized") @@ -2835,7 +2838,7 @@ module RPC = struct Registration.register1 ~chunked:true S.get_script_normalized - (fun ctxt contract () unparsing_mode -> + (fun ctxt contract () (unparsing_mode, normalize_types) -> Contract.get_script ctxt contract >>=? fun (ctxt, script) -> match script with | None -> return_none @@ -2846,7 +2849,7 @@ module RPC = struct ~legacy:true ~allow_forged_in_storage:true unparsing_mode - ~normalize_types:true + ~normalize_types script >>=? fun (script, _ctxt) -> return_some script) @@ -2859,14 +2862,15 @@ module RPC = struct () unparsing_mode - let get_script_normalized ctxt block ~contract ~unparsing_mode = + let get_script_normalized ctxt block ~contract ~unparsing_mode + ~normalize_types = RPC_context.make_call1 S.get_script_normalized ctxt block contract () - unparsing_mode + (unparsing_mode, normalize_types) end module Big_map = struct -- GitLab From 92cfc91e9f533da7717fe6daea5feb4ca263e4a3 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 20:40:11 +0200 Subject: [PATCH 13/15] Proto/Client: push normalize_types further --- src/proto_alpha/lib_client/client_proto_context.ml | 5 +++-- src/proto_alpha/lib_client/client_proto_context.mli | 1 + src/proto_alpha/lib_client/client_proto_fa12.ml | 1 + .../lib_client_commands/client_proto_context_commands.ml | 1 + 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 4dbb04f9fb1f..63dd8fe7d3cd 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -56,12 +56,13 @@ let get_contract_big_map_value (rpc : #rpc_context) ~chain ~block contract key = contract key -let get_script (rpc : #rpc_context) ~chain ~block ~unparsing_mode contract = +let get_script (rpc : #rpc_context) ~chain ~block ~unparsing_mode + ~normalize_types contract = Plugin.RPC.Contract.get_script_normalized rpc (chain, block) ~unparsing_mode - ~normalize_types:true + ~normalize_types ~contract let get_script_hash (rpc : #rpc_context) ~chain ~block contract = diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index 559a088dc426..a50350e65db6 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -83,6 +83,7 @@ val get_script : chain:Shell_services.chain -> block:Shell_services.block -> unparsing_mode:Script_ir_translator.unparsing_mode -> + normalize_types:bool -> Contract.t -> Script.t option tzresult Lwt.t diff --git a/src/proto_alpha/lib_client/client_proto_fa12.ml b/src/proto_alpha/lib_client/client_proto_fa12.ml index 957fb78c75e8..279d411cd7ed 100644 --- a/src/proto_alpha/lib_client/client_proto_fa12.ml +++ b/src/proto_alpha/lib_client/client_proto_fa12.ml @@ -673,6 +673,7 @@ let get_contract_parameter cctxt ~chain ~block contract = ~block contract ~unparsing_mode:Optimized + ~normalize_types:true >>=? function | None -> fail (Contract_has_no_script contract) | Some {code; _} -> ( diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 3e8e4f0fc9b9..fd0621fee904 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -360,6 +360,7 @@ let commands_ro () = ~chain:cctxt#chain ~block:cctxt#block ~unparsing_mode + ~normalize_types:true contract >>=? function | None -> cctxt#error "This is not a smart contract." -- GitLab From bf292c385db7a7faf3e468f3f8f4b549082327b1 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 Mar 2022 20:41:45 +0200 Subject: [PATCH 14/15] Proto/Client: add normalize-types switch to get contract code for --- .../lib_client_commands/client_proto_context_commands.ml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index fd0621fee904..868aadc3e8cf 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -350,17 +350,19 @@ let commands_ro () = command ~group ~desc:"Get the code of a contract." - (args1 (unparsing_mode_arg ~default:"Readable")) + (args2 (unparsing_mode_arg ~default:"Readable") normalize_types_switch) (prefixes ["get"; "contract"; "code"; "for"] @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" @@ stop) - (fun unparsing_mode (_, contract) (cctxt : Protocol_client_context.full) -> + (fun (unparsing_mode, normalize_types) + (_, contract) + (cctxt : Protocol_client_context.full) -> get_script cctxt ~chain:cctxt#chain ~block:cctxt#block ~unparsing_mode - ~normalize_types:true + ~normalize_types contract >>=? function | None -> cctxt#error "This is not a smart contract." -- GitLab From 4a6729a2e8048028a9c5c92244355a52d7cf31e0 Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Thu, 31 Mar 2022 11:35:39 +0200 Subject: [PATCH 15/15] Proto/Doc: update alpha changelog --- docs/protocols/alpha.rst | 47 ++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index 427e29c20b3f..eab380860f72 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -183,25 +183,34 @@ Michelson available in lambdas defined inside a view. (MR :gl:`!3737`) -- Stack variable annotations are ignored and not propagated. All contracts that - used to typecheck correctly before will still typecheck correctly afterwards. - Though more contracts are accepted as branches with different stack variable - annotations won't be rejected any more. - The special annotation ``%@`` of ``PAIR`` has no effect. - RPCs ``typecheck_code``, ``trace_code``, as well as typechecking errors - reporting stack types, won't report stack annotations any more. - In their output encodings, the objects containing the fields ``item`` and - ``annot`` are replaced with the contents of the field ``item``. - (MR :gl:`!4139`) - -- Variable annotations in pairs are ignored and not propagated. - (MR :gl:`!4140`) - -- Type annotations are ignored and not propagated. - (MR :gl:`!4141`) - -- Field annotations are ignored and not propagated. - (MR :gl:`!4175`, :gl:`!4311`, :gl:`!4259`) +- Non-entrypoint annotations are ignored by the typechecker and not propagated. + + - All contracts that used to typecheck correctly before will still typecheck + correctly afterwards. Though more contracts are accepted as branches with + different annotations won't be rejected anymore. + + - The special annotation ``%@`` of ``PAIR`` has no effect. + + - RPCs + ``/chains//blocks//context/contracts/
/typecheck_code``, + ``/chains//blocks//context/contracts/
/trace_code``, + as well as typechecking errors reporting stack types, won't report + annotations anymore. + + In their output encodings, the objects containing the fields ``item`` and + ``annot`` are replaced with the contents of the field ``item``. + + - RPCs ``/chains//blocks//context/contracts/
``, + ``/chains//blocks//context/contracts/
/script/normalized``, + ``/chains//blocks//context/contracts/
/entrypoints``, + ``/chains//blocks//context/contracts/
/entrypoints/normalized``, + ``/chains//blocks//context/contracts/
/entrypoints/``, + ``/chains//blocks//context/contracts/
/entrypoints//normalized`` + accept a new boolean parameter ``normalize_types`` to show types without + their annotations. + + - (MRs :gl:`!4139`, :gl:`!4140`, :gl:`!4141`, :gl:`!4175`, :gl:`!4311`, + :gl:`!4259`, :gl:`!4844`, :gl:`!4876`, :gl:`!4893`) - Annotating the parameter toplevel constructor to designate the root entrypoint is now forbidden. Put the annotation on the parameter type instead. -- GitLab