From f5c1da4040a93819e3d8f9f4129c139ed98750e8 Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Fri, 17 Feb 2023 21:31:44 +0100 Subject: [PATCH] WASM: Introduce the first revision of the WASM PVM --- src/bin_wasm_debugger/main_wasm_debugger.ml | 1 + .../environment_V9.ml | 2 +- src/lib_protocol_environment/sigs/v9.ml | 2 +- .../sigs/v9/wasm_2_0_0.mli | 2 +- src/lib_scoru_wasm/bench/exec.ml | 1 + src/lib_scoru_wasm/fast/test/test_fast.ml | 104 ++++--- src/lib_scoru_wasm/helpers/wasm_utils.ml | 4 +- .../test/helpers/tztest_helper.ml | 41 +++ .../test/test_fixed_nb_ticks.ml | 32 +- src/lib_scoru_wasm/test/test_get_set.ml | 26 +- .../test/test_hash_consistency.ml | 48 +-- .../test/test_host_functions_ticks.ml | 10 +- src/lib_scoru_wasm/test/test_init.ml | 77 ++--- src/lib_scoru_wasm/test/test_reveal.ml | 46 +-- src/lib_scoru_wasm/test/test_wasm_pvm.ml | 276 +++++++++--------- src/lib_scoru_wasm/test/test_wasm_vm.ml | 35 +-- src/lib_scoru_wasm/wasm_pvm_state.ml | 9 +- .../lib_protocol/sc_rollup_wasm.ml | 4 +- ..._0 - RPC API should work and be stable.out | 4 +- tezt/tests/sc_rollup.ml | 17 +- 20 files changed, 425 insertions(+), 316 deletions(-) create mode 100644 src/lib_scoru_wasm/test/helpers/tztest_helper.ml diff --git a/src/bin_wasm_debugger/main_wasm_debugger.ml b/src/bin_wasm_debugger/main_wasm_debugger.ml index 6ac922d495a3..9ab219016b02 100644 --- a/src/bin_wasm_debugger/main_wasm_debugger.ml +++ b/src/bin_wasm_debugger/main_wasm_debugger.ml @@ -68,6 +68,7 @@ let handle_module binary name module_ = let* _ = link ast in let*! tree = initial_tree + ~version:V1 ~ticks_per_snapshot:(Z.to_int64 Wasm_2_0_0PVM.ticks_per_snapshot) ~outbox_validity_period:Wasm_2_0_0PVM.outbox_validity_period ~outbox_message_limit:Wasm_2_0_0PVM.outbox_message_limit diff --git a/src/lib_protocol_environment/environment_V9.ml b/src/lib_protocol_environment/environment_V9.ml index a4af1d588798..7fe120cd5822 100644 --- a/src/lib_protocol_environment/environment_V9.ml +++ b/src/lib_protocol_environment/environment_V9.ml @@ -1129,7 +1129,7 @@ struct type version = Tezos_scoru_wasm.Wasm_pvm_state.version - let v0 = Tezos_scoru_wasm.Wasm_pvm_state.V0 + let v1 = Tezos_scoru_wasm.Wasm_pvm_state.V1 module Make (Tree : Context.TREE with type key = string list and type value = bytes) = diff --git a/src/lib_protocol_environment/sigs/v9.ml b/src/lib_protocol_environment/sigs/v9.ml index 4694f64a1daa..ef0cd1df6681 100644 --- a/src/lib_protocol_environment/sigs/v9.ml +++ b/src/lib_protocol_environment/sigs/v9.ml @@ -12080,7 +12080,7 @@ end type version -val v0 : version +val v1 : version type input = {inbox_level : Bounded.Non_negative_int32.t; message_counter : Z.t} diff --git a/src/lib_protocol_environment/sigs/v9/wasm_2_0_0.mli b/src/lib_protocol_environment/sigs/v9/wasm_2_0_0.mli index a7107b945eb8..0ecc4afac5d5 100644 --- a/src/lib_protocol_environment/sigs/v9/wasm_2_0_0.mli +++ b/src/lib_protocol_environment/sigs/v9/wasm_2_0_0.mli @@ -25,7 +25,7 @@ type version -val v0 : version +val v1 : version type input = {inbox_level : Bounded.Non_negative_int32.t; message_counter : Z.t} diff --git a/src/lib_scoru_wasm/bench/exec.ml b/src/lib_scoru_wasm/bench/exec.ml index b4337cefd878..10dac16b6c51 100644 --- a/src/lib_scoru_wasm/bench/exec.ml +++ b/src/lib_scoru_wasm/bench/exec.ml @@ -105,6 +105,7 @@ let initial_boot_sector_from_kernel ?(max_tick = 1000000000000L) kernel = let open Lwt_syntax in let+ tree = Wasm_utils.initial_tree + ~version:V1 ~ticks_per_snapshot:max_tick ~from_binary:true kernel diff --git a/src/lib_scoru_wasm/fast/test/test_fast.ml b/src/lib_scoru_wasm/fast/test/test_fast.ml index 7a41abd183ba..2c27a79f9f3c 100644 --- a/src/lib_scoru_wasm/fast/test/test_fast.ml +++ b/src/lib_scoru_wasm/fast/test/test_fast.ml @@ -23,9 +23,9 @@ (* *) (*****************************************************************************) -open Tztest module Preimage_map = Map.Make (String) open Wasm_utils +open Tztest_helper let run_fast = Wasm_fast.Internal_for_tests.compute_step_many_with_hooks @@ -119,9 +119,9 @@ and check_reveal ?write_debug ?(images = Preimage_map.empty) ?metadata - [write_debug] is the implementation of the host function to use. - [metadata] is used in case of Reveal_metadata step. - [images] is a hashmap used in case of reveal steps. *) -let test_against_both ?write_debug ?(set_input = Wasm_utils.set_full_input_step) - ?images ?metadata ~from_binary ~kernel ~messages - ?(max_steps = Int64.max_int) () = +let test_against_both ~version ?write_debug + ?(set_input = Wasm_utils.set_full_input_step) ?images ?metadata ~from_binary + ~kernel ~messages ?(max_steps = Int64.max_int) () = let open Lwt.Syntax in let make_folder apply (tree, counter, hashes) message = let* info = Wasm_utils.Wasm.get_info tree in @@ -142,6 +142,7 @@ let test_against_both ?write_debug ?(set_input = Wasm_utils.set_full_input_step) let* initial_tree = Wasm_utils.initial_tree + ~version ~ticks_per_snapshot:Wasm_utils.production_max_tick ~from_binary kernel @@ -180,11 +181,16 @@ let test_against_both ?write_debug ?(set_input = Wasm_utils.set_full_input_step) Lwt_result_syntax.return_unit -let test_computation = +let test_computation ~version = Wasm_utils.test_with_kernel "computation" (fun kernel -> (* Providing 4 empty messages basically means calling the kernel entrypoint 4 times. *) - test_against_both ~from_binary:true ~kernel ~messages:[""; ""; ""; ""] ()) + test_against_both + ~version + ~from_binary:true + ~kernel + ~messages:[""; ""; ""; ""] + ()) (* kernel that does a fixed number of reboot by storing a counter in durable storage @@ -336,20 +342,24 @@ let kernel_bounded_reboot = ) |} -let test_reboot = +let test_reboot ~version () = test_against_both + ~version ~from_binary:false ~kernel:kernel_bounded_reboot ~messages:[""] + () -let test_max_steps = +let test_max_steps ~version () = test_against_both + ~version ~max_steps:23_001_001_001L ~from_binary:false ~kernel:kernel_bounded_reboot ~messages:[""] + () -let test_too_many_reboots = +let test_too_many_reboots ~version () = (* kernel that - increment counter in durable storage - reboots without stopping condition @@ -474,9 +484,9 @@ let test_too_many_reboots = ) |} in - test_against_both ~from_binary:false ~kernel ~messages:[""] + test_against_both ~version ~from_binary:false ~kernel ~messages:[""] () -let test_store_read_write = +let test_store_read_write ~version () = let kernel = {| (module @@ -578,9 +588,14 @@ let test_store_read_write = ) |} in - test_against_both ~from_binary:false ~kernel ~messages:(List.repeat 100 "") + test_against_both + ~version + ~from_binary:false + ~kernel + ~messages:(List.repeat 100 "") + () -let test_read_input = +let test_read_input ~version () = let kernel = {| (module @@ -641,11 +656,13 @@ let test_read_input = let no_of_levels = 257 in test_against_both + ~version ~from_binary:false ~kernel ~messages:(List.repeat no_of_levels msg) + () -let test_big_address = +let test_big_address ~version () = let kernel = {| (module @@ -665,9 +682,9 @@ let test_big_address = |} in let msg = "abcd" in - test_against_both ~from_binary:false ~kernel ~messages:[msg] + test_against_both ~version ~from_binary:false ~kernel ~messages:[msg] () -let test_reveal_preimage = +let test_reveal_preimage ~version () = let example_hash = "this represents the 33-byte hash " in let example_preimage = "This is the expected preimage" in let images = Preimage_map.singleton example_hash example_preimage in @@ -721,11 +738,19 @@ let test_reveal_preimage = |} example_hash in - test_against_both ~images ~from_binary:false ~kernel ~messages:[""; ""] + test_against_both + ~version + ~images + ~from_binary:false + ~kernel + ~messages:[""; ""] + () -let test_tx = +let test_tx ~version () = let open Lwt.Syntax in - Wasm_utils.test_with_kernel "tx-kernel-no-verif" (fun kernel -> + Wasm_utils.test_with_kernel + "tx-kernel-no-verif" + (fun kernel -> let* messages = Wasm_utils.read_test_messages ["deposit.out"; "withdrawal.out"] in @@ -741,14 +766,16 @@ let test_tx = (* TX Kernel ignores origination level *) let metadata = expected_rollup_address ^ "\000\000\000\000" in test_against_both + ~version ~set_input:Wasm_utils.set_full_raw_input_step ~from_binary:true ~metadata ~kernel ~messages ()) + () -let test_compute_step_many_pauses_at_snapshot_when_flag_set () = +let test_compute_step_many_pauses_at_snapshot_when_flag_set ~version () = let open Lwt_result_syntax in let reveal_builtins = Tezos_scoru_wasm.Builtins. @@ -761,6 +788,7 @@ let test_compute_step_many_pauses_at_snapshot_when_flag_set () = in let*! initial_tree = Wasm_utils.initial_tree + ~version ~ticks_per_snapshot:Wasm_utils.production_max_tick ~from_binary:false kernel_bounded_reboot @@ -818,7 +846,7 @@ let test_compute_step_many_pauses_at_snapshot_when_flag_set () = return () -let test_check_nb_ticks () = +let test_check_nb_ticks ~version () = let open Lwt_result_syntax in let reveal_builtins = Tezos_scoru_wasm.Builtins. @@ -831,6 +859,7 @@ let test_check_nb_ticks () = in let*! initial_tree = Wasm_utils.initial_tree + ~version ~ticks_per_snapshot:Wasm_utils.production_max_tick ~from_binary:false kernel_bounded_reboot @@ -857,19 +886,20 @@ let test_check_nb_ticks () = return () let tests = - [ - tztest "Big addresses are working correctly" `Quick test_big_address; - tztest "Computation kernel" `Quick test_computation; - tztest "Store read/write kernel" `Quick test_store_read_write; - tztest "read_input" `Quick test_read_input; - tztest "reboot" `Quick test_reboot; - tztest "max_steps flag" `Quick test_max_steps; - tztest "too many reboots" `Quick test_too_many_reboots; - tztest "compare nb ticks" `Quick test_check_nb_ticks; - tztest "Reveal_preimage kernel" `Quick test_reveal_preimage; - tztest "TX kernel" `Quick test_tx; - tztest - "compute_step_many pauses at snapshot" - `Quick - test_compute_step_many_pauses_at_snapshot_when_flag_set; - ] + tztests_with_pvm + ~versions:[V0; V1] + [ + ("Big addresses are working correctly", `Quick, test_big_address); + ("Computation kernel", `Quick, test_computation); + ("Store read/write kernel", `Quick, test_store_read_write); + ("read_input", `Quick, test_read_input); + ("reboot", `Quick, test_reboot); + ("max_steps flag", `Quick, test_max_steps); + ("too many reboots", `Quick, test_too_many_reboots); + ("compare nb ticks", `Quick, test_check_nb_ticks); + ("Reveal_preimage kernel", `Quick, test_reveal_preimage); + ("TX kernel", `Quick, test_tx); + ( "compute_step_many pauses at snapshot", + `Quick, + test_compute_step_many_pauses_at_snapshot_when_flag_set ); + ] diff --git a/src/lib_scoru_wasm/helpers/wasm_utils.ml b/src/lib_scoru_wasm/helpers/wasm_utils.ml index 640968a802ed..0ee23dfee8eb 100644 --- a/src/lib_scoru_wasm/helpers/wasm_utils.ml +++ b/src/lib_scoru_wasm/helpers/wasm_utils.ml @@ -54,14 +54,14 @@ let default_outbox_validity_period = 10l let default_outbox_message_limit = Z.of_int32 100l -let initial_tree ?(ticks_per_snapshot = default_max_tick) +let initial_tree ~version ?(ticks_per_snapshot = default_max_tick) ?(max_reboots = Constants.maximum_reboots_per_input) ?(from_binary = false) ?(outbox_validity_period = default_outbox_validity_period) ?(outbox_message_limit = default_outbox_message_limit) code = let open Lwt.Syntax in let max_tick_Z = Z.of_int64 ticks_per_snapshot in let* tree = empty_tree () in - let* tree = Wasm.initial_state V0 tree in + let* tree = Wasm.initial_state version tree in let* boot_sector = if from_binary then Lwt.return code else wat2wasm code in let* tree = Wasm.install_boot_sector diff --git a/src/lib_scoru_wasm/test/helpers/tztest_helper.ml b/src/lib_scoru_wasm/test/helpers/tztest_helper.ml new file mode 100644 index 000000000000..417b187fed05 --- /dev/null +++ b/src/lib_scoru_wasm/test/helpers/tztest_helper.ml @@ -0,0 +1,41 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 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. *) +(* *) +(*****************************************************************************) + +open Tezos_scoru_wasm + +let version_to_string version = + Data_encoding.Binary.to_string_exn Wasm_pvm_state.version_encoding version + +let tztests_with_pvm ~versions l = + let tztest ~version title sort test = + Tztest.tztest + Format.(sprintf "%s (%s)" title (version_to_string version)) + sort + (test ~version) + in + List.concat_map + (fun version -> + List.map (fun (title, sort, k) -> tztest ~version title sort k) l) + versions diff --git a/src/lib_scoru_wasm/test/test_fixed_nb_ticks.ml b/src/lib_scoru_wasm/test/test_fixed_nb_ticks.ml index c355d504e4d3..ad610b2cac2c 100644 --- a/src/lib_scoru_wasm/test/test_fixed_nb_ticks.ml +++ b/src/lib_scoru_wasm/test/test_fixed_nb_ticks.ml @@ -31,8 +31,8 @@ Subject: WASM PVM evaluation tests for fixed nb of ticks per top level call *) -open Tztest open Wasm_utils +open Tztest_helper let loop_module = {| @@ -61,13 +61,13 @@ let snapshot_tick = Z.one let input_tick = Z.one -let test_looping_kernel () = +let test_looping_kernel ~version () = let open Lwt_result_syntax in let max_nb_ticks = 5000L in (* This module loops indefinitely. *) let*! loop_module_tree = - initial_tree ~ticks_per_snapshot:max_nb_ticks loop_module + initial_tree ~version ~ticks_per_snapshot:max_nb_ticks loop_module in let*! loop_module_tree = eval_until_input_requested loop_module_tree in let*! tree_with_dummy_input = set_empty_inbox_step 0l loop_module_tree in @@ -76,13 +76,13 @@ let test_looping_kernel () = | Too_many_ticks -> return_unit | _ -> failwith "second: Unexpected stuck state!" -let test_noop_kernel () = +let test_noop_kernel ~version () = let open Lwt_result_syntax in let max_nb_ticks = 5000L in (* This module does a noop. *) let*! noop_module_tree = - initial_tree ~ticks_per_snapshot:max_nb_ticks noop_module + initial_tree ~version ~ticks_per_snapshot:max_nb_ticks noop_module in (* Eval until snapshot, which shouldn't take any tick since the default state is Snapshot. *) @@ -95,7 +95,7 @@ let test_noop_kernel () = (* Twice as much as max ticks, one to load the inbox, the other to execute. *) return (assert (Z.(info.current_tick = of_int64 Int64.(mul 2L max_nb_ticks)))) -let test_stuck_in_decode_kernel () = +let test_stuck_in_decode_kernel ~version () = let open Lwt_result_syntax in (* The PVM needs at least [4] ticks to load the smallest inbox possible: - 1 for Snapshot --> Collect @@ -106,7 +106,7 @@ let test_stuck_in_decode_kernel () = (* This module does a noop. *) let*! noop_module_tree = - initial_tree ~ticks_per_snapshot:max_nb_ticks noop_module + initial_tree ~version ~ticks_per_snapshot:max_nb_ticks noop_module in let*! noop_module_tree = eval_until_input_requested noop_module_tree in (* Collect an inbox. *) @@ -118,13 +118,13 @@ let test_stuck_in_decode_kernel () = (* Twice as much as max ticks, one to load the inbox, the other to execute. *) return (assert (Z.(info.current_tick = of_int64 Int64.(mul 2L max_nb_ticks)))) -let test_stuck_in_init_kernel () = +let test_stuck_in_init_kernel ~version () = let open Lwt_result_syntax in let max_nb_ticks = 1000L in (* This module does a noop. *) let*! noop_module_tree = - initial_tree ~ticks_per_snapshot:max_nb_ticks noop_module + initial_tree ~version ~ticks_per_snapshot:max_nb_ticks noop_module in let*! noop_module_tree = eval_until_input_requested noop_module_tree in (* Adds one input tick, part of the maximum number of ticks per toplevel @@ -153,9 +153,11 @@ let test_stuck_in_init_kernel () = (assert (info.current_tick = Z.add previous_max_nb_ticks new_max_nb_ticks)) let tests = - [ - tztest "nb of ticks limited" `Quick test_looping_kernel; - tztest "evaluation takes fixed nb of ticks" `Quick test_noop_kernel; - tztest "stuck in decode" `Quick test_stuck_in_decode_kernel; - tztest "stuck in init" `Quick test_stuck_in_init_kernel; - ] + tztests_with_pvm + ~versions:[V0; V1] + [ + ("nb of ticks limited", `Quick, test_looping_kernel); + ("evaluation takes fixed nb of ticks", `Quick, test_noop_kernel); + ("stuck in decode", `Quick, test_stuck_in_decode_kernel); + ("stuck in init", `Quick, test_stuck_in_init_kernel); + ] diff --git a/src/lib_scoru_wasm/test/test_get_set.ml b/src/lib_scoru_wasm/test/test_get_set.ml index fd7b3fcb06d5..fe710913e390 100644 --- a/src/lib_scoru_wasm/test/test_get_set.ml +++ b/src/lib_scoru_wasm/test/test_get_set.ml @@ -31,10 +31,10 @@ Subject: Input tests for the tezos-scoru-wasm library *) -open Tztest open Tezos_webassembly_interpreter open Tezos_scoru_wasm open Wasm_utils +open Tztest_helper (* Use context-binary for testing. *) module Context = Tezos_context_memory.Context_binary @@ -115,9 +115,9 @@ let add_input_info ~inbox_level ~message_counter tree = (** Simple test checking get_info after the initialization. Note that we also check that if the tree has no last_input_read set the response to [get_info] has [None] as [last_input_read] *) -let test_get_info () = +let test_get_info ~version () = let open Lwt_syntax in - let* tree = initialise_tree () in + let* tree = initialise_tree ~version () in let expected_info ~inbox_level ~message_counter = let open Wasm_pvm_state in let last_input_read = @@ -154,9 +154,9 @@ let encode_tick_state tree = (** Tests that, after set_input the resulting tree decodes to the correct values. In particular it does check that [get_info] produces the expected value. *) -let test_set_input () = +let test_set_input ~version () = let open Lwt_syntax in - let* tree = initialise_tree () in + let* tree = initialise_tree ~version () in let* tree = encode_tick_state tree in let* tree = Wasm.set_input_step @@ -190,9 +190,9 @@ let test_set_input () = (** Given a [config] whose output has a given payload at position (0,0), if we encode [config] into a tree [get_output output_info tree] produces the same payload. Here the output_info is { outbox_level = 0; message_index = 0 } *) -let test_get_output () = +let test_get_output ~version () = let open Lwt_syntax in - let* tree = initialise_tree () in + let* tree = initialise_tree ~version () in let* tree = add_input_info tree ~inbox_level:5 ~message_counter:10 in let output = Tezos_webassembly_interpreter.Eval.default_output_buffer () in let* Output_buffer.{outbox_level; message_index} = @@ -212,8 +212,10 @@ let test_get_output () = Lwt_result_syntax.return_unit let tests = - [ - tztest "Get info" `Quick test_get_info; - tztest "Set input" `Quick test_set_input; - tztest "Get output" `Quick test_get_output; - ] + tztests_with_pvm + ~versions:[V0; V1] + [ + ("Get info", `Quick, test_get_info); + ("Set input", `Quick, test_set_input); + ("Get output", `Quick, test_get_output); + ] diff --git a/src/lib_scoru_wasm/test/test_hash_consistency.ml b/src/lib_scoru_wasm/test/test_hash_consistency.ml index eaff1eb2e171..30e64894700b 100644 --- a/src/lib_scoru_wasm/test/test_hash_consistency.ml +++ b/src/lib_scoru_wasm/test/test_hash_consistency.ml @@ -23,8 +23,8 @@ (* *) (*****************************************************************************) -open Tztest open Wasm_utils +open Tztest_helper module Context = Tezos_context_memory.Context_binary (* Test that one N-ticks executions(^1) and N one-tick executions(^2) @@ -32,13 +32,17 @@ module Context = Tezos_context_memory.Context_binary (^1): Executing in one decoding-encoding loop N ticks. (^2): Executing one decoding-encoding loop per ticks. *) -let test_execution_correspondance skip count () = +let test_execution_correspondance ~version skip count () = test_with_kernel Kernels.unreachable_kernel (fun kernel -> let open Lwt_result_syntax in let*! tree = - initial_tree ~from_binary:true ~ticks_per_snapshot:40_000L kernel + initial_tree + ~version + ~from_binary:true + ~ticks_per_snapshot:40_000L + kernel in let*! tree_snapshotted = eval_until_input_requested tree in let*! tree_with_dummy_input = set_empty_inbox_step 0l tree_snapshotted in @@ -59,23 +63,21 @@ let test_execution_correspondance skip count () = () let tests = - [ - tztest - "Executions correspondence (ticks 0 to 1,000)" - `Quick - (* Parsing is way slower, so we limit ourselves to 1,000 ticks. *) - (test_execution_correspondance 0L 1_000L); - tztest - "Executions correspondence (ticks 10,000 to 11,000)" - `Quick - (* Parsing is way slower, so we limit ourselves to 1,000 ticks. *) - (test_execution_correspondance 10_000L 1_000L); - tztest - "Executions correspondence (ticks 20,000 to 25,000)" - `Quick - (test_execution_correspondance 20_000L 5_000L); - tztest - "Executions correspondence (ticks 30,000 to 35,000)" - `Quick - (test_execution_correspondance 30_000L 5_000L); - ] + tztests_with_pvm + ~versions:[V0; V1] + [ + ( "Executions correspondence (ticks 0 to 1,000)", + `Quick, + (* Parsing is way slower, so we limit ourselves to 1,000 ticks. *) + test_execution_correspondance 0L 1_000L ); + ( "Executions correspondence (ticks 10,000 to 11,000)", + `Quick, + (* Parsing is way slower, so we limit ourselves to 1,000 ticks. *) + test_execution_correspondance 10_000L 1_000L ); + ( "Executions correspondence (ticks 20,000 to 25,000)", + `Quick, + test_execution_correspondance 20_000L 5_000L ); + ( "Executions correspondence (ticks 30,000 to 35,000)", + `Quick, + test_execution_correspondance 30_000L 5_000L ); + ] diff --git a/src/lib_scoru_wasm/test/test_host_functions_ticks.ml b/src/lib_scoru_wasm/test/test_host_functions_ticks.ml index 0c8fbb12dda9..ff718234788b 100644 --- a/src/lib_scoru_wasm/test/test_host_functions_ticks.ml +++ b/src/lib_scoru_wasm/test/test_host_functions_ticks.ml @@ -32,9 +32,9 @@ tezos-scoru-wasm library *) -open Tztest open Tezos_scoru_wasm open Wasm_utils +open Tztest_helper (* This function return a function to modifiy `write_debug` in the registry, and a function to revert the change. Due to how the registry works right now (a @@ -69,7 +69,7 @@ let register_new_write_debug added_ticks = in (register alternative_write_debug, register current_write_debug) -let test_tickified_host_function () = +let test_tickified_host_function ~version () = let open Lwt_syntax in let run_until_result () = let module_ = @@ -94,7 +94,7 @@ let test_tickified_host_function () = ) |} in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in (* Feeding it with one input *) let* tree = set_empty_inbox_step 0l tree in (* running until waiting for input *) @@ -110,4 +110,6 @@ let test_tickified_host_function () = return_ok_unit let tests = - [tztest "Test tickified host function" `Quick test_tickified_host_function] + tztests_with_pvm + ~versions:[V0; V1] + [("Test tickified host function", `Quick, test_tickified_host_function)] diff --git a/src/lib_scoru_wasm/test/test_init.ml b/src/lib_scoru_wasm/test/test_init.ml index cf3c4593be42..400935618ad4 100644 --- a/src/lib_scoru_wasm/test/test_init.ml +++ b/src/lib_scoru_wasm/test/test_init.ml @@ -23,16 +23,18 @@ (* *) (*****************************************************************************) -open Tztest open Tezos_scoru_wasm open Wasm_utils +open Tztest_helper -let test_memory0_export () = +let test_memory0_export ~version () = let open Lwt_result_syntax in (* This module does not export its memory therefore it should fail. *) - let*! bad_module_tree = initial_tree {| + let*! bad_module_tree = + initial_tree ~version {| (module (memory 1)) - |} in + |} + in let*! bad_module_tree = eval_until_input_requested bad_module_tree in let*! bad_module_tree = set_empty_inbox_step 0l bad_module_tree in let* stuck, _ = eval_until_stuck bad_module_tree in @@ -46,6 +48,7 @@ let test_memory0_export () = trap which is treated below. *) let*! good_module_tree = initial_tree + ~version {| (module (memory 1) @@ -62,7 +65,7 @@ let test_memory0_export () = let*! stuck_flag = has_stuck_flag tree in return (assert stuck_flag) -let test_module_name_size () = +let test_module_name_size ~version () = let open Lwt_result_syntax in let build_module size = let b = Buffer.create size in @@ -86,7 +89,7 @@ let test_module_name_size () = )|} (build size) in - let*! bad_module_tree = initial_tree (build_module 513) in + let*! bad_module_tree = initial_tree ~version (build_module 513) in let*! bad_module_tree = eval_until_input_requested bad_module_tree in let*! bad_module_tree = set_empty_inbox_step 0l bad_module_tree in let* stuck, _ = eval_until_stuck bad_module_tree in @@ -95,14 +98,14 @@ let test_module_name_size () = ~expected_kind:`No_fallback_decode ~expected_reason:"Names cannot exceed 512 bytes" stuck) ; - let*! good_module_tree = initial_tree (build_module 512) in + let*! good_module_tree = initial_tree ~version (build_module 512) in let*! good_module_tree = eval_until_input_requested good_module_tree in let*! good_module_tree = set_empty_inbox_step 0l good_module_tree in let*! tree = eval_until_input_requested good_module_tree in let*! stuck_flag = has_stuck_flag tree in return (assert stuck_flag) -let test_imports () = +let test_imports ~version () = let open Lwt_result_syntax in let build_module module_name item_name = Format.sprintf @@ -124,7 +127,7 @@ let test_imports () = let bad_module_name = "external_module" in let bad_item_name = "f" in let*! bad_module_tree = - initial_tree (build_module bad_module_name bad_item_name) + initial_tree ~version (build_module bad_module_name bad_item_name) in let*! bad_module_tree = eval_until_input_requested bad_module_tree in let*! bad_module_tree = set_empty_inbox_step 0l bad_module_tree in @@ -147,7 +150,7 @@ let test_imports () = in let good_module_name = "smart_rollup_core" in let*! bad_host_func_tree = - initial_tree (build_module good_module_name bad_item_name) + initial_tree ~version (build_module good_module_name bad_item_name) in let*! bad_host_func_tree = eval_until_input_requested bad_host_func_tree in let*! bad_host_func_tree = set_empty_inbox_step 0l bad_host_func_tree in @@ -170,7 +173,7 @@ let test_imports () = in let good_item_name = "read_input" in let*! good_module_tree = - initial_tree (build_module good_module_name good_item_name) + initial_tree ~version (build_module good_module_name good_item_name) in let*! good_module_tree = eval_until_input_requested good_module_tree in let*! good_module_tree = set_empty_inbox_step 0l good_module_tree in @@ -178,10 +181,11 @@ let test_imports () = let*! stuck_flag = has_stuck_flag tree in return (assert stuck_flag) -let test_host_func_start_restriction () = +let test_host_func_start_restriction ~version () = let open Lwt_result_syntax in let*! state = initial_tree + ~version {| (module (import "smart_rollup_core" "write_output" @@ -209,7 +213,7 @@ let test_host_func_start_restriction () = "host functions must not access memory during initialisation" stuck) -let test_bad_entrypoint_name () = +let test_bad_entrypoint_name ~version () = let open Lwt_result_syntax in let module_ = {| @@ -222,7 +226,7 @@ let test_bad_entrypoint_name () = )|} in - let*! bad_module_tree = initial_tree module_ in + let*! bad_module_tree = initial_tree ~version module_ in let*! bad_module_tree = eval_until_input_requested bad_module_tree in let*! bad_module_tree = set_empty_inbox_step 0l bad_module_tree in let* stuck, _ = eval_until_stuck bad_module_tree in @@ -237,7 +241,7 @@ let test_bad_entrypoint_name () = return_unit (* `kernel_run` will be found, but this is not a function. *) -let test_bad_export () = +let test_bad_export ~version () = let open Lwt_result_syntax in let module_ = {| @@ -250,7 +254,7 @@ let test_bad_export () = )|} in - let*! bad_module_tree = initial_tree module_ in + let*! bad_module_tree = initial_tree ~version module_ in let*! bad_module_tree = eval_until_input_requested bad_module_tree in let*! bad_module_tree = set_empty_inbox_step 0l bad_module_tree in let* stuck, _ = eval_until_stuck bad_module_tree in @@ -265,10 +269,11 @@ let test_bad_export () = stuck) ; return_unit -let test_float32_type () = +let test_float32_type ~version () = let open Lwt_result_syntax in let*! state = initial_tree + ~version {| (module (memory 1) @@ -290,10 +295,11 @@ let test_float32_type () = ~expected_reason:"float instructions are forbidden" stuck) -let test_float64_type () = +let test_float64_type ~version () = let open Lwt_result_syntax in let*! state = initial_tree + ~version {| (module (memory 1) @@ -315,10 +321,11 @@ let test_float64_type () = ~expected_reason:"float instructions are forbidden" stuck) -let test_float_value () = +let test_float_value ~version () = let open Lwt_result_syntax in let*! state = initial_tree + ~version {| (module (memory 1) @@ -342,20 +349,18 @@ let test_float_value () = stuck) let tests = - [ - tztest "init requires memory 0 export" `Quick test_memory0_export; - tztest "names are limited to 512 bytes" `Quick test_module_name_size; - tztest "imports only PVM host functions" `Quick test_imports; - tztest - "host functions are restricted in start" - `Quick - test_host_func_start_restriction; - tztest "Check not found `kernel_run` error" `Quick test_bad_entrypoint_name; - tztest - "Check `kernel_run` not being a function error" - `Quick - test_bad_export; - tztest "32 bits float types are forbidden" `Quick test_float32_type; - tztest "64 bits float types are forbidden" `Quick test_float64_type; - tztest "float values are forbidden" `Quick test_float_value; - ] + tztests_with_pvm + ~versions:[V0; V1] + [ + ("init requires memory 0 export", `Quick, test_memory0_export); + ("names are limited to 512 bytes", `Quick, test_module_name_size); + ("imports only PVM host functions", `Quick, test_imports); + ( "host functions are restricted in start", + `Quick, + test_host_func_start_restriction ); + ("Check not found `kernel_run` error", `Quick, test_bad_entrypoint_name); + ("Check `kernel_run` not being a function error", `Quick, test_bad_export); + ("32 bits float types are forbidden", `Quick, test_float32_type); + ("64 bits float types are forbidden", `Quick, test_float64_type); + ("float values are forbidden", `Quick, test_float_value); + ] diff --git a/src/lib_scoru_wasm/test/test_reveal.ml b/src/lib_scoru_wasm/test/test_reveal.ml index e5619c31973c..2b1959888f48 100644 --- a/src/lib_scoru_wasm/test/test_reveal.ml +++ b/src/lib_scoru_wasm/test/test_reveal.ml @@ -31,10 +31,10 @@ Subject: Reveal tests for the tezos-scoru-wasm library *) -open Tztest open Tezos_webassembly_interpreter open Tezos_scoru_wasm open Wasm_utils +open Tztest_helper let reveal_preimage_module hash_addr hash_size preimage_addr max_bytes = Format.sprintf @@ -93,7 +93,7 @@ let reveal_returned_size tree = | _ -> Stdlib.failwith "Incorrect stack") | _ -> Stdlib.failwith "The tick after reveal_builtins is not consistent" -let test_reveal_preimage_gen preimage max_bytes = +let test_reveal_preimage_gen ~version preimage max_bytes = let open Lwt_result_syntax in let hash_addr = 120l in let preimage_addr = 200l in @@ -101,7 +101,7 @@ let test_reveal_preimage_gen preimage max_bytes = let modl = reveal_preimage_module hash_addr hash_size preimage_addr max_bytes in - let*! state = initial_tree modl in + let*! state = initial_tree ~version modl in let*! state_snapshotted = eval_until_input_or_reveal_requested state in let*! state_with_dummy_input = set_empty_inbox_step 0l state_snapshotted in (* Let’s go *) @@ -148,29 +148,29 @@ let test_reveal_preimage_gen preimage max_bytes = (* Test the best conditions for the preimage reveal: its size is below the maximum bytes for the preimage, it will be . *) -let test_reveal_preimage_classic () = +let test_reveal_preimage_classic ~version () = let preimage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse \ elementum nec ex sed porttitor." (* 100 bytes *) in let max_bytes = 200l in - test_reveal_preimage_gen preimage max_bytes + test_reveal_preimage_gen ~version preimage max_bytes -let test_reveal_preimage_above_max () = +let test_reveal_preimage_above_max ~version () = let preimage = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse \ elementum nec ex sed porttitor." (* 100 bytes *) in let max_bytes = 50l in - test_reveal_preimage_gen preimage max_bytes + test_reveal_preimage_gen ~version preimage max_bytes -let test_reveal_metadata () = +let test_reveal_metadata ~version () = let open Lwt_result_syntax in let metadata_addr = 200l in let modl = reveal_metadata_module metadata_addr in - let*! state = initial_tree modl in + let*! state = initial_tree ~version modl in let*! state_snapshotted = eval_until_input_or_reveal_requested state in let*! state_with_dummy_input = set_empty_inbox_step 0l state_snapshotted in (* Let’s go *) @@ -247,7 +247,7 @@ let apply_fast ?(images = Preimage_map.empty) tree = Stdlib.failwith "Fast Execution was expected to run!" ; tree -let test_fast_exec_reveal () = +let test_fast_exec_reveal ~version () = let open Lwt.Syntax in let example_hash = "this represents the 33-byte hash!" in let example_preimage = "This is the expected preimage" in @@ -303,7 +303,7 @@ let test_fast_exec_reveal () = example_hash in - let* tree = initial_tree kernel in + let* tree = initial_tree ~version kernel in let* tree = eval_until_input_or_reveal_requested tree in let* tree = set_empty_inbox_step 0l tree in let* tree = apply_fast ~images tree in @@ -322,15 +322,15 @@ let test_fast_exec_reveal () = Lwt_result_syntax.return_unit let tests = - [ - tztest - "Test reveal_preimage with preimage length below max_bytes" - `Quick - test_reveal_preimage_classic; - tztest - "Test reveal_preimage with preimage length above max_bytes" - `Quick - test_reveal_preimage_above_max; - tztest "Test reveal_metadata" `Quick test_reveal_metadata; - tztest "Test reveal_preimage with Fast Exec" `Quick test_fast_exec_reveal; - ] + tztests_with_pvm + ~versions:[V0; V1] + [ + ( "Test reveal_preimage with preimage length below max_bytes", + `Quick, + test_reveal_preimage_classic ); + ( "Test reveal_preimage with preimage length above max_bytes", + `Quick, + test_reveal_preimage_above_max ); + ("Test reveal_metadata", `Quick, test_reveal_metadata); + ("Test reveal_preimage with Fast Exec", `Quick, test_fast_exec_reveal); + ] diff --git a/src/lib_scoru_wasm/test/test_wasm_pvm.ml b/src/lib_scoru_wasm/test/test_wasm_pvm.ml index 23a21c23d77b..7e57453d3895 100644 --- a/src/lib_scoru_wasm/test/test_wasm_pvm.ml +++ b/src/lib_scoru_wasm/test/test_wasm_pvm.ml @@ -32,12 +32,12 @@ Subject: WASM PVM evaluation tests for the tezos-scoru-wasm library *) -open Tztest open Tezos_scoru_wasm open Wasm_utils +open Tztest_helper open Encodings_util -let should_boot_unreachable_kernel ~batch_size kernel = +let should_boot_unreachable_kernel ~version ~batch_size kernel = let open Lwt_syntax in (* we call recursively the eval function on given increment *) let rec loop_until_input_required batch_size tree = @@ -50,7 +50,7 @@ let should_boot_unreachable_kernel ~batch_size kernel = loop_until_input_required batch_size tree | _ -> return tree in - let* tree = initial_tree ~from_binary:true kernel in + let* tree = initial_tree ~version ~from_binary:true kernel in (* Feeding it with one input *) let* tree = set_empty_inbox_step 0l tree in (* running until waiting for input *) @@ -77,7 +77,7 @@ let should_boot_unreachable_kernel ~batch_size kernel = assert stuck_flag ; return_ok_unit -let should_run_debug_kernel () = +let should_run_debug_kernel ~version () = let open Lwt_syntax in let module_ = {| @@ -101,7 +101,7 @@ let should_run_debug_kernel () = ) |} in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in (* Feeding it with one input *) let* tree = set_empty_inbox_step 0l tree in (* running until waiting for input *) @@ -120,7 +120,7 @@ let add_value ?(content = "a very long value") tree key_steps = value tree -let should_run_store_has_kernel () = +let should_run_store_has_kernel ~version () = let open Lwt_syntax in let module_ = {| @@ -172,7 +172,7 @@ let should_run_store_has_kernel () = ) |} in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in let* tree = add_value tree ["hi"; "bye"] in let* tree = add_value tree ["hello"] in let* tree = add_value tree ["hello"; "universe"] in @@ -201,7 +201,7 @@ let should_run_store_has_kernel () = (* The `should_run_store_list_size_kernel` asserts whether the tree has three subtrees. Note that the `_` subtree is included and so, after adding the `four` subtree the state will receive the stuck tag.*) -let should_run_store_list_size_kernel () = +let should_run_store_list_size_kernel ~version () = let open Lwt_syntax in let module_ = {| @@ -228,7 +228,7 @@ let should_run_store_list_size_kernel () = ) |} in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in let* tree = add_value tree ["one"] in let* tree = add_value tree ["one"; "two"] in let* tree = add_value tree ["one"; "three"] in @@ -251,7 +251,7 @@ let should_run_store_list_size_kernel () = assert stuck_flag ; return_ok_unit -let should_run_store_delete_kernel () = +let should_run_store_delete_kernel ~version () = let module_ = {| (module @@ -286,7 +286,7 @@ let should_run_store_delete_kernel () = |} in let open Lwt_syntax in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in let* tree = add_value tree ["one"] in let* tree = add_value tree ["one"; "two"] in let* tree = add_value tree ["three"] in @@ -325,7 +325,7 @@ let assert_store_value tree path expected_value = assert (Option.equal String.equal value expected_value) (* store_move *) -let should_run_store_move_kernel () = +let should_run_store_move_kernel ~version () = let open Lwt_syntax in let from_path = "/a/b" in let from_path_location = 100 in @@ -359,7 +359,7 @@ let should_run_store_move_kernel () = from_path to_path in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in let* tree = add_value tree ["a"; "b"] ~content:"ab" in let* tree = add_value tree ["a"; "b"; "c"] ~content:"abc" in let* tree = add_value tree ["a"; "b"; "d"] ~content:"abd" in @@ -386,7 +386,7 @@ let should_run_store_move_kernel () = return_ok_unit (* store_copy *) -let should_run_store_copy_kernel () = +let should_run_store_copy_kernel ~version () = let open Lwt_syntax in let from_path = "/a/b" in let from_path_location = 100 in @@ -420,7 +420,7 @@ let should_run_store_copy_kernel () = from_path to_path in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in let* tree = add_value tree ["a"; "b"] ~content:"ab" in let* tree = add_value tree ["a"; "b"; "c"] ~content:"abc" in let* tree = add_value tree ["a"; "b"; "d"] ~content:"abd" in @@ -446,7 +446,7 @@ let should_run_store_copy_kernel () = let* () = assert_store_value tree "/a/b" (Some "ab") in return_ok_unit -let test_modify_read_only_storage_kernel () = +let test_modify_read_only_storage_kernel ~version () = let open Lwt_syntax in let module_ = {| @@ -513,7 +513,7 @@ let test_modify_read_only_storage_kernel () = ) |} in - let* tree = initial_tree ~from_binary:false module_ in + let* tree = initial_tree ~version ~from_binary:false module_ in (* The kernel is not expected to fail, the PVM should not have stuck state on. *) let* state = Wasm.Internal_for_tests.get_tick_state tree in @@ -654,7 +654,7 @@ let build_snapshot_wasm_state_from_set_input durable tree -let test_snapshotable_state () = +let test_snapshotable_state ~version () = let open Lwt_result_syntax in let module_ = {| @@ -667,7 +667,7 @@ let test_snapshotable_state () = ) |} in - let*! tree = initial_tree ~from_binary:false module_ in + let*! tree = initial_tree ~version ~from_binary:false module_ in let*! state = Wasm.Internal_for_tests.get_tick_state tree in let* () = match state with @@ -696,7 +696,7 @@ let test_snapshotable_state () = Wasm_utils.pp_state state -let test_rebuild_snapshotable_state () = +let test_rebuild_snapshotable_state ~version () = let open Lwt_result_syntax in let module_ = {| @@ -709,7 +709,7 @@ let test_rebuild_snapshotable_state () = ) |} in - let*! tree = initial_tree ~from_binary:false module_ in + let*! tree = initial_tree ~version ~from_binary:false module_ in let*! tree = set_empty_inbox_step 0l tree in (* First evaluate until the snapshotable state. *) let*! tree_after_eval = eval_to_snapshot tree in @@ -755,7 +755,7 @@ let test_rebuild_snapshotable_state () = Context_hash.equal hash_input_tree_after_eval hash_input_rebuilded_tree) ; return_unit -let test_unkown_host_function_truncated () = +let test_unkown_host_function_truncated ~version () = let open Lwt_result_syntax in let smart_rollup_core = "smart_rollup_core" in let unknown_function = String.make 100 'a' in @@ -779,7 +779,7 @@ let test_unkown_host_function_truncated () = unknown_function in (* Let's first init the tree to compute. *) - let*! tree = initial_tree ~from_binary:false module_ in + let*! tree = initial_tree ~version ~from_binary:false module_ in (* The tree should be in snapshot state by default, hence in input step. *) let*! tree_with_dummy_input = set_empty_inbox_step 0l tree in let*! tree_stuck = @@ -800,7 +800,7 @@ let test_unkown_host_function_truncated () = assert (is_stuck ~step:`No_fallback_link ~reason state) ; return_unit -let test_bulk_noops () = +let test_bulk_noops ~version () = let open Lwt.Syntax in let module_ = {| @@ -813,7 +813,7 @@ let test_bulk_noops () = ) |} in - let* base_tree = initial_tree ~ticks_per_snapshot:500L module_ in + let* base_tree = initial_tree ~version ~ticks_per_snapshot:500L module_ in let* base_tree = set_empty_inbox_step 0l base_tree in let rec goto_snapshot ticks tree_slow = @@ -835,7 +835,7 @@ let test_bulk_noops () = Lwt_result_syntax.return_unit -let test_durable_store_io () = +let test_durable_store_io ~version () = let open Lwt_result_syntax in let from_path = "/from/value" in let from_path_location = 100 in @@ -890,7 +890,7 @@ let test_durable_store_io () = to_path in (* Let's first init the tree to compute. *) - let*! tree = initial_tree ~from_binary:false modul in + let*! tree = initial_tree ~version ~from_binary:false modul in (* Add content to '/from/value' key in durable *) let content = "abcde" in @@ -1000,11 +1000,11 @@ let assert_kernel tree expected_kernel = in assert (Option.equal String.equal value expected_kernel) -let test_reveal_upgrade_kernel_ok () = +let test_reveal_upgrade_kernel_ok ~version () = let open Lwt_result_syntax in let*! modul = wat2wasm @@ reveal_upgrade_kernel () in (* Let's first init the tree to compute. *) - let*! tree = initial_tree ~from_binary:true modul in + let*! tree = initial_tree ~version ~from_binary:true modul in let*! state_before_first_message = Wasm.Internal_for_tests.get_tick_state tree in @@ -1074,11 +1074,12 @@ let test_reveal_upgrade_kernel_ok () = let*! () = assert_fallback_kernel tree @@ Some preimage in return_unit -let test_reveal_upgrade_kernel_fallsback_on_error ~binary invalid_kernel () = +let test_reveal_upgrade_kernel_fallsback_on_error ~version ~binary + invalid_kernel () = let open Lwt_result_syntax in let*! modul = wat2wasm @@ reveal_upgrade_kernel () in (* Let's first init the tree to compute. *) - let*! tree = initial_tree ~from_binary:true modul in + let*! tree = initial_tree ~version ~from_binary:true modul in let*! tree = eval_until_input_or_reveal_requested tree in let*! state_before_first_message = Wasm.Internal_for_tests.get_tick_state tree @@ -1154,7 +1155,7 @@ let test_reveal_upgrade_kernel_fallsback_on_error ~binary invalid_kernel () = assert (not has_upgrade_error) ; return_unit -let test_pvm_reboot_counter ~pvm_max_reboots () = +let test_pvm_reboot_counter ~version ~pvm_max_reboots () = let open Lwt_result_syntax in let reboot_kernel = {| @@ -1204,6 +1205,7 @@ let test_pvm_reboot_counter ~pvm_max_reboots () = let*! tree = initial_tree + ~version ~max_reboots:(Z.of_int32 pvm_max_reboots) ~from_binary:false reboot_kernel @@ -1212,7 +1214,8 @@ let test_pvm_reboot_counter ~pvm_max_reboots () = check_counter tree 0l -let test_kernel_reboot_gen ~reboots ~expected_reboots ~pvm_max_reboots = +let test_kernel_reboot_gen ~version ~reboots ~expected_reboots ~pvm_max_reboots + = let open Lwt_result_syntax in (* Extracted from the kernel, these are the constant values used to build the initial memory and the addresses where values are stored. *) @@ -1362,6 +1365,7 @@ let test_kernel_reboot_gen ~reboots ~expected_reboots ~pvm_max_reboots = (* Let's first init the tree to compute. *) let*! tree = initial_tree + ~version ~max_reboots:(Z.of_int32 pvm_max_reboots) ~from_binary:false reboot_module @@ -1396,14 +1400,22 @@ let test_kernel_reboot_gen ~reboots ~expected_reboots ~pvm_max_reboots = assert (value = expected_reboots) ; return_unit -let test_kernel_reboot () = +let test_kernel_reboot ~version () = (* The kernel doesn't accept more than 10 reboots between two inputs, this test will succeed. *) - test_kernel_reboot_gen ~reboots:5l ~expected_reboots:5l ~pvm_max_reboots:10l + test_kernel_reboot_gen + ~version + ~reboots:5l + ~expected_reboots:5l + ~pvm_max_reboots:10l -let test_kernel_reboot_failing () = +let test_kernel_reboot_failing ~version () = (* The kernel doesn't accept more than 10 reboots between two inputs, it will then fail after 10. *) - test_kernel_reboot_gen ~reboots:15l ~expected_reboots:10l ~pvm_max_reboots:10l + test_kernel_reboot_gen + ~version + ~reboots:15l + ~expected_reboots:10l + ~pvm_max_reboots:10l (* Set a certain number `n` of dummy inputs and check the scheduling is consistent: @@ -1455,7 +1467,7 @@ let test_set_inputs number_of_inputs level tree = assert (state = Padding) ; tree -let test_inbox_cleanup () = +let test_inbox_cleanup ~version () = let open Lwt_syntax in let check_messages_count tree count = let+ buffer = Wasm.Internal_for_tests.get_input_buffer tree in @@ -1477,7 +1489,11 @@ let test_inbox_cleanup () = in let max_tick = 1000L in let* tree = - initial_tree ~ticks_per_snapshot:max_tick ~from_binary:false module_ + initial_tree + ~version + ~ticks_per_snapshot:max_tick + ~from_binary:false + module_ in let* tree = set_empty_inbox_step 0l tree in (* Before executing: EOL, Info_per_level and SOL. *) @@ -1493,7 +1509,7 @@ let test_inbox_cleanup () = let* () = check_messages_count tree 0 in Lwt_result_syntax.return_unit -let test_scheduling_multiple_inboxes input_numbers = +let test_scheduling_multiple_inboxes ~version input_numbers = let open Lwt_result_syntax in let module_ = {| @@ -1506,7 +1522,7 @@ let test_scheduling_multiple_inboxes input_numbers = ) |} in - let*! initial_tree = initial_tree ~from_binary:false module_ in + let*! initial_tree = initial_tree ~version ~from_binary:false module_ in let+ (_ : Wasm.tree) = List.fold_left_i_es (fun level tree input_number -> @@ -1532,10 +1548,11 @@ let test_scheduling_multiple_inboxes input_numbers = in () -let test_scheduling_one_inbox () = test_scheduling_multiple_inboxes [10] +let test_scheduling_one_inbox ~version () = + test_scheduling_multiple_inboxes ~version [10] -let test_scheduling_five_inboxes () = - test_scheduling_multiple_inboxes [10; 5; 15; 8; 2] +let test_scheduling_five_inboxes ~version () = + test_scheduling_multiple_inboxes ~version [10; 5; 15; 8; 2] (* Module only outputting one message. *) let output_only_module message = @@ -1577,7 +1594,7 @@ let eval_and_test_outboxes_gen test_outbox max_level tree = in go 0l tree -let test_outboxes_at_each_level () = +let test_outboxes_at_each_level ~version () = let open Lwt_syntax in let open Tezos_webassembly_interpreter.Output_buffer in let output_message = "output_message" in @@ -1592,6 +1609,7 @@ let test_outboxes_at_each_level () = let* tree = initial_tree + ~version ~ticks_per_snapshot:1000L (* This kernel takes about 838 ticks to run. *) ~from_binary:false (output_only_module output_message) @@ -1599,7 +1617,7 @@ let test_outboxes_at_each_level () = let* () = eval_and_test_outboxes_gen check_outboxes 5l tree in return_ok_unit -let test_outbox_validity_period () = +let test_outbox_validity_period ~version () = let open Lwt_syntax in let open Tezos_webassembly_interpreter.Output_buffer in let output_message = "output_message" in @@ -1640,6 +1658,7 @@ let test_outbox_validity_period () = let* tree = initial_tree + ~version ~ticks_per_snapshot:1000L (* This kernel takes about 838 ticks to run. *) ~from_binary:false ~outbox_validity_period @@ -1649,94 +1668,83 @@ let test_outbox_validity_period () = return_ok_unit let tests = - [ - tztest - "Test unreachable kernel (tick per tick)" - `Quick - (test_with_kernel - Kernels.unreachable_kernel - (should_boot_unreachable_kernel ~batch_size:1L)); - tztest - "Test unreachable kernel (10 ticks at a time)" - `Quick - (test_with_kernel - Kernels.unreachable_kernel - (should_boot_unreachable_kernel ~batch_size:10L)); - tztest - "Test unreachable kernel (in one go)" - `Quick - (test_with_kernel - Kernels.unreachable_kernel - (should_boot_unreachable_kernel ~batch_size:Int64.max_int)); - tztest "Test write_debug kernel" `Quick should_run_debug_kernel; - tztest "Test store-has kernel" `Quick should_run_store_has_kernel; - tztest - "Test store-list-size kernel" - `Quick - should_run_store_list_size_kernel; - tztest "Test store-delete kernel" `Quick should_run_store_delete_kernel; - tztest "Test store-move kernel" `Quick should_run_store_move_kernel; - tztest "Test store-copy kernel" `Quick should_run_store_copy_kernel; - tztest - "Test modifying read-only storage fails" - `Quick - test_modify_read_only_storage_kernel; - tztest "Test snapshotable state" `Quick test_snapshotable_state; - tztest - "Test rebuild snapshotable state" - `Quick - test_rebuild_snapshotable_state; - tztest - "Test Stuck state is truncated on long messages" - `Quick - test_unkown_host_function_truncated; - tztest "Test bulk no-ops function properly" `Quick test_bulk_noops; - tztest "Test durable store io" `Quick test_durable_store_io; - tztest "Test /readonly/kernel/env/reboot_counter" `Quick - @@ test_pvm_reboot_counter ~pvm_max_reboots:10l; - tztest "Test reboot" `Quick test_kernel_reboot; - tztest - "Test reboot takes too many reboots" - `Quick - test_kernel_reboot_failing; - tztest "Test kernel upgrade ok" `Quick test_reveal_upgrade_kernel_ok; - tztest - "Test kernel upgrade fallsback on decoding error" - `Quick - (test_reveal_upgrade_kernel_fallsback_on_error - ~binary:true - "INVALID WASM!!!"); - tztest - "Test kernel upgrade fallsback on linking error" - `Quick - (test_reveal_upgrade_kernel_fallsback_on_error - ~binary:false - {| + tztests_with_pvm + ~versions:[V0; V1] + [ + ( "Test unreachable kernel (tick per tick)", + `Quick, + fun ~version -> + test_with_kernel + Kernels.unreachable_kernel + (should_boot_unreachable_kernel ~version ~batch_size:1L) ); + ( "Test unreachable kernel (10 ticks at a time)", + `Quick, + fun ~version -> + test_with_kernel + Kernels.unreachable_kernel + (should_boot_unreachable_kernel ~version ~batch_size:10L) ); + ( "Test unreachable kernel (in one go)", + `Quick, + fun ~version -> + test_with_kernel + Kernels.unreachable_kernel + (should_boot_unreachable_kernel ~version ~batch_size:Int64.max_int) + ); + ("Test write_debug kernel", `Quick, should_run_debug_kernel); + ("Test store-has kernel", `Quick, should_run_store_has_kernel); + ("Test store-list-size kernel", `Quick, should_run_store_list_size_kernel); + ("Test store-delete kernel", `Quick, should_run_store_delete_kernel); + ("Test store-move kernel", `Quick, should_run_store_move_kernel); + ("Test store-copy kernel", `Quick, should_run_store_copy_kernel); + ( "Test modifying read-only storage fails", + `Quick, + test_modify_read_only_storage_kernel ); + ("Test snapshotable state", `Quick, test_snapshotable_state); + ( "Test rebuild snapshotable state", + `Quick, + test_rebuild_snapshotable_state ); + ( "Test Stuck state is truncated on long messages", + `Quick, + test_unkown_host_function_truncated ); + ("Test bulk no-ops function properly", `Quick, test_bulk_noops); + ("Test durable store io", `Quick, test_durable_store_io); + ( "Test /readonly/kernel/env/reboot_counter", + `Quick, + test_pvm_reboot_counter ~pvm_max_reboots:10l ); + ("Test reboot", `Quick, test_kernel_reboot); + ("Test reboot takes too many reboots", `Quick, test_kernel_reboot_failing); + ("Test kernel upgrade ok", `Quick, test_reveal_upgrade_kernel_ok); + ( "Test kernel upgrade fallsback on decoding error", + `Quick, + test_reveal_upgrade_kernel_fallsback_on_error + ~binary:true + "INVALID WASM!!!" ); + ( "Test kernel upgrade fallsback on linking error", + `Quick, + test_reveal_upgrade_kernel_fallsback_on_error + ~binary:false + {| (module (import "invalid_module" "write_debug" (func $write_debug (param i32 i32)))) -|}); - tztest - "Test kernel upgrade fallsback on initing error" - `Quick - (test_reveal_upgrade_kernel_fallsback_on_error - ~binary:false - "(module (memory 1))"); - tztest - "Test scheduling with 10 inputs in a unique inbox" - `Quick - test_scheduling_one_inbox; - tztest - "Test scheduling with 5 inboxes with a different input number" - `Quick - test_scheduling_five_inboxes; - tztest "Test inbox clean-up" `Quick test_inbox_cleanup; - tztest - "Test outboxes are created at each level" - `Quick - test_outboxes_at_each_level; - tztest - "Test outbox validity period clean-up" - `Quick - test_outbox_validity_period; - ] +|} + ); + ( "Test kernel upgrade fallsback on initing error", + `Quick, + test_reveal_upgrade_kernel_fallsback_on_error + ~binary:false + "(module (memory 1))" ); + ( "Test scheduling with 10 inputs in a unique inbox", + `Quick, + test_scheduling_one_inbox ); + ( "Test scheduling with 5 inboxes with a different input number", + `Quick, + test_scheduling_five_inboxes ); + ("Test inbox clean-up", `Quick, test_inbox_cleanup); + ( "Test outboxes are created at each level", + `Quick, + test_outboxes_at_each_level ); + ( "Test outbox validity period clean-up", + `Quick, + test_outbox_validity_period ); + ] diff --git a/src/lib_scoru_wasm/test/test_wasm_vm.ml b/src/lib_scoru_wasm/test/test_wasm_vm.ml index 8accb20d65bf..ed8bcacd1108 100644 --- a/src/lib_scoru_wasm/test/test_wasm_vm.ml +++ b/src/lib_scoru_wasm/test/test_wasm_vm.ml @@ -1,8 +1,8 @@ -open Tztest open Tezos_scoru_wasm open Wasm_utils +open Tztest_helper -let init_tree_with_empty_input () = +let init_tree_with_empty_input ~version = let open Lwt_result_syntax in let module_ = {| @@ -15,15 +15,15 @@ let init_tree_with_empty_input () = ) |} in - let*! tree = initial_tree ~from_binary:false module_ in + let*! tree = initial_tree ~version ~from_binary:false module_ in let*! tree = eval_until_input_requested tree in let*! tree = set_empty_inbox_step 0l tree in return tree -let test_padding_state () = +let test_padding_state ~version () = let open Lwt_result_syntax in let open Wasm_pvm_state.Internal_state in - let* tree = init_tree_with_empty_input () in + let* tree = init_tree_with_empty_input ~version in let*! pvm_state = Encodings_util.Tree_encoding_runner.decode Tezos_scoru_wasm.Wasm_pvm.pvm_state_encoding @@ -53,9 +53,9 @@ let test_padding_state () = in return_unit -let test_set_input_step_in_padding () = +let test_set_input_step_in_padding ~version () = let open Lwt_result_syntax in - let* tree = init_tree_with_empty_input () in + let* tree = init_tree_with_empty_input ~version in (* Advance execution for relatively many steps in order to reach Padding tick_state *) let*! tree, _ = Wasm.compute_step_many ~max_steps:(Int64.of_int 10000) tree in @@ -84,9 +84,9 @@ let test_set_input_step_in_padding () = in return_unit -let test_last_input_info_updated_in_set_input_step () = +let test_last_input_info_updated_in_set_input_step ~version () = let open Lwt_result_syntax in - let* tree = init_tree_with_empty_input () in + let* tree = init_tree_with_empty_input ~version in let assert_input_info ?(inp_req = Wasm_pvm_state.Input_required) tree level msg_counter = let expected_info = @@ -129,11 +129,12 @@ let test_last_input_info_updated_in_set_input_step () = return_unit let tests = - [ - tztest "Test eval_has_finished: padding" `Quick test_padding_state; - tztest "Test set_input_state: padding" `Quick test_set_input_step_in_padding; - tztest - "Test set_input_state: update last input info" - `Quick - test_last_input_info_updated_in_set_input_step; - ] + tztests_with_pvm + ~versions:[V0; V1] + [ + ("Test eval_has_finished: padding", `Quick, test_padding_state); + ("Test set_input_state: padding", `Quick, test_set_input_step_in_padding); + ( "Test set_input_state: update last input info", + `Quick, + test_last_input_info_updated_in_set_input_step ); + ] diff --git a/src/lib_scoru_wasm/wasm_pvm_state.ml b/src/lib_scoru_wasm/wasm_pvm_state.ml index cf4fe8c81aeb..45ca8d8d4c9c 100644 --- a/src/lib_scoru_wasm/wasm_pvm_state.ml +++ b/src/lib_scoru_wasm/wasm_pvm_state.ml @@ -24,7 +24,7 @@ (* *) (*****************************************************************************) -type version = V0 +type version = V0 | V1 let version_encoding = (* This encoding is directly used by the protocol. As a consequence, @@ -35,8 +35,11 @@ let version_encoding = bytes. *) Data_encoding.( conv_with_guard - (function V0 -> "2.0.0") - (function "2.0.0" -> Ok V0 | _ -> Error "not a valid version") + (function V0 -> "2.0.0" | V1 -> "2.0.0-r1") + (function + | "2.0.0" -> Ok V0 + | "2.0.0-r1" -> Ok V1 + | _ -> Error "not a valid version") Variable.string) (** Represents the location of an input message. *) diff --git a/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml b/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml index 1156d96954ce..aedc2fdd3ecc 100644 --- a/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml +++ b/src/proto_alpha/lib_protocol/sc_rollup_wasm.ml @@ -81,7 +81,7 @@ let () = (fun () -> WASM_invalid_dissection_distribution) module V2_0_0 = struct - let current_version = Wasm_2_0_0.v0 + let current_version = Wasm_2_0_0.v1 let ticks_per_snapshot = Z.of_int64 11_000_000_000L @@ -121,7 +121,7 @@ module V2_0_0 = struct *) let reference_initial_state_hash = Sc_rollup_repr.State_hash.of_b58check_exn - "srs11XQCynQfGtuUr4c47rAoazGeTfC33R5FmimBKbnMrWwntHURX1" + "srs129wuRkckJpSyDhsqSvzE3qSVnvJZ7nD93r3b6oiBtPxa9LMBHu" open Sc_rollup_repr module PS = Sc_rollup_PVM_sig diff --git a/tezt/tests/expected/sc_rollup.ml/Alpha- wasm_2_0_0 - RPC API should work and be stable.out b/tezt/tests/expected/sc_rollup.ml/Alpha- wasm_2_0_0 - RPC API should work and be stable.out index 29720e48380d..dc9b1dae64fd 100644 --- a/tezt/tests/expected/sc_rollup.ml/Alpha- wasm_2_0_0 - RPC API should work and be stable.out +++ b/tezt/tests/expected/sc_rollup.ml/Alpha- wasm_2_0_0 - RPC API should work and be stable.out @@ -250,10 +250,10 @@ This sequence of operations was run: null ./octez-smart-rollup-client-alpha rpc get '/global/block/head/durable/wasm_2_0_0/value?key=/readonly/wasm_version' -"322e302e30" +"322e302e302d7231" ./octez-smart-rollup-client-alpha rpc get '/global/block/head/durable/wasm_2_0_0/length?key=/readonly/wasm_version' -"5" +"8" ./octez-smart-rollup-client-alpha rpc get '/global/block/head/durable/wasm_2_0_0/subkeys?key=/readonly/kernel' [ "boot.wasm", "env" ] diff --git a/tezt/tests/sc_rollup.ml b/tezt/tests/sc_rollup.ml index 55d00eb6ec76..accbf6386ae3 100644 --- a/tezt/tests/sc_rollup.ml +++ b/tezt/tests/sc_rollup.ml @@ -40,6 +40,10 @@ open Sc_rollup_helpers *) +let default_wasm_pvm_revision = function + | Protocol.Alpha -> "2.0.0-r1" + | Protocol.Lima | Protocol.Mumbai -> "2.0.0" + let assert_some_client_command cmd ~__LOC__ ?hooks client = let*! v_opt = cmd ?hooks client in match v_opt with @@ -4038,7 +4042,7 @@ let test_rpcs ~kind = variant = None; description = "RPC API should work and be stable"; } - @@ fun _protocol sc_rollup_node sc_client sc_rollup node client -> + @@ fun protocol sc_rollup_node sc_client sc_rollup node client -> let* () = Sc_rollup_node.run sc_rollup_node [] in (* Smart rollup address endpoint test *) let*! sc_rollup_address = @@ -4163,7 +4167,9 @@ let test_rpcs ~kind = (fun wasm_version_hex -> Hex.to_string (`Hex wasm_version_hex)) wasm_version_hex_opt in - Check.((wasm_version = Some "2.0.0") (option string)) + Check.( + (wasm_version = Some (default_wasm_pvm_revision protocol)) + (option string)) ~error_msg:"Decoded WASM version is %L but should be %R" ; let*! wasm_version_len = @@ -4174,7 +4180,12 @@ let test_rpcs ~kind = ~operation:Sc_rollup_client.Length ~key:"/readonly/wasm_version" in - Check.((wasm_version_len = Some 5L) (option int64)) + Check.( + (wasm_version_len + = Some + (default_wasm_pvm_revision protocol + |> String.length |> Int64.of_int)) + (option int64)) ~error_msg:"WASM version value length is %L but should be %R" ; let*! kernel_subkeys = -- GitLab