From a70dd2452d839af508047bee8390523d7785d684 Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Sat, 8 Oct 2022 19:59:54 +0200 Subject: [PATCH 1/2] WASM: Fix `Wasm_pvm.get_output` --- src/lib_scoru_wasm/wasm_pvm.ml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/lib_scoru_wasm/wasm_pvm.ml b/src/lib_scoru_wasm/wasm_pvm.ml index fcf9b3d8f5d0..1f6f24ce6082 100644 --- a/src/lib_scoru_wasm/wasm_pvm.ml +++ b/src/lib_scoru_wasm/wasm_pvm.ml @@ -544,11 +544,18 @@ struct let open Wasm_pvm_sig in let {outbox_level; message_index} = output_info in let outbox_level = Bounded.Non_negative_int32.to_value outbox_level in - let* {output; _} = - Tree_encoding_runner.decode durable_buffers_encoding tree + let* candidate = + Tree_encoding_runner.decode + (Tezos_tree_encoding.option durable_buffers_encoding) + tree in - let+ payload = Wasm.Output_buffer.get output outbox_level message_index in - Bytes.to_string payload + match candidate with + | Some {output; _} -> + let+ payload = + Wasm.Output_buffer.get output outbox_level message_index + in + Bytes.to_string payload + | None -> raise (Invalid_argument "get_output: missing output buffer") let get_info tree = let open Lwt_syntax in -- GitLab From eb6c7d4973770f1e366fc1fe8a9f8b594085cedf Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Mon, 10 Oct 2022 16:53:39 +0200 Subject: [PATCH 2/2] Proto,WASM: Make `get_output` exception-free Right now, when we request an invalid payload, the function will raise an exception. Considering that this function is used by the protocol, this is not a correct error handling method. --- src/lib_protocol_environment/environment_V6.ml | 4 +++- src/lib_protocol_environment/environment_V7.ml | 5 ++++- src/lib_protocol_environment/sigs/v8.ml | 2 +- .../sigs/v8/wasm_2_0_0.mli | 2 +- src/lib_scoru_wasm/test/test_get_set.ml | 9 +++++++-- src/lib_scoru_wasm/wasm_pvm.ml | 16 +++++++++------- src/lib_scoru_wasm/wasm_pvm_sig.ml | 2 +- src/proto_alpha/lib_protocol/sc_rollup_wasm.ml | 8 ++++++-- 8 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/lib_protocol_environment/environment_V6.ml b/src/lib_protocol_environment/environment_V6.ml index 8418e886045c..f38743620f8c 100644 --- a/src/lib_protocol_environment/environment_V6.ml +++ b/src/lib_protocol_environment/environment_V6.ml @@ -1083,12 +1083,14 @@ struct Wasm.set_input_step {inbox_level; message_counter} payload tree let get_output {outbox_level; message_index} (tree : Tree.tree) = + let open Lwt_syntax in let outbox_level = Tezos_protocol_environment_structs.V6.Bounded.Int32 .non_negative_of_legacy_non_negative outbox_level in - Wasm.get_output {outbox_level; message_index} tree + let+ payload = Wasm.get_output {outbox_level; message_index} tree in + match payload with Some payload -> payload | None -> "" let convert_input : Tezos_scoru_wasm.Wasm_pvm_sig.input_info -> input = function diff --git a/src/lib_protocol_environment/environment_V7.ml b/src/lib_protocol_environment/environment_V7.ml index 77607a11bea7..c7ba16ff7401 100644 --- a/src/lib_protocol_environment/environment_V7.ml +++ b/src/lib_protocol_environment/environment_V7.ml @@ -1076,7 +1076,10 @@ struct let set_input_step input payload (tree : Tree.tree) = Wasm.set_input_step input payload tree - let get_output output (tree : Tree.tree) = Wasm.get_output output tree + let get_output output (tree : Tree.tree) = + let open Lwt_syntax in + let+ payload = Wasm.get_output output tree in + match payload with Some payload -> payload | None -> "" let get_info (tree : Tree.tree) = let open Lwt_syntax in diff --git a/src/lib_protocol_environment/sigs/v8.ml b/src/lib_protocol_environment/sigs/v8.ml index 77af7ea6c7d6..b22d772383c9 100644 --- a/src/lib_protocol_environment/sigs/v8.ml +++ b/src/lib_protocol_environment/sigs/v8.ml @@ -11790,7 +11790,7 @@ module Make val reveal_step : bytes -> Tree.tree -> Tree.tree Lwt.t - val get_output : output -> Tree.tree -> string Lwt.t + val get_output : output -> Tree.tree -> string option Lwt.t val get_info : Tree.tree -> info Lwt.t end diff --git a/src/lib_protocol_environment/sigs/v8/wasm_2_0_0.mli b/src/lib_protocol_environment/sigs/v8/wasm_2_0_0.mli index f163b28c8d6b..6a460f5db68b 100644 --- a/src/lib_protocol_environment/sigs/v8/wasm_2_0_0.mli +++ b/src/lib_protocol_environment/sigs/v8/wasm_2_0_0.mli @@ -52,7 +52,7 @@ module Make val reveal_step : bytes -> Tree.tree -> Tree.tree Lwt.t - val get_output : output -> Tree.tree -> string Lwt.t + val get_output : output -> Tree.tree -> string option Lwt.t val get_info : Tree.tree -> info Lwt.t end diff --git a/src/lib_scoru_wasm/test/test_get_set.ml b/src/lib_scoru_wasm/test/test_get_set.ml index 77668c47944e..8a3df8641d35 100644 --- a/src/lib_scoru_wasm/test/test_get_set.ml +++ b/src/lib_scoru_wasm/test/test_get_set.ml @@ -236,10 +236,15 @@ let test_get_output () = Output_buffer.set_level output 0l ; let* () = Output_buffer.set_value output @@ Bytes.of_string "hello" in let buffers = Eval.{input = Input_buffer.alloc (); output} in - let* tree = Tree_encoding_runner.encode buffers_encoding buffers tree in + let* tree = + Tree_encoding_runner.encode + (Tezos_tree_encoding.option buffers_encoding) + (Some buffers) + tree + in let output_info = make_output_info ~outbox_level:0 ~message_index:0 in let* payload = Wasm.get_output output_info tree in - assert (payload = "hello") ; + assert (payload = Some "hello") ; Lwt_result_syntax.return_unit let tests = diff --git a/src/lib_scoru_wasm/wasm_pvm.ml b/src/lib_scoru_wasm/wasm_pvm.ml index 1f6f24ce6082..b22967a63005 100644 --- a/src/lib_scoru_wasm/wasm_pvm.ml +++ b/src/lib_scoru_wasm/wasm_pvm.ml @@ -549,13 +549,15 @@ struct (Tezos_tree_encoding.option durable_buffers_encoding) tree in - match candidate with - | Some {output; _} -> - let+ payload = - Wasm.Output_buffer.get output outbox_level message_index - in - Bytes.to_string payload - | None -> raise (Invalid_argument "get_output: missing output buffer") + try + match candidate with + | Some {output; _} -> + let+ payload = + Wasm.Output_buffer.get output outbox_level message_index + in + Some (Bytes.to_string payload) + | None -> Lwt.return None + with _ -> Lwt.return None let get_info tree = let open Lwt_syntax in diff --git a/src/lib_scoru_wasm/wasm_pvm_sig.ml b/src/lib_scoru_wasm/wasm_pvm_sig.ml index b4e8daf86e3f..6ce6d328202e 100644 --- a/src/lib_scoru_wasm/wasm_pvm_sig.ml +++ b/src/lib_scoru_wasm/wasm_pvm_sig.ml @@ -117,7 +117,7 @@ module type S = sig output. The result is meant to be deserialized using [Sc_rollup_PVM_sem.output_encoding]. If the output is missing, this function may raise an exception. *) - val get_output : output_info -> tree -> string Lwt.t + val get_output : output_info -> tree -> string option Lwt.t (** [get_info] provides a typed view of the current machine state. Should not raise. *) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml b/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml index 5afc97ac6e4f..f6f9a3e79dc9 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml @@ -405,7 +405,7 @@ module V2_0_0 = struct let state_of_output_proof s = s.output_proof_state let has_output : PS.output -> bool Monad.t = function - | {outbox_level; message_index; message} -> + | {outbox_level; message_index; message} -> ( let open Monad.Syntax in let* s = get in let* result = @@ -423,7 +423,11 @@ module V2_0_0 = struct Sc_rollup_outbox_message_repr.encoding message in - return @@ Compare.String.(result = message_encoded) + return + @@ + match result with + | Some result -> Compare.String.(result = message_encoded) + | None -> false) let verify_output_proof p = let open Lwt_syntax in -- GitLab