diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index d1110e8e078e373bce869459c5bd78e2525ee3ef..8ff175cddadb7720fcf82f691274be12893e2f89 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -28,6 +28,13 @@ Minor Changes participate in consensus and in governance, or do not have such a minimal stake, respectively. (MR :gl:`!3951`) +- In the ``michelson_v1.runtime_error`` error, which appears in the + error trace of operations failing because of runtime errors (such as + interpreting the ``FAILWITH`` instruction) during the execution of a + smart contract, the ``contract_code`` field is deprecated. The + failed script can still be fetched from the address returned in the + ``contract_handle`` field. + Michelson --------- 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 5676ab594cacc2a41572990ca1405468f4bccd57..fac74b20f77780e782e92769ea4029347c64fb4b 100644 --- a/src/proto_alpha/lib_client/michelson_v1_error_reporter.ml +++ b/src/proto_alpha/lib_client/michelson_v1_error_reporter.ml @@ -69,8 +69,7 @@ let collect_error_locations errs = | Environment.Ecoproto_error ( Ill_formed_type (_, _, _) | No_such_entrypoint _ | Duplicate_entrypoint _ - | Unreachable_entrypoint _ - | Runtime_contract_error (_, _) + | Unreachable_entrypoint _ | Runtime_contract_error _ | Michelson_v1_primitives.Invalid_primitive_name (_, _) | Ill_typed_data (_, _, _) | Ill_typed_contract (_, _) ) @@ -140,7 +139,7 @@ type error += let enrich_runtime_errors cctxt ~chain ~block ~parsed = List.map_s (function - | Environment.Ecoproto_error (Runtime_contract_error (contract, _)) -> ( + | Environment.Ecoproto_error (Runtime_contract_error contract) -> ( (* If we know the script already, we don't fetch it *) match parsed with | Some parsed -> @@ -359,8 +358,7 @@ let report_errors ~details ~show_source ?parsed ppf errs = loc ; if rest <> [] then Format.fprintf ppf "@," ; print_trace locations rest - | Environment.Ecoproto_error (Runtime_contract_error (contract, _script)) - :: rest -> + | Environment.Ecoproto_error (Runtime_contract_error contract) :: rest -> Format.fprintf ppf "@[Runtime error in unknown contract %a@]" diff --git a/src/proto_alpha/lib_protocol/script_interpreter.ml b/src/proto_alpha/lib_protocol/script_interpreter.ml index a8a9e8d476d8968e302d3eefddac3b4e38a98140..54abe192fac79eda70965ffbc85ca879f73344f0 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter.ml @@ -83,7 +83,6 @@ *) open Alpha_context -open Script open Script_typed_ir open Script_ir_translator open Local_gas_counter @@ -107,7 +106,7 @@ type error += Reject of Script.location * Script.expr * execution_trace option type error += Overflow of Script.location * execution_trace option -type error += Runtime_contract_error : Contract.t * Script.expr -> error +type error += Runtime_contract_error of Contract.t type error += Bad_contract_parameter of Contract.t (* `Permanent *) @@ -158,11 +157,10 @@ let () = ~description:"Toplevel error for all runtime script errors" (obj2 (req "contract_handle" Contract.encoding) - (req "contract_code" Script.expr_encoding)) + (req "contract_code" (constant "Deprecated"))) (function - | Runtime_contract_error (contract, expr) -> Some (contract, expr) - | _ -> None) - (fun (contract, expr) -> Runtime_contract_error (contract, expr)) ; + | Runtime_contract_error contract -> Some (contract, ()) | _ -> None) + (fun (contract, ()) -> Runtime_contract_error contract) ; (* Bad contract parameter *) register_error_kind `Permanent @@ -1701,17 +1699,12 @@ let execute logger ctxt mode step_constants ~entrypoint ~internal (Bad_contract_parameter step_constants.self) (parse_data ctxt ~legacy:false ~allow_forged:internal arg_type (box arg)) >>=? fun (arg, ctxt) -> - Script.force_decode_in_context - ~consume_deserialization_gas:When_needed - ctxt - unparsed_script.code - >>?= fun (script_code, ctxt) -> Script_ir_translator.collect_lazy_storage ctxt arg_type arg >>?= fun (to_duplicate, ctxt) -> Script_ir_translator.collect_lazy_storage ctxt storage_type storage >>?= fun (to_update, ctxt) -> trace - (Runtime_contract_error (step_constants.self, script_code)) + (Runtime_contract_error step_constants.self) (interp logger (ctxt, step_constants) code (arg, storage)) >>=? fun ((ops, storage), ctxt) -> Script_ir_translator.extract_lazy_storage_diff diff --git a/src/proto_alpha/lib_protocol/script_interpreter.mli b/src/proto_alpha/lib_protocol/script_interpreter.mli index 1d03e3cb796abbc54f808b0599d737ae720206ff..cde579644f7d859ef517462ac687b83cb14ac555 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter.mli +++ b/src/proto_alpha/lib_protocol/script_interpreter.mli @@ -40,7 +40,7 @@ type error += Reject of Script.location * Script.expr * execution_trace option type error += Overflow of Script.location * execution_trace option -type error += Runtime_contract_error : Contract.t * Script.expr -> error +type error += Runtime_contract_error of Contract.t type error += Bad_contract_parameter of Contract.t (* `Permanent *) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_interpretation.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_interpretation.ml index 5a959042e117401c35a71d69be0f92a9a9920915..2c48604f14c21b52b2533b9b54d000f6dfe4c6b1 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_interpretation.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_interpretation.ml @@ -202,8 +202,7 @@ let error_encoding_tests = [ ("Reject", Reject (0, script_expr_int, None)); ("Overflow", Overflow (0, None)); - ( "Runtime_contract_error", - Runtime_contract_error (contract_zero, script_expr_int) ); + ("Runtime_contract_error", Runtime_contract_error contract_zero); ("Bad_contract_parameter", Bad_contract_parameter contract_zero); ("Cannot_serialize_failure", Cannot_serialize_failure); ("Cannot_serialize_storage", Cannot_serialize_storage); diff --git a/tezt/tests/runtime_script_failure.ml b/tezt/tests/runtime_script_failure.ml index 815df7e297b595dc13ad50e025237eea1a75b1c7..6a0e9b21f37a60cba73b5e1e3dffa798fe567aa9 100644 --- a/tezt/tests/runtime_script_failure.ml +++ b/tezt/tests/runtime_script_failure.ml @@ -61,7 +61,7 @@ let check_client_force = ~storage_limit:10000 ~giver:"bootstrap1" ~receiver:contract_id - ~arg:"20" + ~arg:"\"saucisse\"" ~force:true client in @@ -72,12 +72,23 @@ let check_client_force = ["chains"; "main"; "blocks"; "head"; "operations"; "3"; "0"] client in - let first_result = + let first_operation_result = JSON.( first_manager_operation |-> "contents" |=> 0 |-> "metadata" - |-> "operation_result" |-> "status" |> as_string) + |-> "operation_result") in - assert (first_result = "failed") ; + assert (JSON.(first_operation_result |-> "status" |> as_string = "failed")) ; + let first_failed_script = + JSON.(first_operation_result |-> "errors" |=> 0 |-> "contract_code") + in + (match protocol with + | Alpha -> + (* In Alpha this field is deprecated *) + assert (JSON.(first_failed_script |> as_string = "Deprecated")) + | Hangzhou | Ithaca -> + (* In Hangzhou and Ithaca, this field contains the failed script, it + is a sequence of length 3 (parameter, storage, and code). *) + assert (JSON.(first_failed_script |> as_list |> List.length = 3))) ; return () let register ~protocols = check_client_force ~protocols