From 7a69f141594b117330bed41617ea6b5b3d155d21 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 20 Jun 2023 13:43:55 +0200 Subject: [PATCH 01/11] SCORU/Node: move Fuel module outside of proto directories --- .../fuel.ml | 0 .../lib_sc_rollup_node/fuel.ml | 90 ------------------- src/proto_alpha/lib_sc_rollup_node/fuel.ml | 90 ------------------- 3 files changed, 180 deletions(-) rename src/{proto_016_PtMumbai/lib_sc_rollup_node => lib_smart_rollup_node}/fuel.ml (100%) delete mode 100644 src/proto_017_PtNairob/lib_sc_rollup_node/fuel.ml delete mode 100644 src/proto_alpha/lib_sc_rollup_node/fuel.ml diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/fuel.ml b/src/lib_smart_rollup_node/fuel.ml similarity index 100% rename from src/proto_016_PtMumbai/lib_sc_rollup_node/fuel.ml rename to src/lib_smart_rollup_node/fuel.ml diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/fuel.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/fuel.ml deleted file mode 100644 index 0ba889d6e61c..000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/fuel.ml +++ /dev/null @@ -1,90 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module type S = sig - type t - - (** [consume consumption fuel] consumes the [consumption] amount from the - original [fuel]. It returns [None] when the [consumption] is greater - than the original [fuel] or [Some remaining_fuel]. *) - val consume : t -> t -> t option - - (** The amount of fuel required to run one PVM tick. - {[ - one_tick_consumption = of_ticks 1L - ]} - *) - val one_tick_consumption : t - - (** [of_ticks ticks] gives the amount of fuel required to execute the amount - of [ticks]. *) - val of_ticks : int64 -> t - - val is_empty : t -> bool - - (** The maximum number of ticks that can be executed with the given amount of - fuel. - {[ - max_ticks ∘ of_ticks = Fun.id - of_ticks ∘ max_ticks = Fun.id - ]} - *) - val max_ticks : t -> int64 -end - -(** Free fuel where consumption has no effect. *) -module Free : S = struct - type t = Free - - let one_tick_consumption = Free - - let of_ticks _ = Free - - let consume _ tank = Some tank - - let is_empty _ = false - - let max_ticks _ = Int64.max_int -end - -(** Accounted fuel where each tick consumes one unit of fuel. *) -module Accounted : S = struct - type t = int64 - - let of_ticks i = - assert (Int64.compare i 0L >= 0) ; - i - - let one_tick_consumption = 1L - - let consume consumption fuel = - if Int64.compare fuel consumption >= 0 then - Some (Int64.sub fuel consumption) - else None - - let is_empty fuel = Int64.compare fuel 0L <= 0 - - let max_ticks fuel_left = Int64.max 0L fuel_left -end diff --git a/src/proto_alpha/lib_sc_rollup_node/fuel.ml b/src/proto_alpha/lib_sc_rollup_node/fuel.ml deleted file mode 100644 index 0ba889d6e61c..000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/fuel.ml +++ /dev/null @@ -1,90 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module type S = sig - type t - - (** [consume consumption fuel] consumes the [consumption] amount from the - original [fuel]. It returns [None] when the [consumption] is greater - than the original [fuel] or [Some remaining_fuel]. *) - val consume : t -> t -> t option - - (** The amount of fuel required to run one PVM tick. - {[ - one_tick_consumption = of_ticks 1L - ]} - *) - val one_tick_consumption : t - - (** [of_ticks ticks] gives the amount of fuel required to execute the amount - of [ticks]. *) - val of_ticks : int64 -> t - - val is_empty : t -> bool - - (** The maximum number of ticks that can be executed with the given amount of - fuel. - {[ - max_ticks ∘ of_ticks = Fun.id - of_ticks ∘ max_ticks = Fun.id - ]} - *) - val max_ticks : t -> int64 -end - -(** Free fuel where consumption has no effect. *) -module Free : S = struct - type t = Free - - let one_tick_consumption = Free - - let of_ticks _ = Free - - let consume _ tank = Some tank - - let is_empty _ = false - - let max_ticks _ = Int64.max_int -end - -(** Accounted fuel where each tick consumes one unit of fuel. *) -module Accounted : S = struct - type t = int64 - - let of_ticks i = - assert (Int64.compare i 0L >= 0) ; - i - - let one_tick_consumption = 1L - - let consume consumption fuel = - if Int64.compare fuel consumption >= 0 then - Some (Int64.sub fuel consumption) - else None - - let is_empty fuel = Int64.compare fuel 0L <= 0 - - let max_ticks fuel_left = Int64.max 0L fuel_left -end -- GitLab From 9a63b7ad6917ea65f5bc318c3ee86875bb8534ef Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 20 Jun 2023 15:58:06 +0200 Subject: [PATCH 02/11] SCORU/Node: ticks as Z in interpreter --- .../lib_sc_rollup_node/fueled_pvm.ml | 19 +++++++++---------- .../lib_sc_rollup_node/interpreter.ml | 17 ++++++----------- .../lib_sc_rollup_node/interpreter.mli | 4 ++-- .../lib_sc_rollup_node/interpreter_event.ml | 4 +--- .../lib_sc_rollup_node/refutation_game.ml | 17 ++++++++++++++--- .../lib_sc_rollup_node/simulation.ml | 4 ++-- 6 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml index a88e0ed41619..10e6d7880644 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -26,8 +26,6 @@ open Protocol open Alpha_context module Inbox = Sc_rollup.Inbox -open Protocol -open Alpha_context module type S = sig type fuel @@ -37,8 +35,8 @@ module type S = sig (** Evaluation state for the PVM. *) type eval_state = { state : pvm_state; (** The actual PVM state. *) - state_hash : Sc_rollup.State_hash.t; (** Hash of [state]. *) - tick : Sc_rollup.Tick.t; (** Tick of [state]. *) + state_hash : Octez_smart_rollup.State_hash.t; (** Hash of [state]. *) + tick : Z.t; (** Tick of [state]. *) inbox_level : int32; (** Inbox level in which messages are evaluated. *) message_counter_offset : int; (** Offset for message index, which corresponds to the number of @@ -87,8 +85,8 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct type eval_state = { state : pvm_state; - state_hash : Sc_rollup.State_hash.t; - tick : Sc_rollup.Tick.t; + state_hash : Octez_smart_rollup.State_hash.t; + tick : Z.t; inbox_level : int32; message_counter_offset : int; remaining_fuel : fuel; @@ -462,8 +460,8 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_state = { state; - state_hash; - tick = final_tick; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; + tick = Sc_rollup.Tick.to_z final_tick; inbox_level; message_counter_offset = num_messages; remaining_fuel; @@ -524,12 +522,13 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct messages in let*! final_tick = PVM.get_tick state in + let final_tick = Sc_rollup.Tick.to_z final_tick in let*! state_hash = PVM.state_hash state in - let num_ticks = Sc_rollup.Tick.distance initial_tick final_tick in + let num_ticks = Z.sub final_tick initial_tick in let eval_state = { state; - state_hash; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; tick = final_tick; inbox_level; message_counter_offset = message_counter_offset + num_messages; diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index d4edff9d2b16..80e3b327ad08 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -203,7 +203,7 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = state; state_hash; inbox_level; - tick; + tick = Sc_rollup.Tick.to_z tick; message_counter_offset = 0; remaining_fuel = Fuel.Accounted.of_ticks 0L; remaining_messages = messages; @@ -214,8 +214,7 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = let run_to_tick node_ctxt start_state tick = let open Delayed_write_monad.Lwt_result_syntax in let tick_distance = - Sc_rollup.Tick.distance tick start_state.Fueled_pvm.Accounted.tick - |> Z.to_int64 + Z.sub tick start_state.Fueled_pvm.Accounted.tick |> Z.to_int64 in let>+ eval_result = Fueled_pvm.Accounted.eval_messages @@ -249,13 +248,11 @@ module Tick_state_cache = (Aches.Rache.Transfer (Aches.Rache.LRU) (struct - type t = Sc_rollup.Tick.t * Block_hash.t + type t = Z.t * Block_hash.t - let equal (t1, b1) (t2, b2) = - Sc_rollup.Tick.(t1 = t2) && Block_hash.(b1 = b2) + let equal (t1, b1) (t2, b2) = Z.equal t1 t2 && Block_hash.(b1 = b2) - let hash (tick, block) = - ((Sc_rollup.Tick.to_z tick |> Z.hash) * 13) + Block_hash.hash block + let hash (tick, block) = (Z.hash tick * 13) + Block_hash.hash block end)) let tick_state_cache = Tick_state_cache.create 64 (* size of 2 dissections *) @@ -272,16 +269,14 @@ let memo_state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) (** [state_of_tick node_ctxt ?start_state tick level] returns [Some end_state] for a given [tick] if this [tick] happened before [level]. Otherwise, returns [None].*) -let state_of_tick node_ctxt ?start_state tick level = +let state_of_tick node_ctxt ?start_state ~tick level = let open Lwt_result_syntax in let level = Raw_level.to_int32 level in - let tick = Sc_rollup.Tick.to_z tick in let* event = Node_context.block_with_tick node_ctxt ~max_level:level tick in match event with | None -> return_none | Some event -> assert (event.header.level <= level) ; - let tick = Sc_rollup.Tick.of_z tick in let* result_state = if Node_context.is_loser node_ctxt then (* TODO: https://gitlab.com/tezos/tezos/-/issues/5253 diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.mli b/src/proto_alpha/lib_sc_rollup_node/interpreter.mli index 124eaa96b53d..077c9323aa8a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.mli @@ -41,14 +41,14 @@ val process_head : Octez_smart_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Z.t) tzresult Lwt.t -(** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, +(** [state_of_tick node_ctxt ?start_state ~tick level] returns [Some (state, hash)] for a given [tick] if this [tick] happened before [level]. Otherwise, returns [None]. If provided, the evaluation is resumed from [start_state]. *) val state_of_tick : _ Node_context.t -> ?start_state:Fueled_pvm.Accounted.eval_state -> - Sc_rollup.Tick.t -> + tick:Z.t -> Raw_level.t -> Fueled_pvm.Accounted.eval_state option tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter_event.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter_event.ml index ff8f435c5f35..3eeb93d6b531 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter_event.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter_event.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol.Alpha_context.Sc_rollup - module Simple = struct include Internal_event.Simple @@ -40,7 +38,7 @@ module Simple = struct ~level:Notice ("inbox_level", Data_encoding.int32) ("state_hash", Octez_smart_rollup.State_hash.encoding) - ("ticks", Tick.encoding) + ("ticks", Data_encoding.z) ("num_messages", Data_encoding.int31) let intended_failure = diff --git a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml index 908b37937384..9c8dc865953c 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -339,7 +339,11 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok our_view = let open Lwt_result_syntax in let state_of_tick ?start_state tick = - Interpreter.state_of_tick node_ctxt ?start_state tick last_level + Interpreter.state_of_tick + node_ctxt + ?start_state + ~tick:(Sc_rollup.Tick.to_z tick) + last_level in let state_hash_of_eval_state Fueled_pvm.Accounted.{state_hash; _} = state_hash @@ -408,7 +412,11 @@ let generate_next_dissection ~default_number_of_sections node_ctxt ~opponent | Evaluated ok_state, _ -> Some ok_state in let* our = - Interpreter.state_of_tick node_ctxt ?start_state tick game.inbox_level + Interpreter.state_of_tick + node_ctxt + ?start_state + ~tick:(Sc_rollup.Tick.to_z tick) + game.inbox_level in match (their_hash, our) with | None, None -> @@ -450,7 +458,10 @@ let next_move node_ctxt ~opponent game = let open Lwt_result_syntax in let final_move start_tick = let* start_state = - Interpreter.state_of_tick node_ctxt start_tick game.inbox_level + Interpreter.state_of_tick + node_ctxt + ~tick:(Sc_rollup.Tick.to_z start_tick) + game.inbox_level in match start_state with | None -> diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index d557dbeb97e5..4172ee552a4c 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.ml +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.ml @@ -98,8 +98,8 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) Fueled_pvm. { state; - state_hash; - tick; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; + tick = Sc_rollup.Tick.to_z tick; inbox_level; message_counter_offset = nb_messages_inbox; remaining_fuel = Fuel.Free.of_ticks 0L; -- GitLab From aa71dd4d57a3cb785ebdf6252687292d5577ee28 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 20 Jun 2023 17:46:53 +0200 Subject: [PATCH 03/11] SCORU/Node: use proto agnostic DAC plugin hashes for reveals map --- manifest/main.ml | 1 + opam/octez-smart-rollup-node-lib.opam | 1 + src/lib_smart_rollup_node/dune | 2 ++ src/lib_smart_rollup_node/utils.ml | 30 +++++++++++++++++++ src/lib_smart_rollup_node/utils.mli | 27 +++++++++++++++++ .../lib_sc_rollup_node/RPC_directory.ml | 11 +++---- .../lib_sc_rollup_node/fueled_pvm.ml | 7 +++-- src/proto_alpha/lib_sc_rollup_node/reveals.ml | 6 ++++ .../lib_sc_rollup_node/reveals.mli | 3 ++ .../lib_sc_rollup_node/simulation.ml | 2 +- .../lib_sc_rollup_node/simulation.mli | 5 ++-- 11 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 src/lib_smart_rollup_node/utils.ml create mode 100644 src/lib_smart_rollup_node/utils.mli diff --git a/manifest/main.ml b/manifest/main.ml index 3b0357a1cbe6..35c1ace9ad47 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -4335,6 +4335,7 @@ let octez_smart_rollup_node_lib = octez_node_config; prometheus_app; octez_dal_node_lib |> open_; + octez_dac_lib |> open_; octez_dac_client_lib |> open_; octez_injector |> open_; octez_version_value |> open_; diff --git a/opam/octez-smart-rollup-node-lib.opam b/opam/octez-smart-rollup-node-lib.opam index fd683afcd125..581cc5efb223 100644 --- a/opam/octez-smart-rollup-node-lib.opam +++ b/opam/octez-smart-rollup-node-lib.opam @@ -19,6 +19,7 @@ depends: [ "octez-node-config" "prometheus-app" { >= "1.2" } "tezos-dal-node-lib" + "tezos-dac-lib" "tezos-dac-client-lib" "octez-injector" "tezos-version" diff --git a/src/lib_smart_rollup_node/dune b/src/lib_smart_rollup_node/dune index 4940f27ce14a..f545540ba13f 100644 --- a/src/lib_smart_rollup_node/dune +++ b/src/lib_smart_rollup_node/dune @@ -16,6 +16,7 @@ octez-node-config prometheus-app tezos-dal-node-lib + tezos-dac-lib tezos-dac-client-lib octez-injector tezos-version.value @@ -30,6 +31,7 @@ -open Tezos_client_base -open Tezos_client_base_unix -open Tezos_dal_node_lib + -open Tezos_dac_lib -open Tezos_dac_client_lib -open Octez_injector -open Tezos_version_value diff --git a/src/lib_smart_rollup_node/utils.ml b/src/lib_smart_rollup_node/utils.ml new file mode 100644 index 000000000000..08393c25a930 --- /dev/null +++ b/src/lib_smart_rollup_node/utils.ml @@ -0,0 +1,30 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Reveal_hash_map = Map.Make (struct + type t = Dac_plugin.hash + + let compare = Dac_plugin.raw_compare +end) diff --git a/src/lib_smart_rollup_node/utils.mli b/src/lib_smart_rollup_node/utils.mli new file mode 100644 index 000000000000..795a71cf7339 --- /dev/null +++ b/src/lib_smart_rollup_node/utils.mli @@ -0,0 +1,27 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** A map addressed by (protocol agnostic) DAC reveal hashes. *) +module Reveal_hash_map : Map.S with type key = Dac_plugin.hash diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_directory.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_directory.ml index 02e1beab7f40..4b2a455e015a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_directory.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_directory.ml @@ -119,14 +119,15 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages let reveal_map = match reveal_pages with | Some pages -> + let (module DAC_plugin) = + WithExceptions.Option.get ~loc:__LOC__ @@ Dac_plugin.get Protocol.hash + in let map = List.fold_left (fun map page -> - let hash = - Sc_rollup_reveal_hash.(hash_string ~scheme:Blake2B [page]) - in - Sc_rollup_reveal_hash.Map.add hash page map) - Sc_rollup_reveal_hash.Map.empty + let hash = DAC_plugin.hash_string ~scheme:Blake2B [page] in + Utils.Reveal_hash_map.add hash page map) + Utils.Reveal_hash_map.empty pages in Some map diff --git a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml index 10e6d7880644..cfbf6def8c65 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -72,7 +72,7 @@ module type S = sig inboxes, such as during simulation. When [reveal_map] is provided, it is used as an additional source of data for revelation ticks. *) val eval_messages : - ?reveal_map:string Sc_rollup_reveal_hash.Map.t -> + ?reveal_map:string Utils.Dac_plugin_hash_map.t -> _ Node_context.t -> eval_state -> eval_result Node_context.delayed_write tzresult Lwt.t @@ -99,7 +99,10 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let found_in_map = match reveal_map with | None -> None - | Some map -> Sc_rollup_reveal_hash.Map.find_opt hash map + | Some map -> + Utils.Reveal_hash_map.find_opt + (Reveals.proto_hash_to_dac_hash hash) + map in match found_in_map with | Some data -> return data diff --git a/src/proto_alpha/lib_sc_rollup_node/reveals.ml b/src/proto_alpha/lib_sc_rollup_node/reveals.ml index 6e1be53beb93..ee9001ba0c04 100644 --- a/src/proto_alpha/lib_sc_rollup_node/reveals.ml +++ b/src/proto_alpha/lib_sc_rollup_node/reveals.ml @@ -113,3 +113,9 @@ let get ~dac_client ~data_dir ~pvm_kind hash = |> return in return contents + +let proto_hash_to_dac_hash proto_reveal_hash = + let dac_plugin = + WithExceptions.Option.get ~loc:__LOC__ @@ Dac_plugin.get Protocol.hash + in + proto_hash_to_dac_hash dac_plugin proto_reveal_hash diff --git a/src/proto_alpha/lib_sc_rollup_node/reveals.mli b/src/proto_alpha/lib_sc_rollup_node/reveals.mli index def199a79b32..53e199827112 100644 --- a/src/proto_alpha/lib_sc_rollup_node/reveals.mli +++ b/src/proto_alpha/lib_sc_rollup_node/reveals.mli @@ -73,3 +73,6 @@ val get : pvm_kind:Kind.t -> Protocol.Sc_rollup_reveal_hash.t -> string tzresult Lwt.t + +(** Conversion from protocol reveal hash to protocol agnostic DAC hash. *) +val proto_hash_to_dac_hash : Protocol.Sc_rollup_reveal_hash.t -> Dac_plugin.hash diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index 4172ee552a4c..d9d36a876012 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.ml +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.ml @@ -38,7 +38,7 @@ type t = { ctxt : Context.ro; inbox_level : int32; state : Context.tree; - reveal_map : string Sc_rollup_reveal_hash.Map.t option; + reveal_map : string Utils.Reveal_hash_map.t option; nb_messages_inbox : int; level_position : level_position; info_per_level : info_per_level; diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.mli b/src/proto_alpha/lib_sc_rollup_node/simulation.mli index ac8d8dd03624..745ead3df562 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.mli +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.mli @@ -23,7 +23,6 @@ (* *) (*****************************************************************************) -open Protocol open Protocol.Alpha_context module Fueled_pvm = Fueled_pvm.Free @@ -39,7 +38,7 @@ type t = { ctxt : Context.ro; inbox_level : int32; state : Context.tree; - reveal_map : string Sc_rollup_reveal_hash.Map.t option; + reveal_map : string Utils.Reveal_hash_map.t option; nb_messages_inbox : int; level_position : level_position; info_per_level : info_per_level; @@ -49,7 +48,7 @@ type t = { on top} of [block], i.e. for an hypothetical new inbox (level). *) val start_simulation : Node_context.ro -> - reveal_map:string Sc_rollup_reveal_hash.Map.t option -> + reveal_map:string Utils.Reveal_hash_map.t option -> Layer1.head -> t tzresult Lwt.t -- GitLab From c70e5244767e86f30265b0d288fcecb5a115f64e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 22 Jun 2023 15:29:36 +0200 Subject: [PATCH 04/11] SCORU/Node: move get_boot_sector to Layer1_helpers --- .../lib_sc_rollup_node/interpreter.ml | 43 +------------------ .../lib_sc_rollup_node/layer1_helpers.ml | 38 ++++++++++++++++ .../lib_sc_rollup_node/layer1_helpers.mli | 5 +++ 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index 80e3b327ad08..7e5eeced5ee5 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -26,51 +26,10 @@ open Protocol open Alpha_context -(** [get_boot_sector block_hash node_ctxt] fetches the operations in the - [block_hash] and looks for the bootsector used to originate the rollup we're - following. It must be called with [block_hash.level] = - [node_ctxt.genesis_info.level]. *) -let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = - let open Lwt_result_syntax in - let exception Found_boot_sector of string in - let* block = Layer1_helpers.fetch_tezos_block node_ctxt.l1_ctxt block_hash in - let missing_boot_sector () = - failwith "Boot sector not found in Tezos block %a" Block_hash.pp block_hash - in - Lwt.catch - (fun () -> - let apply (type kind) accu ~source:_ (operation : kind manager_operation) - (result : kind Apply_results.successful_manager_operation_result) = - match (operation, result) with - | ( Sc_rollup_originate {kind; boot_sector; _}, - Sc_rollup_originate_result {address; _} ) - when node_ctxt.rollup_address = address - && node_ctxt.kind = Sc_rollup_proto_types.Kind.to_octez kind -> - raise (Found_boot_sector boot_sector) - | _ -> accu - in - let apply_internal (type kind) accu ~source:_ - (_operation : kind Apply_internal_results.internal_operation) - (_result : - kind Apply_internal_results.successful_internal_operation_result) = - accu - in - let*? () = - Layer1_services.( - process_applied_manager_operations - (Ok ()) - block.operations - {apply; apply_internal}) - in - missing_boot_sector ()) - (function - | Found_boot_sector boot_sector -> return boot_sector - | _ -> missing_boot_sector ()) - let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in match node_ctxt.boot_sector_file with - | None -> get_boot_sector block_hash node_ctxt + | None -> Layer1_helpers.get_boot_sector block_hash node_ctxt | Some boot_sector_file -> let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! boot_sector = Lwt_utils_unix.read_file boot_sector_file in diff --git a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml index b2e0c9363177..011004110d24 100644 --- a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml @@ -186,3 +186,41 @@ let retrieve_genesis_info cctxt rollup_address = commitment_hash = Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; } + +let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = + let open Protocol in + let open Alpha_context in + let open Lwt_result_syntax in + let exception Found_boot_sector of string in + let* block = fetch_tezos_block node_ctxt.l1_ctxt block_hash in + let missing_boot_sector () = + failwith "Boot sector not found in Tezos block %a" Block_hash.pp block_hash + in + Lwt.catch + (fun () -> + let apply (type kind) accu ~source:_ (operation : kind manager_operation) + (result : kind Apply_results.successful_manager_operation_result) = + match (operation, result) with + | ( Sc_rollup_originate {boot_sector; _}, + Sc_rollup_originate_result {address; _} ) + when node_ctxt.rollup_address = address -> + raise (Found_boot_sector boot_sector) + | _ -> accu + in + let apply_internal (type kind) accu ~source:_ + (_operation : kind Apply_internal_results.internal_operation) + (_result : + kind Apply_internal_results.successful_internal_operation_result) = + accu + in + let*? () = + Layer1_services.( + process_applied_manager_operations + (Ok ()) + block.operations + {apply; apply_internal}) + in + missing_boot_sector ()) + (function + | Found_boot_sector boot_sector -> return boot_sector + | _ -> missing_boot_sector ()) diff --git a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli index c82972f95ba0..76a3f7222957 100644 --- a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli +++ b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli @@ -68,3 +68,8 @@ val retrieve_constants : val retrieve_genesis_info : #Client_context.full -> Address.t -> Node_context.genesis_info tzresult Lwt.t + +(** [get_boot_sector block_hash node_ctxt] retrieves the boot sector from the + rollup origination operation in block [block_hash]. Precondition: + [block_hash] has to be the block where the rollup was originated. *) +val get_boot_sector : Block_hash.t -> _ Node_context.t -> string tzresult Lwt.t -- GitLab From ea6506d6104a5bc42f6eecb31c8e536c2e4b6b8e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 22 Jun 2023 15:32:07 +0200 Subject: [PATCH 05/11] SCORU/Node: PVM plugin definition --- src/lib_smart_rollup_node/pvm_plugin_sig.ml | 110 ++++++++++++++++++ .../lib_sc_rollup_node/fueled_pvm.ml | 68 +---------- .../lib_sc_rollup_node/interpreter.ml | 6 +- .../lib_sc_rollup_node/interpreter.mli | 4 +- .../lib_sc_rollup_node/pvm_plugin.ml | 90 ++++++++++++++ .../lib_sc_rollup_node/pvm_plugin.mli | 27 +++++ .../lib_sc_rollup_node/refutation_game.ml | 10 +- .../lib_sc_rollup_node/rollup_node_plugin.ml | 2 + .../lib_sc_rollup_node/simulation.ml | 4 +- 9 files changed, 242 insertions(+), 79 deletions(-) create mode 100644 src/lib_smart_rollup_node/pvm_plugin_sig.ml create mode 100644 src/proto_alpha/lib_sc_rollup_node/pvm_plugin.ml create mode 100644 src/proto_alpha/lib_sc_rollup_node/pvm_plugin.mli diff --git a/src/lib_smart_rollup_node/pvm_plugin_sig.ml b/src/lib_smart_rollup_node/pvm_plugin_sig.ml new file mode 100644 index 000000000000..fb86b8e1f33e --- /dev/null +++ b/src/lib_smart_rollup_node/pvm_plugin_sig.ml @@ -0,0 +1,110 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** Evaluation state for the PVM. *) +type 'fuel eval_state = { + state : Context.tree; (** The actual PVM state. *) + state_hash : State_hash.t; (** Hash of [state]. *) + tick : Z.t; (** Tick of [state]. *) + inbox_level : int32; (** Inbox level in which messages are evaluated. *) + message_counter_offset : int; + (** Offset for message index, which corresponds to the number of + messages of the inbox already evaluated. *) + remaining_fuel : 'fuel; + (** Fuel remaining for the evaluation of the inbox. *) + remaining_messages : string list; + (** Messages of the inbox that remain to be evaluated. *) +} + +type 'fuel eval_result = { + state : 'fuel eval_state; + num_ticks : Z.t; + num_messages : int; +} + +module type FUELED_PVM = sig + type fuel + + (** Evaluation result for the PVM which contains the evaluation state and + additional information. *) + + (** [eval_block_inbox ~fuel node_ctxt (inbox, messages) state] evaluates the + [messages] for the [inbox] in the given [state] of the PVM and returns the + evaluation result containing the new state, the number of messages, the + inbox level and the remaining fuel. *) + val eval_block_inbox : + fuel:fuel -> + _ Node_context.t -> + Inbox.t * string list -> + Context.tree -> + fuel eval_result Node_context.delayed_write tzresult Lwt.t + + (** [eval_messages ?reveal_map ~fuel node_ctxt ~message_counter_offset state + inbox_level messages] evaluates the [messages] for inbox level + [inbox_level] in the given [state] of the PVM and returns the evaluation + results containing the new state, the remaining fuel, and the number of + ticks for the evaluation of these messages. If [messages] is empty, the + PVM progresses until the next input request (within the allocated + [fuel]). [message_counter_offset] is used when we evaluate partial + inboxes, such as during simulation. When [reveal_map] is provided, it is + used as an additional source of data for revelation ticks. *) + val eval_messages : + ?reveal_map:string Utils.Reveal_hash_map.t -> + _ Node_context.t -> + fuel eval_state -> + fuel eval_result Node_context.delayed_write tzresult Lwt.t +end + +module type S = sig + val get_tick : Kind.t -> Context.tree -> Z.t Lwt.t + + val state_hash : Kind.t -> Context.tree -> State_hash.t Lwt.t + + val initial_state : Kind.t -> Context.tree Lwt.t + + val parse_boot_sector : Kind.t -> string -> string option + + val install_boot_sector : + Kind.t -> Context.tree -> string -> Context.tree Lwt.t + + val get_status : _ Node_context.t -> Context.tree -> string Lwt.t + + val get_current_level : Kind.t -> Context.tree -> int32 option Lwt.t + + val start_of_level_serialized : string + + val end_of_level_serialized : string + + val protocol_migration_serialized : string option + + val info_per_level_serialized : + predecessor:Block_hash.t -> predecessor_timestamp:Time.Protocol.t -> string + + module Fueled : sig + module Free : FUELED_PVM with type fuel := Fuel.Free.t + + module Accounted : FUELED_PVM with type fuel := Fuel.Accounted.t + end +end diff --git a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml index cfbf6def8c65..d0ed691d2d1f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -26,75 +26,13 @@ open Protocol open Alpha_context module Inbox = Sc_rollup.Inbox +open Pvm_plugin_sig -module type S = sig - type fuel - - type pvm_state = Context.tree - - (** Evaluation state for the PVM. *) - type eval_state = { - state : pvm_state; (** The actual PVM state. *) - state_hash : Octez_smart_rollup.State_hash.t; (** Hash of [state]. *) - tick : Z.t; (** Tick of [state]. *) - inbox_level : int32; (** Inbox level in which messages are evaluated. *) - message_counter_offset : int; - (** Offset for message index, which corresponds to the number of - messages of the inbox already evaluated. *) - remaining_fuel : fuel; - (** Fuel remaining for the evaluation of the inbox. *) - remaining_messages : string list; - (** Messages of the inbox that remain to be evaluated. *) - } - - (** Evaluation result for the PVM which contains the evaluation state and - additional information. *) - type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} - - (** [eval_block_inbox ~fuel node_ctxt (inbox, messages) state] evaluates the - [messages] for the [inbox] in the given [state] of the PVM and returns the - evaluation result containing the new state, the number of messages, the - inbox level and the remaining fuel. *) - val eval_block_inbox : - fuel:fuel -> - _ Node_context.t -> - Octez_smart_rollup.Inbox.t * string list -> - pvm_state -> - eval_result Node_context.delayed_write tzresult Lwt.t - - (** [eval_messages ?reveal_map ~fuel node_ctxt ~message_counter_offset state - inbox_level messages] evaluates the [messages] for inbox level - [inbox_level] in the given [state] of the PVM and returns the evaluation - results containing the new state, the remaining fuel, and the number of - ticks for the evaluation of these messages. If [messages] is empty, the - PVM progresses until the next input request (within the allocated - [fuel]). [message_counter_offset] is used when we evaluate partial - inboxes, such as during simulation. When [reveal_map] is provided, it is - used as an additional source of data for revelation ticks. *) - val eval_messages : - ?reveal_map:string Utils.Dac_plugin_hash_map.t -> - _ Node_context.t -> - eval_state -> - eval_result Node_context.delayed_write tzresult Lwt.t -end - -module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct +module Make_fueled (F : Fuel.S) : FUELED_PVM with type fuel = F.t = struct type fuel = F.t type pvm_state = Context.tree - type eval_state = { - state : pvm_state; - state_hash : Octez_smart_rollup.State_hash.t; - tick : Z.t; - inbox_level : int32; - message_counter_offset : int; - remaining_fuel : fuel; - remaining_messages : string list; - } - - type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} - let get_reveal ~dac_client ~data_dir ~pvm_kind reveal_map hash = let found_in_map = match reveal_map with @@ -439,7 +377,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_block_inbox ~fuel (node_ctxt : _ Node_context.t) (inbox, messages) (state : pvm_state) : - eval_result Node_context.delayed_write tzresult Lwt.t = + fuel eval_result Node_context.delayed_write tzresult Lwt.t = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in let module PVM = (val Pvm.of_kind node_ctxt.kind) in diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index 7e5eeced5ee5..c9c79e88f647 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -157,7 +157,7 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = @ [unsafe_to_string end_of_level_serialized] in return - Fueled_pvm.Accounted. + Pvm_plugin_sig. { state; state_hash; @@ -173,7 +173,7 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = let run_to_tick node_ctxt start_state tick = let open Delayed_write_monad.Lwt_result_syntax in let tick_distance = - Z.sub tick start_state.Fueled_pvm.Accounted.tick |> Z.to_int64 + Z.sub tick start_state.Pvm_plugin_sig.tick |> Z.to_int64 in let>+ eval_result = Fueled_pvm.Accounted.eval_messages @@ -187,7 +187,7 @@ let state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) tick = let* start_state = match start_state with | Some start_state - when start_state.Fueled_pvm.Accounted.inbox_level = event.header.level -> + when start_state.Pvm_plugin_sig.inbox_level = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.mli b/src/proto_alpha/lib_sc_rollup_node/interpreter.mli index 077c9323aa8a..acf81542788b 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.mli @@ -47,10 +47,10 @@ val process_head : [start_state]. *) val state_of_tick : _ Node_context.t -> - ?start_state:Fueled_pvm.Accounted.eval_state -> + ?start_state:Fuel.Accounted.t Pvm_plugin_sig.eval_state -> tick:Z.t -> Raw_level.t -> - Fueled_pvm.Accounted.eval_state option tzresult Lwt.t + Fuel.Accounted.t Pvm_plugin_sig.eval_state option tzresult Lwt.t (** [state_of_head node_ctxt ctxt head] returns the state corresponding to the block [head], or the state at rollup genesis if the block is before the diff --git a/src/proto_alpha/lib_sc_rollup_node/pvm_plugin.ml b/src/proto_alpha/lib_sc_rollup_node/pvm_plugin.ml new file mode 100644 index 000000000000..650d06161155 --- /dev/null +++ b/src/proto_alpha/lib_sc_rollup_node/pvm_plugin.ml @@ -0,0 +1,90 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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 Protocol +open Alpha_context + +let get_tick kind state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ tick = PVM.get_tick state in + Sc_rollup.Tick.to_z tick + +let state_hash kind state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ hash = PVM.state_hash state in + Sc_rollup_proto_types.State_hash.to_octez hash + +let initial_state kind = + let module PVM = (val Pvm.of_kind kind) in + PVM.initial_state ~empty:(PVM.State.empty ()) + +let parse_boot_sector kind = + let module PVM = (val Pvm.of_kind kind) in + PVM.parse_boot_sector + +let install_boot_sector kind state boot_sector = + let module PVM = (val Pvm.of_kind kind) in + PVM.install_boot_sector state boot_sector + +let get_status (node_ctxt : _ Node_context.t) state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5871 + Use constants for correct protocol. *) + let is_reveal_enabled = + node_ctxt.current_protocol.constants.sc_rollup.reveal_activation_level + |> WithExceptions.Option.get ~loc:__LOC__ + |> Sc_rollup_proto_types.Constants.reveal_activation_level_of_octez + |> Protocol.Alpha_context.Sc_rollup.is_reveal_enabled_predicate + in + let+ status = PVM.get_status ~is_reveal_enabled state in + PVM.string_of_status status + +let get_current_level kind state = + let open Lwt_option_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ current_level = PVM.get_current_level state in + Raw_level.to_int32 current_level + +module Fueled = Fueled_pvm + +let start_of_level_serialized = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized + +let end_of_level_serialized = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string end_of_level_serialized + +let protocol_migration_serialized = + let open Sc_rollup_inbox_message_repr in + Some (unsafe_to_string Raw_context.protocol_migration_serialized_message) + +let info_per_level_serialized ~predecessor ~predecessor_timestamp = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) diff --git a/src/proto_alpha/lib_sc_rollup_node/pvm_plugin.mli b/src/proto_alpha/lib_sc_rollup_node/pvm_plugin.mli new file mode 100644 index 000000000000..e0183f81e636 --- /dev/null +++ b/src/proto_alpha/lib_sc_rollup_node/pvm_plugin.mli @@ -0,0 +1,27 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +include Pvm_plugin_sig.S diff --git a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml index 9c8dc865953c..afabcca77936 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -333,7 +333,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = type pvm_intermediate_state = | Hash of Sc_rollup.State_hash.t - | Evaluated of Fueled_pvm.Accounted.eval_state + | Evaluated of Fuel.Accounted.t Pvm_plugin_sig.eval_state let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok our_view = @@ -345,9 +345,7 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok ~tick:(Sc_rollup.Tick.to_z tick) last_level in - let state_hash_of_eval_state Fueled_pvm.Accounted.{state_hash; _} = - state_hash - in + let state_hash_of_eval_state Pvm_plugin_sig.{state_hash; _} = state_hash in let start_hash, start_tick, start_state = match ok with | Hash hash, tick -> (hash, tick, None) @@ -359,9 +357,7 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok in let our_state, our_tick = our_view in let our_state_hash = - Option.map - (fun Fueled_pvm.Accounted.{state_hash; _} -> state_hash) - our_state + Option.map (fun Pvm_plugin_sig.{state_hash; _} -> state_hash) our_state in let our_stop_chunk = Sc_rollup.Dissection_chunk.{state_hash = our_state_hash; tick = our_tick} diff --git a/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml b/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml index 6d1642bf8f58..af7636f504dc 100644 --- a/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml +++ b/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml @@ -40,6 +40,8 @@ module Plugin : Protocol_plugin_sig.S = struct let process_l1_block_operations = Daemon.process_l1_block_operations end + + module Pvm = Pvm_plugin end let () = Protocol_plugins.register (module Plugin) diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index d9d36a876012..dd39c830ed3d 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.ml +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.ml @@ -95,7 +95,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) let*! state_hash = PVM.state_hash state in let*! tick = PVM.get_tick state in let eval_state = - Fueled_pvm. + Pvm_plugin_sig. { state; state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; @@ -110,7 +110,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) let* eval_result = Fueled_pvm.eval_messages ?reveal_map node_ctxt eval_state in - let Fueled_pvm.{state = {state; _}; num_ticks; num_messages; _} = + let Pvm_plugin_sig.{state = {state; _}; num_ticks; num_messages; _} = Delayed_write_monad.ignore eval_result in let*! ctxt = PVM.State.set ctxt state in -- GitLab From 73b5abe5e2ac6f556592c167fa19d85b16af990f Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 22 Jun 2023 16:04:49 +0200 Subject: [PATCH 06/11] Manifest: need dac plugin for rollup nodes --- manifest/main.ml | 2 +- opam/octez-smart-rollup-node-PtMumbai.opam | 1 + opam/octez-smart-rollup-node-PtNairob.opam | 1 + src/proto_016_PtMumbai/lib_sc_rollup_node/dune | 2 ++ src/proto_017_PtNairob/lib_sc_rollup_node/dune | 2 ++ 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/manifest/main.ml b/manifest/main.ml index 35c1ace9ad47..f872f1241660 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -6326,7 +6326,7 @@ let hash = Protocol.hash (* [dac] is needed for the DAC observer client which is not available in Nairobi and earlier. *) dac |> if_some |> if_ N.(number >= 018) |> open_; - octez_dac_lib |> if_ N.(number >= 018) |> open_; + octez_dac_lib |> open_; octez_dac_client_lib |> if_ N.(number >= 018) |> open_; octez_shell_services |> open_; octez_smart_rollup_lib |> open_; diff --git a/opam/octez-smart-rollup-node-PtMumbai.opam b/opam/octez-smart-rollup-node-PtMumbai.opam index 9087c4c147ad..8ecb52d72069 100644 --- a/opam/octez-smart-rollup-node-PtMumbai.opam +++ b/opam/octez-smart-rollup-node-PtMumbai.opam @@ -24,6 +24,7 @@ depends: [ "tezos-workers" "tezos-dal-node-services" "tezos-dal-node-lib" + "tezos-dac-lib" "tezos-shell-services" "octez-smart-rollup" "tezos-smart-rollup-016-PtMumbai" diff --git a/opam/octez-smart-rollup-node-PtNairob.opam b/opam/octez-smart-rollup-node-PtNairob.opam index 1d964adac6d4..c1e06755a3e3 100644 --- a/opam/octez-smart-rollup-node-PtNairob.opam +++ b/opam/octez-smart-rollup-node-PtNairob.opam @@ -24,6 +24,7 @@ depends: [ "tezos-workers" "tezos-dal-node-services" "tezos-dal-node-lib" + "tezos-dac-lib" "tezos-shell-services" "octez-smart-rollup" "tezos-smart-rollup-017-PtNairob" diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/dune b/src/proto_016_PtMumbai/lib_sc_rollup_node/dune index ff86dd4c55b0..d212f728e646 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/dune +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/dune @@ -22,6 +22,7 @@ tezos-workers tezos-dal-node-services tezos-dal-node-lib + tezos-dac-lib tezos-shell-services octez-smart-rollup tezos-smart-rollup-016-PtMumbai @@ -56,6 +57,7 @@ -open Tezos_protocol_016_PtMumbai_parameters -open Tezos_workers -open Tezos_dal_node_lib + -open Tezos_dac_lib -open Tezos_shell_services -open Octez_smart_rollup -open Tezos_smart_rollup_016_PtMumbai diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/dune b/src/proto_017_PtNairob/lib_sc_rollup_node/dune index 00cf5b4771dc..142fff8a2770 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/dune +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/dune @@ -22,6 +22,7 @@ tezos-workers tezos-dal-node-services tezos-dal-node-lib + tezos-dac-lib tezos-shell-services octez-smart-rollup tezos-smart-rollup-017-PtNairob @@ -56,6 +57,7 @@ -open Tezos_protocol_017_PtNairob_parameters -open Tezos_workers -open Tezos_dal_node_lib + -open Tezos_dac_lib -open Tezos_shell_services -open Octez_smart_rollup -open Tezos_smart_rollup_017_PtNairob -- GitLab From 4c51a5876f08245367aee378db8c2bff57340d9e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 20 Jun 2023 15:58:06 +0200 Subject: [PATCH 07/11] SCORU/Node/Nairobi: PVM pluigin Backport of the commits: - SCORU/Node: ticks as Z in interpreter - SCORU/Node: use proto agnostic DAC plugin hashes for reveals map - SCORU/Node: move get_boot_sector to Layer1_helpers - SCORU/Node: PVM plugin definition --- .../lib_sc_rollup_node/RPC_directory.ml | 11 +-- .../lib_sc_rollup_node/fueled_pvm.ml | 84 +++---------------- .../lib_sc_rollup_node/interpreter.ml | 78 +++++------------ .../lib_sc_rollup_node/interpreter.mli | 8 +- .../lib_sc_rollup_node/layer1_helpers.ml | 40 +++++++++ .../lib_sc_rollup_node/layer1_helpers.mli | 5 ++ .../lib_sc_rollup_node/pvm_plugin.ml | 82 ++++++++++++++++++ .../lib_sc_rollup_node/pvm_plugin.mli | 27 ++++++ .../lib_sc_rollup_node/refutation_game.ml | 35 +++++--- .../lib_sc_rollup_node/reveals.ml | 11 +++ .../lib_sc_rollup_node/reveals.mli | 3 + .../lib_sc_rollup_node/rollup_node_plugin.ml | 2 + .../lib_sc_rollup_node/simulation.ml | 10 +-- .../lib_sc_rollup_node/simulation.mli | 5 +- 14 files changed, 247 insertions(+), 154 deletions(-) create mode 100644 src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.ml create mode 100644 src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.mli diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory.ml index 3f57f74af55a..543c032d20c0 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory.ml @@ -119,14 +119,15 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages let reveal_map = match reveal_pages with | Some pages -> + let (module DAC_plugin) = + WithExceptions.Option.get ~loc:__LOC__ @@ Dac_plugin.get Protocol.hash + in let map = List.fold_left (fun map page -> - let hash = - Sc_rollup_reveal_hash.(hash_string ~scheme:Blake2B [page]) - in - Sc_rollup_reveal_hash.Map.add hash page map) - Sc_rollup_reveal_hash.Map.empty + let hash = DAC_plugin.hash_string ~scheme:Blake2B [page] in + Utils.Reveal_hash_map.add hash page map) + Utils.Reveal_hash_map.empty pages in Some map diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/fueled_pvm.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/fueled_pvm.ml index bb35157ecaeb..4aa526d76528 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/fueled_pvm.ml @@ -26,82 +26,21 @@ open Protocol open Alpha_context module Inbox = Sc_rollup.Inbox -open Protocol -open Alpha_context - -module type S = sig - type fuel - - type pvm_state = Context.tree - - (** Evaluation state for the PVM. *) - type eval_state = { - state : pvm_state; (** The actual PVM state. *) - state_hash : Sc_rollup.State_hash.t; (** Hash of [state]. *) - tick : Sc_rollup.Tick.t; (** Tick of [state]. *) - inbox_level : int32; (** Inbox level in which messages are evaluated. *) - message_counter_offset : int; - (** Offset for message index, which corresponds to the number of - messages of the inbox already evaluated. *) - remaining_fuel : fuel; - (** Fuel remaining for the evaluation of the inbox. *) - remaining_messages : string list; - (** Messages of the inbox that remain to be evaluated. *) - } - - (** Evaluation result for the PVM which contains the evaluation state and - additional information. *) - type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} +open Pvm_plugin_sig - (** [eval_block_inbox ~fuel node_ctxt (inbox, messages) state] evaluates the - [messages] for the [inbox] in the given [state] of the PVM and returns the - evaluation result containing the new state, the number of messages, the - inbox level and the remaining fuel. *) - val eval_block_inbox : - fuel:fuel -> - _ Node_context.t -> - Octez_smart_rollup.Inbox.t * string list -> - pvm_state -> - eval_result Node_context.delayed_write tzresult Lwt.t - - (** [eval_messages ?reveal_map ~fuel node_ctxt ~message_counter_offset state - inbox_level messages] evaluates the [messages] for inbox level - [inbox_level] in the given [state] of the PVM and returns the evaluation - results containing the new state, the remaining fuel, and the number of - ticks for the evaluation of these messages. If [messages] is empty, the - PVM progresses until the next input request (within the allocated - [fuel]). [message_counter_offset] is used when we evaluate partial - inboxes, such as during simulation. When [reveal_map] is provided, it is - used as an additional source of data for revelation ticks. *) - val eval_messages : - ?reveal_map:string Sc_rollup_reveal_hash.Map.t -> - _ Node_context.t -> - eval_state -> - eval_result Node_context.delayed_write tzresult Lwt.t -end - -module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct +module Make_fueled (F : Fuel.S) : FUELED_PVM with type fuel = F.t = struct type fuel = F.t type pvm_state = Context.tree - type eval_state = { - state : pvm_state; - state_hash : Sc_rollup.State_hash.t; - tick : Sc_rollup.Tick.t; - inbox_level : int32; - message_counter_offset : int; - remaining_fuel : fuel; - remaining_messages : string list; - } - - type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} - let get_reveal ~data_dir ~pvm_kind reveal_map hash = let found_in_map = match reveal_map with | None -> None - | Some map -> Sc_rollup_reveal_hash.Map.find_opt hash map + | Some map -> + Utils.Reveal_hash_map.find_opt + (Reveals.proto_hash_to_dac_hash hash) + map in match found_in_map with | Some data -> return data @@ -427,7 +366,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_block_inbox ~fuel (node_ctxt : _ Node_context.t) (inbox, messages) (state : pvm_state) : - eval_result Node_context.delayed_write tzresult Lwt.t = + fuel eval_result Node_context.delayed_write tzresult Lwt.t = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in let module PVM = (val Pvm.of_kind node_ctxt.kind) in @@ -451,8 +390,8 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_state = { state; - state_hash; - tick = final_tick; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; + tick = Sc_rollup.Tick.to_z final_tick; inbox_level; message_counter_offset = num_messages; remaining_fuel; @@ -513,12 +452,13 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct messages in let*! final_tick = PVM.get_tick state in + let final_tick = Sc_rollup.Tick.to_z final_tick in let*! state_hash = PVM.state_hash state in - let num_ticks = Sc_rollup.Tick.distance initial_tick final_tick in + let num_ticks = Z.sub final_tick initial_tick in let eval_state = { state; - state_hash; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; tick = final_tick; inbox_level; message_counter_offset = message_counter_offset + num_messages; diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.ml index c4be2d729b1e..b9c436a37ca4 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.ml @@ -26,48 +26,23 @@ open Protocol open Alpha_context -(** [get_boot_sector block_hash node_ctxt] fetches the operations in the - [block_hash] and looks for the bootsector used to originate the rollup we're - following. It must be called with [block_hash.level] = - [node_ctxt.genesis_info.level]. *) let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in - let exception Found_boot_sector of string in - let* block = Layer1_helpers.fetch_tezos_block node_ctxt.l1_ctxt block_hash in - let missing_boot_sector () = - failwith "Boot sector not found in Tezos block %a" Block_hash.pp block_hash - in - Lwt.catch - (fun () -> - let apply (type kind) accu ~source:_ (operation : kind manager_operation) - (result : kind Apply_results.successful_manager_operation_result) = - match (operation, result) with - | ( Sc_rollup_originate {kind; boot_sector; _}, - Sc_rollup_originate_result {address; _} ) - when Octez_smart_rollup.Address.( - node_ctxt.rollup_address - = Sc_rollup_proto_types.Address.to_octez address) - && node_ctxt.kind = Sc_rollup_proto_types.Kind.to_octez kind -> - raise (Found_boot_sector boot_sector) - | _ -> accu - in - let apply_internal (type kind) accu ~source:_ - (_operation : kind Apply_internal_results.internal_operation) - (_result : - kind Apply_internal_results.successful_internal_operation_result) = - accu - in - let*? () = - Layer1_services.( - process_applied_manager_operations - (Ok ()) - block.operations - {apply; apply_internal}) + match node_ctxt.boot_sector_file with + | None -> Layer1_helpers.get_boot_sector block_hash node_ctxt + | Some boot_sector_file -> + let module PVM = (val Pvm.of_kind node_ctxt.kind) in + let*! boot_sector = Lwt_utils_unix.read_file boot_sector_file in + let*? boot_sector = + Option.value_e + ~error: + [ + Sc_rollup_node_errors.Unparsable_boot_sector + {path = boot_sector_file}; + ] + (PVM.parse_boot_sector boot_sector) in - missing_boot_sector ()) - (function - | Found_boot_sector boot_sector -> return boot_sector - | _ -> missing_boot_sector ()) + return boot_sector let genesis_state block_hash node_ctxt ctxt = let open Lwt_result_syntax in @@ -110,8 +85,6 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} } = Delayed_write_monad.apply node_ctxt eval_result in - let state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash in - let tick = Sc_rollup.Tick.to_z tick in let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! ctxt = PVM.State.set ctxt state in let*! initial_tick = PVM.get_tick predecessor_state in @@ -177,12 +150,12 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = @ [unsafe_to_string end_of_level_serialized] in return - Fueled_pvm.Accounted. + Pvm_plugin_sig. { state; - state_hash; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; inbox_level; - tick; + tick = Sc_rollup.Tick.to_z tick; message_counter_offset = 0; remaining_fuel = Fuel.Accounted.of_ticks 0L; remaining_messages = messages; @@ -193,8 +166,7 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = let run_to_tick node_ctxt start_state tick = let open Delayed_write_monad.Lwt_result_syntax in let tick_distance = - Sc_rollup.Tick.distance tick start_state.Fueled_pvm.Accounted.tick - |> Z.to_int64 + Z.sub tick start_state.Pvm_plugin_sig.tick |> Z.to_int64 in let>+ eval_result = Fueled_pvm.Accounted.eval_messages @@ -208,7 +180,7 @@ let state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) tick = let* start_state = match start_state with | Some start_state - when start_state.Fueled_pvm.Accounted.inbox_level = event.header.level -> + when start_state.Pvm_plugin_sig.inbox_level = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a @@ -228,13 +200,11 @@ module Tick_state_cache = (Aches.Rache.Transfer (Aches.Rache.LRU) (struct - type t = Sc_rollup.Tick.t * Block_hash.t + type t = Z.t * Block_hash.t - let equal (t1, b1) (t2, b2) = - Sc_rollup.Tick.(t1 = t2) && Block_hash.(b1 = b2) + let equal (t1, b1) (t2, b2) = Z.equal t1 t2 && Block_hash.(b1 = b2) - let hash (tick, block) = - ((Sc_rollup.Tick.to_z tick |> Z.hash) * 13) + Block_hash.hash block + let hash (tick, block) = (Z.hash tick * 13) + Block_hash.hash block end)) let tick_state_cache = Tick_state_cache.create 64 (* size of 2 dissections *) @@ -251,16 +221,14 @@ let memo_state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) (** [state_of_tick node_ctxt ?start_state tick level] returns [Some end_state] for a given [tick] if this [tick] happened before [level]. Otherwise, returns [None].*) -let state_of_tick node_ctxt ?start_state tick level = +let state_of_tick node_ctxt ?start_state ~tick level = let open Lwt_result_syntax in let level = Raw_level.to_int32 level in - let tick = Sc_rollup.Tick.to_z tick in let* event = Node_context.block_with_tick node_ctxt ~max_level:level tick in match event with | None -> return_none | Some event -> assert (event.header.level <= level) ; - let tick = Sc_rollup.Tick.of_z tick in let* result_state = if Node_context.is_loser node_ctxt then (* TODO: https://gitlab.com/tezos/tezos/-/issues/5253 diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.mli index 124eaa96b53d..acf81542788b 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.mli @@ -41,16 +41,16 @@ val process_head : Octez_smart_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Z.t) tzresult Lwt.t -(** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, +(** [state_of_tick node_ctxt ?start_state ~tick level] returns [Some (state, hash)] for a given [tick] if this [tick] happened before [level]. Otherwise, returns [None]. If provided, the evaluation is resumed from [start_state]. *) val state_of_tick : _ Node_context.t -> - ?start_state:Fueled_pvm.Accounted.eval_state -> - Sc_rollup.Tick.t -> + ?start_state:Fuel.Accounted.t Pvm_plugin_sig.eval_state -> + tick:Z.t -> Raw_level.t -> - Fueled_pvm.Accounted.eval_state option tzresult Lwt.t + Fuel.Accounted.t Pvm_plugin_sig.eval_state option tzresult Lwt.t (** [state_of_head node_ctxt ctxt head] returns the state corresponding to the block [head], or the state at rollup genesis if the block is before the diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.ml index 254e41b733b4..862f8f25eafb 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.ml @@ -180,3 +180,43 @@ let retrieve_genesis_info cctxt rollup_address = commitment_hash = Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; } + +let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = + let open Protocol in + let open Alpha_context in + let open Lwt_result_syntax in + let exception Found_boot_sector of string in + let* block = fetch_tezos_block node_ctxt.l1_ctxt block_hash in + let missing_boot_sector () = + failwith "Boot sector not found in Tezos block %a" Block_hash.pp block_hash + in + Lwt.catch + (fun () -> + let apply (type kind) accu ~source:_ (operation : kind manager_operation) + (result : kind Apply_results.successful_manager_operation_result) = + match (operation, result) with + | ( Sc_rollup_originate {boot_sector; _}, + Sc_rollup_originate_result {address; _} ) + when Octez_smart_rollup.Address.( + node_ctxt.rollup_address + = Sc_rollup_proto_types.Address.to_octez address) -> + raise (Found_boot_sector boot_sector) + | _ -> accu + in + let apply_internal (type kind) accu ~source:_ + (_operation : kind Apply_internal_results.internal_operation) + (_result : + kind Apply_internal_results.successful_internal_operation_result) = + accu + in + let*? () = + Layer1_services.( + process_applied_manager_operations + (Ok ()) + block.operations + {apply; apply_internal}) + in + missing_boot_sector ()) + (function + | Found_boot_sector boot_sector -> return boot_sector + | _ -> missing_boot_sector ()) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.mli index c82972f95ba0..76a3f7222957 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/layer1_helpers.mli @@ -68,3 +68,8 @@ val retrieve_constants : val retrieve_genesis_info : #Client_context.full -> Address.t -> Node_context.genesis_info tzresult Lwt.t + +(** [get_boot_sector block_hash node_ctxt] retrieves the boot sector from the + rollup origination operation in block [block_hash]. Precondition: + [block_hash] has to be the block where the rollup was originated. *) +val get_boot_sector : Block_hash.t -> _ Node_context.t -> string tzresult Lwt.t diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.ml new file mode 100644 index 000000000000..fbe612a4f49f --- /dev/null +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.ml @@ -0,0 +1,82 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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 Protocol +open Alpha_context + +let get_tick kind state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ tick = PVM.get_tick state in + Sc_rollup.Tick.to_z tick + +let state_hash kind state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ hash = PVM.state_hash state in + Sc_rollup_proto_types.State_hash.to_octez hash + +let initial_state kind = + let module PVM = (val Pvm.of_kind kind) in + PVM.initial_state ~empty:(PVM.State.empty ()) + +let parse_boot_sector kind = + let module PVM = (val Pvm.of_kind kind) in + PVM.parse_boot_sector + +let install_boot_sector kind state boot_sector = + let module PVM = (val Pvm.of_kind kind) in + PVM.install_boot_sector state boot_sector + +let get_status node_ctxt state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind node_ctxt.Node_context.kind) in + let+ status = PVM.get_status state in + PVM.string_of_status status + +let get_current_level kind state = + let open Lwt_option_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ current_level = PVM.get_current_level state in + Raw_level.to_int32 current_level + +module Fueled = Fueled_pvm + +let start_of_level_serialized = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized + +let end_of_level_serialized = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string end_of_level_serialized + +let protocol_migration_serialized = + let open Sc_rollup_inbox_message_repr in + Some (unsafe_to_string Raw_context.protocol_migration_serialized_message) + +let info_per_level_serialized ~predecessor ~predecessor_timestamp = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.mli new file mode 100644 index 000000000000..e0183f81e636 --- /dev/null +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_plugin.mli @@ -0,0 +1,27 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +include Pvm_plugin_sig.S diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game.ml index 66f4dc534390..5a6b60aaa7ed 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game.ml @@ -322,22 +322,26 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = type pvm_intermediate_state = | Hash of Sc_rollup.State_hash.t - | Evaluated of Fueled_pvm.Accounted.eval_state + | Evaluated of Fuel.Accounted.t Pvm_plugin_sig.eval_state let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok our_view = let open Lwt_result_syntax in let state_of_tick ?start_state tick = - Interpreter.state_of_tick node_ctxt ?start_state tick last_level + Interpreter.state_of_tick + node_ctxt + ?start_state + ~tick:(Sc_rollup.Tick.to_z tick) + last_level in - let state_hash_of_eval_state Fueled_pvm.Accounted.{state_hash; _} = - state_hash + let state_hash_of_eval_state Pvm_plugin_sig.{state_hash; _} = + Sc_rollup_proto_types.State_hash.of_octez state_hash in let start_hash, start_tick, start_state = match ok with | Hash hash, tick -> (hash, tick, None) | Evaluated ({state_hash; _} as state), tick -> - (state_hash, tick, Some state) + (Sc_rollup_proto_types.State_hash.of_octez state_hash, tick, Some state) in let start_chunk = Sc_rollup.Dissection_chunk.{state_hash = Some start_hash; tick = start_tick} @@ -345,7 +349,8 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok let our_state, our_tick = our_view in let our_state_hash = Option.map - (fun Fueled_pvm.Accounted.{state_hash; _} -> state_hash) + (fun Pvm_plugin_sig.{state_hash; _} -> + Sc_rollup_proto_types.State_hash.of_octez state_hash) our_state in let our_stop_chunk = @@ -397,7 +402,11 @@ let generate_next_dissection ~default_number_of_sections node_ctxt ~opponent | Evaluated ok_state, _ -> Some ok_state in let* our = - Interpreter.state_of_tick node_ctxt ?start_state tick game.inbox_level + Interpreter.state_of_tick + node_ctxt + ?start_state + ~tick:(Sc_rollup.Tick.to_z tick) + game.inbox_level in match (their_hash, our) with | None, None -> @@ -406,8 +415,11 @@ let generate_next_dissection ~default_number_of_sections node_ctxt ~opponent assert false | Some _, None | None, Some _ -> return (ok, (our, tick)) | Some their_hash, Some ({state_hash = our_hash; _} as our_state) -> - if Sc_rollup.State_hash.equal our_hash their_hash then - traverse (Evaluated our_state, tick) dissection + if + Sc_rollup.State_hash.equal + (Sc_rollup_proto_types.State_hash.of_octez our_hash) + their_hash + then traverse (Evaluated our_state, tick) dissection else return (ok, (our, tick))) in match dissection with @@ -439,7 +451,10 @@ let next_move node_ctxt ~opponent game = let open Lwt_result_syntax in let final_move start_tick = let* start_state = - Interpreter.state_of_tick node_ctxt start_tick game.inbox_level + Interpreter.state_of_tick + node_ctxt + ~tick:(Sc_rollup.Tick.to_z start_tick) + game.inbox_level in match start_state with | None -> diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.ml index 1a8c0a2f5564..2430502bbf78 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.ml @@ -66,6 +66,11 @@ let path data_dir pvm_name hash = let hash = Protocol.Sc_rollup_reveal_hash.to_hex hash in Filename.(concat (concat data_dir pvm_name) hash) +let proto_hash_to_dac_hash ((module Plugin) : Dac_plugin.t) proto_reveal_hash = + proto_reveal_hash + |> Data_encoding.Binary.to_bytes_exn Protocol.Sc_rollup_reveal_hash.encoding + |> Data_encoding.Binary.of_bytes_exn Plugin.encoding + let get ~data_dir ~pvm_kind ~hash = let open Lwt_result_syntax in let filename = @@ -94,3 +99,9 @@ let get ~data_dir ~pvm_kind ~hash = |> return in return contents + +let proto_hash_to_dac_hash proto_reveal_hash = + let dac_plugin = + WithExceptions.Option.get ~loc:__LOC__ @@ Dac_plugin.get Protocol.hash + in + proto_hash_to_dac_hash dac_plugin proto_reveal_hash diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.mli index f218cab75d38..53ad954bf3fe 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.mli @@ -71,3 +71,6 @@ val get : pvm_kind:Kind.t -> hash:Protocol.Sc_rollup_reveal_hash.t -> string tzresult Lwt.t + +(** Conversion from protocol reveal hash to protocol agnostic DAC hash. *) +val proto_hash_to_dac_hash : Protocol.Sc_rollup_reveal_hash.t -> Dac_plugin.hash diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml index 6d1642bf8f58..af7636f504dc 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml @@ -40,6 +40,8 @@ module Plugin : Protocol_plugin_sig.S = struct let process_l1_block_operations = Daemon.process_l1_block_operations end + + module Pvm = Pvm_plugin end let () = Protocol_plugins.register (module Plugin) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.ml index d557dbeb97e5..dd39c830ed3d 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.ml @@ -38,7 +38,7 @@ type t = { ctxt : Context.ro; inbox_level : int32; state : Context.tree; - reveal_map : string Sc_rollup_reveal_hash.Map.t option; + reveal_map : string Utils.Reveal_hash_map.t option; nb_messages_inbox : int; level_position : level_position; info_per_level : info_per_level; @@ -95,11 +95,11 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) let*! state_hash = PVM.state_hash state in let*! tick = PVM.get_tick state in let eval_state = - Fueled_pvm. + Pvm_plugin_sig. { state; - state_hash; - tick; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; + tick = Sc_rollup.Tick.to_z tick; inbox_level; message_counter_offset = nb_messages_inbox; remaining_fuel = Fuel.Free.of_ticks 0L; @@ -110,7 +110,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) let* eval_result = Fueled_pvm.eval_messages ?reveal_map node_ctxt eval_state in - let Fueled_pvm.{state = {state; _}; num_ticks; num_messages; _} = + let Pvm_plugin_sig.{state = {state; _}; num_ticks; num_messages; _} = Delayed_write_monad.ignore eval_result in let*! ctxt = PVM.State.set ctxt state in diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.mli index ac8d8dd03624..745ead3df562 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.mli @@ -23,7 +23,6 @@ (* *) (*****************************************************************************) -open Protocol open Protocol.Alpha_context module Fueled_pvm = Fueled_pvm.Free @@ -39,7 +38,7 @@ type t = { ctxt : Context.ro; inbox_level : int32; state : Context.tree; - reveal_map : string Sc_rollup_reveal_hash.Map.t option; + reveal_map : string Utils.Reveal_hash_map.t option; nb_messages_inbox : int; level_position : level_position; info_per_level : info_per_level; @@ -49,7 +48,7 @@ type t = { on top} of [block], i.e. for an hypothetical new inbox (level). *) val start_simulation : Node_context.ro -> - reveal_map:string Sc_rollup_reveal_hash.Map.t option -> + reveal_map:string Utils.Reveal_hash_map.t option -> Layer1.head -> t tzresult Lwt.t -- GitLab From b2c51b5089259c8405d77cb23c08698d350f0690 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 20 Jun 2023 15:58:06 +0200 Subject: [PATCH 08/11] SCORU/Node/Mumbai: PVM pluigin Backport of the commits: - SCORU/Node: ticks as Z in interpreter - SCORU/Node: use proto agnostic DAC plugin hashes for reveals map - SCORU/Node: move get_boot_sector to Layer1_helpers - SCORU/Node: PVM plugin definition --- .../lib_sc_rollup_node/RPC_directory.ml | 11 +-- .../lib_sc_rollup_node/fueled_pvm.ml | 84 +++---------------- .../lib_sc_rollup_node/interpreter.ml | 78 +++++------------ .../lib_sc_rollup_node/interpreter.mli | 8 +- .../lib_sc_rollup_node/layer1_helpers.ml | 40 +++++++++ .../lib_sc_rollup_node/layer1_helpers.mli | 5 ++ .../lib_sc_rollup_node/pvm_plugin.ml | 84 +++++++++++++++++++ .../lib_sc_rollup_node/pvm_plugin.mli | 27 ++++++ .../lib_sc_rollup_node/refutation_game.ml | 35 +++++--- .../lib_sc_rollup_node/reveals.ml | 11 +++ .../lib_sc_rollup_node/reveals.mli | 3 + .../lib_sc_rollup_node/rollup_node_plugin.ml | 2 + .../lib_sc_rollup_node/simulation.ml | 10 +-- .../lib_sc_rollup_node/simulation.mli | 5 +- 14 files changed, 249 insertions(+), 154 deletions(-) create mode 100644 src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.ml create mode 100644 src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.mli diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory.ml index 3f57f74af55a..543c032d20c0 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory.ml @@ -119,14 +119,15 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages let reveal_map = match reveal_pages with | Some pages -> + let (module DAC_plugin) = + WithExceptions.Option.get ~loc:__LOC__ @@ Dac_plugin.get Protocol.hash + in let map = List.fold_left (fun map page -> - let hash = - Sc_rollup_reveal_hash.(hash_string ~scheme:Blake2B [page]) - in - Sc_rollup_reveal_hash.Map.add hash page map) - Sc_rollup_reveal_hash.Map.empty + let hash = DAC_plugin.hash_string ~scheme:Blake2B [page] in + Utils.Reveal_hash_map.add hash page map) + Utils.Reveal_hash_map.empty pages in Some map diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/fueled_pvm.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/fueled_pvm.ml index bb35157ecaeb..4aa526d76528 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/fueled_pvm.ml @@ -26,82 +26,21 @@ open Protocol open Alpha_context module Inbox = Sc_rollup.Inbox -open Protocol -open Alpha_context - -module type S = sig - type fuel - - type pvm_state = Context.tree - - (** Evaluation state for the PVM. *) - type eval_state = { - state : pvm_state; (** The actual PVM state. *) - state_hash : Sc_rollup.State_hash.t; (** Hash of [state]. *) - tick : Sc_rollup.Tick.t; (** Tick of [state]. *) - inbox_level : int32; (** Inbox level in which messages are evaluated. *) - message_counter_offset : int; - (** Offset for message index, which corresponds to the number of - messages of the inbox already evaluated. *) - remaining_fuel : fuel; - (** Fuel remaining for the evaluation of the inbox. *) - remaining_messages : string list; - (** Messages of the inbox that remain to be evaluated. *) - } - - (** Evaluation result for the PVM which contains the evaluation state and - additional information. *) - type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} +open Pvm_plugin_sig - (** [eval_block_inbox ~fuel node_ctxt (inbox, messages) state] evaluates the - [messages] for the [inbox] in the given [state] of the PVM and returns the - evaluation result containing the new state, the number of messages, the - inbox level and the remaining fuel. *) - val eval_block_inbox : - fuel:fuel -> - _ Node_context.t -> - Octez_smart_rollup.Inbox.t * string list -> - pvm_state -> - eval_result Node_context.delayed_write tzresult Lwt.t - - (** [eval_messages ?reveal_map ~fuel node_ctxt ~message_counter_offset state - inbox_level messages] evaluates the [messages] for inbox level - [inbox_level] in the given [state] of the PVM and returns the evaluation - results containing the new state, the remaining fuel, and the number of - ticks for the evaluation of these messages. If [messages] is empty, the - PVM progresses until the next input request (within the allocated - [fuel]). [message_counter_offset] is used when we evaluate partial - inboxes, such as during simulation. When [reveal_map] is provided, it is - used as an additional source of data for revelation ticks. *) - val eval_messages : - ?reveal_map:string Sc_rollup_reveal_hash.Map.t -> - _ Node_context.t -> - eval_state -> - eval_result Node_context.delayed_write tzresult Lwt.t -end - -module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct +module Make_fueled (F : Fuel.S) : FUELED_PVM with type fuel = F.t = struct type fuel = F.t type pvm_state = Context.tree - type eval_state = { - state : pvm_state; - state_hash : Sc_rollup.State_hash.t; - tick : Sc_rollup.Tick.t; - inbox_level : int32; - message_counter_offset : int; - remaining_fuel : fuel; - remaining_messages : string list; - } - - type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} - let get_reveal ~data_dir ~pvm_kind reveal_map hash = let found_in_map = match reveal_map with | None -> None - | Some map -> Sc_rollup_reveal_hash.Map.find_opt hash map + | Some map -> + Utils.Reveal_hash_map.find_opt + (Reveals.proto_hash_to_dac_hash hash) + map in match found_in_map with | Some data -> return data @@ -427,7 +366,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_block_inbox ~fuel (node_ctxt : _ Node_context.t) (inbox, messages) (state : pvm_state) : - eval_result Node_context.delayed_write tzresult Lwt.t = + fuel eval_result Node_context.delayed_write tzresult Lwt.t = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in let module PVM = (val Pvm.of_kind node_ctxt.kind) in @@ -451,8 +390,8 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_state = { state; - state_hash; - tick = final_tick; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; + tick = Sc_rollup.Tick.to_z final_tick; inbox_level; message_counter_offset = num_messages; remaining_fuel; @@ -513,12 +452,13 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct messages in let*! final_tick = PVM.get_tick state in + let final_tick = Sc_rollup.Tick.to_z final_tick in let*! state_hash = PVM.state_hash state in - let num_ticks = Sc_rollup.Tick.distance initial_tick final_tick in + let num_ticks = Z.sub final_tick initial_tick in let eval_state = { state; - state_hash; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; tick = final_tick; inbox_level; message_counter_offset = message_counter_offset + num_messages; diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.ml index b246c1777d1f..1a72e4792bf8 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.ml @@ -26,48 +26,23 @@ open Protocol open Alpha_context -(** [get_boot_sector block_hash node_ctxt] fetches the operations in the - [block_hash] and looks for the bootsector used to originate the rollup we're - following. It must be called with [block_hash.level] = - [node_ctxt.genesis_info.level]. *) let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in - let exception Found_boot_sector of string in - let* block = Layer1_helpers.fetch_tezos_block node_ctxt.l1_ctxt block_hash in - let missing_boot_sector () = - failwith "Boot sector not found in Tezos block %a" Block_hash.pp block_hash - in - Lwt.catch - (fun () -> - let apply (type kind) accu ~source:_ (operation : kind manager_operation) - (result : kind Apply_results.successful_manager_operation_result) = - match (operation, result) with - | ( Sc_rollup_originate {kind; boot_sector; _}, - Sc_rollup_originate_result {address; _} ) - when Octez_smart_rollup.Address.( - node_ctxt.rollup_address - = Sc_rollup_proto_types.Address.to_octez address) - && node_ctxt.kind = Sc_rollup_proto_types.Kind.to_octez kind -> - raise (Found_boot_sector boot_sector) - | _ -> accu - in - let apply_internal (type kind) accu ~source:_ - (_operation : kind Apply_internal_results.internal_operation) - (_result : - kind Apply_internal_results.successful_internal_operation_result) = - accu - in - let*? () = - Layer1_services.( - process_applied_manager_operations - (Ok ()) - block.operations - {apply; apply_internal}) + match node_ctxt.boot_sector_file with + | None -> Layer1_helpers.get_boot_sector block_hash node_ctxt + | Some boot_sector_file -> + let module PVM = (val Pvm.of_kind node_ctxt.kind) in + let*! boot_sector = Lwt_utils_unix.read_file boot_sector_file in + let*? boot_sector = + Option.value_e + ~error: + [ + Sc_rollup_node_errors.Unparsable_boot_sector + {path = boot_sector_file}; + ] + (PVM.parse_boot_sector boot_sector) in - missing_boot_sector ()) - (function - | Found_boot_sector boot_sector -> return boot_sector - | _ -> missing_boot_sector ()) + return boot_sector let genesis_state block_hash node_ctxt ctxt = let open Lwt_result_syntax in @@ -110,8 +85,6 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} } = Delayed_write_monad.apply node_ctxt eval_result in - let state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash in - let tick = Sc_rollup.Tick.to_z tick in let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! ctxt = PVM.State.set ctxt state in let*! initial_tick = PVM.get_tick predecessor_state in @@ -178,12 +151,12 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = @ [unsafe_to_string end_of_level_serialized] in return - Fueled_pvm.Accounted. + Pvm_plugin_sig. { state; - state_hash; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; inbox_level; - tick; + tick = Sc_rollup.Tick.to_z tick; message_counter_offset = 0; remaining_fuel = Fuel.Accounted.of_ticks 0L; remaining_messages = messages; @@ -194,8 +167,7 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = let run_to_tick node_ctxt start_state tick = let open Delayed_write_monad.Lwt_result_syntax in let tick_distance = - Sc_rollup.Tick.distance tick start_state.Fueled_pvm.Accounted.tick - |> Z.to_int64 + Z.sub tick start_state.Pvm_plugin_sig.tick |> Z.to_int64 in let>+ eval_result = Fueled_pvm.Accounted.eval_messages @@ -209,7 +181,7 @@ let state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) tick = let* start_state = match start_state with | Some start_state - when start_state.Fueled_pvm.Accounted.inbox_level = event.header.level -> + when start_state.Pvm_plugin_sig.inbox_level = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a @@ -229,13 +201,11 @@ module Tick_state_cache = (Aches.Rache.Transfer (Aches.Rache.LRU) (struct - type t = Sc_rollup.Tick.t * Block_hash.t + type t = Z.t * Block_hash.t - let equal (t1, b1) (t2, b2) = - Sc_rollup.Tick.(t1 = t2) && Block_hash.(b1 = b2) + let equal (t1, b1) (t2, b2) = Z.equal t1 t2 && Block_hash.(b1 = b2) - let hash (tick, block) = - ((Sc_rollup.Tick.to_z tick |> Z.hash) * 13) + Block_hash.hash block + let hash (tick, block) = (Z.hash tick * 13) + Block_hash.hash block end)) let tick_state_cache = Tick_state_cache.create 64 (* size of 2 dissections *) @@ -252,16 +222,14 @@ let memo_state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) (** [state_of_tick node_ctxt ?start_state tick level] returns [Some end_state] for a given [tick] if this [tick] happened before [level]. Otherwise, returns [None].*) -let state_of_tick node_ctxt ?start_state tick level = +let state_of_tick node_ctxt ?start_state ~tick level = let open Lwt_result_syntax in let level = Raw_level.to_int32 level in - let tick = Sc_rollup.Tick.to_z tick in let* event = Node_context.block_with_tick node_ctxt ~max_level:level tick in match event with | None -> return_none | Some event -> assert (event.header.level <= level) ; - let tick = Sc_rollup.Tick.of_z tick in let* result_state = if Node_context.is_loser node_ctxt then (* TODO: https://gitlab.com/tezos/tezos/-/issues/5253 diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.mli index 124eaa96b53d..acf81542788b 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.mli @@ -41,16 +41,16 @@ val process_head : Octez_smart_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Z.t) tzresult Lwt.t -(** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, +(** [state_of_tick node_ctxt ?start_state ~tick level] returns [Some (state, hash)] for a given [tick] if this [tick] happened before [level]. Otherwise, returns [None]. If provided, the evaluation is resumed from [start_state]. *) val state_of_tick : _ Node_context.t -> - ?start_state:Fueled_pvm.Accounted.eval_state -> - Sc_rollup.Tick.t -> + ?start_state:Fuel.Accounted.t Pvm_plugin_sig.eval_state -> + tick:Z.t -> Raw_level.t -> - Fueled_pvm.Accounted.eval_state option tzresult Lwt.t + Fuel.Accounted.t Pvm_plugin_sig.eval_state option tzresult Lwt.t (** [state_of_head node_ctxt ctxt head] returns the state corresponding to the block [head], or the state at rollup genesis if the block is before the diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.ml index cf934fb1b3e7..6a56c29476b0 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.ml @@ -181,3 +181,43 @@ let retrieve_genesis_info cctxt rollup_address = commitment_hash = Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; } + +let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = + let open Protocol in + let open Alpha_context in + let open Lwt_result_syntax in + let exception Found_boot_sector of string in + let* block = fetch_tezos_block node_ctxt.l1_ctxt block_hash in + let missing_boot_sector () = + failwith "Boot sector not found in Tezos block %a" Block_hash.pp block_hash + in + Lwt.catch + (fun () -> + let apply (type kind) accu ~source:_ (operation : kind manager_operation) + (result : kind Apply_results.successful_manager_operation_result) = + match (operation, result) with + | ( Sc_rollup_originate {boot_sector; _}, + Sc_rollup_originate_result {address; _} ) + when Octez_smart_rollup.Address.( + node_ctxt.rollup_address + = Sc_rollup_proto_types.Address.to_octez address) -> + raise (Found_boot_sector boot_sector) + | _ -> accu + in + let apply_internal (type kind) accu ~source:_ + (_operation : kind Apply_internal_results.internal_operation) + (_result : + kind Apply_internal_results.successful_internal_operation_result) = + accu + in + let*? () = + Layer1_services.( + process_applied_manager_operations + (Ok ()) + block.operations + {apply; apply_internal}) + in + missing_boot_sector ()) + (function + | Found_boot_sector boot_sector -> return boot_sector + | _ -> missing_boot_sector ()) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.mli index c82972f95ba0..76a3f7222957 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/layer1_helpers.mli @@ -68,3 +68,8 @@ val retrieve_constants : val retrieve_genesis_info : #Client_context.full -> Address.t -> Node_context.genesis_info tzresult Lwt.t + +(** [get_boot_sector block_hash node_ctxt] retrieves the boot sector from the + rollup origination operation in block [block_hash]. Precondition: + [block_hash] has to be the block where the rollup was originated. *) +val get_boot_sector : Block_hash.t -> _ Node_context.t -> string tzresult Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.ml new file mode 100644 index 000000000000..345a8a4e808b --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.ml @@ -0,0 +1,84 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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 Protocol +open Alpha_context + +let get_tick kind state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ tick = PVM.get_tick state in + Sc_rollup.Tick.to_z tick + +let state_hash kind state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ hash = PVM.state_hash state in + Sc_rollup_proto_types.State_hash.to_octez hash + +let initial_state kind = + let module PVM = (val Pvm.of_kind kind) in + PVM.initial_state ~empty:(PVM.State.empty ()) + +let parse_boot_sector kind = + let module PVM = (val Pvm.of_kind kind) in + PVM.parse_boot_sector + +let install_boot_sector kind state boot_sector = + let module PVM = (val Pvm.of_kind kind) in + PVM.install_boot_sector state boot_sector + +let get_status node_ctxt state = + let open Lwt_syntax in + let module PVM = (val Pvm.of_kind node_ctxt.Node_context.kind) in + let+ status = PVM.get_status state in + PVM.string_of_status status + +let get_current_level kind state = + let open Lwt_option_syntax in + let module PVM = (val Pvm.of_kind kind) in + let+ current_level = PVM.get_current_level state in + Raw_level.to_int32 current_level + +module Fueled = Fueled_pvm + +let start_of_level_serialized = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized + +let end_of_level_serialized = + let open Sc_rollup_inbox_message_repr in + unsafe_to_string end_of_level_serialized + +let protocol_migration_serialized = None + +let info_per_level_serialized ~predecessor ~predecessor_timestamp = + let info_per_level = + WithExceptions.Result.get_ok ~loc:__LOC__ + @@ Sc_rollup_inbox_message_repr.( + serialize + (Internal (Info_per_level {predecessor; predecessor_timestamp}))) + in + Sc_rollup_inbox_message_repr.unsafe_to_string info_per_level diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.mli new file mode 100644 index 000000000000..e0183f81e636 --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_plugin.mli @@ -0,0 +1,27 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +include Pvm_plugin_sig.S diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game.ml index a823250a21b3..38b0f8895d1c 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game.ml @@ -321,22 +321,26 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = type pvm_intermediate_state = | Hash of Sc_rollup.State_hash.t - | Evaluated of Fueled_pvm.Accounted.eval_state + | Evaluated of Fuel.Accounted.t Pvm_plugin_sig.eval_state let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok our_view = let open Lwt_result_syntax in let state_of_tick ?start_state tick = - Interpreter.state_of_tick node_ctxt ?start_state tick last_level + Interpreter.state_of_tick + node_ctxt + ?start_state + ~tick:(Sc_rollup.Tick.to_z tick) + last_level in - let state_hash_of_eval_state Fueled_pvm.Accounted.{state_hash; _} = - state_hash + let state_hash_of_eval_state Pvm_plugin_sig.{state_hash; _} = + Sc_rollup_proto_types.State_hash.of_octez state_hash in let start_hash, start_tick, start_state = match ok with | Hash hash, tick -> (hash, tick, None) | Evaluated ({state_hash; _} as state), tick -> - (state_hash, tick, Some state) + (Sc_rollup_proto_types.State_hash.of_octez state_hash, tick, Some state) in let start_chunk = Sc_rollup.Dissection_chunk.{state_hash = Some start_hash; tick = start_tick} @@ -344,7 +348,8 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok let our_state, our_tick = our_view in let our_state_hash = Option.map - (fun Fueled_pvm.Accounted.{state_hash; _} -> state_hash) + (fun Pvm_plugin_sig.{state_hash; _} -> + Sc_rollup_proto_types.State_hash.of_octez state_hash) our_state in let our_stop_chunk = @@ -396,7 +401,11 @@ let generate_next_dissection ~default_number_of_sections node_ctxt ~opponent | Evaluated ok_state, _ -> Some ok_state in let* our = - Interpreter.state_of_tick node_ctxt ?start_state tick game.inbox_level + Interpreter.state_of_tick + node_ctxt + ?start_state + ~tick:(Sc_rollup.Tick.to_z tick) + game.inbox_level in match (their_hash, our) with | None, None -> @@ -405,8 +414,11 @@ let generate_next_dissection ~default_number_of_sections node_ctxt ~opponent assert false | Some _, None | None, Some _ -> return (ok, (our, tick)) | Some their_hash, Some ({state_hash = our_hash; _} as our_state) -> - if Sc_rollup.State_hash.equal our_hash their_hash then - traverse (Evaluated our_state, tick) dissection + if + Sc_rollup.State_hash.equal + (Sc_rollup_proto_types.State_hash.of_octez our_hash) + their_hash + then traverse (Evaluated our_state, tick) dissection else return (ok, (our, tick))) in match dissection with @@ -438,7 +450,10 @@ let next_move node_ctxt ~opponent game = let open Lwt_result_syntax in let final_move start_tick = let* start_state = - Interpreter.state_of_tick node_ctxt start_tick game.inbox_level + Interpreter.state_of_tick + node_ctxt + ~tick:(Sc_rollup.Tick.to_z start_tick) + game.inbox_level in match start_state with | None -> diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.ml index a64538301d1c..eccd18d9b857 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.ml @@ -75,6 +75,11 @@ let path data_dir pvm_name hash = let hash = hash_to_hex hash in Filename.(concat (concat data_dir pvm_name) hash) +let proto_hash_to_dac_hash ((module Plugin) : Dac_plugin.t) proto_reveal_hash = + proto_reveal_hash + |> Data_encoding.Binary.to_bytes_exn Protocol.Sc_rollup_reveal_hash.encoding + |> Data_encoding.Binary.of_bytes_exn Plugin.encoding + let get ~data_dir ~pvm_kind ~hash = let open Lwt_result_syntax in let filename = @@ -103,3 +108,9 @@ let get ~data_dir ~pvm_kind ~hash = |> return in return contents + +let proto_hash_to_dac_hash proto_reveal_hash = + let dac_plugin = + WithExceptions.Option.get ~loc:__LOC__ @@ Dac_plugin.get Protocol.hash + in + proto_hash_to_dac_hash dac_plugin proto_reveal_hash diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.mli index f218cab75d38..53ad954bf3fe 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.mli @@ -71,3 +71,6 @@ val get : pvm_kind:Kind.t -> hash:Protocol.Sc_rollup_reveal_hash.t -> string tzresult Lwt.t + +(** Conversion from protocol reveal hash to protocol agnostic DAC hash. *) +val proto_hash_to_dac_hash : Protocol.Sc_rollup_reveal_hash.t -> Dac_plugin.hash diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml index 6d1642bf8f58..af7636f504dc 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml @@ -40,6 +40,8 @@ module Plugin : Protocol_plugin_sig.S = struct let process_l1_block_operations = Daemon.process_l1_block_operations end + + module Pvm = Pvm_plugin end let () = Protocol_plugins.register (module Plugin) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.ml index ae34e8b10bc3..1b578613831f 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.ml @@ -38,7 +38,7 @@ type t = { ctxt : Context.ro; inbox_level : int32; state : Context.tree; - reveal_map : string Sc_rollup_reveal_hash.Map.t option; + reveal_map : string Utils.Reveal_hash_map.t option; nb_messages_inbox : int; level_position : level_position; info_per_level : info_per_level; @@ -95,11 +95,11 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) let*! state_hash = PVM.state_hash state in let*! tick = PVM.get_tick state in let eval_state = - Fueled_pvm. + Pvm_plugin_sig. { state; - state_hash; - tick; + state_hash = Sc_rollup_proto_types.State_hash.to_octez state_hash; + tick = Sc_rollup.Tick.to_z tick; inbox_level; message_counter_offset = nb_messages_inbox; remaining_fuel = Fuel.Free.of_ticks 0L; @@ -110,7 +110,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) let* eval_result = Fueled_pvm.eval_messages ?reveal_map node_ctxt eval_state in - let Fueled_pvm.{state = {state; _}; num_ticks; num_messages; _} = + let Pvm_plugin_sig.{state = {state; _}; num_ticks; num_messages; _} = Delayed_write_monad.ignore eval_result in let*! ctxt = PVM.State.set ctxt state in diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.mli index ac8d8dd03624..745ead3df562 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.mli @@ -23,7 +23,6 @@ (* *) (*****************************************************************************) -open Protocol open Protocol.Alpha_context module Fueled_pvm = Fueled_pvm.Free @@ -39,7 +38,7 @@ type t = { ctxt : Context.ro; inbox_level : int32; state : Context.tree; - reveal_map : string Sc_rollup_reveal_hash.Map.t option; + reveal_map : string Utils.Reveal_hash_map.t option; nb_messages_inbox : int; level_position : level_position; info_per_level : info_per_level; @@ -49,7 +48,7 @@ type t = { on top} of [block], i.e. for an hypothetical new inbox (level). *) val start_simulation : Node_context.ro -> - reveal_map:string Sc_rollup_reveal_hash.Map.t option -> + reveal_map:string Utils.Reveal_hash_map.t option -> Layer1.head -> t tzresult Lwt.t -- GitLab From 52d85dd7131771e25715ff1c2e38e118b20d8010 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Wed, 28 Jun 2023 10:01:03 +0200 Subject: [PATCH 09/11] SCORU/Node: Protocol plugin requires PVM plugin --- src/lib_smart_rollup_node/protocol_plugin_sig.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib_smart_rollup_node/protocol_plugin_sig.ml b/src/lib_smart_rollup_node/protocol_plugin_sig.ml index 892090be5908..2c9f52ef6931 100644 --- a/src/lib_smart_rollup_node/protocol_plugin_sig.ml +++ b/src/lib_smart_rollup_node/protocol_plugin_sig.ml @@ -297,4 +297,6 @@ module type S = sig module Layer1_helpers : LAYER1_HELPERS module L1_processing : L1_PROCESSING + + module Pvm : Pvm_plugin_sig.S end -- GitLab From 6088b77848e54d4877c853d6d3ea65edf56f1143 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 29 Jun 2023 23:20:41 +0200 Subject: [PATCH 10/11] SCORU/Node: function to retrieve last protocol --- src/lib_smart_rollup_node/node_context.ml | 7 +++++++ src/lib_smart_rollup_node/node_context.mli | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/lib_smart_rollup_node/node_context.ml b/src/lib_smart_rollup_node/node_context.ml index 477c124b2690..83c8bc771647 100644 --- a/src/lib_smart_rollup_node/node_context.ml +++ b/src/lib_smart_rollup_node/node_context.ml @@ -756,6 +756,13 @@ let protocol_of_level node_ctxt level = in Lwt.return (find protocols) +let last_seen_protocol node_ctxt = + let open Lwt_result_syntax in + let+ protocols = Store.Protocols.read node_ctxt.store.protocols in + match protocols with + | None | Some [] -> None + | Some (p :: _) -> Some p.protocol + let save_protocol_info node_ctxt (block : Layer1.header) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in diff --git a/src/lib_smart_rollup_node/node_context.mli b/src/lib_smart_rollup_node/node_context.mli index 7554562347b9..69c9b0bbb661 100644 --- a/src/lib_smart_rollup_node/node_context.mli +++ b/src/lib_smart_rollup_node/node_context.mli @@ -383,6 +383,9 @@ type proto_info = { (** [protocol_of_level t level] returns the protocol of block level [level]. *) val protocol_of_level : _ t -> int32 -> proto_info tzresult Lwt.t +(** Returns the last protocol seen by the rollup node. *) +val last_seen_protocol : _ t -> Protocol_hash.t option tzresult Lwt.t + (** [save_protocol_info t block ~predecessor] saves to disk the protocol information associated to the [block], if there is a protocol change between [block] and [predecessor]. *) -- GitLab From b9bb8f5296cc3afb3227741b3f169c62ff7e94e4 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 4 Jul 2023 12:18:57 +0200 Subject: [PATCH 11/11] SCORU/Node: functions to retrieve correct plugin --- src/lib_smart_rollup_node/protocol_plugins.ml | 24 +++++++++++++++++-- .../protocol_plugins.mli | 20 ++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/lib_smart_rollup_node/protocol_plugins.ml b/src/lib_smart_rollup_node/protocol_plugins.ml index 01571759461c..5c4919b15a44 100644 --- a/src/lib_smart_rollup_node/protocol_plugins.ml +++ b/src/lib_smart_rollup_node/protocol_plugins.ml @@ -57,9 +57,29 @@ let register (plugin : proto_plugin) = Plugin.protocol ; Protocol_hash.Table.add proto_plugins Plugin.protocol plugin +let registered_protocols () = + Protocol_hash.Table.to_seq_keys proto_plugins |> List.of_seq + let proto_plugin_for_protocol protocol = Protocol_hash.Table.find proto_plugins protocol |> Option.to_result ~none:[Unsupported_protocol protocol] -let registered_protocols () = - Protocol_hash.Table.to_seq_keys proto_plugins |> List.of_seq +let proto_plugin_for_level node_ctxt level = + let open Lwt_result_syntax in + let* {protocol; _} = Node_context.protocol_of_level node_ctxt level in + let*? plugin = proto_plugin_for_protocol protocol in + return plugin + +let proto_plugin_for_block node_ctxt block_hash = + let open Lwt_result_syntax in + let* level = Node_context.level_of_hash node_ctxt block_hash in + proto_plugin_for_level node_ctxt level + +let last_proto_plugin node_ctxt = + let open Lwt_result_syntax in + let* protocol = Node_context.last_seen_protocol node_ctxt in + match protocol with + | None -> failwith "No known last protocol, cannot get plugin" + | Some protocol -> + let*? plugin = proto_plugin_for_protocol protocol in + return plugin diff --git a/src/lib_smart_rollup_node/protocol_plugins.mli b/src/lib_smart_rollup_node/protocol_plugins.mli index 8da839659113..f846f0415958 100644 --- a/src/lib_smart_rollup_node/protocol_plugins.mli +++ b/src/lib_smart_rollup_node/protocol_plugins.mli @@ -29,9 +29,25 @@ type proto_plugin = (module Protocol_plugin_sig.S) rollup node. *) val register : proto_plugin -> unit +(** Returns the list of registered protocols. *) +val registered_protocols : unit -> Protocol_hash.t list + +(** {2 Using the correct protocol plugin} *) + (** Return the protocol plugin for a given protocol (or an error if not supported). *) val proto_plugin_for_protocol : Protocol_hash.t -> proto_plugin tzresult -(** Returns the list of registered protocols. *) -val registered_protocols : unit -> Protocol_hash.t list +(** Return the protocol plugin for a given level (or an error if not + supported). *) +val proto_plugin_for_level : + _ Node_context.t -> int32 -> proto_plugin tzresult Lwt.t + +(** Return the protocol plugin for a given block (or an error if not + supported). *) +val proto_plugin_for_block : + _ Node_context.t -> Block_hash.t -> proto_plugin tzresult Lwt.t + +(** Returns the plugin corresponding to the last protocol seen by the rollup + node. *) +val last_proto_plugin : _ Node_context.t -> proto_plugin tzresult Lwt.t -- GitLab