From 70cdb4ea74154d94fc19ec897283e96820ff896e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Mon, 3 Jul 2023 11:20:37 +0200 Subject: [PATCH 01/15] SCORU/Node: custom protocol constants --- src/lib_smart_rollup/rollup_constants.ml | 51 +++++++++++++++++++ .../sc_rollup_proto_types.ml | 23 +++++++++ .../sc_rollup_proto_types.mli | 13 +++++ .../lib_sc_rollup_node/RPC_server.ml | 3 +- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 22 ++++++-- .../lib_sc_rollup_node/dal_slots_tracker.ml | 21 ++++---- .../lib_sc_rollup_node/fueled_pvm.ml | 11 ++-- .../lib_sc_rollup_node/layer1_helpers.ml | 32 ++++++++++++ .../lib_sc_rollup_node/layer1_helpers.mli | 5 ++ .../lib_sc_rollup_node/node_context.ml | 41 ++++----------- .../lib_sc_rollup_node/node_context.mli | 12 +++-- .../lib_sc_rollup_node/publisher.ml | 5 +- .../lib_sc_rollup_node/refutation_game.ml | 8 ++- .../test/helpers/helpers.ml | 22 ++++---- .../test/helpers/helpers.mli | 4 +- 15 files changed, 198 insertions(+), 75 deletions(-) create mode 100644 src/lib_smart_rollup/rollup_constants.ml diff --git a/src/lib_smart_rollup/rollup_constants.ml b/src/lib_smart_rollup/rollup_constants.ml new file mode 100644 index 000000000000..728262942373 --- /dev/null +++ b/src/lib_smart_rollup/rollup_constants.ml @@ -0,0 +1,51 @@ +(*****************************************************************************) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** Protocol agnostic representation for protocol constants. *) + +type dal_constants = { + feature_enable : bool; + attestation_lag : int; + number_of_slots : int; +} + +type reveal_activation_level = { + blake2B : int32; + metadata : int32; + dal_page : int32; +} + +type sc_rollup_constants = { + challenge_window_in_blocks : int; + commitment_period_in_blocks : int; + reveal_activation_level : reveal_activation_level option; +} + +type protocol_constants = { + minimal_block_delay : int64; + delay_increment_per_round : int64; + sc_rollup : sc_rollup_constants; + dal : dal_constants; +} diff --git a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.ml b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.ml index daef0157af63..b85e403c010d 100644 --- a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.ml +++ b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.ml @@ -322,3 +322,26 @@ module Dal = struct Octez_smart_rollup.Dal.Slot_history_cache.encoding end end + +module Constants = struct + type reveal_activation_level = + Constants.Parametric.sc_rollup_reveal_activation_level + + let reveal_activation_level_of_octez + Octez_smart_rollup.Rollup_constants.{blake2B; metadata; dal_page} : + reveal_activation_level = + { + raw_data = {blake2B = Raw_level.of_int32_exn blake2B}; + metadata = Raw_level.of_int32_exn metadata; + dal_page = Raw_level.of_int32_exn dal_page; + } + + let reveal_activation_level_to_octez + Constants.Parametric.{raw_data = {blake2B}; metadata; dal_page} : + Octez_smart_rollup.Rollup_constants.reveal_activation_level = + { + blake2B = Raw_level.to_int32 blake2B; + metadata = Raw_level.to_int32 metadata; + dal_page = Raw_level.to_int32 dal_page; + } +end diff --git a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.mli b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.mli index b20fa0dcd218..e1426d860a98 100644 --- a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.mli +++ b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_proto_types.mli @@ -160,3 +160,16 @@ module Dal : sig val to_octez : t -> Octez_smart_rollup.Dal.Slot_history_cache.t end end + +module Constants : sig + type reveal_activation_level = + Constants.Parametric.sc_rollup_reveal_activation_level + + val reveal_activation_level_of_octez : + Octez_smart_rollup.Rollup_constants.reveal_activation_level -> + reveal_activation_level + + val reveal_activation_level_to_octez : + reveal_activation_level -> + Octez_smart_rollup.Rollup_constants.reveal_activation_level +end diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml index 9f429eed2452..35d0bf020c3a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml @@ -399,8 +399,7 @@ let commitment_level_of_inbox_level (node_ctxt : _ Node_context.t) inbox_level = let+ last_published_commitment = Reference.get node_ctxt.lpc in let commitment_period = Int32.of_int - node_ctxt.protocol_constants.parametric.sc_rollup - .commitment_period_in_blocks + node_ctxt.protocol_constants.sc_rollup.commitment_period_in_blocks in let last_published = Raw_level.to_int32 last_published_commitment.inbox_level diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index 042f606463da..f38295ebadd2 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -639,12 +639,9 @@ let run node_ctxt configuration { cctxt = (node_ctxt.cctxt :> Client_context.full); fee_parameters = configuration.fee_parameters; - minimal_block_delay = - node_ctxt.protocol_constants.Constants.parametric - .minimal_block_delay |> Period.to_seconds; + minimal_block_delay = node_ctxt.protocol_constants.minimal_block_delay; delay_increment_per_round = - node_ctxt.protocol_constants.Constants.parametric - .delay_increment_per_round |> Period.to_seconds; + node_ctxt.protocol_constants.delay_increment_per_round; } ~data_dir:node_ctxt.data_dir ~signers @@ -794,6 +791,19 @@ module Internal_for_tests = struct return l2_block end +(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 + The constants are retrieved from the latest tezos block. These constants can + be different from the ones used at the creation at the rollup because of a + protocol amendment that modifies some of them. This need to be fixed when the + rollup nodes will be able to handle the migration of protocol. +*) +let retrieve_constants cctxt = + let open Lwt_result_syntax in + let+ {parametric; _} = + Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) + in + Layer1_helpers.constants_of_parametric parametric + module Rollup_node_daemon_components : Daemon_components.S = struct module Batcher = Batcher module RPC_server = RPC_server @@ -830,6 +840,7 @@ let run Layer1.fetch_tezos_shell_header l1_ctxt head.header.predecessor in let*! () = Event.received_first_block head.hash Protocol.hash in + let* constants = retrieve_constants cctxt in let* node_ctxt = Node_context.init cctxt @@ -837,6 +848,7 @@ let run ?log_kernel_debug_file Read_write l1_ctxt + constants ~proto_level:predecessor.proto_level configuration in diff --git a/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml b/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml index 9d73b5447eb2..1bc869c4ff4f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml +++ b/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml @@ -68,9 +68,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = we reduce the lag to 1, then the slots header will never be confirmed. *) let open Lwt_result_syntax in - let lag = - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag - in + let lag = node_ctxt.Node_context.protocol_constants.dal.attestation_lag in (* we are downloading endorsemented for slots at level [level], so we need to download the data at level [level - lag]. *) @@ -119,7 +117,8 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3884 avoid going back and forth between bitsets and lists of slot indexes. *) -let to_slot_index_list (constants : Constants.Parametric.t) bitset = +let to_slot_index_list (constants : Rollup_constants.protocol_constants) bitset + = let open Result_syntax in let number_of_slots = constants.dal.number_of_slots in let all_slots = Misc.(0 --> (number_of_slots - 1)) in @@ -140,17 +139,17 @@ let download_and_save_slots {published_block_hash; confirmed_slots_indexes} = let open Lwt_result_syntax in let*? all_slots = - Bitset.fill ~length:protocol_constants.parametric.dal.number_of_slots + Bitset.fill ~length:protocol_constants.dal.number_of_slots |> Environment.wrap_tzresult in let*? not_confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric + @@ to_slot_index_list protocol_constants @@ Bitset.diff all_slots confirmed_slots_indexes in let*? confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric confirmed_slots_indexes + @@ to_slot_index_list protocol_constants confirmed_slots_indexes in (* The contents of each slot index are written to a different location on disk, therefore calls to store contents for different slot indexes can @@ -193,7 +192,7 @@ module Confirmed_slots_history = struct let*? relevant_slots_indexes = Environment.wrap_tzresult @@ to_slot_index_list - node_ctxt.Node_context.protocol_constants.parametric + node_ctxt.Node_context.protocol_constants confirmed_slots_indexes in List.map_ep @@ -220,8 +219,7 @@ module Confirmed_slots_history = struct let should_process_dal_slots node_ctxt block_level = let open Node_context in let lag = - Int32.of_int - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag + Int32.of_int node_ctxt.Node_context.protocol_constants.dal.attestation_lag in let block_level = Raw_level.to_int32 block_level in let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in @@ -274,8 +272,7 @@ module Confirmed_slots_history = struct ~find:Node_context.find_confirmed_slots_histories ~default:(fun node_ctxt _block -> let num_slots = - node_ctxt.Node_context.protocol_constants.parametric.dal - .number_of_slots + node_ctxt.Node_context.protocol_constants.dal.number_of_slots in (* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3788 Put an accurate value for capacity. The value 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 105475761166..32ada8e6b5ef 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -130,15 +130,18 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct message_index ~fuel start_tick failing_ticks state = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5871 + Use constants for correct protocol. *) let is_reveal_enabled = - Sc_rollup.is_reveal_enabled_predicate - node_ctxt.protocol_constants.parametric.sc_rollup - .reveal_activation_level + node_ctxt.protocol_constants.sc_rollup.reveal_activation_level + |> WithExceptions.Option.get ~loc:__LOC__ + |> Sc_rollup_proto_types.Constants.reveal_activation_level_of_octez + |> Sc_rollup.is_reveal_enabled_predicate in let module PVM = (val node_ctxt.pvm) in let metadata = Node_context.metadata node_ctxt in let dal_attestation_lag = - node_ctxt.protocol_constants.parametric.dal.attestation_lag + node_ctxt.protocol_constants.dal.attestation_lag in let reveal_builtins = Tezos_scoru_wasm.Builtins. 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 8312c2584373..a7ae7b7db7bc 100644 --- a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml @@ -52,3 +52,35 @@ let fetch_tezos_block l1_ctxt hash = Protocol.name let prefetch_tezos_blocks = Layer1.prefetch_tezos_blocks fetch extract_header + +let constants_of_parametric + Protocol.Alpha_context.Constants.Parametric. + { + minimal_block_delay; + delay_increment_per_round; + sc_rollup = + { + challenge_window_in_blocks; + commitment_period_in_blocks; + reveal_activation_level; + _; + }; + dal = {feature_enable; attestation_lag; number_of_slots; _}; + _; + } = + let open Protocol.Alpha_context in + Rollup_constants. + { + minimal_block_delay = Period.to_seconds minimal_block_delay; + delay_increment_per_round = Period.to_seconds delay_increment_per_round; + sc_rollup = + { + challenge_window_in_blocks; + commitment_period_in_blocks; + reveal_activation_level = + Some + (Sc_rollup_proto_types.Constants.reveal_activation_level_to_octez + reveal_activation_level); + }; + dal = {feature_enable; attestation_lag; number_of_slots}; + } 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 3b6fc64abf0a..3fd949075da5 100644 --- a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli +++ b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli @@ -38,3 +38,8 @@ val fetch_tezos_block : asynchronously. NOTE: the number of blocks to prefetch must not be greater than the size of the blocks cache otherwise they will be lost. *) val prefetch_tezos_blocks : t -> head list -> unit + +(** Convert protocol constants to their protocol agnostic representation. *) +val constants_of_parametric : + Protocol.Alpha_context.Constants.Parametric.t -> + Rollup_constants.protocol_constants diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index 39790d0df0e9..976a5e3f26ab 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -49,7 +49,7 @@ type 'a t = { kind : Sc_rollup.Kind.t; pvm : (module Pvm.S); fee_parameters : Configuration.fee_parameters; - protocol_constants : Constants.t; + protocol_constants : Rollup_constants.protocol_constants; proto_level : int; loser_mode : Loser_mode.t; lockfile : Lwt_unix.file_descr; @@ -81,15 +81,6 @@ let get_fee_parameter node_ctxt purpose = Configuration.Operator_purpose_map.find purpose node_ctxt.fee_parameters |> Option.value ~default:(Configuration.default_fee_parameter ~purpose ()) -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 - The constants are retrieved from the latest tezos block. These constants can - be different from the ones used at the creation at the rollup because of a - protocol amendment that modifies some of them. This need to be fixed when the - rollup nodes will be able to handle the migration of protocol. -*) -let retrieve_constants cctxt = - Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) - let get_last_cemented_commitment (cctxt : Protocol_client_context.full) rollup_address = let open Lwt_result_syntax in @@ -269,7 +260,8 @@ let check_config config = () let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file - mode l1_ctxt ~proto_level + mode l1_ctxt (protocol_constants : Rollup_constants.protocol_constants) + ~proto_level Configuration.( { sc_rollup_address = rollup_address; @@ -307,8 +299,7 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file (* Convert to protocol rollup address *) Sc_rollup_proto_types.Address.of_octez rollup_address in - let* protocol_constants = retrieve_constants cctxt - and* lcc = get_last_cemented_commitment cctxt rollup_address + let* lcc = get_last_cemented_commitment cctxt rollup_address and* lpc = Option.filter_map_es (get_last_published_commitment cctxt rollup_address) @@ -324,7 +315,7 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file ~kind:(Sc_rollup_proto_types.Kind.to_octez kind) in let*! () = - if dal_cctxt = None && protocol_constants.parametric.dal.feature_enable then + if dal_cctxt = None && protocol_constants.dal.feature_enable then Event.warn_dal_enabled_no_node () else Lwt.return_unit in @@ -423,8 +414,7 @@ let metadata node_ctxt = Sc_rollup.Metadata.{address; origination_level} let dal_supported node_ctxt = - node_ctxt.dal_cctxt <> None - && node_ctxt.protocol_constants.parametric.dal.feature_enable + node_ctxt.dal_cctxt <> None && node_ctxt.protocol_constants.dal.feature_enable let readonly (node_ctxt : _ t) = { @@ -1126,7 +1116,7 @@ let get_slot_header {store; protocol_constants; _} ~published_in_block_hash ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) in Sc_rollup_proto_types.Dal.Slot_header.of_octez - ~number_of_slots:protocol_constants.parametric.dal.number_of_slots + ~number_of_slots:protocol_constants.dal.number_of_slots header let get_all_slot_headers {store; protocol_constants; _} ~published_in_block_hash @@ -1139,7 +1129,7 @@ let get_all_slot_headers {store; protocol_constants; _} ~published_in_block_hash in List.rev_map (Sc_rollup_proto_types.Dal.Slot_header.of_octez - ~number_of_slots:protocol_constants.parametric.dal.number_of_slots) + ~number_of_slots:protocol_constants.dal.number_of_slots) headers |> List.rev @@ -1152,7 +1142,7 @@ let get_slot_indexes {store; protocol_constants; _} ~published_in_block_hash = in List.rev_map (Sc_rollup_proto_types.Dal.Slot_index.of_octez - ~number_of_slots:protocol_constants.parametric.dal.number_of_slots) + ~number_of_slots:protocol_constants.dal.number_of_slots) indexes |> List.rev @@ -1182,7 +1172,7 @@ let list_slots_statuses {store; protocol_constants; _} ~confirmed_in_block_hash List.rev_map (fun (index, status) -> ( Sc_rollup_proto_types.Dal.Slot_index.of_octez - ~number_of_slots:protocol_constants.parametric.dal.number_of_slots + ~number_of_slots:protocol_constants.dal.number_of_slots index, status )) statuses @@ -1218,18 +1208,9 @@ let save_confirmed_slots_histories {store; _} block hist = (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez hist) module Internal_for_tests = struct - let create_node_context cctxt - ?(constants = Default_parameters.constants_mainnet) ~data_dir kind = + let create_node_context cctxt protocol_constants ~data_dir kind = let open Lwt_result_syntax in let l2_blocks_cache_size = Configuration.default_l2_blocks_cache_size in - let protocol_constants = - constants - |> Data_encoding.Binary.to_bytes_exn Constants.Parametric.encoding - |> Data_encoding.Binary.of_bytes_exn Constants_parametric_repr.encoding - |> Constants_repr.all_of_parametric - |> Data_encoding.Binary.to_bytes_exn Constants_repr.encoding - |> Data_encoding.Binary.of_bytes_exn Constants.encoding - in let* lockfile = lock ~data_dir in let* store = Store.load diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli index ae996303fb00..105aaf31327a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.mli @@ -66,7 +66,7 @@ type 'a t = { pvm : (module Pvm.S); (** The PVM used by the smart rollup. *) fee_parameters : Configuration.fee_parameters; (** Fee parameters to use when injecting operations in layer 1. *) - protocol_constants : Constants.t; + protocol_constants : Rollup_constants.protocol_constants; (** Protocol constants retrieved from the Tezos node. *) proto_level : int; (** Protocol supported by this rollup node (represented as a protocol @@ -125,9 +125,10 @@ val get_fee_parameter : protocol. *) val protocol_max_batch_size : int -(** [init cctxt ~data_dir mode l1_ctxt ~proto_level configuration] initializes - the rollup representation. The rollup origination level and kind are fetched - via an RPC call to the layer1 node that [cctxt] uses for RPC requests. +(** [init cctxt ~data_dir mode l1_ctxt constants ~proto_level configuration] + initializes the rollup representation. The rollup origination level and kind + are fetched via an RPC call to the layer1 node that [cctxt] uses for RPC + requests. *) val init : Protocol_client_context.full -> @@ -135,6 +136,7 @@ val init : ?log_kernel_debug_file:string -> 'a Store_sigs.mode -> Layer1.t -> + Rollup_constants.protocol_constants -> proto_level:int -> Configuration.t -> 'a t tzresult Lwt.t @@ -485,7 +487,7 @@ module Internal_for_tests : sig rollup node functions. *) val create_node_context : Protocol_client_context.full -> - ?constants:Constants.Parametric.t -> + Rollup_constants.protocol_constants -> data_dir:string -> Sc_rollup.Kind.t -> Store_sigs.rw t tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.ml b/src/proto_alpha/lib_sc_rollup_node/publisher.ml index d2ad6afc0248..b895f20a86d6 100644 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.ml +++ b/src/proto_alpha/lib_sc_rollup_node/publisher.ml @@ -71,12 +71,11 @@ let sub_level level decrement = Raw_level.Internal_for_tests.sub level decrement let sc_rollup_commitment_period node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup + node_ctxt.Node_context.protocol_constants.sc_rollup .commitment_period_in_blocks let sc_rollup_challenge_window node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup - .challenge_window_in_blocks + node_ctxt.Node_context.protocol_constants.sc_rollup.challenge_window_in_blocks let next_commitment_level node_ctxt last_commitment_level = add_level last_commitment_level (sc_rollup_commitment_period node_ctxt) 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 1595337ec7c1..0da15782b35e 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -121,9 +121,13 @@ let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag (dal_params : Dal.parameters) start_state = let open Lwt_result_syntax in let module PVM = (val node_ctxt.pvm) in + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5871 + Use constants for correct protocol. *) let is_reveal_enabled = - Sc_rollup.is_reveal_enabled_predicate - node_ctxt.protocol_constants.parametric.sc_rollup.reveal_activation_level + node_ctxt.protocol_constants.sc_rollup.reveal_activation_level + |> WithExceptions.Option.get ~loc:__LOC__ + |> Sc_rollup_proto_types.Constants.reveal_activation_level_of_octez + |> Sc_rollup.is_reveal_enabled_predicate in let*! input_request = PVM.is_input_state ~is_reveal_enabled start_state in match input_request with diff --git a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml index e888c6b40313..12fa65f05879 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml @@ -39,16 +39,18 @@ let block_hash_of_level level = Block_hash.of_string_exn s let default_constants = - let constants = Default_parameters.constants_test in - let sc_rollup = - { - constants.sc_rollup with - arith_pvm_enable = true; - challenge_window_in_blocks = 4032; - commitment_period_in_blocks = 3; - } + let test_constants = + Layer1_helpers.constants_of_parametric Default_parameters.constants_test in - {constants with sc_rollup} + { + test_constants with + sc_rollup = + { + test_constants.sc_rollup with + challenge_window_in_blocks = 4032; + commitment_period_in_blocks = 3; + }; + } let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let open Lwt_result_syntax in @@ -136,7 +138,7 @@ let initialize_node_context ?(constants = default_constants) kind ~boot_sector = let* ctxt = Node_context.Internal_for_tests.create_node_context cctxt - ~constants + constants ~data_dir kind in diff --git a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli index b6571220f74a..5336713010ec 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli +++ b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli @@ -39,7 +39,7 @@ open Alpha_context context need to use this function in order to avoid file descriptor leaks. *) val with_node_context : - ?constants:Constants.Parametric.t -> + ?constants:Rollup_constants.protocol_constants -> Sc_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> @@ -108,7 +108,7 @@ end val alcotest : string -> Alcotest.speed_level -> - ?constants:Constants.Parametric.t -> + ?constants:Rollup_constants.protocol_constants -> Sc_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> -- GitLab From 392a2635a3b196ad3e329c6a754dfd07010a7c1c Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 13 Jun 2023 18:43:36 +0200 Subject: [PATCH 02/15] SCORU/Node: custom genesis info type --- src/lib_scoru_sequencer/seq_batcher.ml | 13 ++--- .../lib_sc_rollup_node/commitment_event.ml | 2 +- .../lib_sc_rollup_node/commitment_event.mli | 2 +- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 48 +++++++++++-------- .../lib_sc_rollup_node/dal_slots_tracker.ml | 4 +- .../lib_sc_rollup_node/fueled_pvm.ml | 11 ++++- src/proto_alpha/lib_sc_rollup_node/inbox.ml | 4 +- .../lib_sc_rollup_node/interpreter.ml | 11 ++--- .../lib_sc_rollup_node/node_context.ml | 26 +++++----- .../lib_sc_rollup_node/node_context.mli | 22 +++++---- .../lib_sc_rollup_node/publisher.ml | 24 +++++----- .../lib_sc_rollup_node/refutation_game.ml | 9 +++- .../lib_sc_rollup_node/simulation.ml | 9 ++-- .../test/helpers/helpers.ml | 12 ++--- 14 files changed, 104 insertions(+), 93 deletions(-) diff --git a/src/lib_scoru_sequencer/seq_batcher.ml b/src/lib_scoru_sequencer/seq_batcher.ml index 471804b7940e..c478ee8853a9 100644 --- a/src/lib_scoru_sequencer/seq_batcher.ml +++ b/src/lib_scoru_sequencer/seq_batcher.ml @@ -69,19 +69,15 @@ let inject_batches state = List.iter_es (inject_sequence state) let get_previous_delayed_inbox_size node_ctxt (head : Layer1.head) = let open Lwt_result_syntax in - let*? level = Environment.wrap_tzresult @@ Raw_level.of_int32 head.level in let*? () = error_unless - Raw_level.(level >= node_ctxt.Node_context.genesis_info.level) + (head.level >= node_ctxt.Node_context.genesis_info.level) (Exn (Failure "Cannot obtain delayed inbox before origination level")) in let* previous_head = Node_context.get_predecessor node_ctxt head in - let*? previous_level = - Environment.wrap_tzresult @@ Raw_level.of_int32 previous_head.level - in - let first_inbox_level = Raw_level.succ node_ctxt.genesis_info.level in + let first_inbox_level = Int32.succ node_ctxt.genesis_info.level in let* ctxt = - if Raw_level.(previous_level < first_inbox_level) then + if previous_head.level < first_inbox_level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -205,8 +201,7 @@ let on_register_messages state (messages : string list) = let on_new_head state head = let open Lwt_result_syntax in let* () = produce_batch_sequences state head in - when_ (head.level >= Raw_level.to_int32 state.node_ctxt.genesis_info.level) - @@ fun () -> + when_ (head.level >= state.node_ctxt.genesis_info.level) @@ fun () -> let* simulation_ctxt = Simulation.start_simulation ~reveal_map:None state.node_ctxt head in diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml index 92c014f0ab7c..5943efb784c3 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml +++ b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml @@ -92,7 +92,7 @@ module Simple = struct ~name:"sc_rollup_node_commitment_process_head" ~msg:"Computing and storing new commitment for level {level}" ~level:Notice - ("level", Raw_level.encoding) + ("level", Data_encoding.int32) let publish_commitment = declare_2 diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli b/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli index 89b337266710..ea1c1d4d60b5 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli +++ b/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli @@ -73,7 +73,7 @@ val commitment_parent_is_not_lcc : (** [compute_commitment level] emits the event that a new commitment is being computed and stored for the block at the given [level]. *) -val compute_commitment : Raw_level.t -> unit Lwt.t +val compute_commitment : int32 -> unit Lwt.t (** [publish_commitment hash level] emits the event that a new commitment is being published. *) diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index f38295ebadd2..e5675d884fac 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -299,13 +299,13 @@ let process_l1_block_operations node_ctxt (head : Layer1.header) = return_unit let before_origination (node_ctxt : _ Node_context.t) (header : Layer1.header) = - let origination_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let origination_level = node_ctxt.genesis_info.level in header.level < origination_level let previous_context (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in - if predecessor.level < Raw_level.to_int32 node_ctxt.genesis_info.level then + if predecessor.level < node_ctxt.genesis_info.level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -413,13 +413,11 @@ let rec process_head (daemon_components : (module Daemon_components.S)) head.hash (Sc_rollup_proto_types.Inbox.to_octez inbox) in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -428,7 +426,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -474,9 +472,7 @@ let on_layer_1_head (daemon_components : (module Daemon_components.S)) node_ctxt | None -> (* if no head has been processed yet, we want to handle all blocks since, and including, the rollup origination. *) - let origination_level = - Raw_level.to_int32 node_ctxt.genesis_info.level - in + let origination_level = node_ctxt.genesis_info.level in `Level (Int32.pred origination_level) in let stripped_head = Layer1.head_of_header head in @@ -675,7 +671,7 @@ let run node_ctxt configuration Metrics.Info.init_rollup_node_info ~id:configuration.sc_rollup_address ~mode:configuration.mode - ~genesis_level:(Raw_level.to_int32 node_ctxt.genesis_info.level) + ~genesis_level:node_ctxt.genesis_info.level ~pvm_kind:(Sc_rollup.Kind.to_string node_ctxt.kind) ; let fatal_error_exit e = Format.eprintf "%!%a@.Exiting.@." pp_print_trace e ; @@ -754,13 +750,11 @@ module Internal_for_tests = struct let commitment_hash = Option.map Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -769,7 +763,7 @@ module Internal_for_tests = struct Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -804,6 +798,18 @@ let retrieve_constants cctxt = in Layer1_helpers.constants_of_parametric parametric +let retrieve_genesis_info cctxt rollup_address = + let open Lwt_result_syntax in + let+ {level; commitment_hash} = + RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, `Head 0) rollup_address + in + Node_context. + { + level = Raw_level.to_int32 level; + commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; + } + module Rollup_node_daemon_components : Daemon_components.S = struct module Batcher = Batcher module RPC_server = RPC_server @@ -840,7 +846,10 @@ let run Layer1.fetch_tezos_shell_header l1_ctxt head.header.predecessor in let*! () = Event.received_first_block head.hash Protocol.hash in - let* constants = retrieve_constants cctxt in + let* constants = retrieve_constants cctxt + and* genesis_info = + retrieve_genesis_info cctxt configuration.sc_rollup_address + in let* node_ctxt = Node_context.init cctxt @@ -849,6 +858,7 @@ let run Read_write l1_ctxt constants + genesis_info ~proto_level:predecessor.proto_level configuration in diff --git a/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml b/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml index 1bc869c4ff4f..61d4cd7ea1ac 100644 --- a/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml +++ b/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml @@ -32,7 +32,7 @@ let ancestor_hash ~number_of_levels let genesis_level = genesis_info.level in let rec go number_of_levels (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - if level < Raw_level.to_int32 genesis_level then return_none + if level < genesis_level then return_none else if number_of_levels = 0 then return_some hash else let* pred_head = Node_context.get_predecessor_opt node_ctxt head in @@ -222,7 +222,7 @@ module Confirmed_slots_history = struct Int32.of_int node_ctxt.Node_context.protocol_constants.dal.attestation_lag in let block_level = Raw_level.to_int32 block_level in - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let genesis_level = node_ctxt.genesis_info.level in Int32.(block_level >= add lag genesis_level) let dal_entry_of_block_hash node_ctxt 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 32ada8e6b5ef..b930e11aa3c8 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -119,6 +119,15 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct exception Error_wrapper of tztrace + let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = + Raw_level.of_int32_exn node_ctxt.genesis_info.level + in + Sc_rollup.Metadata.{address; origination_level} + (** [eval_until_input node_ctxt reveal_map level message_index ~fuel start_tick failing_ticks state] advances a PVM [state] until it wants more inputs or there are no more [fuel] (if [Some fuel] is @@ -139,7 +148,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct |> Sc_rollup.is_reveal_enabled_predicate in let module PVM = (val node_ctxt.pvm) in - let metadata = Node_context.metadata node_ctxt in + let metadata = metadata node_ctxt in let dal_attestation_lag = node_ctxt.protocol_constants.dal.attestation_lag in diff --git a/src/proto_alpha/lib_sc_rollup_node/inbox.ml b/src/proto_alpha/lib_sc_rollup_node/inbox.ml index a99e1218bca8..19c5091a9188 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/lib_sc_rollup_node/inbox.ml @@ -159,9 +159,7 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) (head : Layer1.header) = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.level >= first_inbox_level then (* We compute the inbox of this block using the inbox of its predecessor. That way, the computation of inboxes is robust to chain diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index 77143300570d..bc2a6f4f3aa2 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -98,9 +98,7 @@ let state_of_head node_ctxt ctxt Layer1.{hash; level} = let*! state = Context.PVMState.find ctxt in match state with | None -> - let genesis_level = - Raw_level.to_int32 node_ctxt.Node_context.genesis_info.level - in + let genesis_level = node_ctxt.Node_context.genesis_info.level in if level = genesis_level then genesis_state hash node_ctxt ctxt else tzfail (Sc_rollup_node_errors.Missing_PVM_state (hash, level)) | Some state -> return (ctxt, state) @@ -142,9 +140,7 @@ let process_head (node_ctxt : _ Node_context.t) ctxt ~(predecessor : Layer1.header) (head : Layer1.header) (inbox, inbox_messages) = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.Layer1.level >= first_inbox_level then let*? inbox_messages = List.map_e Sc_rollup.Inbox_message.serialize inbox_messages @@ -156,8 +152,7 @@ let process_head (node_ctxt : _ Node_context.t) ctxt (Layer1.head_of_header predecessor) (Layer1.head_of_header head) (inbox, inbox_messages) - else if head.Layer1.level = Raw_level.to_int32 node_ctxt.genesis_info.level - then + else if head.Layer1.level = node_ctxt.genesis_info.level then let* ctxt, state = genesis_state head.hash node_ctxt ctxt in let*! ctxt = Context.PVMState.set ctxt state in return (ctxt, 0, 0L, Sc_rollup.Tick.initial) diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index 976a5e3f26ab..61c0bd064186 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -29,6 +29,11 @@ open Alpha_context type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} +type genesis_info = { + level : int32; + commitment_hash : Octez_smart_rollup.Commitment.Hash.t; +} + type 'a store = 'a Store.t type debug_logger = string -> unit Lwt.t @@ -43,7 +48,7 @@ type 'a t = { boot_sector_file : string option; mode : Configuration.mode; operators : Configuration.operators; - genesis_info : Sc_rollup.Commitment.genesis_info; + genesis_info : genesis_info; injector_retention_period : int; block_finality_time : int; kind : Sc_rollup.Kind.t; @@ -261,7 +266,7 @@ let check_config config = let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file mode l1_ctxt (protocol_constants : Rollup_constants.protocol_constants) - ~proto_level + genesis_info ~proto_level Configuration.( { sc_rollup_address = rollup_address; @@ -306,8 +311,6 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file publisher and* kind = RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () - and* genesis_info = - RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, cctxt#block) rollup_address in let*! () = Event.rollup_exists @@ -408,11 +411,6 @@ let checkout_context node_ctxt block_hash = (block_hash, Some context_hash)) | Some ctxt -> return ctxt -let metadata node_ctxt = - let address = node_ctxt.rollup_address in - let origination_level = node_ctxt.genesis_info.Sc_rollup.Commitment.level in - Sc_rollup.Metadata.{address; origination_level} - let dal_supported node_ctxt = node_ctxt.dal_cctxt <> None && node_ctxt.protocol_constants.dal.feature_enable @@ -618,7 +616,7 @@ let tick_search ~big_step_blocks node_ctxt head tick = (* The starting block contains the tick we want, we are done. *) return_some head else - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let genesis_level = node_ctxt.genesis_info.level in let rec find_big_step (end_block : Sc_rollup_block.t) = let start_level = Int32.sub end_block.header.level (Int32.of_int big_step_blocks) @@ -808,7 +806,7 @@ let find_inbox_by_block_hash ({store; _} as node_ctxt) block_hash = (Sc_rollup_proto_types.Inbox_hash.of_octez inbox_hash) let genesis_inbox node_ctxt = - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let genesis_level = node_ctxt.genesis_info.level in Plugin.RPC.Sc_rollup.inbox node_ctxt.cctxt (node_ctxt.cctxt#chain, `Level genesis_level) @@ -823,7 +821,7 @@ let inbox_of_head node_ctxt Layer1.{hash = block_hash; level = block_level} = That is, every block after the origination level. We then join the bandwagon and build the inbox on top of the protocol's inbox at the end of the origination level. *) - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let genesis_level = node_ctxt.genesis_info.level in if block_level = genesis_level then genesis_inbox node_ctxt else if block_level > genesis_level then (* Invariant broken, the inbox for this level should exist. *) @@ -959,7 +957,7 @@ type proto_info = { let protocol_of_level node_ctxt level = let open Lwt_result_syntax in - assert (level >= Raw_level.to_int32 node_ctxt.genesis_info.level) ; + assert (level >= node_ctxt.genesis_info.level) ; let* protocols = Store.Protocols.read node_ctxt.store.protocols in let*? protocols = match protocols with @@ -1222,7 +1220,7 @@ module Internal_for_tests = struct Context.load Read_write (Configuration.default_context_dir data_dir) in let genesis_info = - Sc_rollup.Commitment.{level = Raw_level.root; commitment_hash = Hash.zero} + {level = 0l; commitment_hash = Octez_smart_rollup.Commitment.Hash.zero} in let l1_ctxt = Layer1.Internal_for_tests.dummy cctxt in let lcc = diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli index 105aaf31327a..ec5d15b05bb8 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.mli @@ -31,6 +31,11 @@ open Alpha_context type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} +type genesis_info = { + level : int32; + commitment_hash : Octez_smart_rollup.Commitment.Hash.t; +} + (** Abstract type for store to force access through this module. *) type 'a store constraint 'a = [< `Read | `Write > `Read] @@ -52,10 +57,10 @@ type 'a t = { (** Optional path to the boot sector file. Useful only if the smart rollup was bootstrapped and not originated. *) mode : Configuration.mode; - (** Mode of the node, see {!Configuration.mode}. *) + (** Mode of the node, see {!type:Configuration.mode}. *) operators : Configuration.operators; (** Addresses of the rollup node operators by purposes. *) - genesis_info : Sc_rollup.Commitment.genesis_info; + genesis_info : genesis_info; (** Origination information of the smart rollup. *) injector_retention_period : int; (** Number of blocks the injector will keep information about included @@ -125,10 +130,10 @@ val get_fee_parameter : protocol. *) val protocol_max_batch_size : int -(** [init cctxt ~data_dir mode l1_ctxt constants ~proto_level configuration] - initializes the rollup representation. The rollup origination level and kind - are fetched via an RPC call to the layer1 node that [cctxt] uses for RPC - requests. +(** [init cctxt ~data_dir mode l1_ctxt constants genesis_info ~proto_level + configuration] initializes the rollup representation. The rollup origination + level and kind are fetched via an RPC call to the layer1 node that [cctxt] + uses for RPC requests. *) val init : Protocol_client_context.full -> @@ -137,6 +142,7 @@ val init : 'a Store_sigs.mode -> Layer1.t -> Rollup_constants.protocol_constants -> + genesis_info -> proto_level:int -> Configuration.t -> 'a t tzresult Lwt.t @@ -148,10 +154,6 @@ val close : _ t -> unit tzresult Lwt.t [block_hash]. *) val checkout_context : 'a t -> Block_hash.t -> 'a Context.t tzresult Lwt.t -(** [metadata node_ctxt] creates a {!Sc_rollup.Metadata.t} using the information - stored in [node_ctxt]. *) -val metadata : _ t -> Sc_rollup.Metadata.t - (** Returns [true] if the rollup node supports the DAL and if DAL is enabled for the current protocol. *) val dal_supported : _ t -> bool diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.ml b/src/proto_alpha/lib_sc_rollup_node/publisher.ml index b895f20a86d6..481f32eb9590 100644 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.ml +++ b/src/proto_alpha/lib_sc_rollup_node/publisher.ml @@ -63,7 +63,7 @@ end let add_level level increment = (* We only use this function with positive increments so it is safe *) if increment < 0 then invalid_arg "Commitment.add_level negative increment" ; - Raw_level.Internal_for_tests.add level increment + Int32.add level (Int32.of_int increment) let sub_level level decrement = (* We only use this function with positive increments so it is safe *) @@ -78,7 +78,9 @@ let sc_rollup_challenge_window node_ctxt = node_ctxt.Node_context.protocol_constants.sc_rollup.challenge_window_in_blocks let next_commitment_level node_ctxt last_commitment_level = - add_level last_commitment_level (sc_rollup_commitment_period node_ctxt) + add_level + (Raw_level.to_int32 last_commitment_level) + (sc_rollup_commitment_period node_ctxt) type state = Node_context.ro @@ -102,8 +104,7 @@ let build_commitment (node_ctxt : _ Node_context.t) | Some pvm_state -> Ok pvm_state | None -> error_with - "PVM state for commitment at level %a is not available" - Raw_level.pp + "PVM state for commitment at level %ld is not available" inbox_level in let*! compressed_state = PVM.state_hash pvm_state in @@ -125,7 +126,7 @@ let build_commitment (node_ctxt : _ Node_context.t) Sc_rollup.Commitment. { predecessor = prev_commitment; - inbox_level; + inbox_level = Raw_level.of_int32_exn inbox_level; number_of_ticks; compressed_state; } @@ -144,7 +145,7 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = Sc_rollup.Commitment. { predecessor = Hash.zero; - inbox_level = node_ctxt.genesis_info.level; + inbox_level = Raw_level.of_int32_exn node_ctxt.genesis_info.level; number_of_ticks = Sc_rollup.Number_of_ticks.zero; compressed_state; } @@ -168,7 +169,7 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor current_level ctxt = let open Lwt_result_syntax in - if Raw_level.(current_level = node_ctxt.genesis_info.level) then + if current_level = node_ctxt.genesis_info.level then let*! () = Commitment_event.compute_commitment current_level in let+ genesis_commitment = genesis_commitment node_ctxt ctxt in Some genesis_commitment @@ -184,7 +185,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let next_commitment_level = next_commitment_level node_ctxt last_commitment.inbox_level in - if Raw_level.(current_level = next_commitment_level) then + if current_level = next_commitment_level then let*! () = Commitment_event.compute_commitment current_level in let+ commitment = build_commitment @@ -200,7 +201,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let process_head (node_ctxt : _ Node_context.t) ~predecessor Layer1.{level; header = _; _} ctxt = let open Lwt_result_syntax in - let current_level = Raw_level.of_int32_exn level in + let current_level = level in let* commitment = create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt in @@ -217,7 +218,7 @@ let missing_commitments (node_ctxt : _ Node_context.t) = let lpc_level = match Reference.get node_ctxt.lpc with | None -> node_ctxt.genesis_info.level - | Some lpc -> lpc.inbox_level + | Some lpc -> Raw_level.to_int32 lpc.inbox_level in let* head = Node_context.last_processed_head_opt node_ctxt in let next_head_level = @@ -234,7 +235,8 @@ let missing_commitments (node_ctxt : _ Node_context.t) = | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> (* Commitment is before or at the LCC, we have reached the end. *) return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lpc_level) -> + | Some commitment + when Raw_level.to_int32 commitment.inbox_level <= lpc_level -> (* Commitment is before the last published one, we have also reached the end because we only publish commitments that are for the inbox of a finalized L1 block. *) 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 0da15782b35e..ee980043e72f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -160,6 +160,13 @@ let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag pages_per_slot)) | _ -> return_none +let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = Raw_level.of_int32_exn node_ctxt.genesis_info.level in + Sc_rollup.Metadata.{address; origination_level} + let generate_proof (node_ctxt : _ Node_context.t) game start_state = let open Lwt_result_syntax in let module PVM = (val node_ctxt.pvm) in @@ -279,7 +286,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let page_info = page_info end end in - let metadata = Node_context.metadata node_ctxt in + let metadata = metadata node_ctxt in let*! start_tick = PVM.get_tick start_state in let is_reveal_enabled = Sc_rollup.is_reveal_enabled_predicate diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index a13a580a5e13..71130d96c2a1 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.ml +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.ml @@ -54,15 +54,14 @@ let simulate_info_per_level (node_ctxt : [`Read] Node_context.t) predecessor = let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - let*? level = Environment.wrap_tzresult @@ Raw_level.of_int32 level in let*? () = error_unless - Raw_level.(level >= node_ctxt.Node_context.genesis_info.level) + (level >= node_ctxt.Node_context.genesis_info.level) (Exn (Failure "Cannot simulate before origination level")) in - let first_inbox_level = Raw_level.succ node_ctxt.genesis_info.level in + let first_inbox_level = Int32.succ node_ctxt.genesis_info.level in let* ctxt = - if Raw_level.(level < first_inbox_level) then + if level < first_inbox_level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -70,7 +69,7 @@ let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = in let* ctxt, state = Interpreter.state_of_head node_ctxt ctxt head in let+ info_per_level = simulate_info_per_level node_ctxt hash in - let inbox_level = Raw_level.succ level in + let inbox_level = Raw_level.of_int32_exn (Int32.succ level) in { ctxt; inbox_level; diff --git a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml index 12fa65f05879..7c5300730f03 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml @@ -55,11 +55,7 @@ let default_constants = let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let open Lwt_result_syntax in let head = - Layer1. - { - hash = Block_hash.zero; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; - } + Layer1.{hash = Block_hash.zero; level = node_ctxt.genesis_info.level} in let* () = Node_context.save_level node_ctxt head in let predecessor = head in @@ -68,7 +64,7 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = Sc_rollup.Inbox.genesis ~predecessor_timestamp ~predecessor:predecessor.hash - node_ctxt.genesis_info.level + (Raw_level.of_int32_exn node_ctxt.genesis_info.level) in let* inbox_hash = Node_context.save_inbox node_ctxt inbox in let inbox_witness = Sc_rollup.Inbox.current_witness inbox in @@ -83,7 +79,7 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let*! context_hash = Octez_smart_rollup_node.Context.commit ctxt in let commitment = Sc_rollup.Commitment.genesis_commitment - ~origination_level:node_ctxt.genesis_info.level + ~origination_level:(Raw_level.of_int32_exn node_ctxt.genesis_info.level) ~genesis_state_hash in let* commitment_hash = Node_context.save_commitment node_ctxt commitment in @@ -92,7 +88,7 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = Sc_rollup_block. { block_hash = head.hash; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; + level = node_ctxt.genesis_info.level; predecessor = predecessor.hash; commitment_hash = Some commitment_hash; previous_commitment_hash; -- GitLab From 0b492e3c1702a973a83681fa99ede6ae1de4fd74 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 27 Jun 2023 11:21:37 +0200 Subject: [PATCH 03/15] SCORU/Node: save genesis inbox on disk --- src/proto_alpha/lib_sc_rollup_node/inbox.ml | 11 ++++++----- src/proto_alpha/lib_sc_rollup_node/node_context.ml | 8 +++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/inbox.ml b/src/proto_alpha/lib_sc_rollup_node/inbox.ml index 19c5091a9188..f33011998964 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/lib_sc_rollup_node/inbox.ml @@ -181,11 +181,12 @@ let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) collected_messages else let* inbox = Node_context.genesis_inbox node_ctxt in - return - ( Sc_rollup.Inbox.hash inbox, - inbox, - Sc_rollup.Inbox.current_witness inbox, - [] ) + let witness = Sc_rollup.Inbox.current_witness inbox in + let* () = + Node_context.save_messages node_ctxt witness ~block_hash:head.hash [] + in + let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + return (inbox_hash, inbox, witness, []) let start () = Inbox_event.starting () diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index 61c0bd064186..d366bb1e267e 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -814,16 +814,14 @@ let genesis_inbox node_ctxt = let inbox_of_head node_ctxt Layer1.{hash = block_hash; level = block_level} = let open Lwt_result_syntax in let* possible_inbox = find_inbox_by_block_hash node_ctxt block_hash in - (* Pre-condition: forall l. (l > genesis_level) => inbox[l] <> None. *) + (* Pre-condition: forall l. (l >= genesis_level) => inbox[l] <> None. *) match possible_inbox with | None -> (* The inbox exists for each tezos block the rollup should care about. - That is, every block after the origination level. We then join + That is, every block at or after the origination level. We then join the bandwagon and build the inbox on top of the protocol's inbox at the end of the origination level. *) - let genesis_level = node_ctxt.genesis_info.level in - if block_level = genesis_level then genesis_inbox node_ctxt - else if block_level > genesis_level then + if block_level >= node_ctxt.genesis_info.level then (* Invariant broken, the inbox for this level should exist. *) failwith "The inbox for block hash %a (level = %ld) is missing." -- GitLab From 5309789a9b14d9de0ce898212dd48e3ed6e20c44 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 1 Jun 2023 10:54:37 +0200 Subject: [PATCH 04/15] SCORU/Node/Injector: run configuration checks on init --- src/lib_injector/injector_functor.ml | 1 + src/lib_injector/injector_protocol.ml | 10 ++++ src/lib_injector/injector_protocol.mli | 8 +++ src/lib_injector/injector_sigs.ml | 3 ++ .../lib_sc_rollup_node/sc_rollup_injector.ml | 53 +++++++++++++++++++ .../lib_sc_rollup_node/sc_rollup_injector.ml | 53 +++++++++++++++++++ .../lib_sc_rollup_node/sc_rollup_injector.ml | 53 +++++++++++++++++++ .../lib_sc_rollup_node/sc_rollup_injector.ml | 53 +++++++++++++++++++ 8 files changed, 234 insertions(+) diff --git a/src/lib_injector/injector_functor.ml b/src/lib_injector/injector_functor.ml index cc5fb99770ba..2aa820d2f7a7 100644 --- a/src/lib_injector/injector_functor.ml +++ b/src/lib_injector/injector_functor.ml @@ -1440,6 +1440,7 @@ module Make (Parameters : PARAMETERS) = struct Signature.Public_key_hash.Map.empty signers in + let*? () = Inj_proto.check_registered_proto_clients state in let*! l1_ctxt = Layer_1.start ~name:"injector" ~reconnection_delay cctxt in let* head_protocols = protocols_of_head cctxt in let* () = diff --git a/src/lib_injector/injector_protocol.ml b/src/lib_injector/injector_protocol.ml index bccf22b5fab4..cab16c949847 100644 --- a/src/lib_injector/injector_protocol.ml +++ b/src/lib_injector/injector_protocol.ml @@ -43,4 +43,14 @@ module Make (Parameters : PARAMETERS) = struct let proto_client_for_protocol protocol = WithExceptions.Option.to_exn ~none:Protocol_not_found @@ Protocol_hash.Table.find proto_clients protocol + + let registered_proto_clients () = + Protocol_hash.Table.to_seq proto_clients |> List.of_seq + + let check_registered_proto_clients state = + Protocol_hash.Table.iter_e + (fun _proto_hash (proto_client : proto_client) -> + let module Proto_client = (val proto_client) in + Proto_client.checks state) + proto_clients end diff --git a/src/lib_injector/injector_protocol.mli b/src/lib_injector/injector_protocol.mli index 282069b5a703..5c53b3c9fa25 100644 --- a/src/lib_injector/injector_protocol.mli +++ b/src/lib_injector/injector_protocol.mli @@ -44,4 +44,12 @@ module Make (Parameters : PARAMETERS) : sig this case the injector will not be able to inject operations in blocks of this protocol. *) val proto_client_for_protocol : Protocol_hash.t -> proto_client + + (** Returns the list of protocol clients registered. *) + val registered_proto_clients : unit -> (Protocol_hash.t * proto_client) list + + (** Runs the [checks] functions on all registered protocol clients for the + injector. *) + val check_registered_proto_clients : + Parameters.state -> (unit, tztrace) result end diff --git a/src/lib_injector/injector_sigs.ml b/src/lib_injector/injector_sigs.ml index a3caa29d1462..1ab160a081f5 100644 --- a/src/lib_injector/injector_sigs.ml +++ b/src/lib_injector/injector_sigs.ml @@ -242,6 +242,9 @@ module type PROTOCOL_CLIENT = sig block following [block_header], with respect to the current time. *) val time_until_next_block : state -> Tezos_base.Block_header.shell_header option -> Ptime.span + + (** Run protocol specific checks for injector configuration/state. *) + val checks : state -> unit tzresult end (** Output signature for functor {!Injector_functor.Make}. *) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_injector.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_injector.ml index 1e60a17330cd..3c99b84bf38e 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_injector.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_injector.ml @@ -389,6 +389,59 @@ module Proto_client = struct Ptime.diff (Time.System.of_protocol_exn next_level_timestamp) (Time.System.now ()) + + let check_fee_parameters Injector.{fee_parameters; _} = + let check_value purpose name compare to_string mempool_default value = + if compare mempool_default value > 0 then + error_with + "Bad configuration fee_parameter.%s for %s. It must be at least %s \ + for operations of the injector to be propagated." + name + (Configuration.string_of_purpose purpose) + (to_string mempool_default) + else Ok () + in + let check purpose + { + Injector_sigs.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee = _; + fee_cap = _; + burn_cap = _; + } = + let open Result_syntax in + let+ () = + check_value + purpose + "minimal_fees" + Int64.compare + Int64.to_string + (Protocol.Alpha_context.Tez.to_mutez + Plugin.Mempool.default_minimal_fees) + minimal_fees.mutez + and+ () = + check_value + purpose + "minimal_nanotez_per_byte" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_byte + minimal_nanotez_per_byte + and+ () = + check_value + purpose + "minimal_nanotez_per_gas_unit" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_gas_unit + minimal_nanotez_per_gas_unit + in + () + in + Configuration.Operator_purpose_map.iter_e check fee_parameters + + let checks state = check_fee_parameters state end let () = Injector.register_proto_client Protocol.hash (module Proto_client) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/sc_rollup_injector.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/sc_rollup_injector.ml index 1e60a17330cd..3c99b84bf38e 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/sc_rollup_injector.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/sc_rollup_injector.ml @@ -389,6 +389,59 @@ module Proto_client = struct Ptime.diff (Time.System.of_protocol_exn next_level_timestamp) (Time.System.now ()) + + let check_fee_parameters Injector.{fee_parameters; _} = + let check_value purpose name compare to_string mempool_default value = + if compare mempool_default value > 0 then + error_with + "Bad configuration fee_parameter.%s for %s. It must be at least %s \ + for operations of the injector to be propagated." + name + (Configuration.string_of_purpose purpose) + (to_string mempool_default) + else Ok () + in + let check purpose + { + Injector_sigs.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee = _; + fee_cap = _; + burn_cap = _; + } = + let open Result_syntax in + let+ () = + check_value + purpose + "minimal_fees" + Int64.compare + Int64.to_string + (Protocol.Alpha_context.Tez.to_mutez + Plugin.Mempool.default_minimal_fees) + minimal_fees.mutez + and+ () = + check_value + purpose + "minimal_nanotez_per_byte" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_byte + minimal_nanotez_per_byte + and+ () = + check_value + purpose + "minimal_nanotez_per_gas_unit" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_gas_unit + minimal_nanotez_per_gas_unit + in + () + in + Configuration.Operator_purpose_map.iter_e check fee_parameters + + let checks state = check_fee_parameters state end let () = Injector.register_proto_client Protocol.hash (module Proto_client) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml index 15950e96c941..b88c8e74322a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml @@ -391,6 +391,59 @@ module Proto_client = struct Ptime.diff (Time.System.of_protocol_exn next_level_timestamp) (Time.System.now ()) + + let check_fee_parameters Injector.{fee_parameters; _} = + let check_value purpose name compare to_string mempool_default value = + if compare mempool_default value > 0 then + error_with + "Bad configuration fee_parameter.%s for %s. It must be at least %s \ + for operations of the injector to be propagated." + name + (Configuration.string_of_purpose purpose) + (to_string mempool_default) + else Ok () + in + let check purpose + { + Injector_sigs.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee = _; + fee_cap = _; + burn_cap = _; + } = + let open Result_syntax in + let+ () = + check_value + purpose + "minimal_fees" + Int64.compare + Int64.to_string + (Protocol.Alpha_context.Tez.to_mutez + Plugin.Mempool.default_minimal_fees) + minimal_fees.mutez + and+ () = + check_value + purpose + "minimal_nanotez_per_byte" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_byte + minimal_nanotez_per_byte + and+ () = + check_value + purpose + "minimal_nanotez_per_gas_unit" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_gas_unit + minimal_nanotez_per_gas_unit + in + () + in + Configuration.Operator_purpose_map.iter_e check fee_parameters + + let checks state = check_fee_parameters state end let () = Injector.register_proto_client Protocol.hash (module Proto_client) diff --git a/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml b/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml index 15950e96c941..b88c8e74322a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml +++ b/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml @@ -391,6 +391,59 @@ module Proto_client = struct Ptime.diff (Time.System.of_protocol_exn next_level_timestamp) (Time.System.now ()) + + let check_fee_parameters Injector.{fee_parameters; _} = + let check_value purpose name compare to_string mempool_default value = + if compare mempool_default value > 0 then + error_with + "Bad configuration fee_parameter.%s for %s. It must be at least %s \ + for operations of the injector to be propagated." + name + (Configuration.string_of_purpose purpose) + (to_string mempool_default) + else Ok () + in + let check purpose + { + Injector_sigs.minimal_fees; + minimal_nanotez_per_byte; + minimal_nanotez_per_gas_unit; + force_low_fee = _; + fee_cap = _; + burn_cap = _; + } = + let open Result_syntax in + let+ () = + check_value + purpose + "minimal_fees" + Int64.compare + Int64.to_string + (Protocol.Alpha_context.Tez.to_mutez + Plugin.Mempool.default_minimal_fees) + minimal_fees.mutez + and+ () = + check_value + purpose + "minimal_nanotez_per_byte" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_byte + minimal_nanotez_per_byte + and+ () = + check_value + purpose + "minimal_nanotez_per_gas_unit" + Q.compare + Q.to_string + Plugin.Mempool.default_minimal_nanotez_per_gas_unit + minimal_nanotez_per_gas_unit + in + () + in + Configuration.Operator_purpose_map.iter_e check fee_parameters + + let checks state = check_fee_parameters state end let () = Injector.register_proto_client Protocol.hash (module Proto_client) -- GitLab From e0ec695eb3fb502728feaaa76ab2434fc716e4e5 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 1 Jun 2023 10:56:48 +0200 Subject: [PATCH 05/15] SCORU/Node/batcher: check config on init --- src/proto_alpha/lib_sc_rollup_node/batcher.ml | 45 ++++++++- .../lib_sc_rollup_node/node_context.ml | 94 ------------------- .../lib_sc_rollup_node/node_context.mli | 4 - 3 files changed, 42 insertions(+), 101 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/batcher.ml b/src/proto_alpha/lib_sc_rollup_node/batcher.ml index cf4199967009..c12a772eb85b 100644 --- a/src/proto_alpha/lib_sc_rollup_node/batcher.ml +++ b/src/proto_alpha/lib_sc_rollup_node/batcher.ml @@ -229,6 +229,38 @@ let on_new_head state head = (* Forget failing messages *) List.iter (Message_queue.remove state.messages) failing +(** Maximum size of an L2 batch in bytes that can fit in an operation of the + protocol. *) +let protocol_max_batch_size = + let open Protocol in + let open Alpha_context in + let empty_message_op : _ Operation.t = + let open Operation in + { + shell = {branch = Block_hash.zero}; + protocol_data = + { + signature = Some Signature.zero; + contents = + Single + (Manager_operation + { + source = Signature.Public_key_hash.zero; + fee = Tez.of_mutez_exn Int64.max_int; + counter = Manager_counter.Internal_for_tests.of_int max_int; + gas_limit = + Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); + storage_limit = Z.of_int max_int; + operation = Sc_rollup_add_messages {messages = [""]}; + }); + }; + } + in + Protocol.Constants_repr.max_operation_data_length + - Data_encoding.Binary.length + Operation.encoding_with_legacy_attestation_name + (Operation.pack empty_message_op) + let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = let open Lwt_syntax in let conf = @@ -238,9 +270,7 @@ let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = min_batch_size = conf.min_batch_size; max_batch_elements = conf.max_batch_elements; max_batch_size = - Option.value - conf.max_batch_size - ~default:Node_context.protocol_max_batch_size; + Option.value conf.max_batch_size ~default:protocol_max_batch_size; } in return @@ -329,8 +359,17 @@ let table = Worker.create_table Queue let worker_promise, worker_waker = Lwt.task () +let check_batcher_config Configuration.{max_batch_size; _} = + match max_batch_size with + | Some m when m > protocol_max_batch_size -> + error_with + "batcher.max_batch_size must be smaller than %d" + protocol_max_batch_size + | _ -> Ok () + let init conf ~signer node_ctxt = let open Lwt_result_syntax in + let*? () = check_batcher_config conf in let node_ctxt = Node_context.readonly node_ctxt in let+ worker = Worker.launch table () {node_ctxt; signer; conf} (module Handlers) diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index d366bb1e267e..9721ecbc0198 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -171,99 +171,6 @@ let pvm_of_kind : Protocol.Alpha_context.Sc_rollup.Kind.t -> (module Pvm.S) = | Example_arith -> (module Arith_pvm) | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) -let check_fee_parameters Configuration.{fee_parameters; _} = - let check_value purpose name compare to_string mempool_default value = - if compare mempool_default value > 0 then - error_with - "Bad configuration fee_parameter.%s for %s. It must be at least %s for \ - operations of the injector to be propagated." - name - (Configuration.string_of_purpose purpose) - (to_string mempool_default) - else Ok () - in - let check purpose - { - Injector_sigs.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee = _; - fee_cap = _; - burn_cap = _; - } = - let open Result_syntax in - let+ () = - check_value - purpose - "minimal_fees" - Int64.compare - Int64.to_string - (Tez.to_mutez Plugin.Mempool.default_minimal_fees) - minimal_fees.mutez - and+ () = - check_value - purpose - "minimal_nanotez_per_byte" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_byte - minimal_nanotez_per_byte - and+ () = - check_value - purpose - "minimal_nanotez_per_gas_unit" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_gas_unit - minimal_nanotez_per_gas_unit - in - () - in - Configuration.Operator_purpose_map.iter_e check fee_parameters - -let protocol_max_batch_size = - let empty_message_op : _ Operation.t = - let open Protocol in - let open Alpha_context in - let open Operation in - { - shell = {branch = Block_hash.zero}; - protocol_data = - { - signature = Some Signature.zero; - contents = - Single - (Manager_operation - { - source = Signature.Public_key_hash.zero; - fee = Tez.of_mutez_exn Int64.max_int; - counter = Manager_counter.Internal_for_tests.of_int max_int; - gas_limit = - Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); - storage_limit = Z.of_int max_int; - operation = Sc_rollup_add_messages {messages = [""]}; - }); - }; - } - in - Protocol.Constants_repr.max_operation_data_length - - Data_encoding.Binary.length - Operation.encoding_with_legacy_attestation_name - (Operation.pack empty_message_op) - -let check_batcher_config Configuration.{batcher = {max_batch_size; _}; _} = - match max_batch_size with - | Some m when m > protocol_max_batch_size -> - error_with - "batcher.max_batch_size must be smaller than %d" - protocol_max_batch_size - | _ -> Ok () - -let check_config config = - let open Result_syntax in - let+ () = check_fee_parameters config and+ () = check_batcher_config config in - () - let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file mode l1_ctxt (protocol_constants : Rollup_constants.protocol_constants) genesis_info ~proto_level @@ -280,7 +187,6 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file _; } as configuration) = let open Lwt_result_syntax in - let*? () = check_config configuration in let* lockfile = lock ~data_dir in let* () = Store_migration.maybe_run_migration diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli index ec5d15b05bb8..a429851920b0 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.mli @@ -126,10 +126,6 @@ val is_loser : _ t -> bool val get_fee_parameter : _ t -> Configuration.purpose -> Injector_sigs.fee_parameter -(** Maximum size of an L2 batch in bytes that can fit in an operation of the - protocol. *) -val protocol_max_batch_size : int - (** [init cctxt ~data_dir mode l1_ctxt constants genesis_info ~proto_level configuration] initializes the rollup representation. The rollup origination level and kind are fetched via an RPC call to the layer1 node that [cctxt] -- GitLab From b124d827e037314a89fe5f61cbbc94e7326ce997 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 9 Jun 2023 14:08:24 +0200 Subject: [PATCH 06/15] Manifest: rollup node depends on DAL and DAC clients --- manifest/main.ml | 2 ++ opam/octez-smart-rollup-node.opam | 2 ++ src/lib_smart_rollup_node/dune | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/manifest/main.ml b/manifest/main.ml index e410db9d4cb8..911045aac376 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -4131,6 +4131,8 @@ let octez_smart_rollup_node_lib = cohttp_lwt_unix; octez_node_config; prometheus_app; + octez_dal_node_lib |> open_; + octez_dac_client_lib |> open_; octez_injector |> open_; octez_version_value |> open_; octez_layer2_store |> open_; diff --git a/opam/octez-smart-rollup-node.opam b/opam/octez-smart-rollup-node.opam index db2390f3e97b..12c31d0dcd7b 100644 --- a/opam/octez-smart-rollup-node.opam +++ b/opam/octez-smart-rollup-node.opam @@ -18,6 +18,8 @@ depends: [ "cohttp-lwt-unix" { >= "4.0.0" & != "5.1.0" } "octez-node-config" "prometheus-app" { >= "1.2" } + "tezos-dal-node-lib" + "tezos-dac-client-lib" "octez-injector" "tezos-version" "tezos-layer2-store" diff --git a/src/lib_smart_rollup_node/dune b/src/lib_smart_rollup_node/dune index ae2cce70ad79..d57b6e625ece 100644 --- a/src/lib_smart_rollup_node/dune +++ b/src/lib_smart_rollup_node/dune @@ -15,6 +15,8 @@ cohttp-lwt-unix octez-node-config prometheus-app + tezos-dal-node-lib + tezos-dac-client-lib octez-injector tezos-version.value tezos_layer2_store @@ -27,6 +29,8 @@ -open Tezos_crypto -open Tezos_client_base -open Tezos_client_base_unix + -open Tezos_dal_node_lib + -open Tezos_dac_client_lib -open Octez_injector -open Tezos_version_value -open Tezos_layer2_store -- GitLab From e1df73c0262edc94fa722e225ec87bfad4dc042c Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 16 Jun 2023 10:54:01 +0200 Subject: [PATCH 07/15] SCORU/Node: remove protocol from events --- .../lib_sc_rollup_node/commitment_event.ml | 12 ++++++------ .../lib_sc_rollup_node/commitment_event.mli | 6 +++--- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 4 ++-- src/proto_alpha/lib_sc_rollup_node/interpreter.ml | 6 +++++- .../lib_sc_rollup_node/interpreter_event.ml | 4 ++-- src/proto_alpha/lib_sc_rollup_node/publisher.ml | 2 +- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml index 5943efb784c3..c477e81f6885 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml +++ b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml @@ -72,8 +72,8 @@ module Simple = struct "Last cemented commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let last_published_commitment_updated = declare_2 @@ -83,8 +83,8 @@ module Simple = struct "Last published commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let compute_commitment = declare_1 @@ -100,8 +100,8 @@ module Simple = struct ~name:"sc_rollup_node_publish_commitment" ~msg:"Publishing commitment {hash} for inbox level {level}" ~level:Notice - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let commitment_parent_is_not_lcc = declare_3 diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli b/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli index ea1c1d4d60b5..5a26a50ec34f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli +++ b/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli @@ -51,13 +51,13 @@ val commitment_will_not_be_published : cemented commitment was updated to the given [hash] at the given inbox [level]. *) val last_cemented_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [last_published_commitment_updated hash level] emits the event that the last published commitment was updated to the given [hash] at the given inbox [level]. *) val last_published_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [commitment_parent_is_not_lcc predecessor_hash last_cemented_commitment_hash] emits the event that a commitment at the given inbox [level] is being @@ -78,7 +78,7 @@ val compute_commitment : int32 -> unit Lwt.t (** [publish_commitment hash level] emits the event that a new commitment is being published. *) val publish_commitment : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** Events emmitted by the Publisher worker *) module Publisher : sig diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index e5675d884fac..1829c9f7b1f9 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -110,7 +110,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let*! () = Commitment_event.last_published_commitment_updated commitment_hash - (Raw_level.of_int32_exn head.Layer1.level) + head.Layer1.level in return_unit | ( Sc_rollup_publish {commitment = their_commitment; rollup}, @@ -183,7 +183,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) {commitment = proto_commitment_hash; level = proto_inbox_level} ; Commitment_event.last_cemented_commitment_updated proto_commitment_hash - proto_inbox_level) + inbox_level) else Lwt.return_unit in return_unit diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index bc2a6f4f3aa2..c020b4e5cc73 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -130,7 +130,11 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} let*! initial_tick = PVM.get_tick predecessor_state in (* Produce events. *) let*! () = - Interpreter_event.transitioned_pvm inbox_level state_hash tick num_messages + Interpreter_event.transitioned_pvm + (Raw_level.to_int32 inbox_level) + state_hash + tick + num_messages in return (ctxt, num_messages, Z.to_int64 num_ticks, initial_tick) 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 80fab8ac3274..ff8f435c5f35 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter_event.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter_event.ml @@ -38,8 +38,8 @@ module Simple = struct "Transitioned PVM at inbox level {inbox_level} to {state_hash} at tick \ {ticks} with {num_messages} messages" ~level:Notice - ("inbox_level", Protocol.Alpha_context.Raw_level.encoding) - ("state_hash", State_hash.encoding) + ("inbox_level", Data_encoding.int32) + ("state_hash", Octez_smart_rollup.State_hash.encoding) ("ticks", Tick.encoding) ("num_messages", Data_encoding.int31) diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.ml b/src/proto_alpha/lib_sc_rollup_node/publisher.ml index 481f32eb9590..9eb23531bb2d 100644 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.ml +++ b/src/proto_alpha/lib_sc_rollup_node/publisher.ml @@ -281,7 +281,7 @@ let publish_commitment (node_ctxt : _ Node_context.t) ~source let*! () = Commitment_event.publish_commitment (Sc_rollup.Commitment.hash_uncarbonated commitment) - commitment.inbox_level + (Raw_level.to_int32 commitment.inbox_level) in let* _hash = Injector.add_pending_operation ~source publish_operation in return_unit -- GitLab From 7e6e07c280688eaf8586d0e304f5d3c6f0a3af89 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 16 Jun 2023 12:07:05 +0200 Subject: [PATCH 08/15] SCORU/Node: interpreter and inboxes on serialized messages --- .../lib_sc_rollup_node/RPC_server.ml | 3 -- src/proto_alpha/lib_sc_rollup_node/batcher.ml | 13 ++++--- .../lib_sc_rollup_node/fueled_pvm.ml | 11 +++--- src/proto_alpha/lib_sc_rollup_node/inbox.ml | 34 ++++++++++++++++++- src/proto_alpha/lib_sc_rollup_node/inbox.mli | 8 ++--- .../lib_sc_rollup_node/interpreter.ml | 29 +++++++--------- .../lib_sc_rollup_node/interpreter.mli | 2 +- .../lib_sc_rollup_node/refutation_game.ml | 5 +++ .../lib_sc_rollup_node/simulation.ml | 31 +++++++---------- .../lib_sc_rollup_node/simulation.mli | 5 +-- 10 files changed, 82 insertions(+), 59 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml index 35d0bf020c3a..c444033a4c1a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml @@ -365,9 +365,6 @@ let () = let () = Block_directory.register0 Sc_rollup_services.Global.Block.simulate @@ fun (node_ctxt, block) () {messages; reveal_pages; insight_requests} -> - let messages = - List.map Alpha_context.Sc_rollup.Inbox_message.unsafe_of_string messages - in simulate_messages node_ctxt block ~reveal_pages ~insight_requests messages let () = diff --git a/src/proto_alpha/lib_sc_rollup_node/batcher.ml b/src/proto_alpha/lib_sc_rollup_node/batcher.ml index c12a772eb85b..eaf5b902f150 100644 --- a/src/proto_alpha/lib_sc_rollup_node/batcher.ml +++ b/src/proto_alpha/lib_sc_rollup_node/batcher.ml @@ -153,11 +153,14 @@ let produce_batches state ~only_full = let simulate node_ctxt simulation_ctxt (messages : L2_message.t list) = let open Lwt_result_syntax in let*? ext_messages = - List.map_e - (fun m -> - Sc_rollup.Inbox_message.(serialize (External (L2_message.content m)))) - messages - |> Environment.wrap_tzresult + Environment.wrap_tzresult + @@ List.map_e + (fun m -> + let open Result_syntax in + let open Sc_rollup.Inbox_message in + let+ msg = serialize @@ External (L2_message.content m) in + unsafe_to_string msg) + messages in let+ simulation_ctxt, _ticks = Simulation.simulate_messages node_ctxt simulation_ctxt ext_messages 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 b930e11aa3c8..9999b986c0a6 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -46,7 +46,7 @@ module type S = sig messages of the inbox already evaluated. *) remaining_fuel : fuel; (** Fuel remaining for the evaluation of the inbox. *) - remaining_messages : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; (** Messages of the inbox that remain to be evaluated. *) } @@ -61,7 +61,7 @@ module type S = sig val eval_block_inbox : fuel:fuel -> _ Node_context.t -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.serialized list -> + Sc_rollup.Inbox.t * string list -> pvm_state -> eval_result Node_context.delayed_write tzresult Lwt.t @@ -93,7 +93,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct inbox_level : Raw_level.t; message_counter_offset : int; remaining_fuel : fuel; - remaining_messages : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; } type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} @@ -391,10 +391,9 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct (* Consumed all fuel *) return (state, fuel, message_index - message_counter_offset, messages) | message :: messages -> ( + let payload = Sc_rollup.Inbox_message.unsafe_of_string message in let message_counter = Z.of_int message_index in - let input = - Sc_rollup.{inbox_level; message_counter; payload = message} - in + let input = Sc_rollup.{inbox_level; message_counter; payload} in let failing_ticks = Loser_mode.is_failure node_ctxt.Node_context.loser_mode diff --git a/src/proto_alpha/lib_sc_rollup_node/inbox.ml b/src/proto_alpha/lib_sc_rollup_node/inbox.ml index f33011998964..d7d9e3999fed 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/lib_sc_rollup_node/inbox.ml @@ -78,7 +78,16 @@ let get_messages Node_context.{l1_ctxt; _} head = block.operations {apply; apply_internal}) in - return (List.rev rev_messages) + let*? messages = + Environment.wrap_tzresult + @@ List.rev_map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + rev_messages + in + return messages let same_as_layer_1 node_ctxt head_hash inbox = let open Lwt_result_syntax in @@ -129,6 +138,13 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block let predecessor_timestamp = predecessor.header.timestamp in let inbox_metrics = Metrics.Inbox.metrics in Prometheus.Gauge.set inbox_metrics.head_inbox_level @@ Int32.to_float level ; + let*? messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let* ( _messages_history, witness_hash, inbox, @@ -153,6 +169,15 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block messages in let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + let*? messages_with_protocol_internal_messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + messages_with_protocol_internal_messages + in return (inbox_hash, inbox, witness_hash, messages_with_protocol_internal_messages) @@ -197,6 +222,13 @@ let payloads_history_of_messages ~is_first_block ~predecessor (* The inbox is not necessary to compute the payloads *) Sc_rollup.Inbox.genesis ~predecessor_timestamp ~predecessor Raw_level.root in + let* messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let+ ( payloads_history, _history, _inbox, diff --git a/src/proto_alpha/lib_sc_rollup_node/inbox.mli b/src/proto_alpha/lib_sc_rollup_node/inbox.mli index fed5e0503071..e4ac1cbeddc7 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.mli +++ b/src/proto_alpha/lib_sc_rollup_node/inbox.mli @@ -47,7 +47,7 @@ val process_head : (Sc_rollup.Inbox.Hash.t * Sc_rollup.Inbox.t * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + * string list) tzresult Lwt.t @@ -79,7 +79,7 @@ val payloads_history_of_messages : is_first_block:bool -> predecessor:Block_hash.t -> predecessor_timestamp:Timestamp.time -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup.Inbox_merkelized_payload_hashes.History.t tzresult (** [same_as_layer_1 node_ctxt block node_inbox] ensures that the rollup @@ -98,11 +98,11 @@ module Internal_for_tests : sig is_first_block:bool -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox_message.t list -> + string list -> (Sc_rollup.Inbox.Hash.t * Sc_rollup.Inbox.t * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + * string list) tzresult Lwt.t end diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index c020b4e5cc73..3d3f9530e378 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -141,21 +141,16 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} (** [process_head node_ctxt ctxt ~predecessor head] runs the PVM for the given head. *) let process_head (node_ctxt : _ Node_context.t) ctxt - ~(predecessor : Layer1.header) (head : Layer1.header) (inbox, inbox_messages) - = + ~(predecessor : Layer1.header) (head : Layer1.header) inbox_and_messages = let open Lwt_result_syntax in let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.Layer1.level >= first_inbox_level then - let*? inbox_messages = - List.map_e Sc_rollup.Inbox_message.serialize inbox_messages - |> Environment.wrap_tzresult - in transition_pvm node_ctxt ctxt (Layer1.head_of_header predecessor) (Layer1.head_of_header head) - (inbox, inbox_messages) + inbox_and_messages else if head.Layer1.level = node_ctxt.genesis_info.level then let* ctxt, state = genesis_state head.hash node_ctxt ctxt in let*! ctxt = Context.PVMState.set ctxt state in @@ -192,20 +187,22 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = let module PVM = (val node_ctxt.pvm) in let*! tick = PVM.get_tick state in let*! state_hash = PVM.state_hash state in + let*? messages = + (List.map_e Sc_rollup.Inbox_message.serialize messages + |> Environment.wrap_tzresult + :> string list tzresult) + in let messages = - let open Sc_rollup.Inbox_message in - Internal Start_of_level + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized :: (if is_first_block then - [Internal Sc_rollup.Inbox_message.protocol_migration_internal_message] + [unsafe_to_string Raw_context.protocol_migration_serialized_message] else []) - @ Internal (Info_per_level {predecessor; predecessor_timestamp}) + @ unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) :: messages - @ [Internal End_of_level] - in - let*? messages = - List.map_e Sc_rollup.Inbox_message.serialize messages - |> Environment.wrap_tzresult + @ [unsafe_to_string end_of_level_serialized] in return Fueled_pvm.Accounted. diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.mli b/src/proto_alpha/lib_sc_rollup_node/interpreter.mli index 44cabfbbab1e..a8ae28be123a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.mli @@ -38,7 +38,7 @@ val process_head : 'a Context.t -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.t list -> + Sc_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Sc_rollup.Tick.t) tzresult Lwt.t (** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, 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 ee980043e72f..5bca9b1d25eb 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -262,6 +262,11 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let* {is_first_block; predecessor; predecessor_timestamp; messages} = Node_context.get_messages node_ctxt witness in + let*? messages = + (List.map_e Sc_rollup.Inbox_message.serialize messages + |> Environment.wrap_tzresult + :> string list tzresult) + in let*? hist = Inbox.payloads_history_of_messages ~is_first_block diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index 71130d96c2a1..30062b762fef 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.ml +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.ml @@ -125,22 +125,15 @@ let simulate_messages (node_ctxt : Node_context.ro) sim messages = (sim.level_position = End) (Exn (Failure "Level for simulation is ended")) in - let*? messages = - let open Result_syntax in + let messages = if sim.level_position = Start then let {predecessor_timestamp; predecessor} = sim.info_per_level in - let open Sc_rollup.Inbox_message in - let* internals = - List.map_e - serialize - [ - Internal Start_of_level; - Internal (Info_per_level {predecessor_timestamp; predecessor}); - ] - |> Environment.wrap_tzresult - in - return (internals @ messages) - else return messages + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized + :: unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) + :: messages + else messages in let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim messages in ({sim with level_position = Middle}, num_ticks) @@ -152,10 +145,10 @@ let end_simulation node_ctxt sim = (sim.level_position = End) (Exn (Failure "Level for simulation is ended")) in - let*? eol = - Sc_rollup.Inbox_message.serialize - (Sc_rollup.Inbox_message.Internal End_of_level) - |> Environment.wrap_tzresult + let+ sim, num_ticks = + simulate_messages_no_checks + node_ctxt + sim + [Sc_rollup_inbox_message_repr.(unsafe_to_string end_of_level_serialized)] in - let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim [eol] in ({sim with level_position = End}, num_ticks) diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.mli b/src/proto_alpha/lib_sc_rollup_node/simulation.mli index 2c0a627ffff2..6a5bae9c769d 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.mli +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.mli @@ -58,10 +58,7 @@ val start_simulation : simulation state, the remaining fuel (when [?fuel] is provided) and the number of ticks that happened. *) val simulate_messages : - Node_context.ro -> - t -> - Sc_rollup.Inbox_message.serialized list -> - (t * Z.t) tzresult Lwt.t + Node_context.ro -> t -> string list -> (t * Z.t) tzresult Lwt.t (** [end_simulation node_ctxt sim] adds and [End_of_level] message and marks the simulation as ended. *) -- GitLab From fb808072d4118cc4ce9d8e8397e35535397efd8e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 16 Jun 2023 10:44:51 +0200 Subject: [PATCH 09/15] SCORU/Node: remove Protocol dependency from Node_context --- src/lib_scoru_sequencer/seq_batcher.ml | 13 +- .../lib_sc_rollup_node/daemon.ml | 6 +- .../lib_sc_rollup_node/daemon.ml | 6 +- .../lib_sc_rollup_node/daemon.ml | 5 +- .../sc_rollup_services.ml | 26 +- .../lib_sc_rollup_node/RPC_server.ml | 66 ++-- .../block_directory_helpers.ml | 6 +- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 76 ++--- .../lib_sc_rollup_node/dal_pages_request.ml | 9 +- .../lib_sc_rollup_node/dal_slots_tracker.ml | 58 ++-- .../lib_sc_rollup_node/fueled_pvm.ml | 22 +- src/proto_alpha/lib_sc_rollup_node/inbox.ml | 19 +- src/proto_alpha/lib_sc_rollup_node/inbox.mli | 12 +- .../lib_sc_rollup_node/interpreter.ml | 24 +- .../lib_sc_rollup_node/interpreter.mli | 2 +- .../lib_sc_rollup_node/layer1_helpers.ml | 84 +++++ .../lib_sc_rollup_node/layer1_helpers.mli | 28 ++ .../lib_sc_rollup_node/node_context.ml | 304 ++++-------------- .../lib_sc_rollup_node/node_context.mli | 107 +++--- src/proto_alpha/lib_sc_rollup_node/outbox.ml | 5 +- src/proto_alpha/lib_sc_rollup_node/outbox.mli | 2 +- .../lib_sc_rollup_node/publisher.ml | 79 ++--- .../lib_sc_rollup_node/publisher.mli | 6 +- src/proto_alpha/lib_sc_rollup_node/pvm_rpc.ml | 2 +- .../refutation_coordinator.ml | 28 +- .../lib_sc_rollup_node/refutation_game.ml | 18 +- src/proto_alpha/lib_sc_rollup_node/reveals.ml | 4 +- .../lib_sc_rollup_node/reveals.mli | 2 +- .../lib_sc_rollup_node/simulation.ml | 4 +- .../lib_sc_rollup_node/simulation.mli | 2 +- .../lib_sc_rollup_node/test/canary.ml | 10 +- .../test/helpers/helpers.ml | 17 +- .../test/helpers/helpers.mli | 8 +- 33 files changed, 490 insertions(+), 570 deletions(-) diff --git a/src/lib_scoru_sequencer/seq_batcher.ml b/src/lib_scoru_sequencer/seq_batcher.ml index c478ee8853a9..dcaa70d5661f 100644 --- a/src/lib_scoru_sequencer/seq_batcher.ml +++ b/src/lib_scoru_sequencer/seq_batcher.ml @@ -143,11 +143,14 @@ let produce_batch_sequences state head = let simulate node_ctxt simulation_ctxt (messages : L2_message.t list) = let open Lwt_result_syntax in let*? ext_messages = - List.map_e - (fun m -> - Sc_rollup.Inbox_message.(serialize (External (L2_message.content m)))) - messages - |> Environment.wrap_tzresult + Environment.wrap_tzresult + @@ List.map_e + (fun m -> + let open Result_syntax in + let open Sc_rollup.Inbox_message in + let+ msg = serialize @@ External (L2_message.content m) in + unsafe_to_string msg) + messages in let+ simulation_ctxt, _ticks = Simulation.simulate_messages node_ctxt simulation_ctxt ext_messages diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml index f7bd8ddc57bf..aea99805db4e 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml @@ -714,9 +714,9 @@ let run node_ctxt configuration match head with | Some head -> if - Sc_rollup_block.most_recent_commitment head.header - = Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.commitment_hash + Octez_smart_rollup.Commitment.Hash.( + Sc_rollup_block.most_recent_commitment head.header + = node_ctxt.genesis_info.commitment_hash) then fatal_error_exit e else error_to_degraded_mode e | None -> fatal_error_exit e diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml index dc949dac91c4..cb8d52f455b3 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml @@ -705,9 +705,9 @@ let run node_ctxt configuration match head with | Some head -> if - Sc_rollup_block.most_recent_commitment head.header - = Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.commitment_hash + Octez_smart_rollup.Commitment.Hash.( + Sc_rollup_block.most_recent_commitment head.header + = node_ctxt.genesis_info.commitment_hash) then fatal_error_exit e else error_to_degraded_mode e | None -> fatal_error_exit e diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml index 042f606463da..6ba66bd96b1e 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml @@ -706,8 +706,9 @@ let run node_ctxt configuration match head with | Some head -> if - Sc_rollup_block.most_recent_commitment head.header - = node_ctxt.genesis_info.commitment_hash + Octez_smart_rollup.Commitment.Hash.( + Sc_rollup_block.most_recent_commitment head.header + = node_ctxt.genesis_info.commitment_hash) then fatal_error_exit e else error_to_degraded_mode e | None -> fatal_error_exit e diff --git a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml index 62664a971c3a..b6539529a288 100644 --- a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -52,7 +52,7 @@ type eval_result = { state_hash : Sc_rollup.State_hash.t; status : string; output : Sc_rollup.output list; - inbox_level : Raw_level.t; + inbox_level : int32; num_ticks : Z.t; insights : bytes option list; (** The simulation can ask to look at values on the state after @@ -98,8 +98,8 @@ type message_status = l1_level : int32; finalized : bool; cemented : bool; - commitment : Sc_rollup.Commitment.t; - commitment_hash : Sc_rollup.Commitment.Hash.t; + commitment : Octez_smart_rollup.Commitment.t; + commitment_hash : Octez_smart_rollup.Commitment.Hash.t; first_published_at_level : int32; published_at_level : int32; } @@ -109,13 +109,13 @@ module Encodings = struct let commitment_with_hash = obj2 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) let commitment_with_hash_and_level_infos = obj4 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (opt "first_published_at_level" int32) (opt "published_at_level" int32) @@ -141,7 +141,7 @@ module Encodings = struct ~description:"Output produced by evaluation of the messages") (req "inbox_level" - Raw_level.encoding + int32 ~description:"Level of the inbox that would contain these messages") (req "num_ticks" @@ -320,8 +320,8 @@ module Encodings = struct (req "level" int32))) (req "finalized" bool) (req "cemented" bool) - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (req "first_published_at_level" int32) (req "published_at_level" int32)) (function @@ -606,7 +606,7 @@ module Global = struct Tezos_rpc.Service.get_service ~description:"Rollup inbox for block" ~query:Tezos_rpc.Query.empty - ~output:Sc_rollup.Inbox.encoding + ~output:Octez_smart_rollup.Inbox.encoding (path / "inbox") let ticks = @@ -721,9 +721,7 @@ module Global = struct ~output: Data_encoding.( list - @@ obj2 - (req "index" Dal.Slot_index.encoding) - (req "status" dal_slot_status_encoding)) + @@ obj2 (req "index" int31) (req "status" dal_slot_status_encoding)) (path / "dal" / "processed_slots") module Outbox = struct diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml index c444033a4c1a..461e74fca335 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml @@ -209,24 +209,21 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages insight_requests in let num_ticks = Z.(num_ticks_0 + num_ticks_end) in - let*! outbox = PVM.get_outbox inbox_level state in + let level = Raw_level.of_int32_exn inbox_level in + let*! outbox = PVM.get_outbox level state in let output = - List.filter - (fun Sc_rollup.{outbox_level; _} -> outbox_level = inbox_level) - outbox + List.filter (fun Sc_rollup.{outbox_level; _} -> outbox_level = level) outbox in let*! state_hash = PVM.state_hash state in - let* parametric_constants = - let cctxt = node_ctxt.cctxt in - Protocol.Constants_services.parametric cctxt (cctxt#chain, `Level level) - in - let*! status = - PVM.get_status - ~is_reveal_enabled: - (Sc_rollup.is_reveal_enabled_predicate - parametric_constants.sc_rollup.reveal_activation_level) - state + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5871 + Use constants for correct protocol. *) + let is_reveal_enabled = + node_ctxt.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 let status = PVM.string_of_status status in return Sc_rollup_services. @@ -282,7 +279,6 @@ let () = | Some head -> let commitment_hash = Sc_rollup_block.most_recent_commitment head.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let+ commitment = Node_context.find_commitment node_ctxt commitment_hash @@ -296,9 +292,7 @@ let () = match Reference.get node_ctxt.lpc with | None -> return_none | Some commitment -> - let hash = - Alpha_context.Sc_rollup.Commitment.hash_uncarbonated commitment - in + let hash = Octez_smart_rollup.Commitment.hash commitment in (* The corresponding level in Store.Commitments.published_at_level is available only when the commitment has been published and included in a block. *) @@ -319,30 +313,29 @@ let () = let open Lwt_result_syntax in let* state = get_state node_ctxt block in let module PVM = (val node_ctxt.pvm) in - let* current_level = Node_context.level_of_hash node_ctxt block in - let* parametric_constants = - let cctxt = node_ctxt.cctxt in - Protocol.Constants_services.parametric - cctxt - (cctxt#chain, `Level current_level) - in - let*! status = - PVM.get_status - ~is_reveal_enabled: - (Alpha_context.Sc_rollup.is_reveal_enabled_predicate - parametric_constants.sc_rollup.reveal_activation_level) - state + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5871 + Use constants for correct protocol. *) + let is_reveal_enabled = + node_ctxt.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 return (PVM.string_of_status status) let () = Block_directory.register0 Sc_rollup_services.Global.Block.dal_slots @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in - let* slots = + let+ slots = Node_context.get_all_slot_headers node_ctxt ~published_in_block_hash:block in - return slots + List.rev_map + (Sc_rollup_proto_types.Dal.Slot_header.of_octez + ~number_of_slots:node_ctxt.protocol_constants.dal.number_of_slots) + slots + |> List.rev let () = Block_directory.register0 Sc_rollup_services.Global.Block.dal_processed_slots @@ -398,20 +391,17 @@ let commitment_level_of_inbox_level (node_ctxt : _ Node_context.t) inbox_level = Int32.of_int node_ctxt.protocol_constants.sc_rollup.commitment_period_in_blocks in - let last_published = - Raw_level.to_int32 last_published_commitment.inbox_level - in + let last_published = last_published_commitment.inbox_level in let open Int32 in div (sub last_published inbox_level) commitment_period |> mul commitment_period |> sub last_published |> Raw_level.of_int32_exn let inbox_info_of_level (node_ctxt : _ Node_context.t) inbox_level = - let open Alpha_context in let open Lwt_result_syntax in let+ finalized_level = Node_context.get_finalized_level node_ctxt in let finalized = Compare.Int32.(inbox_level <= finalized_level) in let lcc = Reference.get node_ctxt.lcc in - let cemented = Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) in + let cemented = Compare.Int32.(inbox_level <= lcc.level) in (finalized, cemented) let () = diff --git a/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml index a4ccb383a729..e7cba968fb78 100644 --- a/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol - (* Conveniences to construct RPC directory against a subcontext of the Node_context *) @@ -43,9 +41,7 @@ let get_finalized node_ctxt = let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> let lcc = Reference.get node_ctxt.lcc in - Node_context.hash_of_level - node_ctxt - (Alpha_context.Raw_level.to_int32 lcc.level) + Node_context.hash_of_level node_ctxt lcc.level let block_of_prefix node_ctxt block = match block with diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index 1829c9f7b1f9..ea72e8fdcd56 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -94,10 +94,12 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let save_lpc = match Reference.get node_ctxt.lpc with | None -> true - | Some lpc -> Raw_level.(commitment.inbox_level >= lpc.inbox_level) + | Some lpc -> + Raw_level.to_int32 commitment.inbox_level >= lpc.inbox_level in + let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in if save_lpc then Reference.set node_ctxt.lpc (Some commitment) ; - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let* () = Node_context.set_commitment_published_at_level node_ctxt @@ -155,7 +157,6 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) | ( Sc_rollup_cement _, Sc_rollup_cement_result {inbox_level; commitment_hash; _} ) -> (* Cemented commitment ---------------------------------------------- *) - let proto_inbox_level = inbox_level in let proto_commitment_hash = commitment_hash in let inbox_level = Raw_level.to_int32 inbox_level in let commitment_hash = @@ -177,10 +178,10 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) in let lcc = Reference.get node_ctxt.lcc in let*! () = - if inbox_level > Raw_level.to_int32 lcc.level then ( + if inbox_level > lcc.level then ( Reference.set node_ctxt.lcc - {commitment = proto_commitment_hash; level = proto_inbox_level} ; + {commitment = proto_commitment_hash; level = inbox_level} ; Commitment_event.last_cemented_commitment_updated proto_commitment_hash inbox_level) @@ -218,7 +219,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) Node_context.save_slot_header node_ctxt ~published_in_block_hash:head.Layer1.hash - slot_header + (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) in return_unit | _, _ -> @@ -408,10 +409,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) in let* () = unless (catching_up && Option.is_none commitment_hash) @@ fun () -> - Inbox.same_as_layer_1 - node_ctxt - head.hash - (Sc_rollup_proto_types.Inbox.to_octez inbox) + Inbox.same_as_layer_1 node_ctxt head.hash inbox in let level = head.level in let* previous_commitment_hash = @@ -574,7 +572,7 @@ let check_initial_state_hash {Node_context.cctxt; rollup_address; pvm; _} = let module PVM = (val pvm) in let* l1_reference_initial_state_hash = RPC.Sc_rollup.initial_pvm_state_hash - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, cctxt#block) rollup_address in @@ -672,7 +670,7 @@ let run node_ctxt configuration ~id:configuration.sc_rollup_address ~mode:configuration.mode ~genesis_level:node_ctxt.genesis_info.level - ~pvm_kind:(Sc_rollup.Kind.to_string node_ctxt.kind) ; + ~pvm_kind:(Octez_smart_rollup.Kind.to_string node_ctxt.kind) ; let fatal_error_exit e = Format.eprintf "%!%a@.Exiting.@." pp_print_trace e ; let*! _ = Lwt_exit.exit_and_wait 1 in @@ -699,8 +697,9 @@ let run node_ctxt configuration match head with | Some head -> if - Sc_rollup_block.most_recent_commitment head.header - = node_ctxt.genesis_info.commitment_hash + Octez_smart_rollup.Commitment.Hash.( + Sc_rollup_block.most_recent_commitment head.header + = node_ctxt.genesis_info.commitment_hash) then fatal_error_exit e else error_to_degraded_mode e | None -> fatal_error_exit e @@ -785,31 +784,6 @@ module Internal_for_tests = struct return l2_block end -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 - The constants are retrieved from the latest tezos block. These constants can - be different from the ones used at the creation at the rollup because of a - protocol amendment that modifies some of them. This need to be fixed when the - rollup nodes will be able to handle the migration of protocol. -*) -let retrieve_constants cctxt = - let open Lwt_result_syntax in - let+ {parametric; _} = - Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) - in - Layer1_helpers.constants_of_parametric parametric - -let retrieve_genesis_info cctxt rollup_address = - let open Lwt_result_syntax in - let+ {level; commitment_hash} = - RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, `Head 0) rollup_address - in - Node_context. - { - level = Raw_level.to_int32 level; - commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; - } - module Rollup_node_daemon_components : Daemon_components.S = struct module Batcher = Batcher module RPC_server = RPC_server @@ -846,10 +820,25 @@ let run Layer1.fetch_tezos_shell_header l1_ctxt head.header.predecessor in let*! () = Event.received_first_block head.hash Protocol.hash in - let* constants = retrieve_constants cctxt - and* genesis_info = - retrieve_genesis_info cctxt configuration.sc_rollup_address + let publisher = + Configuration.Operator_purpose_map.find + Publish + configuration.sc_rollup_node_operators in + let* constants = Layer1_helpers.retrieve_constants cctxt + and* genesis_info = + Layer1_helpers.retrieve_genesis_info cctxt configuration.sc_rollup_address + and* lcc = + Layer1_helpers.get_last_cemented_commitment + cctxt + configuration.sc_rollup_address + and* lpc = + Option.filter_map_es + (Layer1_helpers.get_last_published_commitment + cctxt + configuration.sc_rollup_address) + publisher + and* kind = Layer1_helpers.get_kind cctxt configuration.sc_rollup_address in let* node_ctxt = Node_context.init cctxt @@ -859,6 +848,9 @@ let run l1_ctxt constants genesis_info + ~lcc + ~lpc + kind ~proto_level:predecessor.proto_level configuration in diff --git a/src/proto_alpha/lib_sc_rollup_node/dal_pages_request.ml b/src/proto_alpha/lib_sc_rollup_node/dal_pages_request.ml index 5744e9f67728..322c201aa67c 100644 --- a/src/proto_alpha/lib_sc_rollup_node/dal_pages_request.ml +++ b/src/proto_alpha/lib_sc_rollup_node/dal_pages_request.ml @@ -95,18 +95,17 @@ let download_confirmed_slot_pages ({Node_context.dal_cctxt; _} as node_ctxt) let* published_in_block_hash = Node_context.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in - let* {commitment; _} = + let* header = Node_context.get_slot_header node_ctxt ~published_in_block_hash index in let dal_cctxt = WithExceptions.Option.get ~loc:__LOC__ dal_cctxt in (* DAL must be configured for this point to be reached *) - get_slot_pages dal_cctxt commitment + get_slot_pages dal_cctxt header.commitment let storage_invariant_broken published_level index = failwith "Internal error: [Node_context.find_slot_status] is supposed to have \ - registered the status of the slot %a published at level %a in the store" - Dal.Slot_index.pp + registered the status of the slot %d published at level %a in the store" index Raw_level.pp published_level @@ -120,6 +119,7 @@ let slot_pages ~dal_attestation_lag node_ctxt ~published_level node_ctxt in + let index = Sc_rollup_proto_types.Dal.Slot_index.to_octez index in let* processed = Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in @@ -142,6 +142,7 @@ let page_content ~dal_attestation_lag node_ctxt page_id = ~published_level node_ctxt in + let index = Sc_rollup_proto_types.Dal.Slot_index.to_octez index in let* processed = Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in diff --git a/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml b/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml index 61d4cd7ea1ac..d48444cd9513 100644 --- a/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml +++ b/src/proto_alpha/lib_sc_rollup_node/dal_slots_tracker.ml @@ -102,10 +102,15 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = node_ctxt ~published_in_block_hash:published_block_hash in + let number_of_slots = + node_ctxt.Node_context.protocol_constants.dal.number_of_slots + in let confirmed_slots_indexes_list = List.filter (Dal.Attestation.is_attested confirmed_slots) - published_slots_indexes + (List.filter_map + (Dal.Slot_index.of_int_opt ~number_of_slots) + published_slots_indexes) in let*? confirmed_slots_indexes = Environment.wrap_tzresult @@ -119,16 +124,8 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = avoid going back and forth between bitsets and lists of slot indexes. *) let to_slot_index_list (constants : Rollup_constants.protocol_constants) bitset = - let open Result_syntax in - let number_of_slots = constants.dal.number_of_slots in - let all_slots = Misc.(0 --> (number_of_slots - 1)) in - let+ filtered = List.filter_e (Bitset.mem bitset) all_slots in - (* Because the maximum slot index is smaller than the number_of_slots protocol - constants, and this value is smaller than the hard limit imposed for slots, - then Dal.Slot_index.to_int will always return a defined value. See - `src/proto_alpha/lib_protocol/constants_repr.ml`. - *) - List.filter_map (Dal.Slot_index.of_int_opt ~number_of_slots) filtered + let all_slots = Misc.(0 --> (constants.dal.number_of_slots - 1)) in + List.filter_e (Bitset.mem bitset) all_slots (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/4139. Use a shared storage between dal and rollup node to store slots data. @@ -175,7 +172,9 @@ let download_and_save_slots in let*! () = Dal_slots_tracker_event.slot_has_been_confirmed - s_slot + (Sc_rollup_proto_types.Dal.Slot_index.of_octez + ~number_of_slots:protocol_constants.dal.number_of_slots + s_slot) published_block_hash current_block_hash in @@ -197,17 +196,24 @@ module Confirmed_slots_history = struct in List.map_ep (fun slot_index -> - Node_context.get_slot_header - node_ctxt - ~published_in_block_hash:published_block_hash - slot_index) + let+ h = + Node_context.get_slot_header + node_ctxt + ~published_in_block_hash:published_block_hash + slot_index + in + Sc_rollup_proto_types.Dal.Slot_header.of_octez + ~number_of_slots:node_ctxt.protocol_constants.dal.number_of_slots + h) relevant_slots_indexes let read_slots_history_from_l1 {Node_context.cctxt; _} block = let open Lwt_result_syntax in (* We return the empty Slots_history if DAL is not enabled. *) let* slots_list_opt = - RPC.Dal.dal_confirmed_slots_history cctxt (cctxt#chain, `Hash (block, 0)) + RPC.Dal.dal_confirmed_slots_history + (new Protocol_client_context.wrap_full cctxt) + (cctxt#chain, `Hash (block, 0)) in return @@ Option.value slots_list_opt ~default:Dal.Slots_history.genesis @@ -257,19 +263,29 @@ module Confirmed_slots_history = struct block_level let slots_history_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_history node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history" - ~find:Node_context.find_confirmed_slots_history + ~find ~default:read_slots_history_from_l1 let slots_history_cache_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_histories node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history cache" - ~find:Node_context.find_confirmed_slots_histories + ~find ~default:(fun node_ctxt _block -> let num_slots = node_ctxt.Node_context.protocol_constants.dal.number_of_slots @@ -320,13 +336,13 @@ module Confirmed_slots_history = struct Node_context.save_confirmed_slots_history node_ctxt head_hash - slots_history + (Sc_rollup_proto_types.Dal.Slot_history.to_octez slots_history) in let* () = Node_context.save_confirmed_slots_histories node_ctxt head_hash - slots_cache + (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez slots_cache) in return () 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 9999b986c0a6..289924e06aba 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -39,8 +39,7 @@ module type S = sig 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 : Raw_level.t; - (** Inbox level in which messages are evaluated. *) + 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. *) @@ -61,7 +60,7 @@ module type S = sig val eval_block_inbox : fuel:fuel -> _ Node_context.t -> - Sc_rollup.Inbox.t * string list -> + Octez_smart_rollup.Inbox.t * string list -> pvm_state -> eval_result Node_context.delayed_write tzresult Lwt.t @@ -90,7 +89,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct state : pvm_state; state_hash : Sc_rollup.State_hash.t; tick : Sc_rollup.Tick.t; - inbox_level : Raw_level.t; + inbox_level : int32; message_counter_offset : int; remaining_fuel : fuel; remaining_messages : string list; @@ -381,7 +380,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_messages ~reveal_map ~fuel node_ctxt ~message_counter_offset state inbox_level messages = let open Delayed_write_monad.Lwt_result_syntax in - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in (* Iterate the PVM state with all the messages. *) let rec feed_messages (state, fuel) message_index = function | [] -> @@ -393,7 +392,14 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct | message :: messages -> ( let payload = Sc_rollup.Inbox_message.unsafe_of_string message in let message_counter = Z.of_int message_index in - let input = Sc_rollup.{inbox_level; message_counter; payload} in + let input = + Sc_rollup. + { + inbox_level = Raw_level.of_int32_exn inbox_level; + message_counter; + payload; + } + in let failing_ticks = Loser_mode.is_failure node_ctxt.Node_context.loser_mode @@ -436,7 +442,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let open Delayed_write_monad.Lwt_result_syntax in let module PVM = (val node_ctxt.pvm) in (* Obtain inbox and its messages for this block. *) - let inbox_level = Inbox.inbox_level inbox in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in let*! initial_tick = PVM.get_tick state in (* Evaluate all the messages for this level. *) let>* state, remaining_fuel, num_messages, remaining_messages = @@ -481,7 +487,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let>* state, remaining_fuel, num_messages, remaining_messages = match messages with | [] -> - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in let message_index = message_counter_offset - 1 in let failing_ticks = Loser_mode.is_failure diff --git a/src/proto_alpha/lib_sc_rollup_node/inbox.ml b/src/proto_alpha/lib_sc_rollup_node/inbox.ml index d7d9e3999fed..108334f2544e 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/lib_sc_rollup_node/inbox.ml @@ -93,6 +93,7 @@ let same_as_layer_1 node_ctxt head_hash inbox = let open Lwt_result_syntax in let head_block = `Hash (head_hash, 0) in let Node_context.{cctxt; _} = node_ctxt in + let cctxt = new Protocol_client_context.wrap_full cctxt in let* layer1_inbox = Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, head_block) in @@ -138,6 +139,8 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block let predecessor_timestamp = predecessor.header.timestamp in let inbox_metrics = Metrics.Inbox.metrics in Prometheus.Gauge.set inbox_metrics.head_inbox_level @@ Int32.to_float level ; + let inbox = Sc_rollup_proto_types.Inbox.of_octez inbox in + let serialized_messages = messages in let*? messages = Environment.wrap_tzresult @@ List.map_e @@ -166,9 +169,13 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block node_ctxt witness_hash ~block_hash:head.hash - messages + serialized_messages in + let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + let witness_hash = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez witness_hash + in let*? messages_with_protocol_internal_messages = Environment.wrap_tzresult @@ List.map_e @@ -205,8 +212,14 @@ let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) head collected_messages else - let* inbox = Node_context.genesis_inbox node_ctxt in - let witness = Sc_rollup.Inbox.current_witness inbox in + let* inbox = + Layer1_helpers.genesis_inbox + (new Protocol_client_context.wrap_full node_ctxt.cctxt) + ~genesis_level:node_ctxt.genesis_info.level + in + let Octez_smart_rollup.Inbox.{hash = witness; _} = + Octez_smart_rollup.Inbox.Skip_list.content inbox.old_levels_messages + in let* () = Node_context.save_messages node_ctxt witness ~block_hash:head.hash [] in diff --git a/src/proto_alpha/lib_sc_rollup_node/inbox.mli b/src/proto_alpha/lib_sc_rollup_node/inbox.mli index e4ac1cbeddc7..915b87728b2a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.mli +++ b/src/proto_alpha/lib_sc_rollup_node/inbox.mli @@ -44,9 +44,9 @@ val process_head : Node_context.rw -> predecessor:Layer1.header -> Layer1.header -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t * string list) tzresult Lwt.t @@ -99,9 +99,9 @@ module Internal_for_tests : sig predecessor:Layer1.header -> Layer1.header -> string list -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t * string list) tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index 3d3f9530e378..0aeaa12eccf9 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -44,7 +44,8 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = match (operation, result) with | ( Sc_rollup_originate {kind; boot_sector; _}, Sc_rollup_originate_result {address; _} ) - when node_ctxt.rollup_address = address && node_ctxt.kind = kind -> + 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 @@ -130,11 +131,7 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} let*! initial_tick = PVM.get_tick predecessor_state in (* Produce events. *) let*! () = - Interpreter_event.transitioned_pvm - (Raw_level.to_int32 inbox_level) - state_hash - tick - num_messages + Interpreter_event.transitioned_pvm inbox_level state_hash tick num_messages in return (ctxt, num_messages, Z.to_int64 num_ticks, initial_tick) @@ -183,15 +180,10 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez block.header.inbox_witness) in - let inbox_level = Sc_rollup.Inbox.inbox_level inbox in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in let module PVM = (val node_ctxt.pvm) in let*! tick = PVM.get_tick state in let*! state_hash = PVM.state_hash state in - let*? messages = - (List.map_e Sc_rollup.Inbox_message.serialize messages - |> Environment.wrap_tzresult - :> string list tzresult) - in let messages = let open Sc_rollup_inbox_message_repr in unsafe_to_string start_of_level_serialized @@ -236,8 +228,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 Raw_level.to_int32 start_state.Fueled_pvm.Accounted.inbox_level - = event.header.level -> + when start_state.Fueled_pvm.Accounted.inbox_level = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a @@ -282,11 +273,14 @@ let memo_state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) returns [None].*) 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 <= Raw_level.to_int32 level) ; + 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 a8ae28be123a..48cff9f6ceb5 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.mli @@ -38,7 +38,7 @@ val process_head : 'a Context.t -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox.t * string list -> + Octez_smart_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Sc_rollup.Tick.t) tzresult Lwt.t (** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, 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 a7ae7b7db7bc..6e8fcdf54076 100644 --- a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml @@ -53,6 +53,64 @@ let fetch_tezos_block l1_ctxt hash = let prefetch_tezos_blocks = Layer1.prefetch_tezos_blocks fetch extract_header +let get_last_cemented_commitment (cctxt : Protocol_client_context.full) + rollup_address : Node_context.lcc tzresult Lwt.t = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ commitment, level = + Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level + cctxt + (cctxt#chain, `Head 0) + rollup_address + in + { + Node_context.commitment = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment; + level = Protocol.Alpha_context.Raw_level.to_int32 level; + } + +let get_last_published_commitment (cctxt : Protocol_client_context.full) + rollup_address operator = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let*! res = + Plugin.RPC.Sc_rollup.staked_on_commitment + cctxt + (cctxt#chain, `Head 0) + rollup_address + operator + in + match res with + | Error trace + when TzTrace.fold + (fun exists -> function + | Environment.Ecoproto_error + Protocol.Sc_rollup_errors.Sc_rollup_not_staked -> + true + | _ -> exists) + false + trace -> + return_none + | Error trace -> fail trace + | Ok None -> return_none + | Ok (Some (_staked_hash, staked_commitment)) -> + return_some (Sc_rollup_proto_types.Commitment.to_octez staked_commitment) + +let get_kind cctxt rollup_address = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ kind = + RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () + in + Sc_rollup_proto_types.Kind.to_octez kind + +let genesis_inbox cctxt ~genesis_level = + let open Lwt_result_syntax in + let+ inbox = + Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, `Level genesis_level) + in + Sc_rollup_proto_types.Inbox.to_octez inbox + let constants_of_parametric Protocol.Alpha_context.Constants.Parametric. { @@ -84,3 +142,29 @@ let constants_of_parametric }; dal = {feature_enable; attestation_lag; number_of_slots}; } + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 + The constants are retrieved from the latest tezos block. These constants can + be different from the ones used at the creation at the rollup because of a + protocol amendment that modifies some of them. This need to be fixed when the + rollup nodes will be able to handle the migration of protocol. +*) +let retrieve_constants ?(block = `Head 0) cctxt = + let open Lwt_result_syntax in + let+ {parametric; _} = + Protocol.Constants_services.all cctxt (cctxt#chain, block) + in + constants_of_parametric parametric + +let retrieve_genesis_info cctxt rollup_address = + let open Lwt_result_syntax in + let open Protocol.Alpha_context in + let+ {level; commitment_hash} = + RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, `Head 0) rollup_address + in + Node_context. + { + level = Raw_level.to_int32 level; + commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; + } 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 3fd949075da5..605c80fcbdd0 100644 --- a/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli +++ b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.mli @@ -39,7 +39,35 @@ val fetch_tezos_block : than the size of the blocks cache otherwise they will be lost. *) val prefetch_tezos_blocks : t -> head list -> unit +val get_last_cemented_commitment : + Protocol_client_context.full -> Address.t -> Node_context.lcc tzresult Lwt.t + +val get_last_published_commitment : + Protocol_client_context.full -> + Address.t -> + Signature.public_key_hash -> + Commitment.t option tzresult Lwt.t + +val get_kind : + Protocol_client_context.full -> Address.t -> Kind.t tzresult Lwt.t + +val genesis_inbox : + Protocol_client_context.full -> + genesis_level:int32 -> + Octez_smart_rollup.Inbox.t tzresult Lwt.t + (** Convert protocol constants to their protocol agnostic representation. *) val constants_of_parametric : Protocol.Alpha_context.Constants.Parametric.t -> Rollup_constants.protocol_constants + +(** Retrieve protocol agnotic constants for the head of the chain. *) +val retrieve_constants : + ?block:Block_services.block -> + Protocol_client_context.full -> + Rollup_constants.protocol_constants tzresult Lwt.t + +val retrieve_genesis_info : + Protocol_client_context.full -> + Address.t -> + Node_context.genesis_info tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index 9721ecbc0198..df5bfd3f73f8 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -24,34 +24,28 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +type lcc = {commitment : Commitment.Hash.t; level : int32} -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -type genesis_info = { - level : int32; - commitment_hash : Octez_smart_rollup.Commitment.Hash.t; -} +type genesis_info = {level : int32; commitment_hash : Commitment.Hash.t} type 'a store = 'a Store.t type debug_logger = string -> unit Lwt.t type 'a t = { - cctxt : Protocol_client_context.full; + cctxt : Client_context.full; dal_cctxt : Dal_node_client.cctxt option; dac_client : Dac_observer_client.t option; data_dir : string; l1_ctxt : Layer1.t; - rollup_address : Sc_rollup.t; + rollup_address : Address.t; boot_sector_file : string option; mode : Configuration.mode; operators : Configuration.operators; genesis_info : genesis_info; injector_retention_period : int; block_finality_time : int; - kind : Sc_rollup.Kind.t; + kind : Kind.t; pvm : (module Pvm.S); fee_parameters : Configuration.fee_parameters; protocol_constants : Rollup_constants.protocol_constants; @@ -61,7 +55,7 @@ type 'a t = { store : 'a store; context : 'a Context.index; lcc : ('a, lcc) Reference.t; - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; + lpc : ('a, Commitment.t option) Reference.t; kernel_debug_logger : debug_logger; finaliser : unit -> unit Lwt.t; } @@ -86,42 +80,6 @@ let get_fee_parameter node_ctxt purpose = Configuration.Operator_purpose_map.find purpose node_ctxt.fee_parameters |> Option.value ~default:(Configuration.default_fee_parameter ~purpose ()) -let get_last_cemented_commitment (cctxt : Protocol_client_context.full) - rollup_address = - let open Lwt_result_syntax in - let+ commitment, level = - Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level - cctxt - (cctxt#chain, `Head 0) - rollup_address - in - {commitment; level} - -let get_last_published_commitment (cctxt : Protocol_client_context.full) - rollup_address operator = - let open Lwt_result_syntax in - let*! res = - Plugin.RPC.Sc_rollup.staked_on_commitment - cctxt - (cctxt#chain, `Head 0) - rollup_address - operator - in - match res with - | Error trace - when TzTrace.fold - (fun exists -> function - | Environment.Ecoproto_error Sc_rollup_errors.Sc_rollup_not_staked - -> - true - | _ -> exists) - false - trace -> - return_none - | Error trace -> fail trace - | Ok None -> return_none - | Ok (Some (_staked_hash, staked_commitment)) -> return_some staked_commitment - let lock ~data_dir = let lockfile_path = Filename.concat data_dir "lock" in let lock_aux ~data_dir = @@ -166,14 +124,13 @@ let make_kernel_logger ?log_kernel_debug_file data_dir = in Lwt_io.of_fd ~close:(fun () -> Lwt_unix.close fd) ~mode:Lwt_io.Output fd -let pvm_of_kind : Protocol.Alpha_context.Sc_rollup.Kind.t -> (module Pvm.S) = - function +let pvm_of_kind : Kind.t -> (module Pvm.S) = function | Example_arith -> (module Arith_pvm) | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) -let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file - mode l1_ctxt (protocol_constants : Rollup_constants.protocol_constants) - genesis_info ~proto_level +let init (cctxt : #Client_context.full) ~data_dir ?log_kernel_debug_file mode + l1_ctxt (protocol_constants : Rollup_constants.protocol_constants) + genesis_info ~lcc ~lpc kind ~proto_level Configuration.( { sc_rollup_address = rollup_address; @@ -205,24 +162,7 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file Context.load mode (Configuration.default_context_dir data_dir) in let* () = Context.Rollup.check_or_set_address mode context rollup_address in - let publisher = Configuration.Operator_purpose_map.find Publish operators in - let rollup_address = - (* Convert to protocol rollup address *) - Sc_rollup_proto_types.Address.of_octez rollup_address - in - let* lcc = get_last_cemented_commitment cctxt rollup_address - and* lpc = - Option.filter_map_es - (get_last_published_commitment cctxt rollup_address) - publisher - and* kind = - RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () - in - let*! () = - Event.rollup_exists - ~addr:rollup_address - ~kind:(Sc_rollup_proto_types.Kind.to_octez kind) - in + let*! () = Event.rollup_exists ~addr:rollup_address ~kind in let*! () = if dal_cctxt = None && protocol_constants.dal.feature_enable then Event.warn_dal_enabled_no_node () @@ -234,8 +174,7 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file Dac_observer_client.init { observer_endpoint; - reveal_data_dir = - Filename.concat data_dir (Sc_rollup.Kind.to_string kind); + reveal_data_dir = Filename.concat data_dir (Kind.to_string kind); timeout_seconds = configuration.dac_timeout; }) configuration.dac_observer_endpoint @@ -256,7 +195,7 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file in return { - cctxt; + cctxt = (cctxt :> Client_context.full); dal_cctxt; dac_client; data_dir; @@ -566,7 +505,7 @@ let block_with_tick ({store; _} as node_ctxt) ~max_level tick = let open Lwt_result_option_syntax in Error.trace_lwt_result_with "Could not retrieve block with tick %a" - Sc_rollup.Tick.pp + Z.pp_print tick @@ let** head = Store.L2_head.read store.l2_head in (* We start by taking big steps of 4096 blocks for the first @@ -575,37 +514,17 @@ let block_with_tick ({store; _} as node_ctxt) ~max_level tick = the refutation period as the big_step_blocks to do a dichotomy on the full space but we anticipate refutation to happen most of the time close to the head. *) - let max_level = Raw_level.to_int32 max_level in let** head = if head.header.level <= max_level then return_some head else find_l2_block_by_level node_ctxt max_level in - tick_search ~big_step_blocks:4096 node_ctxt head (Sc_rollup.Tick.to_z tick) + tick_search ~big_step_blocks:4096 node_ctxt head tick -let find_octez_commitment {store; _} commitment_hash = +let find_commitment {store; _} commitment_hash = let open Lwt_result_syntax in let+ commitment = Store.Commitments.read store.commitments commitment_hash in Option.map fst commitment -let find_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let+ commitment = find_octez_commitment node_ctxt commitment_hash in - Option.map Sc_rollup_proto_types.Commitment.of_octez commitment - -let get_octez_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let* commitment = find_octez_commitment node_ctxt commitment_hash in - match commitment with - | None -> - failwith - "Could not retrieve commitment %a" - Octez_smart_rollup.Commitment.Hash.pp - commitment_hash - | Some i -> return i - let get_commitment node_ctxt commitment_hash = let open Lwt_result_syntax in let* commitment = find_commitment node_ctxt commitment_hash in @@ -613,7 +532,7 @@ let get_commitment node_ctxt commitment_hash = | None -> failwith "Could not retrieve commitment %a" - Sc_rollup.Commitment.Hash.pp + Commitment.Hash.pp commitment_hash | Some i -> return i @@ -623,21 +542,18 @@ let commitment_exists {store; _} hash = let save_commitment {store; _} commitment = let open Lwt_result_syntax in - let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in - let hash = Octez_smart_rollup.Commitment.hash commitment in + let hash = Commitment.hash commitment in let+ () = Store.Commitments.append store.commitments ~key:hash ~value:commitment in - Sc_rollup_proto_types.Commitment_hash.of_octez hash + hash let commitment_published_at_level {store; _} commitment = - let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in Store.Commitments_published_at_level.find store.commitments_published_at_level commitment let set_commitment_published_at_level {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in Store.Commitments_published_at_level.add store.commitments_published_at_level hash @@ -646,9 +562,6 @@ type commitment_source = Anyone | Us let commitment_was_published {store; _} ~source commitment_hash = let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in match source with | Anyone -> Store.Commitments_published_at_level.mem @@ -664,20 +577,14 @@ let commitment_was_published {store; _} ~source commitment_hash = | Some {published_at_level = Some _; _} -> true | _ -> false) -let find_octez_inbox {store; _} inbox_hash = +let find_inbox {store; _} inbox_hash = let open Lwt_result_syntax in let+ inbox = Store.Inboxes.read store.inboxes inbox_hash in Option.map fst inbox -let find_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in - let+ inbox = find_octez_inbox node_ctxt inbox_hash in - Option.map Sc_rollup_proto_types.Inbox.of_octez inbox - -let get_octez_inbox node_ctxt inbox_hash = +let get_inbox node_ctxt inbox_hash = let open Lwt_result_syntax in - let* inbox = find_octez_inbox node_ctxt inbox_hash in + let* inbox = find_inbox node_ctxt inbox_hash in match inbox with | None -> failwith @@ -686,36 +593,18 @@ let get_octez_inbox node_ctxt inbox_hash = inbox_hash | Some i -> return i -let get_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let* inbox = find_inbox node_ctxt inbox_hash in - match inbox with - | None -> - failwith "Could not retrieve inbox %a" Sc_rollup.Inbox.Hash.pp inbox_hash - | Some i -> return i - let save_inbox {store; _} inbox = let open Lwt_result_syntax in - let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in let hash = Octez_smart_rollup.Inbox.hash inbox in let+ () = Store.Inboxes.append store.inboxes ~key:hash ~value:inbox in - Sc_rollup_proto_types.Inbox_hash.of_octez hash + hash let find_inbox_by_block_hash ({store; _} as node_ctxt) block_hash = let open Lwt_result_syntax in let* header = Store.L2_blocks.header store.l2_blocks block_hash in match header with | None -> return_none - | Some {inbox_hash; _} -> - find_inbox - node_ctxt - (Sc_rollup_proto_types.Inbox_hash.of_octez inbox_hash) - -let genesis_inbox node_ctxt = - let genesis_level = node_ctxt.genesis_info.level in - Plugin.RPC.Sc_rollup.inbox - node_ctxt.cctxt - (node_ctxt.cctxt#chain, `Level genesis_level) + | Some {inbox_hash; _} -> find_inbox node_ctxt inbox_hash let inbox_of_head node_ctxt Layer1.{hash = block_hash; level = block_level} = let open Lwt_result_syntax in @@ -751,8 +640,8 @@ let get_inbox_by_block_hash node_ctxt hash = type messages_info = { is_first_block : bool; predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; + predecessor_timestamp : Time.Protocol.t; + messages : string list; } let find_messages node_ctxt messages_hash = @@ -772,13 +661,6 @@ let find_messages node_ctxt messages_hash = let is_first_block = pred_header.header.proto_level <> grand_parent_header.header.proto_level in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e - (fun m -> - Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string m)) - messages - in return_some { is_first_block; @@ -799,10 +681,7 @@ let get_messages_aux find pp node_ctxt hash = | Some res -> return res let get_messages node_ctxt = - get_messages_aux - find_messages - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.pp - node_ctxt + get_messages_aux find_messages Merkelized_payload_hashes_hash.pp node_ctxt let get_messages_without_proto_messages node_ctxt = get_messages_aux @@ -812,7 +691,7 @@ let get_messages_without_proto_messages node_ctxt = match msg with | None -> return_none | Some (messages, _block_hash) -> return_some messages) - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp + Merkelized_payload_hashes_hash.pp node_ctxt let get_num_messages {store; _} hash = @@ -825,17 +704,12 @@ let get_num_messages {store; _} hash = | None -> failwith "Could not retrieve number of messages for inbox witness %a" - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp + Merkelized_payload_hashes_hash.pp hash | Some (messages, _block_hash) -> return (List.length messages) let save_messages {store; _} key ~block_hash messages = - let open Lwt_result_syntax in let key = Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez key in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e Sc_rollup.Inbox_message.serialize messages - in Store.Messages.append store.messages ~key @@ -845,11 +719,11 @@ let save_messages {store; _} key ~block_hash messages = let get_full_l2_block node_ctxt block_hash = let open Lwt_result_syntax in let* block = get_l2_block node_ctxt block_hash in - let* inbox = get_octez_inbox node_ctxt block.header.inbox_hash + let* inbox = get_inbox node_ctxt block.header.inbox_hash and* messages = get_messages_without_proto_messages node_ctxt block.header.inbox_witness and* commitment = - Option.map_es (get_octez_commitment node_ctxt) block.header.commitment_hash + Option.map_es (get_commitment node_ctxt) block.header.commitment_hash in return {block with content = {Sc_rollup_block.inbox; messages; commitment}} @@ -1001,113 +875,64 @@ let save_protocol_info node_ctxt (block : Layer1.header) in Store.Protocols.write node_ctxt.store.protocols protocols -let get_slot_header {store; protocol_constants; _} ~published_in_block_hash - slot_index = +let get_slot_header {store; _} ~published_in_block_hash slot_index = Error.trace_lwt_result_with - "Could not retrieve slot header for slot index %a published in block %a" - Dal.Slot_index.pp + "Could not retrieve slot header for slot index %d published in block %a" slot_index Block_hash.pp published_in_block_hash - @@ - let open Lwt_result_syntax in - let+ header = - Store.Dal_slots_headers.get - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - in - Sc_rollup_proto_types.Dal.Slot_header.of_octez - ~number_of_slots:protocol_constants.dal.number_of_slots - header + @@ Store.Dal_slots_headers.get + store.irmin_store + ~primary_key:published_in_block_hash + ~secondary_key:slot_index -let get_all_slot_headers {store; protocol_constants; _} ~published_in_block_hash - = - let open Lwt_result_syntax in - let+ headers = - Store.Dal_slots_headers.list_values - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map - (Sc_rollup_proto_types.Dal.Slot_header.of_octez - ~number_of_slots:protocol_constants.dal.number_of_slots) - headers - |> List.rev +let get_all_slot_headers {store; _} ~published_in_block_hash = + Store.Dal_slots_headers.list_values + store.irmin_store + ~primary_key:published_in_block_hash -let get_slot_indexes {store; protocol_constants; _} ~published_in_block_hash = - let open Lwt_result_syntax in - let+ indexes = - Store.Dal_slots_headers.list_secondary_keys - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map - (Sc_rollup_proto_types.Dal.Slot_index.of_octez - ~number_of_slots:protocol_constants.dal.number_of_slots) - indexes - |> List.rev +let get_slot_indexes {store; _} ~published_in_block_hash = + Store.Dal_slots_headers.list_secondary_keys + store.irmin_store + ~primary_key:published_in_block_hash let save_slot_header {store; _} ~published_in_block_hash - (slot_header : Dal.Slot.Header.t) = + (slot_header : Dal.Slot_header.t) = Store.Dal_slots_headers.add store.irmin_store ~primary_key:published_in_block_hash - ~secondary_key: - (Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_header.id.index) - (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) + ~secondary_key:slot_header.id.index + slot_header let find_slot_status {store; _} ~confirmed_in_block_hash slot_index = Store.Dal_slots_statuses.find store.irmin_store ~primary_key:confirmed_in_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) + ~secondary_key:slot_index -let list_slots_statuses {store; protocol_constants; _} ~confirmed_in_block_hash - = - let open Lwt_result_syntax in - let+ statuses = - Store.Dal_slots_statuses.list_secondary_keys_with_values - store.irmin_store - ~primary_key:confirmed_in_block_hash - in - List.rev_map - (fun (index, status) -> - ( Sc_rollup_proto_types.Dal.Slot_index.of_octez - ~number_of_slots:protocol_constants.dal.number_of_slots - index, - status )) - statuses - |> List.rev +let list_slots_statuses {store; _} ~confirmed_in_block_hash = + Store.Dal_slots_statuses.list_secondary_keys_with_values + store.irmin_store + ~primary_key:confirmed_in_block_hash let save_slot_status {store; _} current_block_hash slot_index status = Store.Dal_slots_statuses.add store.irmin_store ~primary_key:current_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) + ~secondary_key:slot_index status let find_confirmed_slots_history {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_history.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez res + Store.Dal_confirmed_slots_history.find store.irmin_store block let save_confirmed_slots_history {store; _} block hist = - Store.Dal_confirmed_slots_history.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history.to_octez hist) + Store.Dal_confirmed_slots_history.add store.irmin_store block hist let find_confirmed_slots_histories {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_histories.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez res + Store.Dal_confirmed_slots_histories.find store.irmin_store block let save_confirmed_slots_histories {store; _} block hist = - Store.Dal_confirmed_slots_histories.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez hist) + Store.Dal_confirmed_slots_histories.add store.irmin_store block hist module Internal_for_tests = struct let create_node_context cctxt protocol_constants ~data_dir kind = @@ -1123,23 +948,18 @@ module Internal_for_tests = struct let* context = Context.load Read_write (Configuration.default_context_dir data_dir) in - let genesis_info = - {level = 0l; commitment_hash = Octez_smart_rollup.Commitment.Hash.zero} - in + let genesis_info = {level = 0l; commitment_hash = Commitment.Hash.zero} in let l1_ctxt = Layer1.Internal_for_tests.dummy cctxt in - let lcc = - Reference.new_ - {commitment = Sc_rollup.Commitment.Hash.zero; level = Raw_level.root} - in + let lcc = Reference.new_ {commitment = Commitment.Hash.zero; level = 0l} in let lpc = Reference.new_ None in return { - cctxt; + cctxt = (cctxt :> Client_context.full); dal_cctxt = None; dac_client = None; data_dir; l1_ctxt; - rollup_address = Sc_rollup.Address.zero; + rollup_address = Address.zero; boot_sector_file = None; mode = Observer; operators = Configuration.Operator_purpose_map.empty; diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli index a429851920b0..3ed0a3d322da 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.mli @@ -26,15 +26,9 @@ (** This module describes the execution context of the node. *) -open Protocol -open Alpha_context +type lcc = {commitment : Commitment.Hash.t; level : int32} -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -type genesis_info = { - level : int32; - commitment_hash : Octez_smart_rollup.Commitment.Hash.t; -} +type genesis_info = {level : int32; commitment_hash : Commitment.Hash.t} (** Abstract type for store to force access through this module. *) type 'a store constraint 'a = [< `Read | `Write > `Read] @@ -42,8 +36,7 @@ type 'a store constraint 'a = [< `Read | `Write > `Read] type debug_logger = string -> unit Lwt.t type 'a t = { - cctxt : Protocol_client_context.full; - (** Client context used by the rollup node. *) + cctxt : Client_context.full; (** Client context used by the rollup node. *) dal_cctxt : Dal_node_client.cctxt option; (** DAL client context to query the dal node, if the rollup node supports the DAL. *) @@ -52,7 +45,7 @@ type 'a t = { data_dir : string; (** Node data dir. *) l1_ctxt : Layer1.t; (** Layer 1 context to fetch blocks and monitor heads, etc.*) - rollup_address : Sc_rollup.t; (** Smart rollup tracked by the rollup node. *) + rollup_address : Address.t; (** Smart rollup tracked by the rollup node. *) boot_sector_file : string option; (** Optional path to the boot sector file. Useful only if the smart rollup was bootstrapped and not originated. *) @@ -67,7 +60,7 @@ type 'a t = { operations. *) block_finality_time : int; (** Deterministic block finality time for the layer 1 protocol. *) - kind : Sc_rollup.Kind.t; (** Kind of the smart rollup. *) + kind : Kind.t; (** Kind of the smart rollup. *) pvm : (module Pvm.S); (** The PVM used by the smart rollup. *) fee_parameters : Configuration.fee_parameters; (** Fee parameters to use when injecting operations in layer 1. *) @@ -85,7 +78,7 @@ type 'a t = { context : 'a Context.index; (** The persistent context for the rollup node. *) lcc : ('a, lcc) Reference.t; (** Last cemented commitment and its level. *) - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; + lpc : ('a, Commitment.t option) Reference.t; (** The last published commitment, i.e. commitment that the operator is staked on. *) kernel_debug_logger : debug_logger; @@ -132,13 +125,16 @@ val get_fee_parameter : uses for RPC requests. *) val init : - Protocol_client_context.full -> + #Client_context.full -> data_dir:string -> ?log_kernel_debug_file:string -> 'a Store_sigs.mode -> Layer1.t -> Rollup_constants.protocol_constants -> genesis_info -> + lcc:lcc -> + lpc:Commitment.t option -> + Kind.t -> proto_level:int -> Configuration.t -> 'a t tzresult Lwt.t @@ -256,34 +252,26 @@ val get_tezos_reorg_for_new_head : block exists (the tick happened after [max_level], or we are too late), the function returns [None]. *) val block_with_tick : - _ t -> - max_level:Raw_level.t -> - Sc_rollup.Tick.t -> - Sc_rollup_block.t option tzresult Lwt.t + _ t -> max_level:int32 -> Z.t -> Sc_rollup_block.t option tzresult Lwt.t (** {3 Commitments} *) (** [get_commitment t hash] returns the commitment with [hash] stored by the rollup node. *) -val get_commitment : - _ t -> Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t tzresult Lwt.t +val get_commitment : _ t -> Commitment.Hash.t -> Commitment.t tzresult Lwt.t (** Same as {!get_commitment} but returns [None] if this commitment hash is not known by the rollup node. *) val find_commitment : - _ t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.t option tzresult Lwt.t + _ t -> Commitment.Hash.t -> Commitment.t option tzresult Lwt.t (** [commitment_exists t hash] returns [true] if the commitment with [hash] is known (i.e. stored) by the rollup node. *) -val commitment_exists : - _ t -> Sc_rollup.Commitment.Hash.t -> bool tzresult Lwt.t +val commitment_exists : _ t -> Commitment.Hash.t -> bool tzresult Lwt.t (** [save_commitment t commitment] saves a commitment in the store an returns is hash. *) -val save_commitment : - rw -> Sc_rollup.Commitment.t -> Sc_rollup.Commitment.Hash.t tzresult Lwt.t +val save_commitment : rw -> Commitment.t -> Commitment.Hash.t tzresult Lwt.t (** [commitment_published_at_level t hash] returns the levels at which the commitment was first published and the one at which it was included by in a @@ -292,14 +280,14 @@ val save_commitment : L1). *) val commitment_published_at_level : _ t -> - Sc_rollup.Commitment.Hash.t -> + Commitment.Hash.t -> Store.Commitments_published_at_level.element option tzresult Lwt.t (** [save_commitment_published_at_level t hash levels] saves the publication/inclusion information for a commitment with [hash]. *) val set_commitment_published_at_level : rw -> - Sc_rollup.Commitment.Hash.t -> + Commitment.Hash.t -> Store.Commitments_published_at_level.element -> unit tzresult Lwt.t @@ -310,73 +298,70 @@ type commitment_source = Anyone | Us the publication status for commitments we published ourselves [`Us] or that [`Anyone] published. *) val commitment_was_published : - _ t -> - source:commitment_source -> - Sc_rollup.Commitment.Hash.t -> - bool tzresult Lwt.t + _ t -> source:commitment_source -> Commitment.Hash.t -> bool tzresult Lwt.t (** {3 Inboxes} *) type messages_info = { is_first_block : bool; predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; + predecessor_timestamp : Time.Protocol.t; + messages : string list; } (** [get_inbox t inbox_hash] retrieves the inbox whose hash is [inbox_hash] from the rollup node's storage. *) val get_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t + _ t -> + Octez_smart_rollup.Inbox.Hash.t -> + Octez_smart_rollup.Inbox.t tzresult Lwt.t (** Same as {!get_inbox} but returns [None] if this inbox is not known. *) val find_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t option tzresult Lwt.t + _ t -> + Octez_smart_rollup.Inbox.Hash.t -> + Octez_smart_rollup.Inbox.t option tzresult Lwt.t (** [save_inbox t inbox] remembers the [inbox] in the storage. It is associated to its hash which is returned. *) val save_inbox : - rw -> Sc_rollup.Inbox.t -> Sc_rollup.Inbox.Hash.t tzresult Lwt.t + rw -> + Octez_smart_rollup.Inbox.t -> + Octez_smart_rollup.Inbox.Hash.t tzresult Lwt.t (** [inbox_of_head node_ctxt block] returns the latest inbox at the given [block]. This function always returns [inbox] for all levels at and after the rollup genesis. NOTE: It requires the L2 block for [block.hash] to have been saved. *) -val inbox_of_head : _ t -> Layer1.head -> Sc_rollup.Inbox.t tzresult Lwt.t +val inbox_of_head : + _ t -> Layer1.head -> Octez_smart_rollup.Inbox.t tzresult Lwt.t (** Same as {!get_inbox} but uses the Layer 1 block hash for this inbox instead. *) val get_inbox_by_block_hash : - _ t -> Block_hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [genesis_inbox t] is the genesis inbox for the rollup [t.sc_rollup_address]. *) -val genesis_inbox : _ t -> Sc_rollup.Inbox.t tzresult Lwt.t + _ t -> Block_hash.t -> Octez_smart_rollup.Inbox.t tzresult Lwt.t (** [get_messages t witness_hash] retrieves the messages for the merkelized payloads hash [witness_hash] stored by the rollup node. *) val get_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info tzresult Lwt.t + _ t -> Merkelized_payload_hashes_hash.t -> messages_info tzresult Lwt.t (** Same as {!get_messages} but returns [None] if the payloads hash is not known. *) val find_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info option tzresult Lwt.t + _ t -> Merkelized_payload_hashes_hash.t -> messages_info option tzresult Lwt.t (** [get_num_messages t witness_hash] retrieves the number of messages for the inbox witness [witness_hash] stored by the rollup node. *) val get_num_messages : - _ t -> Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> int tzresult Lwt.t + _ t -> Merkelized_payload_hashes_hash.t -> int tzresult Lwt.t (** [save_messages t payloads_hash ~block_hash messages] associates the list of [messages] to the [payloads_hash]. The payload hash must be computed by calling, e.g. {!Sc_rollup.Inbox.add_all_messages}. *) val save_messages : rw -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> + Merkelized_payload_hashes_hash.t -> block_hash:Block_hash.t -> - Sc_rollup.Inbox_message.t list -> + string list -> unit tzresult Lwt.t (** Return values for {!protocol_of_level}. *) @@ -408,7 +393,7 @@ val get_slot_header : _ t -> published_in_block_hash:Block_hash.t -> Dal.Slot_index.t -> - Dal.Slot.Header.t tzresult Lwt.t + Dal.Slot_header.t tzresult Lwt.t (** [get_all_slot_headers t ~published_in_block_hash] returns the slot headers for all the slots that were published in the provided block hash on Layer @@ -416,7 +401,7 @@ val get_slot_header : val get_all_slot_headers : _ t -> published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t list tzresult Lwt.t + Dal.Slot_header.t list tzresult Lwt.t (** [get_slot_indexes t ~published_in_block_hash] returns the slot indexes whose headers were published in the provided block hash on Layer 1. *) @@ -430,7 +415,7 @@ val get_slot_indexes : val save_slot_header : rw -> published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t -> + Dal.Slot_header.t -> unit tzresult Lwt.t (** [find_slot_status t ~confirmed_in_block_hash index] returns [None] if the @@ -466,16 +451,16 @@ val save_slot_status : Missing docstrings. *) val find_confirmed_slots_history : - _ t -> Block_hash.t -> Dal.Slots_history.t option tzresult Lwt.t + _ t -> Block_hash.t -> Dal.Slot_history.t option tzresult Lwt.t val save_confirmed_slots_history : - rw -> Block_hash.t -> Dal.Slots_history.t -> unit tzresult Lwt.t + rw -> Block_hash.t -> Dal.Slot_history.t -> unit tzresult Lwt.t val find_confirmed_slots_histories : - _ t -> Block_hash.t -> Dal.Slots_history.History_cache.t option tzresult Lwt.t + _ t -> Block_hash.t -> Dal.Slot_history_cache.t option tzresult Lwt.t val save_confirmed_slots_histories : - rw -> Block_hash.t -> Dal.Slots_history.History_cache.t -> unit tzresult Lwt.t + rw -> Block_hash.t -> Dal.Slot_history_cache.t -> unit tzresult Lwt.t (**/**) @@ -484,9 +469,9 @@ module Internal_for_tests : sig connect to any layer 1 node. It is meant to be used in unit tests for the rollup node functions. *) val create_node_context : - Protocol_client_context.full -> + #Client_context.full -> Rollup_constants.protocol_constants -> data_dir:string -> - Sc_rollup.Kind.t -> + Kind.t -> Store_sigs.rw t tzresult Lwt.t end diff --git a/src/proto_alpha/lib_sc_rollup_node/outbox.ml b/src/proto_alpha/lib_sc_rollup_node/outbox.ml index a76f94397d5e..a807f9f82321 100644 --- a/src/proto_alpha/lib_sc_rollup_node/outbox.ml +++ b/src/proto_alpha/lib_sc_rollup_node/outbox.ml @@ -24,14 +24,11 @@ (*****************************************************************************) open Node_context -open Protocol.Alpha_context let get_state_of_lcc node_ctxt = let open Lwt_result_syntax in let lcc = Reference.get node_ctxt.lcc in - let* block_hash = - Node_context.hash_of_level node_ctxt (Raw_level.to_int32 lcc.level) - in + let* block_hash = Node_context.hash_of_level node_ctxt lcc.level in let* ctxt = Node_context.checkout_context node_ctxt block_hash in let*! state = Context.PVMState.find ctxt in return state diff --git a/src/proto_alpha/lib_sc_rollup_node/outbox.mli b/src/proto_alpha/lib_sc_rollup_node/outbox.mli index 71e8c4a1f28d..1b172b048f4b 100644 --- a/src/proto_alpha/lib_sc_rollup_node/outbox.mli +++ b/src/proto_alpha/lib_sc_rollup_node/outbox.mli @@ -32,4 +32,4 @@ open Protocol.Alpha_context val proof_of_output : Node_context.rw -> Sc_rollup.output -> - (Sc_rollup.Commitment.Hash.t * string) tzresult Lwt.t + (Octez_smart_rollup.Commitment.Hash.t * string) tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.ml b/src/proto_alpha/lib_sc_rollup_node/publisher.ml index 9eb23531bb2d..193bc2ae67e5 100644 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.ml +++ b/src/proto_alpha/lib_sc_rollup_node/publisher.ml @@ -68,7 +68,8 @@ let add_level level increment = let sub_level level decrement = (* We only use this function with positive increments so it is safe *) if decrement < 0 then invalid_arg "Commitment.sub_level negative decrement" ; - Raw_level.Internal_for_tests.sub level decrement + let r = Int32.sub level (Int32.of_int decrement) in + if r < 0l then None else Some r let sc_rollup_commitment_period node_ctxt = node_ctxt.Node_context.protocol_constants.sc_rollup @@ -78,24 +79,18 @@ let sc_rollup_challenge_window node_ctxt = node_ctxt.Node_context.protocol_constants.sc_rollup.challenge_window_in_blocks let next_commitment_level node_ctxt last_commitment_level = - add_level - (Raw_level.to_int32 last_commitment_level) - (sc_rollup_commitment_period node_ctxt) + add_level last_commitment_level (sc_rollup_commitment_period node_ctxt) type state = Node_context.ro let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Lwt_result_syntax in - let* block = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 inbox_level) - in + let* block = Node_context.get_l2_block_by_level node_ctxt inbox_level in return (Sc_rollup_block.final_tick block) let build_commitment (node_ctxt : _ Node_context.t) - (prev_commitment : Sc_rollup.Commitment.Hash.t) ~prev_commitment_level - ~inbox_level ctxt = + (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) + ~prev_commitment_level ~inbox_level ctxt = let open Lwt_result_syntax in let module PVM = (val node_ctxt.pvm) in let*! pvm_state = PVM.State.find ctxt in @@ -111,22 +106,18 @@ let build_commitment (node_ctxt : _ Node_context.t) let*! tick = PVM.get_tick pvm_state in let* prev_commitment_tick = tick_of_level node_ctxt prev_commitment_level in let distance = Z.sub (Sc_rollup.Tick.to_z tick) prev_commitment_tick in - let number_of_ticks = - distance |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value - in - let*? number_of_ticks = - match number_of_ticks with - | Some number_of_ticks -> - if number_of_ticks = Sc_rollup.Number_of_ticks.zero then - error_with "A 0-tick commitment is impossible" - else Ok number_of_ticks - | None -> error_with "Invalid number of ticks for commitment" + let number_of_ticks = Z.to_int64 distance in + let*? () = + if number_of_ticks = 0L then error_with "A 0-tick commitment is impossible" + else if number_of_ticks < 0L then + error_with "Invalid number of ticks for commitment" + else Ok () in return - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = prev_commitment; - inbox_level = Raw_level.of_int32_exn inbox_level; + inbox_level; number_of_ticks; compressed_state; } @@ -142,21 +133,21 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = in let*! compressed_state = PVM.state_hash pvm_state in let commitment = - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = Hash.zero; - inbox_level = Raw_level.of_int32_exn node_ctxt.genesis_info.level; - number_of_ticks = Sc_rollup.Number_of_ticks.zero; + inbox_level = node_ctxt.genesis_info.level; + number_of_ticks = 0L; compressed_state; } in (* Ensure the initial state corresponds to the one of the rollup's in the protocol. A mismatch is possible if a wrong external boot sector was provided. *) - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let+ () = fail_unless - Sc_rollup.Commitment.Hash.( + Octez_smart_rollup.Commitment.Hash.( commitment_hash = node_ctxt.genesis_info.commitment_hash) (Sc_rollup_node_errors.Invalid_genesis_state { @@ -218,7 +209,7 @@ let missing_commitments (node_ctxt : _ Node_context.t) = let lpc_level = match Reference.get node_ctxt.lpc with | None -> node_ctxt.genesis_info.level - | Some lpc -> Raw_level.to_int32 lpc.inbox_level + | Some lpc -> lpc.inbox_level in let* head = Node_context.last_processed_head_opt node_ctxt in let next_head_level = @@ -232,11 +223,10 @@ let missing_commitments (node_ctxt : _ Node_context.t) = let lcc = Reference.get node_ctxt.lcc in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* Commitment is before or at the LCC, we have reached the end. *) return acc - | Some commitment - when Raw_level.to_int32 commitment.inbox_level <= lpc_level -> + | Some commitment when commitment.inbox_level <= lpc_level -> (* Commitment is before the last published one, we have also reached the end because we only publish commitments that are for the inbox of a finalized L1 block. *) @@ -269,19 +259,15 @@ let missing_commitments (node_ctxt : _ Node_context.t) = gather [] commitment let publish_commitment (node_ctxt : _ Node_context.t) ~source - (commitment : Sc_rollup.Commitment.t) = + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let publish_operation = - L1_operation.Publish - { - rollup = node_ctxt.rollup_address; - commitment = Sc_rollup_proto_types.Commitment.to_octez commitment; - } + L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} in let*! () = Commitment_event.publish_commitment - (Sc_rollup.Commitment.hash_uncarbonated commitment) - (Raw_level.to_int32 commitment.inbox_level) + (Octez_smart_rollup.Commitment.hash commitment) + commitment.inbox_level in let* _hash = Injector.add_pending_operation ~source publish_operation in return_unit @@ -301,7 +287,8 @@ let on_publish_commitments (node_ctxt : state) = let* commitments = missing_commitments node_ctxt in List.iter_es (publish_commitment node_ctxt ~source) commitments -let publish_single_commitment node_ctxt (commitment : Sc_rollup.Commitment.t) = +let publish_single_commitment node_ctxt + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let operator = Node_context.get_operator node_ctxt Publish in let lcc = Reference.get node_ctxt.lcc in @@ -346,12 +333,10 @@ let latest_cementable_commitment (node_ctxt : _ Node_context.t) @@ sub_level commitment.inbox_level (sc_rollup_challenge_window node_ctxt) in let lcc = Reference.get node_ctxt.lcc in - if Raw_level.(cementable_level_bound <= lcc.level) then return_none + if cementable_level_bound <= lcc.level then return_none else let** cementable_bound_block = - Node_context.find_l2_block_by_level - node_ctxt - (Raw_level.to_int32 cementable_level_bound) + Node_context.find_l2_block_by_level node_ctxt cementable_level_bound in let cementable_commitment = Sc_rollup_block.most_recent_commitment cementable_bound_block.header @@ -369,7 +354,7 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* If we have moved backward passed or at the current LCC then we have reached the end. *) return acc @@ -404,7 +389,7 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = Layer 1 node as a failsafe. *) let* green_light = Plugin.RPC.Sc_rollup.can_be_cemented - node_ctxt.cctxt + (new Protocol_client_context.wrap_full node_ctxt.cctxt) (node_ctxt.cctxt#chain, `Head 0) node_ctxt.rollup_address first_cementable diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.mli b/src/proto_alpha/lib_sc_rollup_node/publisher.mli index 79990b2198ad..36c8c655ece7 100644 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.mli +++ b/src/proto_alpha/lib_sc_rollup_node/publisher.mli @@ -50,16 +50,14 @@ val process_head : predecessor:Block_hash.t -> Layer1.header -> Context.rw -> - Protocol.Alpha_context.Sc_rollup.Commitment.Hash.t option tzresult Lwt.t + Octez_smart_rollup.Commitment.Hash.t option tzresult Lwt.t (** [publish_single_commitment node_ctxt commitment] publishes a single [commitment] if it is missing. This function is meant to be used by the {e accuser} mode to sparingly publish commitments when it detects a conflict. *) val publish_single_commitment : - _ Node_context.t -> - Protocol.Alpha_context.Sc_rollup.Commitment.t -> - unit tzresult Lwt.t + _ Node_context.t -> Octez_smart_rollup.Commitment.t -> unit tzresult Lwt.t (** Initialize worker for publishing and cementing commitments. *) val init : _ Node_context.t -> unit tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/pvm_rpc.ml b/src/proto_alpha/lib_sc_rollup_node/pvm_rpc.ml index 06c5c60b5e51..a8d946e87b6a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/pvm_rpc.ml +++ b/src/proto_alpha/lib_sc_rollup_node/pvm_rpc.ml @@ -35,6 +35,6 @@ end let no_rpc = (module No_rpc : S) let of_kind = function - | Protocol.Alpha_context.Sc_rollup.Kind.Example_arith -> no_rpc + | Kind.Example_arith -> no_rpc | Wasm_2_0_0 -> (module Wasm_2_0_0_rpc.Make_RPC (Wasm_2_0_0_pvm.Durable_state) : S) diff --git a/src/proto_alpha/lib_sc_rollup_node/refutation_coordinator.ml b/src/proto_alpha/lib_sc_rollup_node/refutation_coordinator.ml index b841d2e7353c..d78834ff4e34 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_coordinator.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_coordinator.ml @@ -31,7 +31,11 @@ module Player = Refutation_player module Pkh_map = Signature.Public_key_hash.Map module Pkh_table = Signature.Public_key_hash.Table -type state = {node_ctxt : Node_context.rw; pending_opponents : unit Pkh_table.t} +type state = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + pending_opponents : unit Pkh_table.t; +} let get_conflicts cctxt head_block = Plugin.RPC.Sc_rollup.conflicts cctxt (cctxt#chain, head_block) @@ -72,9 +76,11 @@ let on_process Layer1.{hash; level} state = (* Not injecting refutations, don't play refutation games *) return_unit | Some self -> - let Node_context.{rollup_address; cctxt; _} = node_ctxt in + let Node_context.{rollup_address; _} = node_ctxt in (* Current conflicts in L1 *) - let* conflicts = get_conflicts cctxt head_block rollup_address self in + let* conflicts = + get_conflicts state.cctxt head_block rollup_address self + in (* Map of opponents the node is playing against to the corresponding player worker *) let opponent_players = @@ -85,7 +91,7 @@ let on_process Layer1.{hash; level} state = let new_conflicts = untracked_conflicts opponent_players conflicts in (* L1 ongoing games *) let* ongoing_games = - get_ongoing_games cctxt head_block rollup_address self + get_ongoing_games state.cctxt head_block rollup_address self in (* Map between opponents and their corresponding games *) let ongoing_game_map = make_game_map self ongoing_games in @@ -121,7 +127,10 @@ let on_process Layer1.{hash; level} state = module Types = struct type nonrec state = state - type parameters = {node_ctxt : Node_context.rw} + type parameters = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + } end module Name = struct @@ -157,8 +166,8 @@ module Handlers = struct type launch_error = error trace - let on_launch _w () Types.{node_ctxt} = - return {node_ctxt; pending_opponents = Pkh_table.create 5} + let on_launch _w () Types.{node_ctxt; cctxt} = + return {node_ctxt; cctxt; pending_opponents = Pkh_table.create 5} let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : unit tzresult Lwt.t = @@ -187,7 +196,10 @@ let worker_promise, worker_waker = Lwt.task () let init node_ctxt = let open Lwt_result_syntax in let*! () = Refutation_game_event.Coordinator.starting () in - let+ worker = Worker.launch table () {node_ctxt} (module Handlers) in + let cctxt = + new Protocol_client_context.wrap_full node_ctxt.Node_context.cctxt + in + let+ worker = Worker.launch table () {node_ctxt; cctxt} (module Handlers) in Lwt.wakeup worker_waker worker (* This is a refutation coordinator for a single scoru *) 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 5bca9b1d25eb..aa8bfe0c7e04 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -204,7 +204,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let* parametric_constants = let cctxt = node_ctxt.cctxt in Protocol.Constants_services.parametric - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, `Level snapshot_level_int32) in let dal_l1_parameters = parametric_constants.dal in @@ -231,7 +231,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = Reveals.get ?dac_client:node_ctxt.dac_client ~data_dir:node_ctxt.data_dir - ~pvm_kind:PVM.kind + ~pvm_kind:(Sc_rollup_proto_types.Kind.to_octez PVM.kind) hash in match res with Ok data -> return @@ Some data | Error _ -> return None @@ -251,7 +251,12 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = inbox_hash pp_print_trace err - | Ok inbox -> Option.map Sc_rollup.Inbox.take_snapshot inbox + | Ok inbox -> + Option.map + (fun i -> + Sc_rollup.Inbox.take_snapshot + (Sc_rollup_proto_types.Inbox.of_octez i)) + inbox let get_payloads_history witness = Lwt.map @@ -262,11 +267,6 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let* {is_first_block; predecessor; predecessor_timestamp; messages} = Node_context.get_messages node_ctxt witness in - let*? messages = - (List.map_e Sc_rollup.Inbox_message.serialize messages - |> Environment.wrap_tzresult - :> string list tzresult) - in let*? hist = Inbox.payloads_history_of_messages ~is_first_block @@ -505,7 +505,7 @@ let timeout_reached ~self head_block node_ctxt staker1 staker2 = let Node_context.{rollup_address; cctxt; _} = node_ctxt in let* game_result = Plugin.RPC.Sc_rollup.timeout_reached - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, head_block) rollup_address staker1 diff --git a/src/proto_alpha/lib_sc_rollup_node/reveals.ml b/src/proto_alpha/lib_sc_rollup_node/reveals.ml index 77d6937abfc0..e3efc65ed384 100644 --- a/src/proto_alpha/lib_sc_rollup_node/reveals.ml +++ b/src/proto_alpha/lib_sc_rollup_node/reveals.ml @@ -73,7 +73,9 @@ let proto_hash_to_dac_hash ((module Plugin) : Dac_plugin.t) proto_reveal_hash = let get ?dac_client ~data_dir ~pvm_kind hash = let open Lwt_result_syntax in let* contents = - let filename = path data_dir (Sc_rollup.Kind.to_string pvm_kind) hash in + let filename = + path data_dir (Octez_smart_rollup.Kind.to_string pvm_kind) hash + in let* file_contents = file_contents filename in match file_contents with | Some contents -> return contents diff --git a/src/proto_alpha/lib_sc_rollup_node/reveals.mli b/src/proto_alpha/lib_sc_rollup_node/reveals.mli index 921b0e6b027b..921e2869adf9 100644 --- a/src/proto_alpha/lib_sc_rollup_node/reveals.mli +++ b/src/proto_alpha/lib_sc_rollup_node/reveals.mli @@ -69,6 +69,6 @@ type source = val get : ?dac_client:Dac_observer_client.t -> data_dir:string -> - pvm_kind:Protocol.Alpha_context.Sc_rollup.Kind.t -> + pvm_kind:Kind.t -> Protocol.Sc_rollup_reveal_hash.t -> string tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index 30062b762fef..5e9394e6f74a 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.ml +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.ml @@ -36,7 +36,7 @@ type info_per_level = { type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; @@ -69,7 +69,7 @@ let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = in let* ctxt, state = Interpreter.state_of_head node_ctxt ctxt head in let+ info_per_level = simulate_info_per_level node_ctxt hash in - let inbox_level = Raw_level.of_int32_exn (Int32.succ level) in + let inbox_level = Int32.succ level in { ctxt; inbox_level; diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.mli b/src/proto_alpha/lib_sc_rollup_node/simulation.mli index 6a5bae9c769d..ac8d8dd03624 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.mli +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.mli @@ -37,7 +37,7 @@ type info_per_level = { (** Type of the state for a simulation. *) type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; diff --git a/src/proto_alpha/lib_sc_rollup_node/test/canary.ml b/src/proto_alpha/lib_sc_rollup_node/test/canary.ml index 5e0877462c9e..bbfaf914ecc4 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/canary.ml +++ b/src/proto_alpha/lib_sc_rollup_node/test/canary.ml @@ -32,7 +32,6 @@ *) open Octez_smart_rollup -open Protocol.Alpha_context let build_chain node_ctxt ~genesis ~length = let open Lwt_result_syntax in @@ -85,15 +84,10 @@ let tests = Helpers.alcotest "canary arith" `Quick - Sc_rollup.Kind.Example_arith - ~boot_sector:"" - canary_test; - Helpers.alcotest - "canary wasm" - `Quick - Sc_rollup.Kind.Wasm_2_0_0 + Example_arith ~boot_sector:"" canary_test; + Helpers.alcotest "canary wasm" `Quick Wasm_2_0_0 ~boot_sector:"" canary_test; ] let () = diff --git a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml index 7c5300730f03..2a9ae9577f8e 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml @@ -66,7 +66,11 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = ~predecessor:predecessor.hash (Raw_level.of_int32_exn node_ctxt.genesis_info.level) in - let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + let* inbox_hash = + Node_context.save_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox.to_octez inbox) + in let inbox_witness = Sc_rollup.Inbox.current_witness inbox in let ctxt = Octez_smart_rollup_node.Context.empty node_ctxt.context in let num_ticks = 0L in @@ -82,7 +86,11 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = ~origination_level:(Raw_level.of_int32_exn node_ctxt.genesis_info.level) ~genesis_state_hash in - let* commitment_hash = Node_context.save_commitment node_ctxt commitment in + let* commitment_hash = + Node_context.save_commitment + node_ctxt + (Sc_rollup_proto_types.Commitment.to_octez commitment) + in let previous_commitment_hash = node_ctxt.genesis_info.commitment_hash in let header = Sc_rollup_block. @@ -215,10 +223,7 @@ let append_dummy_l2_chain node_ctxt ~length = in let batches = Stdlib.List.init length (fun i -> - [ - Sc_rollup.Inbox_message.External - (Z.to_bits (Z.of_int (i + head_level + 1))); - ]) + ["\001" (* External tag *) ^ Z.to_bits (Z.of_int (i + head_level + 1))]) in append_l2_blocks node_ctxt batches diff --git a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli index 5336713010ec..c4c75569f722 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli +++ b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli @@ -40,7 +40,7 @@ open Alpha_context leaks. *) val with_node_context : ?constants:Rollup_constants.protocol_constants -> - Sc_rollup.Kind.t -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> @@ -64,7 +64,7 @@ val add_l2_genesis_block : val append_l2_block : [`Read | `Write] Node_context.t -> ?is_first_block:bool -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup_block.t tzresult Lwt.t (** [append_l2_block node_ctxt message_batches] appends as many blocks as there @@ -72,7 +72,7 @@ val append_l2_block : messages. The portion of the chain that was added is returned. *) val append_l2_blocks : [`Read | `Write] Node_context.t -> - Sc_rollup.Inbox_message.t list list -> + string list list -> Sc_rollup_block.t list tzresult Lwt.t (** [append_dummy_l2_chain node_ctxt ~length] append [length] L2 blocks with an @@ -109,7 +109,7 @@ val alcotest : string -> Alcotest.speed_level -> ?constants:Rollup_constants.protocol_constants -> - Sc_rollup.Kind.t -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> -- GitLab From 1ac250ccb3121479ec2217ca2bc4d81dbcb927dd Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 1 Jun 2023 17:22:26 +0200 Subject: [PATCH 10/15] SCORU/Node: remove PVM first class module from node context --- .../lib_sc_rollup_node/RPC_server.ml | 12 +- .../lib_sc_rollup_node/arith_pvm.ml | 2 +- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 4 +- .../lib_sc_rollup_node/fueled_pvm.ml | 8 +- .../lib_sc_rollup_node/interpreter.ml | 8 +- .../lib_sc_rollup_node/node_context.ml | 7 -- .../lib_sc_rollup_node/node_context.mli | 1 - src/proto_alpha/lib_sc_rollup_node/outbox.ml | 2 +- .../lib_sc_rollup_node/publisher.ml | 4 +- src/proto_alpha/lib_sc_rollup_node/pvm.ml | 80 +------------- src/proto_alpha/lib_sc_rollup_node/pvm_sig.ml | 103 ++++++++++++++++++ .../lib_sc_rollup_node/refutation_game.ml | 6 +- .../lib_sc_rollup_node/simulation.ml | 2 +- .../test/helpers/helpers.ml | 2 +- .../lib_sc_rollup_node/wasm_2_0_0_pvm.ml | 2 +- 15 files changed, 133 insertions(+), 110 deletions(-) create mode 100644 src/proto_alpha/lib_sc_rollup_node/pvm_sig.ml diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml index 461e74fca335..5227b3609bb1 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml @@ -173,7 +173,7 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages ~insight_requests messages = let open Lwt_result_syntax in let open Alpha_context in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let reveal_map = match reveal_pages with | Some pages -> @@ -234,7 +234,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in return tick @@ -243,7 +243,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! hash = PVM.state_hash state in return hash @@ -252,7 +252,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! current_level = PVM.get_current_level state in return current_level @@ -312,7 +312,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) 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 = @@ -346,7 +346,7 @@ let () = @@ fun (node_ctxt, block, outbox_level) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! outbox = PVM.get_outbox outbox_level state in return outbox diff --git a/src/proto_alpha/lib_sc_rollup_node/arith_pvm.ml b/src/proto_alpha/lib_sc_rollup_node/arith_pvm.ml index 4466bff7a115..5f9cfa0bf289 100644 --- a/src/proto_alpha/lib_sc_rollup_node/arith_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/arith_pvm.ml @@ -44,7 +44,7 @@ module Arith_proof_format = .tree_proof_encoding end) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.ArithPVM.Make (Arith_proof_format) include PVM diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index ea72e8fdcd56..bf2509aa9a8f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -567,9 +567,9 @@ let install_finalizer (daemon_components : (module Daemon_components.S)) let* () = Event.shutdown_node exit_status in Tezos_base_unix.Internal_event_unix.close () -let check_initial_state_hash {Node_context.cctxt; rollup_address; pvm; _} = +let check_initial_state_hash {Node_context.cctxt; rollup_address; kind; _} = let open Lwt_result_syntax in - let module PVM = (val pvm) in + let module PVM = (val Pvm.of_kind kind) in let* l1_reference_initial_state_hash = RPC.Sc_rollup.initial_pvm_state_hash (new Protocol_client_context.wrap_full cctxt) 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 289924e06aba..dc3cc376a79f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml @@ -146,7 +146,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct |> Sc_rollup_proto_types.Constants.reveal_activation_level_of_octez |> Sc_rollup.is_reveal_enabled_predicate in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let metadata = metadata node_ctxt in let dal_attestation_lag = node_ctxt.protocol_constants.dal.attestation_lag @@ -324,7 +324,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct ~fuel ~failing_ticks state input = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* res = eval_until_input node_ctxt @@ -440,7 +440,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct 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 node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in (* Obtain inbox and its messages for this block. *) let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in let*! initial_tick = PVM.get_tick state in @@ -483,7 +483,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct } = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* state, remaining_fuel, num_messages, remaining_messages = match messages with | [] -> diff --git a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index 0aeaa12eccf9..98bdca5ffbf2 100644 --- a/src/proto_alpha/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml @@ -72,7 +72,7 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = match node_ctxt.boot_sector_file with | None -> get_boot_sector block_hash node_ctxt | Some boot_sector_file -> - let module PVM = (val node_ctxt.pvm) in + 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 @@ -88,7 +88,7 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let genesis_state block_hash node_ctxt ctxt = let open Lwt_result_syntax in let* boot_sector = get_boot_sector block_hash node_ctxt in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! genesis_state = PVM.install_boot_sector initial_state boot_sector in let*! ctxt = PVM.State.set ctxt genesis_state in @@ -126,7 +126,7 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} } = Delayed_write_monad.apply node_ctxt eval_result in - let module PVM = (val node_ctxt.pvm) 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 (* Produce events. *) @@ -181,7 +181,7 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = block.header.inbox_witness) in let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in let*! state_hash = PVM.state_hash state in let messages = diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index df5bfd3f73f8..ce931f136c38 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -46,7 +46,6 @@ type 'a t = { injector_retention_period : int; block_finality_time : int; kind : Kind.t; - pvm : (module Pvm.S); fee_parameters : Configuration.fee_parameters; protocol_constants : Rollup_constants.protocol_constants; proto_level : int; @@ -124,10 +123,6 @@ let make_kernel_logger ?log_kernel_debug_file data_dir = in Lwt_io.of_fd ~close:(fun () -> Lwt_unix.close fd) ~mode:Lwt_io.Output fd -let pvm_of_kind : Kind.t -> (module Pvm.S) = function - | Example_arith -> (module Arith_pvm) - | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) - let init (cctxt : #Client_context.full) ~data_dir ?log_kernel_debug_file mode l1_ctxt (protocol_constants : Rollup_constants.protocol_constants) genesis_info ~lcc ~lpc kind ~proto_level @@ -208,7 +203,6 @@ let init (cctxt : #Client_context.full) ~data_dir ?log_kernel_debug_file mode lcc = Reference.new_ lcc; lpc = Reference.new_ lpc; kind; - pvm = pvm_of_kind kind; injector_retention_period = 0; block_finality_time = 2; fee_parameters; @@ -967,7 +961,6 @@ module Internal_for_tests = struct lcc; lpc; kind; - pvm = pvm_of_kind kind; injector_retention_period = 0; block_finality_time = 2; fee_parameters = Configuration.default_fee_parameters; diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli index 3ed0a3d322da..0b4fcc19c5a6 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.mli @@ -61,7 +61,6 @@ type 'a t = { block_finality_time : int; (** Deterministic block finality time for the layer 1 protocol. *) kind : Kind.t; (** Kind of the smart rollup. *) - pvm : (module Pvm.S); (** The PVM used by the smart rollup. *) fee_parameters : Configuration.fee_parameters; (** Fee parameters to use when injecting operations in layer 1. *) protocol_constants : Rollup_constants.protocol_constants; diff --git a/src/proto_alpha/lib_sc_rollup_node/outbox.ml b/src/proto_alpha/lib_sc_rollup_node/outbox.ml index a807f9f82321..e9a3abe628fa 100644 --- a/src/proto_alpha/lib_sc_rollup_node/outbox.ml +++ b/src/proto_alpha/lib_sc_rollup_node/outbox.ml @@ -45,7 +45,7 @@ let proof_of_output node_ctxt output = *) failwith "Error producing outbox proof (no cemented state in the node)" | Some state -> ( - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! proof = PVM.produce_output_proof node_ctxt.context state output in match proof with | Ok proof -> diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.ml b/src/proto_alpha/lib_sc_rollup_node/publisher.ml index 193bc2ae67e5..e1180ebffafc 100644 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.ml +++ b/src/proto_alpha/lib_sc_rollup_node/publisher.ml @@ -92,7 +92,7 @@ let build_commitment (node_ctxt : _ Node_context.t) (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) ~prev_commitment_level ~inbox_level ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with @@ -124,7 +124,7 @@ let build_commitment (node_ctxt : _ Node_context.t) let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with diff --git a/src/proto_alpha/lib_sc_rollup_node/pvm.ml b/src/proto_alpha/lib_sc_rollup_node/pvm.ml index 2ae9c9f725f9..e71be750758e 100644 --- a/src/proto_alpha/lib_sc_rollup_node/pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/pvm.ml @@ -24,80 +24,8 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +module type S = Pvm_sig.S -(** Desired module type of a PVM from the L2 node's perspective *) -module type S = sig - include - Sc_rollup.PVM.S - with type context = Context.rw_index - and type state = Context.tree - and type hash = Sc_rollup.State_hash.t - - (** Kind of the PVM. *) - val kind : Sc_rollup.Kind.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) - val get_tick : state -> Sc_rollup.Tick.t Lwt.t - - (** PVM status *) - type status - - (** [get_status ~is_reveal_enabled state] gives you the current execution status for the PVM. *) - val get_status : - is_reveal_enabled:Sc_rollup.is_reveal_enabled -> state -> status Lwt.t - - (** [string_of_status status] returns a string representation of [status]. *) - val string_of_status : status -> string - - (** [get_outbox outbox_level state] returns a list of outputs - available in the outbox of [state] at a given [outbox_level]. *) - val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t - - (** [eval_many ~max_steps s0] returns a state [s1] resulting from the - execution of up to [~max_steps] steps of the rollup at state [s0]. *) - val eval_many : - reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> - write_debug:Tezos_scoru_wasm.Builtins.write_debug -> - is_reveal_enabled:Sc_rollup.is_reveal_enabled -> - ?stop_at_snapshot:bool -> - max_steps:int64 -> - state -> - (state * int64) Lwt.t - - val new_dissection : - default_number_of_sections:int -> - start_chunk:Sc_rollup.Dissection_chunk.t -> - our_stop_chunk:Sc_rollup.Dissection_chunk.t -> - Sc_rollup.Tick.t list - - (** State storage for this PVM. *) - module State : sig - (** [empty ()] is the empty state. *) - val empty : unit -> state - - (** [find context] returns the PVM state stored in the [context], if any. *) - val find : _ Context.t -> state option Lwt.t - - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - - (** [set context state] saves the PVM state [state] in the context and - returns the updated context. Note: [set] does not perform any write on - disk, this information must be committed using {!val:Context.commit}. *) - val set : 'a Context.t -> state -> 'a Context.t Lwt.t - end - - (** Inspect durable state using a more specialised way of reading the - PVM state. - For example in WASM, it decodes the durable storage in the state - before reading values. - *) - module Inspect_durable_state : sig - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - end -end +let of_kind : Kind.t -> (module S) = function + | Example_arith -> (module Arith_pvm) + | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) diff --git a/src/proto_alpha/lib_sc_rollup_node/pvm_sig.ml b/src/proto_alpha/lib_sc_rollup_node/pvm_sig.ml new file mode 100644 index 000000000000..2ae9c9f725f9 --- /dev/null +++ b/src/proto_alpha/lib_sc_rollup_node/pvm_sig.ml @@ -0,0 +1,103 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022-2023 TriliTech *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** Desired module type of a PVM from the L2 node's perspective *) +module type S = sig + include + Sc_rollup.PVM.S + with type context = Context.rw_index + and type state = Context.tree + and type hash = Sc_rollup.State_hash.t + + (** Kind of the PVM. *) + val kind : Sc_rollup.Kind.t + + (** [get_tick state] gets the total tick counter for the given PVM state. *) + val get_tick : state -> Sc_rollup.Tick.t Lwt.t + + (** PVM status *) + type status + + (** [get_status ~is_reveal_enabled state] gives you the current execution status for the PVM. *) + val get_status : + is_reveal_enabled:Sc_rollup.is_reveal_enabled -> state -> status Lwt.t + + (** [string_of_status status] returns a string representation of [status]. *) + val string_of_status : status -> string + + (** [get_outbox outbox_level state] returns a list of outputs + available in the outbox of [state] at a given [outbox_level]. *) + val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t + + (** [eval_many ~max_steps s0] returns a state [s1] resulting from the + execution of up to [~max_steps] steps of the rollup at state [s0]. *) + val eval_many : + reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> + write_debug:Tezos_scoru_wasm.Builtins.write_debug -> + is_reveal_enabled:Sc_rollup.is_reveal_enabled -> + ?stop_at_snapshot:bool -> + max_steps:int64 -> + state -> + (state * int64) Lwt.t + + val new_dissection : + default_number_of_sections:int -> + start_chunk:Sc_rollup.Dissection_chunk.t -> + our_stop_chunk:Sc_rollup.Dissection_chunk.t -> + Sc_rollup.Tick.t list + + (** State storage for this PVM. *) + module State : sig + (** [empty ()] is the empty state. *) + val empty : unit -> state + + (** [find context] returns the PVM state stored in the [context], if any. *) + val find : _ Context.t -> state option Lwt.t + + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + + (** [set context state] saves the PVM state [state] in the context and + returns the updated context. Note: [set] does not perform any write on + disk, this information must be committed using {!val:Context.commit}. *) + val set : 'a Context.t -> state -> 'a Context.t Lwt.t + end + + (** Inspect durable state using a more specialised way of reading the + PVM state. + For example in WASM, it decodes the durable storage in the state + before reading values. + *) + module Inspect_durable_state : sig + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + end +end 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 aa8bfe0c7e04..98e174b5a653 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -120,7 +120,7 @@ let page_membership_proof params page_index slot_data = let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag (dal_params : Dal.parameters) start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) 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 = @@ -169,7 +169,7 @@ let metadata (node_ctxt : _ Node_context.t) = let generate_proof (node_ctxt : _ Node_context.t) game start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let snapshot = game.inbox_snapshot in (* NOTE: [snapshot_level_int32] below refers to the level of the snapshotted inbox (from the skip list) which also matches [game.start_level - 1]. *) @@ -362,7 +362,7 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok let our_stop_chunk = Sc_rollup.Dissection_chunk.{state_hash = our_state_hash; tick = our_tick} in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let* dissection = Game_helpers.make_dissection ~state_of_tick diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index 5e9394e6f74a..d557dbeb97e5 100644 --- a/src/proto_alpha/lib_sc_rollup_node/simulation.ml +++ b/src/proto_alpha/lib_sc_rollup_node/simulation.ml @@ -91,7 +91,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) info_per_level = _; } as sim) messages = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! state_hash = PVM.state_hash state in let*! tick = PVM.get_tick state in let eval_state = diff --git a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml index 2a9ae9577f8e..6aeab3d04a78 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml @@ -74,7 +74,7 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let inbox_witness = Sc_rollup.Inbox.current_witness inbox in let ctxt = Octez_smart_rollup_node.Context.empty node_ctxt.context in let num_ticks = 0L in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let initial_tick = Sc_rollup.Tick.initial in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! state = PVM.install_boot_sector initial_state boot_sector in diff --git a/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_pvm.ml b/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_pvm.ml index 7b53be26ebde..2d5937615019 100644 --- a/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_pvm.ml +++ b/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_pvm.ml @@ -123,7 +123,7 @@ end module Durable_state = Make_durable_state (Make_wrapped_tree (Wasm_2_0_0_proof_format.Tree)) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.Wasm_2_0_0PVM.Make (Make_backend) (Wasm_2_0_0_proof_format) include PVM -- GitLab From cb4cfda7106b885c3755ec2fdd1648484642185a Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 15 Jun 2023 17:18:25 +0200 Subject: [PATCH 11/15] SCORU/Node: node Node_context outside of proto directory --- src/lib_scoru_sequencer/rpc_server.ml | 7 +++---- .../node_context.ml | 17 +++++------------ .../node_context.mli | 0 .../lib_sc_rollup_node/test/canary.ml | 1 + .../lib_sc_rollup_node/test/helpers/helpers.mli | 1 + 5 files changed, 10 insertions(+), 16 deletions(-) rename src/{proto_alpha/lib_sc_rollup_node => lib_smart_rollup_node}/node_context.ml (98%) rename src/{proto_alpha/lib_sc_rollup_node => lib_smart_rollup_node}/node_context.mli (100%) diff --git a/src/lib_scoru_sequencer/rpc_server.ml b/src/lib_scoru_sequencer/rpc_server.ml index 597802619e5b..8f3e6bd134bf 100644 --- a/src/lib_scoru_sequencer/rpc_server.ml +++ b/src/lib_scoru_sequencer/rpc_server.ml @@ -27,12 +27,11 @@ open Tezos_rpc_http_server open RPC_directory_helpers open Octez_smart_rollup_node -module Sc_rollup_node = Octez_smart_rollup_node_alpha module Local_directory = Make_directory (struct include Sc_rollup_services.Local - type context = Sc_rollup_node.Node_context.rw + type context = Node_context.rw type subcontext = unit @@ -53,13 +52,13 @@ let () = Local_directory.register0 Sc_rollup_services.Local.injection @@ fun _node_ctxt () messages -> Seq_batcher.register_messages messages -let register (node_ctxt : _ Sc_rollup_node.Node_context.t) = +let register (node_ctxt : _ Node_context.t) = List.fold_left (fun dir f -> Tezos_rpc.Directory.merge dir (f node_ctxt)) Tezos_rpc.Directory.empty [Local_directory.build_directory] -let start (node_ctxt : _ Sc_rollup_node.Node_context.t) configuration = +let start (node_ctxt : _ Node_context.t) configuration = let open Lwt_result_syntax in let Configuration.{rpc_addr; rpc_port; _} = configuration in let rpc_addr = P2p_addr.of_string_exn rpc_addr in diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/lib_smart_rollup_node/node_context.ml similarity index 98% rename from src/proto_alpha/lib_sc_rollup_node/node_context.ml rename to src/lib_smart_rollup_node/node_context.ml index ce931f136c38..2e34b972c4d6 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/lib_smart_rollup_node/node_context.ml @@ -103,7 +103,7 @@ let lock ~data_dir = in return lockfile in - trace (Sc_rollup_node_errors.Could_not_acquire_lock lockfile_path) + trace (Rollup_node_errors.Could_not_acquire_lock lockfile_path) @@ lock_aux ~data_dir let unlock {lockfile; _} = @@ -237,16 +237,17 @@ let checkout_context node_ctxt block_hash = Store.L2_blocks.header node_ctxt.store.l2_blocks block_hash in let*? context_hash = + let open Result_syntax in match l2_header with | None -> - error (Sc_rollup_node_errors.Cannot_checkout_context (block_hash, None)) - | Some {context; _} -> ok context + tzfail (Rollup_node_errors.Cannot_checkout_context (block_hash, None)) + | Some {context; _} -> return context in let*! ctxt = Context.checkout node_ctxt.context context_hash in match ctxt with | None -> tzfail - (Sc_rollup_node_errors.Cannot_checkout_context + (Rollup_node_errors.Cannot_checkout_context (block_hash, Some context_hash)) | Some ctxt -> return ctxt @@ -531,7 +532,6 @@ let get_commitment node_ctxt commitment_hash = | Some i -> return i let commitment_exists {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in Store.Commitments.mem store.commitments hash let save_commitment {store; _} commitment = @@ -640,9 +640,6 @@ type messages_info = { let find_messages node_ctxt messages_hash = let open Lwt_result_syntax in - let messages_hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez messages_hash - in let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in match msg with | None -> return_none @@ -690,9 +687,6 @@ let get_messages_without_proto_messages node_ctxt = let get_num_messages {store; _} hash = let open Lwt_result_syntax in - let hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez hash - in let* msg = Store.Messages.read store.messages hash in match msg with | None -> @@ -703,7 +697,6 @@ let get_num_messages {store; _} hash = | Some (messages, _block_hash) -> return (List.length messages) let save_messages {store; _} key ~block_hash messages = - let key = Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez key in Store.Messages.append store.messages ~key diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/lib_smart_rollup_node/node_context.mli similarity index 100% rename from src/proto_alpha/lib_sc_rollup_node/node_context.mli rename to src/lib_smart_rollup_node/node_context.mli diff --git a/src/proto_alpha/lib_sc_rollup_node/test/canary.ml b/src/proto_alpha/lib_sc_rollup_node/test/canary.ml index bbfaf914ecc4..8b5b7a0cc7d9 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/canary.ml +++ b/src/proto_alpha/lib_sc_rollup_node/test/canary.ml @@ -32,6 +32,7 @@ *) open Octez_smart_rollup +open Octez_smart_rollup_node let build_chain node_ctxt ~genesis ~length = let open Lwt_result_syntax in diff --git a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli index c4c75569f722..d18d3f989dd9 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli +++ b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.mli @@ -26,6 +26,7 @@ open Octez_smart_rollup open Protocol open Alpha_context +open Octez_smart_rollup_node (** {1 Helper functions to build and run unit tests for the rollup node} *) -- GitLab From 1ca1d6abfbee710693056658b9645a48a939699c Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Wed, 31 May 2023 09:00:20 +0200 Subject: [PATCH 12/15] SCORU/Node/Nairobi: Backport !8948 - SCORU/Node: custom protocol constants - SCORU/Node: custom genesis info type - SCORU/Node: save genesis inbox on disk - SCORU/Node/batcher: check config on init - SCORU/Node: remove protocol from events - SCORU/Node: interpreter and inboxes on serialized messages - SCORU/Node: remove Protocol dependency from Node_context - SCORU/Node: remove PVM first class module from node context - SCORU/Node: node Node_context outside of proto directory --- .../sc_rollup_services.ml | 26 +- .../lib_sc_rollup_node/RPC_server.ml | 55 +- .../lib_sc_rollup_node/arith_pvm.ml | 2 +- .../lib_sc_rollup_node/batcher.ml | 58 +- .../block_directory_helpers.ml | 6 +- .../lib_sc_rollup_node/commitment_event.ml | 14 +- .../lib_sc_rollup_node/commitment_event.mli | 8 +- .../lib_sc_rollup_node/daemon.ml | 136 +- .../lib_sc_rollup_node/dal_pages_request.ml | 9 +- .../lib_sc_rollup_node/dal_slots_tracker.ml | 72 +- .../lib_sc_rollup_node/fueled_pvm.ml | 46 +- .../lib_sc_rollup_node/inbox.ml | 68 +- .../lib_sc_rollup_node/inbox.mli | 20 +- .../lib_sc_rollup_node/interpreter.ml | 69 +- .../lib_sc_rollup_node/interpreter.mli | 2 +- .../lib_sc_rollup_node/interpreter_event.ml | 8 +- .../lib_sc_rollup_node/layer1_helpers.ml | 110 ++ .../lib_sc_rollup_node/layer1_helpers.mli | 33 + .../lib_sc_rollup_node/node_context.ml | 1257 ----------------- .../lib_sc_rollup_node/node_context.mli | 487 ------- .../lib_sc_rollup_node/outbox.ml | 7 +- .../lib_sc_rollup_node/outbox.mli | 2 +- .../lib_sc_rollup_node/publisher.ml | 121 +- .../lib_sc_rollup_node/publisher.mli | 6 +- .../lib_sc_rollup_node/pvm.ml | 78 +- .../lib_sc_rollup_node/pvm_rpc.ml | 2 +- .../lib_sc_rollup_node/pvm_sig.ml | 101 ++ .../refutation_coordinator.ml | 48 +- .../lib_sc_rollup_node/refutation_game.ml | 50 +- .../refutation_game_event.ml | 8 +- .../lib_sc_rollup_node/reveals.ml | 4 +- .../lib_sc_rollup_node/reveals.mli | 2 +- .../lib_sc_rollup_node/simulation.ml | 44 +- .../lib_sc_rollup_node/simulation.mli | 7 +- .../lib_sc_rollup_node/test/canary.ml | 11 +- .../test/helpers/helpers.ml | 69 +- .../test/helpers/helpers.mli | 13 +- .../lib_sc_rollup_node/wasm_2_0_0_pvm.ml | 2 +- 38 files changed, 780 insertions(+), 2281 deletions(-) delete mode 100644 src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml delete mode 100644 src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli create mode 100644 src/proto_017_PtNairob/lib_sc_rollup_node/pvm_sig.ml diff --git a/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml index 62664a971c3a..b6539529a288 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -52,7 +52,7 @@ type eval_result = { state_hash : Sc_rollup.State_hash.t; status : string; output : Sc_rollup.output list; - inbox_level : Raw_level.t; + inbox_level : int32; num_ticks : Z.t; insights : bytes option list; (** The simulation can ask to look at values on the state after @@ -98,8 +98,8 @@ type message_status = l1_level : int32; finalized : bool; cemented : bool; - commitment : Sc_rollup.Commitment.t; - commitment_hash : Sc_rollup.Commitment.Hash.t; + commitment : Octez_smart_rollup.Commitment.t; + commitment_hash : Octez_smart_rollup.Commitment.Hash.t; first_published_at_level : int32; published_at_level : int32; } @@ -109,13 +109,13 @@ module Encodings = struct let commitment_with_hash = obj2 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) let commitment_with_hash_and_level_infos = obj4 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (opt "first_published_at_level" int32) (opt "published_at_level" int32) @@ -141,7 +141,7 @@ module Encodings = struct ~description:"Output produced by evaluation of the messages") (req "inbox_level" - Raw_level.encoding + int32 ~description:"Level of the inbox that would contain these messages") (req "num_ticks" @@ -320,8 +320,8 @@ module Encodings = struct (req "level" int32))) (req "finalized" bool) (req "cemented" bool) - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (req "first_published_at_level" int32) (req "published_at_level" int32)) (function @@ -606,7 +606,7 @@ module Global = struct Tezos_rpc.Service.get_service ~description:"Rollup inbox for block" ~query:Tezos_rpc.Query.empty - ~output:Sc_rollup.Inbox.encoding + ~output:Octez_smart_rollup.Inbox.encoding (path / "inbox") let ticks = @@ -721,9 +721,7 @@ module Global = struct ~output: Data_encoding.( list - @@ obj2 - (req "index" Dal.Slot_index.encoding) - (req "status" dal_slot_status_encoding)) + @@ obj2 (req "index" int31) (req "status" dal_slot_status_encoding)) (path / "dal" / "processed_slots") module Outbox = struct diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml index 6f049377dd2b..6777c7e83d39 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml @@ -122,16 +122,14 @@ module Common = struct let open Lwt_result_syntax in let* l2_block = Node_context.get_l2_block node_ctxt block in let+ num_messages = - Node_context.get_num_messages - node_ctxt - (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez - l2_block.header.inbox_witness) + Node_context.get_num_messages node_ctxt l2_block.header.inbox_witness in Z.of_int num_messages let () = Global_directory.register0 Sc_rollup_services.Global.sc_rollup_address - @@ fun node_ctxt () () -> return @@ node_ctxt.rollup_address + @@ fun node_ctxt () () -> + return @@ Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address let () = Global_directory.register0 Sc_rollup_services.Global.current_tezos_head @@ -173,7 +171,7 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages ~insight_requests messages = let open Lwt_result_syntax in let open Alpha_context in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let reveal_map = match reveal_pages with | Some pages -> @@ -209,11 +207,10 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages insight_requests in let num_ticks = Z.(num_ticks_0 + num_ticks_end) in - let*! outbox = PVM.get_outbox inbox_level state in + let level = Raw_level.of_int32_exn inbox_level in + let*! outbox = PVM.get_outbox level state in let output = - List.filter - (fun Sc_rollup.{outbox_level; _} -> outbox_level = inbox_level) - outbox + List.filter (fun Sc_rollup.{outbox_level; _} -> outbox_level = level) outbox in let*! state_hash = PVM.state_hash state in let*! status = PVM.get_status state in @@ -227,7 +224,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in return tick @@ -236,7 +233,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! hash = PVM.state_hash state in return hash @@ -245,7 +242,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! current_level = PVM.get_current_level state in return current_level @@ -272,7 +269,6 @@ let () = | Some head -> let commitment_hash = Sc_rollup_block.most_recent_commitment head.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let+ commitment = Node_context.find_commitment node_ctxt commitment_hash @@ -286,9 +282,7 @@ let () = match Reference.get node_ctxt.lpc with | None -> return_none | Some commitment -> - let hash = - Alpha_context.Sc_rollup.Commitment.hash_uncarbonated commitment - in + let hash = Octez_smart_rollup.Commitment.hash commitment in (* The corresponding level in Store.Commitments.published_at_level is available only when the commitment has been published and included in a block. *) @@ -308,7 +302,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! status = PVM.get_status state in return (PVM.string_of_status status) @@ -316,10 +310,10 @@ let () = Block_directory.register0 Sc_rollup_services.Global.Block.dal_slots @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in - let* slots = + let+ slots = Node_context.get_all_slot_headers node_ctxt ~published_in_block_hash:block in - return slots + List.rev_map Sc_rollup_proto_types.Dal.Slot_header.of_octez slots |> List.rev let () = Block_directory.register0 Sc_rollup_services.Global.Block.dal_processed_slots @@ -330,21 +324,21 @@ let () = @@ fun (node_ctxt, block, outbox_level) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! outbox = PVM.get_outbox outbox_level state in return outbox let () = Proof_helpers_directory.register0 Sc_rollup_services.Global.Helpers.outbox_proof - @@ fun node_ctxt output () -> Outbox.proof_of_output node_ctxt output + @@ fun node_ctxt output () -> + let open Lwt_result_syntax in + let+ commitment, proof = Outbox.proof_of_output node_ctxt output in + (Sc_rollup_proto_types.Commitment_hash.of_octez commitment, proof) let () = Block_directory.register0 Sc_rollup_services.Global.Block.simulate @@ fun (node_ctxt, block) () {messages; reveal_pages; insight_requests} -> - let messages = - List.map Alpha_context.Sc_rollup.Inbox_message.unsafe_of_string messages - in simulate_messages node_ctxt block ~reveal_pages ~insight_requests messages let () = @@ -376,23 +370,19 @@ let commitment_level_of_inbox_level (node_ctxt : _ Node_context.t) inbox_level = let+ last_published_commitment = Reference.get node_ctxt.lpc in let commitment_period = Int32.of_int - node_ctxt.protocol_constants.parametric.sc_rollup - .commitment_period_in_blocks - in - let last_published = - Raw_level.to_int32 last_published_commitment.inbox_level + node_ctxt.protocol_constants.sc_rollup.commitment_period_in_blocks in + let last_published = last_published_commitment.inbox_level in let open Int32 in div (sub last_published inbox_level) commitment_period |> mul commitment_period |> sub last_published |> Raw_level.of_int32_exn let inbox_info_of_level (node_ctxt : _ Node_context.t) inbox_level = - let open Alpha_context in let open Lwt_result_syntax in let+ finalized_level = Node_context.get_finalized_level node_ctxt in let finalized = Compare.Int32.(inbox_level <= finalized_level) in let lcc = Reference.get node_ctxt.lcc in - let cemented = Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) in + let cemented = Compare.Int32.(inbox_level <= lcc.level) in (finalized, cemented) let () = @@ -461,7 +451,6 @@ let () = WithExceptions.Option.get ~loc:__LOC__ block.header.commitment_hash - |> Sc_rollup_proto_types.Commitment_hash.of_octez in (* Commitment computed *) let* published_at = diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/arith_pvm.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/arith_pvm.ml index 97b5b0b1aa00..0ad11390bf1c 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/arith_pvm.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/arith_pvm.ml @@ -44,7 +44,7 @@ module Arith_proof_format = .tree_proof_encoding end) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.ArithPVM.Make (Arith_proof_format) include PVM diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/batcher.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/batcher.ml index cf4199967009..fccf828b61bb 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/batcher.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/batcher.ml @@ -153,11 +153,14 @@ let produce_batches state ~only_full = let simulate node_ctxt simulation_ctxt (messages : L2_message.t list) = let open Lwt_result_syntax in let*? ext_messages = - List.map_e - (fun m -> - Sc_rollup.Inbox_message.(serialize (External (L2_message.content m)))) - messages - |> Environment.wrap_tzresult + Environment.wrap_tzresult + @@ List.map_e + (fun m -> + let open Result_syntax in + let open Sc_rollup.Inbox_message in + let+ msg = serialize @@ External (L2_message.content m) in + unsafe_to_string msg) + messages in let+ simulation_ctxt, _ticks = Simulation.simulate_messages node_ctxt simulation_ctxt ext_messages @@ -229,6 +232,38 @@ let on_new_head state head = (* Forget failing messages *) List.iter (Message_queue.remove state.messages) failing +(** Maximum size of an L2 batch in bytes that can fit in an operation of the + protocol. *) +let protocol_max_batch_size = + let open Protocol in + let open Alpha_context in + let empty_message_op : _ Operation.t = + let open Operation in + { + shell = {branch = Block_hash.zero}; + protocol_data = + { + signature = Some Signature.zero; + contents = + Single + (Manager_operation + { + source = Signature.Public_key_hash.zero; + fee = Tez.of_mutez_exn Int64.max_int; + counter = Manager_counter.Internal_for_tests.of_int max_int; + gas_limit = + Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); + storage_limit = Z.of_int max_int; + operation = Sc_rollup_add_messages {messages = [""]}; + }); + }; + } + in + Protocol.Constants_repr.max_operation_data_length + - Data_encoding.Binary.length + Operation.encoding + (Operation.pack empty_message_op) + let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = let open Lwt_syntax in let conf = @@ -238,9 +273,7 @@ let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = min_batch_size = conf.min_batch_size; max_batch_elements = conf.max_batch_elements; max_batch_size = - Option.value - conf.max_batch_size - ~default:Node_context.protocol_max_batch_size; + Option.value conf.max_batch_size ~default:protocol_max_batch_size; } in return @@ -329,8 +362,17 @@ let table = Worker.create_table Queue let worker_promise, worker_waker = Lwt.task () +let check_batcher_config Configuration.{max_batch_size; _} = + match max_batch_size with + | Some m when m > protocol_max_batch_size -> + error_with + "batcher.max_batch_size must be smaller than %d" + protocol_max_batch_size + | _ -> Ok () + let init conf ~signer node_ctxt = let open Lwt_result_syntax in + let*? () = check_batcher_config conf in let node_ctxt = Node_context.readonly node_ctxt in let+ worker = Worker.launch table () {node_ctxt; signer; conf} (module Handlers) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.ml index a4ccb383a729..e7cba968fb78 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol - (* Conveniences to construct RPC directory against a subcontext of the Node_context *) @@ -43,9 +41,7 @@ let get_finalized node_ctxt = let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> let lcc = Reference.get node_ctxt.lcc in - Node_context.hash_of_level - node_ctxt - (Alpha_context.Raw_level.to_int32 lcc.level) + Node_context.hash_of_level node_ctxt lcc.level let block_of_prefix node_ctxt block = match block with diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.ml index 92c014f0ab7c..c477e81f6885 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.ml @@ -72,8 +72,8 @@ module Simple = struct "Last cemented commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let last_published_commitment_updated = declare_2 @@ -83,8 +83,8 @@ module Simple = struct "Last published commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let compute_commitment = declare_1 @@ -92,7 +92,7 @@ module Simple = struct ~name:"sc_rollup_node_commitment_process_head" ~msg:"Computing and storing new commitment for level {level}" ~level:Notice - ("level", Raw_level.encoding) + ("level", Data_encoding.int32) let publish_commitment = declare_2 @@ -100,8 +100,8 @@ module Simple = struct ~name:"sc_rollup_node_publish_commitment" ~msg:"Publishing commitment {hash} for inbox level {level}" ~level:Notice - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let commitment_parent_is_not_lcc = declare_3 diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.mli index 89b337266710..5a26a50ec34f 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.mli @@ -51,13 +51,13 @@ val commitment_will_not_be_published : cemented commitment was updated to the given [hash] at the given inbox [level]. *) val last_cemented_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [last_published_commitment_updated hash level] emits the event that the last published commitment was updated to the given [hash] at the given inbox [level]. *) val last_published_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [commitment_parent_is_not_lcc predecessor_hash last_cemented_commitment_hash] emits the event that a commitment at the given inbox [level] is being @@ -73,12 +73,12 @@ val commitment_parent_is_not_lcc : (** [compute_commitment level] emits the event that a new commitment is being computed and stored for the block at the given [level]. *) -val compute_commitment : Raw_level.t -> unit Lwt.t +val compute_commitment : int32 -> unit Lwt.t (** [publish_commitment hash level] emits the event that a new commitment is being published. *) val publish_commitment : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** Events emmitted by the Publisher worker *) module Publisher : sig diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml index cb8d52f455b3..003433875727 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml @@ -32,24 +32,21 @@ open Apply_results (** Returns [Some c] if [their_commitment] is refutable where [c] is our commitment for the same inbox level. *) let is_refutable_commitment node_ctxt - (their_commitment : Sc_rollup.Commitment.t) their_commitment_hash = + (their_commitment : Octez_smart_rollup.Commitment.t) their_commitment_hash = let open Lwt_result_syntax in let* l2_block = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 their_commitment.inbox_level) + Node_context.get_l2_block_by_level node_ctxt their_commitment.inbox_level in let* our_commitment_and_hash = Option.filter_map_es (fun hash -> - let hash = Sc_rollup_proto_types.Commitment_hash.of_octez hash in let+ commitment = Node_context.find_commitment node_ctxt hash in Option.map (fun c -> (c, hash)) commitment) l2_block.header.commitment_hash in match our_commitment_and_hash with | Some (our_commitment, our_commitment_hash) - when Sc_rollup.Commitment.Hash.( + when Octez_smart_rollup.Commitment.Hash.( their_commitment_hash <> our_commitment_hash && their_commitment.predecessor = our_commitment.predecessor) -> return our_commitment_and_hash @@ -76,7 +73,7 @@ let accuser_publish_commitment_when_refutable node_ctxt ~other rollup ~level:their_commitment.inbox_level ~other in - assert (Sc_rollup.Address.(node_ctxt.rollup_address = rollup)) ; + assert (Octez_smart_rollup.Address.(node_ctxt.rollup_address = rollup)) ; Publisher.publish_single_commitment node_ctxt our_commitment (** Process an L1 SCORU operation (for the node's rollup) which is included @@ -94,10 +91,12 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let save_lpc = match Reference.get node_ctxt.lpc with | None -> true - | Some lpc -> Raw_level.(commitment.inbox_level >= lpc.inbox_level) + | Some lpc -> + Raw_level.to_int32 commitment.inbox_level >= lpc.inbox_level in + let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in if save_lpc then Reference.set node_ctxt.lpc (Some commitment) ; - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let* () = Node_context.set_commitment_published_at_level node_ctxt @@ -110,7 +109,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let*! () = Commitment_event.last_published_commitment_updated commitment_hash - (Raw_level.of_int32_exn head.Layer1.level) + head.Layer1.level in return_unit | ( Sc_rollup_publish {commitment = their_commitment; rollup}, @@ -118,6 +117,9 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) {published_at_level; staked_hash = their_commitment_hash; _} ) -> (* Commitment published by someone else *) (* We first register the publication information *) + let their_commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez their_commitment_hash + in let* known_commitment = Node_context.commitment_exists node_ctxt their_commitment_hash in @@ -146,6 +148,10 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) in (* An accuser node will publish its commitment if the other one is refutable. *) + let rollup = Sc_rollup_proto_types.Address.to_octez rollup in + let their_commitment = + Sc_rollup_proto_types.Commitment.to_octez their_commitment + in accuser_publish_commitment_when_refutable node_ctxt ~other:source @@ -155,8 +161,6 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) | ( Sc_rollup_cement _, Sc_rollup_cement_result {inbox_level; commitment_hash; _} ) -> (* Cemented commitment ---------------------------------------------- *) - let proto_inbox_level = inbox_level in - let proto_commitment_hash = commitment_hash in let inbox_level = Raw_level.to_int32 inbox_level in let commitment_hash = Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash @@ -177,13 +181,13 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) in let lcc = Reference.get node_ctxt.lcc in let*! () = - if inbox_level > Raw_level.to_int32 lcc.level then ( + if inbox_level > lcc.level then ( Reference.set node_ctxt.lcc - {commitment = proto_commitment_hash; level = proto_inbox_level} ; + {commitment = commitment_hash; level = inbox_level} ; Commitment_event.last_cemented_commitment_updated - proto_commitment_hash - proto_inbox_level) + commitment_hash + inbox_level) else Lwt.return_unit in return_unit @@ -218,7 +222,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) Node_context.save_slot_header node_ctxt ~published_in_block_hash:head.Layer1.hash - slot_header + (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) in return_unit | _, _ -> @@ -237,7 +241,9 @@ let process_l1_operation (type kind) node_ctxt (head : Layer1.header) ~source | Sc_rollup_timeout {rollup; _} | Sc_rollup_execute_outbox_message {rollup; _} | Sc_rollup_recover_bond {sc_rollup = rollup; staker = _} -> - Sc_rollup.Address.(rollup = node_ctxt.Node_context.rollup_address) + Octez_smart_rollup.Address.( + Sc_rollup_proto_types.Address.to_octez rollup + = node_ctxt.Node_context.rollup_address) | Dal_publish_slot_header _ -> true | Reveal _ | Transaction _ | Origination _ | Delegation _ | Update_consensus_key _ | Register_global_constant _ | Set_deposits_limit _ @@ -299,13 +305,13 @@ let process_l1_block_operations node_ctxt (head : Layer1.header) = return_unit let before_origination (node_ctxt : _ Node_context.t) (header : Layer1.header) = - let origination_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let origination_level = node_ctxt.genesis_info.level in header.level < origination_level let previous_context (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in - if predecessor.level < Raw_level.to_int32 node_ctxt.genesis_info.level then + if predecessor.level < node_ctxt.genesis_info.level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -376,11 +382,6 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* inbox_hash, inbox, inbox_witness, messages = Inbox.process_head node_ctxt ~predecessor head in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez - inbox_witness - in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* () = when_ (Node_context.dal_supported node_ctxt) @@ fun () -> Dal_slots_tracker.process_head node_ctxt (Layer1.head_of_header head) @@ -401,25 +402,15 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* commitment_hash = Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt in - let commitment_hash = - Option.map - Sc_rollup_proto_types.Commitment_hash.to_octez - commitment_hash - in let* () = unless (catching_up && Option.is_none commitment_hash) @@ fun () -> - Inbox.same_as_layer_1 - node_ctxt - head.hash - (Sc_rollup_proto_types.Inbox.to_octez inbox) + Inbox.same_as_layer_1 node_ctxt head.hash inbox in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -428,7 +419,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -473,9 +464,7 @@ let on_layer_1_head (daemon_components : (module Daemon_components.S)) node_ctxt | None -> (* if no head has been processed yet, we want to handle all blocks since, and including, the rollup origination. *) - let origination_level = - Raw_level.to_int32 node_ctxt.genesis_info.level - in + let origination_level = node_ctxt.genesis_info.level in `Level (Int32.pred origination_level) in let stripped_head = Layer1.head_of_header head in @@ -572,15 +561,15 @@ let install_finalizer (daemon_components : (module Daemon_components.S)) let* () = Event.shutdown_node exit_status in Tezos_base_unix.Internal_event_unix.close () -let check_initial_state_hash {Node_context.cctxt; rollup_address; pvm; _} = +let check_initial_state_hash {Node_context.cctxt; rollup_address; kind; _} = let open Lwt_result_syntax in + let module PVM = (val Pvm.of_kind kind) in let* l1_reference_initial_state_hash = RPC.Sc_rollup.initial_pvm_state_hash - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, cctxt#block) - rollup_address + (Sc_rollup_proto_types.Address.of_octez rollup_address) in - let module PVM = (val pvm) in let*! s = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! l2_initial_state_hash = PVM.state_hash s in let l1_reference_initial_state_hash = @@ -638,12 +627,9 @@ let run node_ctxt configuration { cctxt = (node_ctxt.cctxt :> Client_context.full); fee_parameters = configuration.fee_parameters; - minimal_block_delay = - node_ctxt.protocol_constants.Constants.parametric - .minimal_block_delay |> Period.to_seconds; + minimal_block_delay = node_ctxt.protocol_constants.minimal_block_delay; delay_increment_per_round = - node_ctxt.protocol_constants.Constants.parametric - .delay_increment_per_round |> Period.to_seconds; + node_ctxt.protocol_constants.delay_increment_per_round; } ~data_dir:node_ctxt.data_dir ~signers @@ -677,8 +663,8 @@ let run node_ctxt configuration Metrics.Info.init_rollup_node_info ~id:configuration.sc_rollup_address ~mode:configuration.mode - ~genesis_level:(Raw_level.to_int32 node_ctxt.genesis_info.level) - ~pvm_kind:(Sc_rollup.Kind.to_string node_ctxt.kind) ; + ~genesis_level:node_ctxt.genesis_info.level + ~pvm_kind:(Octez_smart_rollup.Kind.to_string node_ctxt.kind) ; let fatal_error_exit e = Format.eprintf "%!%a@.Exiting.@." pp_print_trace e ; let*! _ = Lwt_exit.exit_and_wait 1 in @@ -737,11 +723,6 @@ module Internal_for_tests = struct head messages in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez - inbox_witness - in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* ctxt, _num_messages, num_ticks, initial_tick = Interpreter.process_head node_ctxt ctxt ~predecessor head (inbox, messages) in @@ -753,16 +734,11 @@ module Internal_for_tests = struct head ctxt in - let commitment_hash = - Option.map Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -771,7 +747,7 @@ module Internal_for_tests = struct Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -829,6 +805,25 @@ let run Layer1.fetch_tezos_shell_header l1_ctxt head.header.predecessor in let*! () = Event.received_first_block head.hash Protocol.hash in + let publisher = + Configuration.Operator_purpose_map.find + Publish + configuration.sc_rollup_node_operators + in + let* constants = Layer1_helpers.retrieve_constants cctxt + and* genesis_info = + Layer1_helpers.retrieve_genesis_info cctxt configuration.sc_rollup_address + and* lcc = + Layer1_helpers.get_last_cemented_commitment + cctxt + configuration.sc_rollup_address + and* lpc = + Option.filter_map_es + (Layer1_helpers.get_last_published_commitment + cctxt + configuration.sc_rollup_address) + publisher + and* kind = Layer1_helpers.get_kind cctxt configuration.sc_rollup_address in let* node_ctxt = Node_context.init cctxt @@ -836,6 +831,11 @@ let run ?log_kernel_debug_file Read_write l1_ctxt + constants + genesis_info + ~lcc + ~lpc + kind ~proto_level:predecessor.proto_level configuration in diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/dal_pages_request.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/dal_pages_request.ml index 5744e9f67728..f95fc6e4b0e0 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/dal_pages_request.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/dal_pages_request.ml @@ -95,18 +95,17 @@ let download_confirmed_slot_pages ({Node_context.dal_cctxt; _} as node_ctxt) let* published_in_block_hash = Node_context.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in - let* {commitment; _} = + let* header = Node_context.get_slot_header node_ctxt ~published_in_block_hash index in let dal_cctxt = WithExceptions.Option.get ~loc:__LOC__ dal_cctxt in (* DAL must be configured for this point to be reached *) - get_slot_pages dal_cctxt commitment + get_slot_pages dal_cctxt header.commitment let storage_invariant_broken published_level index = failwith "Internal error: [Node_context.find_slot_status] is supposed to have \ - registered the status of the slot %a published at level %a in the store" - Dal.Slot_index.pp + registered the status of the slot %d published at level %a in the store" index Raw_level.pp published_level @@ -120,6 +119,7 @@ let slot_pages ~dal_attestation_lag node_ctxt ~published_level node_ctxt in + let index = Dal.Slot_index.to_int index in let* processed = Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in @@ -142,6 +142,7 @@ let page_content ~dal_attestation_lag node_ctxt page_id = ~published_level node_ctxt in + let index = Dal.Slot_index.to_int index in let* processed = Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/dal_slots_tracker.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/dal_slots_tracker.ml index ced86b18711f..e8f011e00c7f 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/dal_slots_tracker.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/dal_slots_tracker.ml @@ -33,7 +33,7 @@ let ancestor_hash ~number_of_levels let genesis_level = genesis_info.level in let rec go number_of_levels (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - if level < Raw_level.to_int32 genesis_level then return_none + if level < genesis_level then return_none else if number_of_levels = 0 then return_some hash else let* pred_head = Node_context.get_predecessor_opt node_ctxt head in @@ -69,9 +69,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = we reduce the lag to 1, then the slots header will never be confirmed. *) let open Lwt_result_syntax in - let lag = - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag - in + let lag = node_ctxt.Node_context.protocol_constants.dal.attestation_lag in (* we are downloading endorsemented for slots at level [level], so we need to download the data at level [level - lag]. *) @@ -108,7 +106,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = let confirmed_slots_indexes_list = List.filter (Dal.Attestation.is_attested confirmed_slots) - published_slots_indexes + (List.filter_map Dal.Slot_index.of_int_opt published_slots_indexes) in let*? confirmed_slots_indexes = Environment.wrap_tzresult @@ -120,16 +118,10 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3884 avoid going back and forth between bitsets and lists of slot indexes. *) -let to_slot_index_list (constants : Constants.Parametric.t) bitset = - let open Result_syntax in +let to_slot_index_list (constants : Rollup_constants.protocol_constants) bitset + = let all_slots = Misc.(0 --> (constants.dal.number_of_slots - 1)) in - let+ filtered = List.filter_e (Bitset.mem bitset) all_slots in - (* Because the maximum slot index is smaller than the number_of_slots protocol - constants, and this value is smaller than the hard limit imposed for slots, - then Dal.Slot_index.to_int will always return a defined value. See - `src/proto_alpha/lib_protocol/constants_repr.ml`. - *) - List.filter_map Dal.Slot_index.of_int_opt filtered + List.filter_e (Bitset.mem bitset) all_slots (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/4139. Use a shared storage between dal and rollup node to store slots data. @@ -140,17 +132,17 @@ let download_and_save_slots {published_block_hash; confirmed_slots_indexes} = let open Lwt_result_syntax in let*? all_slots = - Bitset.fill ~length:protocol_constants.parametric.dal.number_of_slots + Bitset.fill ~length:protocol_constants.dal.number_of_slots |> Environment.wrap_tzresult in let*? not_confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric + @@ to_slot_index_list protocol_constants @@ Bitset.diff all_slots confirmed_slots_indexes in let*? confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric confirmed_slots_indexes + @@ to_slot_index_list protocol_constants confirmed_slots_indexes in (* The contents of each slot index are written to a different location on disk, therefore calls to store contents for different slot indexes can @@ -174,6 +166,9 @@ let download_and_save_slots s_slot `Confirmed in + let*? s_slot = + Environment.wrap_tzresult @@ Dal.Slot_index.of_int s_slot + in let*! () = Dal_slots_tracker_event.slot_has_been_confirmed s_slot @@ -193,22 +188,27 @@ module Confirmed_slots_history = struct let*? relevant_slots_indexes = Environment.wrap_tzresult @@ to_slot_index_list - node_ctxt.Node_context.protocol_constants.parametric + node_ctxt.Node_context.protocol_constants confirmed_slots_indexes in List.map_ep (fun slot_index -> - Node_context.get_slot_header - node_ctxt - ~published_in_block_hash:published_block_hash - slot_index) + let+ h = + Node_context.get_slot_header + node_ctxt + ~published_in_block_hash:published_block_hash + slot_index + in + Sc_rollup_proto_types.Dal.Slot_header.of_octez h) relevant_slots_indexes let read_slots_history_from_l1 {Node_context.cctxt; _} block = let open Lwt_result_syntax in (* We return the empty Slots_history if DAL is not enabled. *) let* slots_list_opt = - RPC.Dal.dal_confirmed_slots_history cctxt (cctxt#chain, `Hash (block, 0)) + RPC.Dal.dal_confirmed_slots_history + (new Protocol_client_context.wrap_full cctxt) + (cctxt#chain, `Hash (block, 0)) in return @@ Option.value slots_list_opt ~default:Dal.Slots_history.genesis @@ -220,11 +220,10 @@ module Confirmed_slots_history = struct let should_process_dal_slots node_ctxt block_level = let open Node_context in let lag = - Int32.of_int - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag + Int32.of_int node_ctxt.Node_context.protocol_constants.dal.attestation_lag in let block_level = Raw_level.to_int32 block_level in - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let genesis_level = node_ctxt.genesis_info.level in Int32.(block_level >= add lag genesis_level) let dal_entry_of_block_hash node_ctxt @@ -259,23 +258,32 @@ module Confirmed_slots_history = struct block_level let slots_history_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_history node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history" - ~find:Node_context.find_confirmed_slots_history + ~find ~default:read_slots_history_from_l1 let slots_history_cache_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_histories node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history cache" - ~find:Node_context.find_confirmed_slots_histories + ~find ~default:(fun node_ctxt _block -> let num_slots = - node_ctxt.Node_context.protocol_constants.parametric.dal - .number_of_slots + node_ctxt.Node_context.protocol_constants.dal.number_of_slots in (* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3788 Put an accurate value for capacity. The value @@ -323,13 +331,13 @@ module Confirmed_slots_history = struct Node_context.save_confirmed_slots_history node_ctxt head_hash - slots_history + (Sc_rollup_proto_types.Dal.Slot_history.to_octez slots_history) in let* () = Node_context.save_confirmed_slots_histories node_ctxt head_hash - slots_cache + (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez slots_cache) in return () end 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 573d866ace87..b56a7d48c8fc 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 @@ -39,14 +39,13 @@ module type S = sig 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 : Raw_level.t; - (** Inbox level in which messages are evaluated. *) + 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 : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; (** Messages of the inbox that remain to be evaluated. *) } @@ -61,7 +60,7 @@ module type S = sig val eval_block_inbox : fuel:fuel -> _ Node_context.t -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.serialized list -> + Octez_smart_rollup.Inbox.t * string list -> pvm_state -> eval_result Node_context.delayed_write tzresult Lwt.t @@ -90,10 +89,10 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct state : pvm_state; state_hash : Sc_rollup.State_hash.t; tick : Sc_rollup.Tick.t; - inbox_level : Raw_level.t; + inbox_level : int32; message_counter_offset : int; remaining_fuel : fuel; - remaining_messages : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; } type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} @@ -119,6 +118,15 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct exception Error_wrapper of tztrace + let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = + Raw_level.of_int32_exn node_ctxt.genesis_info.level + in + Sc_rollup.Metadata.{address; origination_level} + (** [eval_until_input node_ctxt reveal_map level message_index ~fuel start_tick failing_ticks state] advances a PVM [state] until it wants more inputs or there are no more [fuel] (if [Some fuel] is @@ -130,10 +138,10 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct message_index ~fuel start_tick failing_ticks state = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in - let metadata = Node_context.metadata node_ctxt in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in + let metadata = metadata node_ctxt in let dal_attestation_lag = - node_ctxt.protocol_constants.parametric.dal.attestation_lag + node_ctxt.protocol_constants.dal.attestation_lag in let reveal_builtins = Tezos_scoru_wasm.Builtins. @@ -306,7 +314,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct ~fuel ~failing_ticks state input = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* res = eval_until_input node_ctxt @@ -362,7 +370,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_messages ~reveal_map ~fuel node_ctxt ~message_counter_offset state inbox_level messages = let open Delayed_write_monad.Lwt_result_syntax in - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in (* Iterate the PVM state with all the messages. *) let rec feed_messages (state, fuel) message_index = function | [] -> @@ -372,9 +380,15 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct (* Consumed all fuel *) return (state, fuel, message_index - message_counter_offset, messages) | message :: messages -> ( + let payload = Sc_rollup.Inbox_message.unsafe_of_string message in let message_counter = Z.of_int message_index in let input = - Sc_rollup.{inbox_level; message_counter; payload = message} + Sc_rollup. + { + inbox_level = Raw_level.of_int32_exn inbox_level; + message_counter; + payload; + } in let failing_ticks = Loser_mode.is_failure @@ -416,9 +430,9 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct 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 node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in (* Obtain inbox and its messages for this block. *) - let inbox_level = Inbox.inbox_level inbox in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in let*! initial_tick = PVM.get_tick state in (* Evaluate all the messages for this level. *) let>* state, remaining_fuel, num_messages, remaining_messages = @@ -459,11 +473,11 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct } = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* state, remaining_fuel, num_messages, remaining_messages = match messages with | [] -> - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in let message_index = message_counter_offset - 1 in let failing_ticks = Loser_mode.is_failure diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.ml index 37458f1e0432..7715bd437a89 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.ml @@ -78,12 +78,22 @@ let get_messages Node_context.{l1_ctxt; _} head = block.operations {apply; apply_internal}) in - return (List.rev rev_messages) + let*? messages = + Environment.wrap_tzresult + @@ List.rev_map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + rev_messages + in + return messages let same_as_layer_1 node_ctxt head_hash inbox = let open Lwt_result_syntax in let head_block = `Hash (head_hash, 0) in let Node_context.{cctxt; _} = node_ctxt in + let cctxt = new Protocol_client_context.wrap_full cctxt in let* layer1_inbox = Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, head_block) in @@ -129,6 +139,15 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block let predecessor_timestamp = predecessor.header.timestamp in let inbox_metrics = Metrics.Inbox.metrics in Prometheus.Gauge.set inbox_metrics.head_inbox_level @@ Int32.to_float level ; + let inbox = Sc_rollup_proto_types.Inbox.of_octez inbox in + let serialized_messages = messages in + let*? messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let* ( _messages_history, witness_hash, inbox, @@ -140,6 +159,11 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block inbox messages in + let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in + let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + let witness_hash = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez witness_hash + in Metrics.Inbox.Stats.set messages_with_protocol_internal_messages ~is_internal:(function @@ -150,18 +174,24 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block node_ctxt witness_hash ~block_hash:head.hash - messages + serialized_messages + in + let*? messages_with_protocol_internal_messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + messages_with_protocol_internal_messages in - let* inbox_hash = Node_context.save_inbox node_ctxt inbox in return (inbox_hash, inbox, witness_hash, messages_with_protocol_internal_messages) let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) (head : Layer1.header) = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.level >= first_inbox_level then (* We compute the inbox of this block using the inbox of its predecessor. That way, the computation of inboxes is robust to chain @@ -182,12 +212,19 @@ let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) head collected_messages else - let* inbox = Node_context.genesis_inbox node_ctxt in - return - ( Sc_rollup.Inbox.hash inbox, - inbox, - Sc_rollup.Inbox.current_witness inbox, - [] ) + let* inbox = + Layer1_helpers.genesis_inbox + (new Protocol_client_context.wrap_full node_ctxt.cctxt) + ~genesis_level:node_ctxt.genesis_info.level + in + let Octez_smart_rollup.Inbox.{hash = witness; _} = + Octez_smart_rollup.Inbox.Skip_list.content inbox.old_levels_messages + in + let* () = + Node_context.save_messages node_ctxt witness ~block_hash:head.hash [] + in + let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + return (inbox_hash, inbox, witness, []) let start () = Inbox_event.starting () @@ -198,6 +235,13 @@ let payloads_history_of_messages ~is_first_block ~predecessor (* The inbox is not necessary to compute the payloads *) Sc_rollup.Inbox.genesis ~predecessor_timestamp ~predecessor Raw_level.root in + let* messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let+ ( payloads_history, _history, _inbox, diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.mli index cd78e43783e4..88a64b038972 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/inbox.mli @@ -44,10 +44,10 @@ val process_head : Node_context.rw -> predecessor:Layer1.header -> Layer1.header -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t + * string list) tzresult Lwt.t @@ -79,7 +79,7 @@ val payloads_history_of_messages : is_first_block:bool -> predecessor:Block_hash.t -> predecessor_timestamp:Timestamp.time -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup.Inbox_merkelized_payload_hashes.History.t tzresult (** [same_as_layer_1 node_ctxt block node_inbox] ensures that the rollup @@ -98,11 +98,11 @@ module Internal_for_tests : sig is_first_block:bool -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox_message.t list -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + string list -> + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t + * string list) tzresult Lwt.t end 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 bb64d5d879b6..dee1f6fdb114 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.ml @@ -44,7 +44,10 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = match (operation, result) with | ( Sc_rollup_originate {kind; boot_sector; _}, Sc_rollup_originate_result {address; _} ) - when node_ctxt.rollup_address = address && node_ctxt.kind = kind -> + 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 @@ -69,7 +72,7 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let genesis_state block_hash node_ctxt ctxt = let open Lwt_result_syntax in let* boot_sector = get_boot_sector block_hash node_ctxt in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! genesis_state = PVM.install_boot_sector initial_state boot_sector in let*! ctxt = PVM.State.set ctxt genesis_state in @@ -80,9 +83,7 @@ let state_of_head node_ctxt ctxt Layer1.{hash; level} = let*! state = Context.PVMState.find ctxt in match state with | None -> - let genesis_level = - Raw_level.to_int32 node_ctxt.Node_context.genesis_info.level - in + let genesis_level = node_ctxt.Node_context.genesis_info.level in if level = genesis_level then genesis_state hash node_ctxt ctxt else tzfail (Sc_rollup_node_errors.Missing_PVM_state (hash, level)) | Some state -> return (ctxt, state) @@ -109,7 +110,9 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} } = Delayed_write_monad.apply node_ctxt eval_result in - let module PVM = (val node_ctxt.pvm) 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 (* Produce events. *) @@ -121,25 +124,17 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} (** [process_head node_ctxt ctxt ~predecessor head] runs the PVM for the given head. *) let process_head (node_ctxt : _ Node_context.t) ctxt - ~(predecessor : Layer1.header) (head : Layer1.header) (inbox, inbox_messages) - = + ~(predecessor : Layer1.header) (head : Layer1.header) inbox_and_messages = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.Layer1.level >= first_inbox_level then - let*? inbox_messages = - List.map_e Sc_rollup.Inbox_message.serialize inbox_messages - |> Environment.wrap_tzresult - in transition_pvm node_ctxt ctxt (Layer1.head_of_header predecessor) (Layer1.head_of_header head) - (inbox, inbox_messages) - else if head.Layer1.level = Raw_level.to_int32 node_ctxt.genesis_info.level - then + inbox_and_messages + else if head.Layer1.level = node_ctxt.genesis_info.level then let* ctxt, state = genesis_state head.hash node_ctxt ctxt in let*! ctxt = Context.PVMState.set ctxt state in return (ctxt, 0, 0L, Sc_rollup.Tick.initial) @@ -160,35 +155,25 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = ctxt Layer1.{hash = block.header.predecessor; level = pred_level} in - let* inbox = - Node_context.get_inbox - node_ctxt - (Sc_rollup_proto_types.Inbox_hash.of_octez block.header.inbox_hash) - in + let* inbox = Node_context.get_inbox node_ctxt block.header.inbox_hash in let* {is_first_block; predecessor; predecessor_timestamp; messages} = - Node_context.get_messages - node_ctxt - (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez - block.header.inbox_witness) + Node_context.get_messages node_ctxt block.header.inbox_witness in - let inbox_level = Sc_rollup.Inbox.inbox_level inbox in - let module PVM = (val node_ctxt.pvm) in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in let*! state_hash = PVM.state_hash state in let messages = - let open Sc_rollup.Inbox_message in - Internal Start_of_level + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized :: (if is_first_block then - [Internal Sc_rollup.Inbox_message.protocol_migration_internal_message] + [unsafe_to_string Raw_context.protocol_migration_serialized_message] else []) - @ Internal (Info_per_level {predecessor; predecessor_timestamp}) + @ unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) :: messages - @ [Internal End_of_level] - in - let*? messages = - List.map_e Sc_rollup.Inbox_message.serialize messages - |> Environment.wrap_tzresult + @ [unsafe_to_string end_of_level_serialized] in return Fueled_pvm.Accounted. @@ -222,8 +207,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 Raw_level.to_int32 start_state.Fueled_pvm.Accounted.inbox_level - = event.header.level -> + when start_state.Fueled_pvm.Accounted.inbox_level = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a @@ -268,11 +252,14 @@ let memo_state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) returns [None].*) 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 <= Raw_level.to_int32 level) ; + 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 44cabfbbab1e..48cff9f6ceb5 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter.mli @@ -38,7 +38,7 @@ val process_head : 'a Context.t -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.t list -> + Octez_smart_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Sc_rollup.Tick.t) tzresult Lwt.t (** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter_event.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter_event.ml index 80fab8ac3274..967bbe9094f2 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter_event.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/interpreter_event.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol.Alpha_context.Sc_rollup - module Simple = struct include Internal_event.Simple @@ -38,9 +36,9 @@ module Simple = struct "Transitioned PVM at inbox level {inbox_level} to {state_hash} at tick \ {ticks} with {num_messages} messages" ~level:Notice - ("inbox_level", Protocol.Alpha_context.Raw_level.encoding) - ("state_hash", State_hash.encoding) - ("ticks", Tick.encoding) + ("inbox_level", Data_encoding.int32) + ("state_hash", Octez_smart_rollup.State_hash.encoding) + ("ticks", Data_encoding.n) ("num_messages", Data_encoding.int31) let intended_failure = 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 8312c2584373..f15e34e99d15 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 @@ -52,3 +52,113 @@ let fetch_tezos_block l1_ctxt hash = Protocol.name let prefetch_tezos_blocks = Layer1.prefetch_tezos_blocks fetch extract_header + +let get_last_cemented_commitment (cctxt : Protocol_client_context.full) + rollup_address : Node_context.lcc tzresult Lwt.t = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ commitment, level = + Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level + cctxt + (cctxt#chain, `Head 0) + rollup_address + in + { + Node_context.commitment = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment; + level = Protocol.Alpha_context.Raw_level.to_int32 level; + } + +let get_last_published_commitment (cctxt : Protocol_client_context.full) + rollup_address operator = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let*! res = + Plugin.RPC.Sc_rollup.staked_on_commitment + cctxt + (cctxt#chain, `Head 0) + rollup_address + operator + in + match res with + | Error trace + when TzTrace.fold + (fun exists -> function + | Environment.Ecoproto_error + Protocol.Sc_rollup_errors.Sc_rollup_not_staked -> + true + | _ -> exists) + false + trace -> + return_none + | Error trace -> fail trace + | Ok None -> return_none + | Ok (Some (_staked_hash, staked_commitment)) -> + return_some (Sc_rollup_proto_types.Commitment.to_octez staked_commitment) + +let get_kind cctxt rollup_address = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ kind = + RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () + in + Sc_rollup_proto_types.Kind.to_octez kind + +let genesis_inbox cctxt ~genesis_level = + let open Lwt_result_syntax in + let+ inbox = + Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, `Level genesis_level) + in + Sc_rollup_proto_types.Inbox.to_octez inbox + +let constants_of_parametric + Protocol.Alpha_context.Constants.Parametric. + { + minimal_block_delay; + delay_increment_per_round; + sc_rollup = {challenge_window_in_blocks; commitment_period_in_blocks; _}; + dal = {feature_enable; attestation_lag; number_of_slots; _}; + _; + } = + let open Protocol.Alpha_context in + Rollup_constants. + { + minimal_block_delay = Period.to_seconds minimal_block_delay; + delay_increment_per_round = Period.to_seconds delay_increment_per_round; + sc_rollup = + { + challenge_window_in_blocks; + commitment_period_in_blocks; + reveal_activation_level = None; + }; + dal = {feature_enable; attestation_lag; number_of_slots}; + } + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 + The constants are retrieved from the latest tezos block. These constants can + be different from the ones used at the creation at the rollup because of a + protocol amendment that modifies some of them. This need to be fixed when the + rollup nodes will be able to handle the migration of protocol. +*) +let retrieve_constants ?(block = `Head 0) cctxt = + let open Lwt_result_syntax in + let+ {parametric; _} = + Protocol.Constants_services.all cctxt (cctxt#chain, block) + in + constants_of_parametric parametric + +let retrieve_genesis_info cctxt rollup_address = + let open Lwt_result_syntax in + let open Protocol.Alpha_context in + let+ {level; commitment_hash} = + RPC.Sc_rollup.genesis_info + cctxt + (cctxt#chain, `Head 0) + (Sc_rollup_proto_types.Address.of_octez rollup_address) + in + Node_context. + { + level = Raw_level.to_int32 level; + commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; + } 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 3b6fc64abf0a..605c80fcbdd0 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 @@ -38,3 +38,36 @@ val fetch_tezos_block : asynchronously. NOTE: the number of blocks to prefetch must not be greater than the size of the blocks cache otherwise they will be lost. *) val prefetch_tezos_blocks : t -> head list -> unit + +val get_last_cemented_commitment : + Protocol_client_context.full -> Address.t -> Node_context.lcc tzresult Lwt.t + +val get_last_published_commitment : + Protocol_client_context.full -> + Address.t -> + Signature.public_key_hash -> + Commitment.t option tzresult Lwt.t + +val get_kind : + Protocol_client_context.full -> Address.t -> Kind.t tzresult Lwt.t + +val genesis_inbox : + Protocol_client_context.full -> + genesis_level:int32 -> + Octez_smart_rollup.Inbox.t tzresult Lwt.t + +(** Convert protocol constants to their protocol agnostic representation. *) +val constants_of_parametric : + Protocol.Alpha_context.Constants.Parametric.t -> + Rollup_constants.protocol_constants + +(** Retrieve protocol agnotic constants for the head of the chain. *) +val retrieve_constants : + ?block:Block_services.block -> + Protocol_client_context.full -> + Rollup_constants.protocol_constants tzresult Lwt.t + +val retrieve_genesis_info : + Protocol_client_context.full -> + Address.t -> + Node_context.genesis_info tzresult Lwt.t diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml deleted file mode 100644 index 920de832a917..000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml +++ /dev/null @@ -1,1257 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 TriliTech *) -(* 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 - -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -type 'a store = 'a Store.t - -type debug_logger = string -> unit Lwt.t - -type 'a t = { - cctxt : Protocol_client_context.full; - dal_cctxt : Dal_node_client.cctxt option; - data_dir : string; - l1_ctxt : Layer1.t; - rollup_address : Sc_rollup.t; - mode : Configuration.mode; - operators : Configuration.operators; - genesis_info : Sc_rollup.Commitment.genesis_info; - injector_retention_period : int; - block_finality_time : int; - kind : Sc_rollup.Kind.t; - pvm : (module Pvm.S); - fee_parameters : Configuration.fee_parameters; - protocol_constants : Constants.t; - proto_level : int; - loser_mode : Loser_mode.t; - lockfile : Lwt_unix.file_descr; - store : 'a store; - context : 'a Context.index; - lcc : ('a, lcc) Reference.t; - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; - kernel_debug_logger : debug_logger; - finaliser : unit -> unit Lwt.t; -} - -type rw = [`Read | `Write] t - -type ro = [`Read] t - -let () = - if - Tezos_crypto.Hashed.Smart_rollup_address.size - <> Protocol.Alpha_context.Sc_rollup.Address.size - then - Format.ksprintf - Stdlib.failwith - "Protocol %s is not compatible with rollup addresses of size %d" - Protocol.name - Tezos_crypto.Hashed.Smart_rollup_address.size - -let get_operator node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.operators - -let is_operator node_ctxt pkh = - Configuration.Operator_purpose_map.exists - (fun _ operator -> Signature.Public_key_hash.(operator = pkh)) - node_ctxt.operators - -let is_accuser {mode; _} = mode = Accuser - -let is_loser {loser_mode; _} = loser_mode <> Loser_mode.no_failures - -let get_fee_parameter node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.fee_parameters - |> Option.value ~default:(Configuration.default_fee_parameter ~purpose ()) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 - The constants are retrieved from the latest tezos block. These constants can - be different from the ones used at the creation at the rollup because of a - protocol amendment that modifies some of them. This need to be fixed when the - rollup nodes will be able to handle the migration of protocol. -*) -let retrieve_constants cctxt = - Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) - -let get_last_cemented_commitment (cctxt : Protocol_client_context.full) - rollup_address = - let open Lwt_result_syntax in - let+ commitment, level = - Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level - cctxt - (cctxt#chain, `Head 0) - rollup_address - in - {commitment; level} - -let get_last_published_commitment (cctxt : Protocol_client_context.full) - rollup_address operator = - let open Lwt_result_syntax in - let*! res = - Plugin.RPC.Sc_rollup.staked_on_commitment - cctxt - (cctxt#chain, `Head 0) - rollup_address - operator - in - match res with - | Error trace - when TzTrace.fold - (fun exists -> function - | Environment.Ecoproto_error Sc_rollup_errors.Sc_rollup_not_staked - -> - true - | _ -> exists) - false - trace -> - return_none - | Error trace -> fail trace - | Ok None -> return_none - | Ok (Some (_staked_hash, staked_commitment)) -> return_some staked_commitment - -let lock ~data_dir = - let lockfile_path = Filename.concat data_dir "lock" in - let lock_aux ~data_dir = - let open Lwt_result_syntax in - let*! () = Event.acquiring_lock () in - let*! () = Lwt_utils_unix.create_dir data_dir in - let* lockfile = - protect @@ fun () -> - Lwt_unix.openfile - lockfile_path - [Unix.O_CREAT; O_RDWR; O_CLOEXEC; O_SYNC] - 0o644 - |> Lwt_result.ok - in - let* () = - protect ~on_error:(fun err -> - let*! () = Lwt_unix.close lockfile in - fail err) - @@ fun () -> - let*! () = Lwt_unix.lockf lockfile Unix.F_LOCK 0 in - return_unit - in - return lockfile - in - trace (Sc_rollup_node_errors.Could_not_acquire_lock lockfile_path) - @@ lock_aux ~data_dir - -let unlock {lockfile; _} = - Lwt.finalize - (fun () -> Lwt_unix.lockf lockfile Unix.F_ULOCK 0) - (fun () -> Lwt_unix.close lockfile) - -let make_kernel_logger ?log_kernel_debug_file data_dir = - let open Lwt_syntax in - let path = - match log_kernel_debug_file with - | None -> Filename.concat data_dir "kernel.log" - | Some path -> path - in - let+ fd = - Lwt_unix.openfile path Lwt_unix.[O_WRONLY; O_CREAT; O_APPEND] 0o0644 - in - Lwt_io.of_fd ~close:(fun () -> Lwt_unix.close fd) ~mode:Lwt_io.Output fd - -let pvm_of_kind : Protocol.Alpha_context.Sc_rollup.Kind.t -> (module Pvm.S) = - function - | Example_arith -> (module Arith_pvm) - | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) - -let check_fee_parameters Configuration.{fee_parameters; _} = - let check_value purpose name compare to_string mempool_default value = - if compare mempool_default value > 0 then - error_with - "Bad configuration fee_parameter.%s for %s. It must be at least %s for \ - operations of the injector to be propagated." - name - (Configuration.string_of_purpose purpose) - (to_string mempool_default) - else Ok () - in - let check purpose - { - Injector_sigs.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee = _; - fee_cap = _; - burn_cap = _; - } = - let open Result_syntax in - let+ () = - check_value - purpose - "minimal_fees" - Int64.compare - Int64.to_string - (Tez.to_mutez Plugin.Mempool.default_minimal_fees) - minimal_fees.mutez - and+ () = - check_value - purpose - "minimal_nanotez_per_byte" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_byte - minimal_nanotez_per_byte - and+ () = - check_value - purpose - "minimal_nanotez_per_gas_unit" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_gas_unit - minimal_nanotez_per_gas_unit - in - () - in - Configuration.Operator_purpose_map.iter_e check fee_parameters - -let protocol_max_batch_size = - let empty_message_op : _ Operation.t = - let open Protocol in - let open Alpha_context in - let open Operation in - { - shell = {branch = Block_hash.zero}; - protocol_data = - { - signature = Some Signature.zero; - contents = - Single - (Manager_operation - { - source = Signature.Public_key_hash.zero; - fee = Tez.of_mutez_exn Int64.max_int; - counter = Manager_counter.Internal_for_tests.of_int max_int; - gas_limit = - Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); - storage_limit = Z.of_int max_int; - operation = Sc_rollup_add_messages {messages = [""]}; - }); - }; - } - in - Protocol.Constants_repr.max_operation_data_length - - Data_encoding.Binary.length - Operation.encoding - (Operation.pack empty_message_op) - -let check_batcher_config Configuration.{batcher = {max_batch_size; _}; _} = - match max_batch_size with - | Some m when m > protocol_max_batch_size -> - error_with - "batcher.max_batch_size must be smaller than %d" - protocol_max_batch_size - | _ -> Ok () - -let check_config config = - let open Result_syntax in - let+ () = check_fee_parameters config and+ () = check_batcher_config config in - () - -let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file - mode l1_ctxt ~proto_level - Configuration.( - { - sc_rollup_address; - sc_rollup_node_operators = operators; - mode = operating_mode; - fee_parameters; - loser_mode; - l2_blocks_cache_size; - dal_node_endpoint; - _; - } as configuration) = - let open Lwt_result_syntax in - let*? () = check_config configuration in - let* lockfile = lock ~data_dir in - let* () = - Store_migration.maybe_run_migration - ~storage_dir:(Configuration.default_storage_dir data_dir) - in - let dal_cctxt = - Option.map Dal_node_client.make_unix_cctxt dal_node_endpoint - in - let* store = - Store.load - mode - ~l2_blocks_cache_size - Configuration.(default_storage_dir data_dir) - in - let* context = - Context.load mode (Configuration.default_context_dir data_dir) - in - let* () = - Context.Rollup.check_or_set_address mode context sc_rollup_address - in - let publisher = Configuration.Operator_purpose_map.find Publish operators in - let rollup_address = - (* Convert to protocol rollup address *) - Sc_rollup_proto_types.Address.of_octez sc_rollup_address - in - let* protocol_constants = retrieve_constants cctxt - and* lcc = get_last_cemented_commitment cctxt rollup_address - and* lpc = - Option.filter_map_es - (get_last_published_commitment cctxt rollup_address) - publisher - and* kind = - RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () - and* genesis_info = - RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, cctxt#block) rollup_address - in - let*! () = - Event.rollup_exists - ~addr:sc_rollup_address - ~kind:(Sc_rollup_proto_types.Kind.to_octez kind) - in - let*! () = - if dal_cctxt = None && protocol_constants.parametric.dal.feature_enable then - Event.warn_dal_enabled_no_node () - else Lwt.return_unit - in - let*! kernel_debug_logger, kernel_debug_finaliser = - let open Lwt_syntax in - let kernel_debug = Event.kernel_debug in - if configuration.log_kernel_debug then - let+ chan = make_kernel_logger ?log_kernel_debug_file data_dir in - let kernel_debug msg = - let* () = Lwt_io.write chan msg in - let* () = Lwt_io.flush chan in - let* () = kernel_debug msg in - return_unit - in - (kernel_debug, fun () -> Lwt_io.close chan) - else return (kernel_debug, fun () -> return_unit) - in - return - { - cctxt; - dal_cctxt; - data_dir; - l1_ctxt; - rollup_address; - mode = operating_mode; - operators; - genesis_info; - lcc = Reference.new_ lcc; - lpc = Reference.new_ lpc; - kind; - pvm = pvm_of_kind kind; - injector_retention_period = 0; - block_finality_time = 2; - fee_parameters; - protocol_constants; - proto_level; - loser_mode; - lockfile; - store; - context; - kernel_debug_logger; - finaliser = kernel_debug_finaliser; - } - -let close ({cctxt; store; context; l1_ctxt; _} as node_ctxt) = - let open Lwt_result_syntax in - let message = cctxt#message in - let*! () = message "Shutting down L1@." in - let*! () = Layer1.shutdown l1_ctxt in - let*! () = message "Closing context@." in - let*! () = Context.close context in - let*! () = message "Closing store@." in - let* () = Store.close store in - let*! () = message "Releasing lock@." in - let*! () = unlock node_ctxt in - return_unit - -let checkout_context node_ctxt block_hash = - let open Lwt_result_syntax in - let* l2_header = - Store.L2_blocks.header node_ctxt.store.l2_blocks block_hash - in - let*? context_hash = - match l2_header with - | None -> - error (Sc_rollup_node_errors.Cannot_checkout_context (block_hash, None)) - | Some {context; _} -> ok context - in - let*! ctxt = Context.checkout node_ctxt.context context_hash in - match ctxt with - | None -> - tzfail - (Sc_rollup_node_errors.Cannot_checkout_context - (block_hash, Some context_hash)) - | Some ctxt -> return ctxt - -let metadata node_ctxt = - let address = node_ctxt.rollup_address in - let origination_level = node_ctxt.genesis_info.Sc_rollup.Commitment.level in - Sc_rollup.Metadata.{address; origination_level} - -let dal_supported node_ctxt = - node_ctxt.dal_cctxt <> None - && node_ctxt.protocol_constants.parametric.dal.feature_enable - -let readonly (node_ctxt : _ t) = - { - node_ctxt with - store = Store.readonly node_ctxt.store; - context = Context.readonly node_ctxt.context; - lcc = Reference.readonly node_ctxt.lcc; - lpc = Reference.readonly node_ctxt.lpc; - } - -type 'a delayed_write = ('a, rw) Delayed_write_monad.t - -(** Abstraction over store *) - -module Lwt_result_option_syntax = struct - let ( let** ) a f = - let open Lwt_result_syntax in - let* a in - match a with None -> return_none | Some a -> f a -end - -let hash_of_level_opt {store; cctxt; _} level = - let open Lwt_result_syntax in - let* hash = Store.Levels_to_hashes.find store.levels_to_hashes level in - match hash with - | Some hash -> return_some hash - | None -> - let*! hash = - Tezos_shell_services.Shell_services.Blocks.hash - cctxt - ~chain:cctxt#chain - ~block:(`Level level) - () - in - return (Result.to_option hash) - -let hash_of_level node_ctxt level = - let open Lwt_result_syntax in - let* hash = hash_of_level_opt node_ctxt level in - match hash with - | Some h -> return h - | None -> failwith "Cannot retrieve hash of level %ld" level - -let level_of_hash {l1_ctxt; store; _} hash = - let open Lwt_result_syntax in - let* l2_header = Store.L2_blocks.header store.l2_blocks hash in - match l2_header with - | Some {level; _} -> return level - | None -> - let+ {level; _} = Layer1.fetch_tezos_shell_header l1_ctxt hash in - level - -let save_level {store; _} Layer1.{hash; level} = - Store.Levels_to_hashes.add store.levels_to_hashes level hash - -let save_l2_head {store; _} (head : Sc_rollup_block.t) = - let open Lwt_result_syntax in - let head_info = {head with header = (); content = ()} in - let* () = - Store.L2_blocks.append - store.l2_blocks - ~key:head.header.block_hash - ~header:head.header - ~value:head_info - in - Store.L2_head.write store.l2_head head - -let is_processed {store; _} head = Store.L2_blocks.mem store.l2_blocks head - -let last_processed_head_opt {store; _} = Store.L2_head.read store.l2_head - -let mark_finalized_level {store; _} level = - Store.Last_finalized_level.write store.last_finalized_level level - -let get_finalized_level {store; _} = - let open Lwt_result_syntax in - let+ level = Store.Last_finalized_level.read store.last_finalized_level in - Option.value level ~default:0l - -let get_l2_block {store; _} block_hash = - let open Lwt_result_syntax in - let* block = Store.L2_blocks.read store.l2_blocks block_hash in - match block with - | None -> - failwith "Could not retrieve L2 block for %a" Block_hash.pp block_hash - | Some (info, header) -> return {info with Sc_rollup_block.header} - -let find_l2_block {store; _} block_hash = - let open Lwt_result_syntax in - let+ block = Store.L2_blocks.read store.l2_blocks block_hash in - Option.map (fun (info, header) -> {info with Sc_rollup_block.header}) block - -let get_l2_block_by_level node_ctxt level = - let open Lwt_result_syntax in - Error.trace_lwt_result_with "Could not retrieve L2 block at level %ld" level - @@ let* block_hash = hash_of_level node_ctxt level in - get_l2_block node_ctxt block_hash - -let find_l2_block_by_level node_ctxt level = - let open Lwt_result_syntax in - let* block_hash = hash_of_level_opt node_ctxt level in - match block_hash with - | None -> return_none - | Some block_hash -> find_l2_block node_ctxt block_hash - -let get_finalized_head_opt node_ctxt = - let open Lwt_result_syntax in - let* level = - Store.Last_finalized_level.read node_ctxt.store.last_finalized_level - in - match level with - | None -> return_none - | Some level -> find_l2_block_by_level node_ctxt level - -let head_of_block_level (hash, level) = {Layer1.hash; level} - -let block_level_of_head Layer1.{hash; level} = (hash, level) - -let get_l2_block_predecessor node_ctxt hash = - let open Lwt_result_syntax in - let+ header = Store.L2_blocks.header node_ctxt.store.l2_blocks hash in - Option.map - (fun {Sc_rollup_block.predecessor; level; _} -> - (predecessor, Int32.pred level)) - header - -let get_predecessor_opt node_ctxt (hash, level) = - let open Lwt_result_syntax in - let* pred = get_l2_block_predecessor node_ctxt hash in - match pred with - | Some p -> return_some p - | None -> - (* [head] is not already known in the L2 chain *) - Layer1.get_predecessor_opt node_ctxt.l1_ctxt (hash, level) - -let get_predecessor node_ctxt (hash, level) = - let open Lwt_result_syntax in - let* pred = get_l2_block_predecessor node_ctxt hash in - match pred with - | Some p -> return p - | None -> - (* [head] is not already known in the L2 chain *) - Layer1.get_predecessor node_ctxt.l1_ctxt (hash, level) - -let header_of_hash node_ctxt hash = - let open Lwt_result_syntax in - let+ header = Layer1.fetch_tezos_shell_header node_ctxt.l1_ctxt hash in - {Layer1.hash; level = header.level; header} - -let header_of_head node_ctxt Layer1.{hash; level = _} = - header_of_hash node_ctxt hash - -let get_tezos_reorg_for_new_head node_ctxt old_head new_head = - let open Lwt_result_syntax in - let old_head = - match old_head with - | `Level l -> `Level l - | `Head Layer1.{hash; level} -> `Head (hash, level) - in - let+ reorg = - Layer1.get_tezos_reorg_for_new_head - node_ctxt.l1_ctxt - ~get_old_predecessor:(get_predecessor node_ctxt) - old_head - (block_level_of_head new_head) - in - Reorg.map head_of_block_level reorg - -let get_predecessor_opt node_ctxt head = - let open Lwt_result_syntax in - let+ res = get_predecessor_opt node_ctxt (block_level_of_head head) in - Option.map head_of_block_level res - -let get_predecessor node_ctxt head = - let open Lwt_result_syntax in - let+ res = get_predecessor node_ctxt (block_level_of_head head) in - head_of_block_level res - -let get_predecessor_header_opt node_ctxt head = - let open Lwt_result_syntax in - let* res = get_predecessor_opt node_ctxt (Layer1.head_of_header head) in - Option.map_es (header_of_head node_ctxt) res - -let get_predecessor_header node_ctxt head = - let open Lwt_result_syntax in - let* res = get_predecessor node_ctxt (Layer1.head_of_header head) in - header_of_head node_ctxt res - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/4128 - Unit test the function tick_search. *) - -(** Returns the block that is right before [tick]. [big_step_blocks] is used to - first look for a block before the [tick] *) -let tick_search ~big_step_blocks node_ctxt head tick = - let open Lwt_result_syntax in - if Z.Compare.(head.Sc_rollup_block.initial_tick <= tick) then - if Z.Compare.(Sc_rollup_block.final_tick head < tick) then - (* The head block does not contain the tick *) - return_none - else - (* The starting block contains the tick we want, we are done. *) - return_some head - else - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - let rec find_big_step (end_block : Sc_rollup_block.t) = - let start_level = - Int32.sub end_block.header.level (Int32.of_int big_step_blocks) - in - let start_level = - if start_level < genesis_level then genesis_level else start_level - in - let* start_block = get_l2_block_by_level node_ctxt start_level in - if Z.Compare.(start_block.initial_tick <= tick) then - return (start_block, end_block) - else find_big_step start_block - in - let block_level Sc_rollup_block.{header = {level; _}; _} = - Int32.to_int level - in - let rec dicho start_block end_block = - (* Precondition: - [start_block <> end_block => - end_block.initial_tick > tick >= start_block.initial_tick] *) - let start_level = block_level start_block in - let end_level = block_level end_block in - if end_level - start_level <= 1 then - (* We have found the interval where the tick happened *) - return_some start_block - else - let middle_level = start_level + ((end_level - start_level) / 2) in - let* block_middle = - get_l2_block_by_level node_ctxt (Int32.of_int middle_level) - in - if Z.Compare.(block_middle.initial_tick <= tick) then - dicho block_middle end_block - else dicho start_block block_middle - in - (* First linear approximation *) - let* start_block, end_block = find_big_step head in - (* Then do dichotomy on interval [start_block; end_block] *) - dicho start_block end_block - -let block_with_tick ({store; _} as node_ctxt) ~max_level tick = - let open Lwt_result_syntax in - let open Lwt_result_option_syntax in - Error.trace_lwt_result_with - "Could not retrieve block with tick %a" - Sc_rollup.Tick.pp - tick - @@ let** head = Store.L2_head.read store.l2_head in - (* We start by taking big steps of 4096 blocks for the first - approximation. This means we need at most 20 big steps to start a - dichotomy on a 4096 blocks interval (at most 12 steps). We could take - the refutation period as the big_step_blocks to do a dichotomy on the - full space but we anticipate refutation to happen most of the time close - to the head. *) - let max_level = Raw_level.to_int32 max_level in - let** head = - if head.header.level <= max_level then return_some head - else find_l2_block_by_level node_ctxt max_level - in - tick_search ~big_step_blocks:4096 node_ctxt head (Sc_rollup.Tick.to_z tick) - -let find_octez_commitment {store; _} commitment_hash = - let open Lwt_result_syntax in - let+ commitment = Store.Commitments.read store.commitments commitment_hash in - Option.map fst commitment - -let find_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let+ commitment = find_octez_commitment node_ctxt commitment_hash in - Option.map Sc_rollup_proto_types.Commitment.of_octez commitment - -let get_octez_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let* commitment = find_octez_commitment node_ctxt commitment_hash in - match commitment with - | None -> - failwith - "Could not retrieve commitment %a" - Octez_smart_rollup.Commitment.Hash.pp - commitment_hash - | Some i -> return i - -let get_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let* commitment = find_commitment node_ctxt commitment_hash in - match commitment with - | None -> - failwith - "Could not retrieve commitment %a" - Sc_rollup.Commitment.Hash.pp - commitment_hash - | Some i -> return i - -let commitment_exists {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in - Store.Commitments.mem store.commitments hash - -let save_commitment {store; _} commitment = - let open Lwt_result_syntax in - let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in - let hash = Octez_smart_rollup.Commitment.hash commitment in - let+ () = - Store.Commitments.append store.commitments ~key:hash ~value:commitment - in - Sc_rollup_proto_types.Commitment_hash.of_octez hash - -let commitment_published_at_level {store; _} commitment = - let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in - Store.Commitments_published_at_level.find - store.commitments_published_at_level - commitment - -let set_commitment_published_at_level {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in - Store.Commitments_published_at_level.add - store.commitments_published_at_level - hash - -type commitment_source = Anyone | Us - -let commitment_was_published {store; _} ~source commitment_hash = - let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - match source with - | Anyone -> - Store.Commitments_published_at_level.mem - store.commitments_published_at_level - commitment_hash - | Us -> ( - let+ info = - Store.Commitments_published_at_level.find - store.commitments_published_at_level - commitment_hash - in - match info with - | Some {published_at_level = Some _; _} -> true - | _ -> false) - -let find_octez_inbox {store; _} inbox_hash = - let open Lwt_result_syntax in - let+ inbox = Store.Inboxes.read store.inboxes inbox_hash in - Option.map fst inbox - -let find_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in - let+ inbox = find_octez_inbox node_ctxt inbox_hash in - Option.map Sc_rollup_proto_types.Inbox.of_octez inbox - -let get_octez_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let* inbox = find_octez_inbox node_ctxt inbox_hash in - match inbox with - | None -> - failwith - "Could not retrieve inbox %a" - Octez_smart_rollup.Inbox.Hash.pp - inbox_hash - | Some i -> return i - -let get_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let* inbox = find_inbox node_ctxt inbox_hash in - match inbox with - | None -> - failwith "Could not retrieve inbox %a" Sc_rollup.Inbox.Hash.pp inbox_hash - | Some i -> return i - -let save_inbox {store; _} inbox = - let open Lwt_result_syntax in - let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in - let hash = Octez_smart_rollup.Inbox.hash inbox in - let+ () = Store.Inboxes.append store.inboxes ~key:hash ~value:inbox in - Sc_rollup_proto_types.Inbox_hash.of_octez hash - -let find_inbox_by_block_hash ({store; _} as node_ctxt) block_hash = - let open Lwt_result_syntax in - let* header = Store.L2_blocks.header store.l2_blocks block_hash in - match header with - | None -> return_none - | Some {inbox_hash; _} -> - find_inbox - node_ctxt - (Sc_rollup_proto_types.Inbox_hash.of_octez inbox_hash) - -let genesis_inbox node_ctxt = - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - Plugin.RPC.Sc_rollup.inbox - node_ctxt.cctxt - (node_ctxt.cctxt#chain, `Level genesis_level) - -let inbox_of_head node_ctxt Layer1.{hash = block_hash; level = block_level} = - let open Lwt_result_syntax in - let* possible_inbox = find_inbox_by_block_hash node_ctxt block_hash in - (* Pre-condition: forall l. (l > genesis_level) => inbox[l] <> None. *) - match possible_inbox with - | None -> - (* The inbox exists for each tezos block the rollup should care about. - That is, every block after the origination level. We then join - the bandwagon and build the inbox on top of the protocol's inbox - at the end of the origination level. *) - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - if block_level = genesis_level then genesis_inbox node_ctxt - else if block_level > genesis_level then - (* Invariant broken, the inbox for this level should exist. *) - failwith - "The inbox for block hash %a (level = %ld) is missing." - Block_hash.pp - block_hash - block_level - else - (* The rollup node should not care about levels before the genesis - level. *) - failwith - "Asking for the inbox before the genesis level (i.e. %ld), out of \ - the scope of the rollup's node" - block_level - | Some inbox -> return inbox - -let get_inbox_by_block_hash node_ctxt hash = - let open Lwt_result_syntax in - let* level = level_of_hash node_ctxt hash in - inbox_of_head node_ctxt {hash; level} - -type messages_info = { - is_first_block : bool; - predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; -} - -let find_messages node_ctxt messages_hash = - let open Lwt_result_syntax in - let messages_hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez messages_hash - in - let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in - match msg with - | None -> return_none - | Some (messages, block_hash) -> - let* header = header_of_hash node_ctxt block_hash in - let* pred_header = header_of_hash node_ctxt header.header.predecessor in - let* grand_parent_header = - header_of_hash node_ctxt pred_header.header.predecessor - in - let is_first_block = - pred_header.header.proto_level <> grand_parent_header.header.proto_level - in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e - (fun m -> - Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string m)) - messages - in - return_some - { - is_first_block; - predecessor = pred_header.hash; - predecessor_timestamp = pred_header.header.timestamp; - messages; - } - -let get_messages_aux find pp node_ctxt hash = - let open Lwt_result_syntax in - let* res = find node_ctxt hash in - match res with - | None -> - failwith - "Could not retrieve messages with payloads merkelized hash %a" - pp - hash - | Some res -> return res - -let get_messages node_ctxt = - get_messages_aux - find_messages - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.pp - node_ctxt - -let get_messages_without_proto_messages node_ctxt = - get_messages_aux - (fun node_ctxt messages_hash -> - let open Lwt_result_syntax in - let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in - match msg with - | None -> return_none - | Some (messages, _block_hash) -> return_some messages) - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp - node_ctxt - -let get_num_messages {store; _} hash = - let open Lwt_result_syntax in - let hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez hash - in - let* msg = Store.Messages.read store.messages hash in - match msg with - | None -> - failwith - "Could not retrieve number of messages for inbox witness %a" - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp - hash - | Some (messages, _block_hash) -> return (List.length messages) - -let save_messages {store; _} key ~block_hash messages = - let open Lwt_result_syntax in - let key = Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez key in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e Sc_rollup.Inbox_message.serialize messages - in - Store.Messages.append - store.messages - ~key - ~header:block_hash - ~value:(messages :> string list) - -let get_full_l2_block node_ctxt block_hash = - let open Lwt_result_syntax in - let* block = get_l2_block node_ctxt block_hash in - let* inbox = get_octez_inbox node_ctxt block.header.inbox_hash - and* messages = - get_messages_without_proto_messages node_ctxt block.header.inbox_witness - and* commitment = - Option.map_es (get_octez_commitment node_ctxt) block.header.commitment_hash - in - return {block with content = {Sc_rollup_block.inbox; messages; commitment}} - -type proto_info = { - proto_level : int; - first_level_of_protocol : bool; - protocol : Protocol_hash.t; -} - -let protocol_of_level node_ctxt level = - let open Lwt_result_syntax in - assert (level >= Raw_level.to_int32 node_ctxt.genesis_info.level) ; - let* protocols = Store.Protocols.read node_ctxt.store.protocols in - let*? protocols = - match protocols with - | None | Some [] -> - error_with "Cannot infer protocol for level %ld: no protocol info" level - | Some protos -> Ok protos - in - let rec find = function - | [] -> - error_with "Cannot infer protocol for level %ld: no information" level - | {Store.Protocols.level = p_level; proto_level; protocol} :: protos -> ( - (* Latest protocols appear first in the list *) - match p_level with - | First_known l when level >= l -> - Ok {protocol; proto_level; first_level_of_protocol = false} - | Activation_level l when level > l -> - (* The block at the activation level is of the previous protocol, so - we are in the protocol that was activated at [l] only when the - level we query is after [l]. *) - Ok - { - protocol; - proto_level; - first_level_of_protocol = level = Int32.succ l; - } - | _ -> (find [@tailcall]) protos) - in - Lwt.return (find protocols) - -let save_protocol_info node_ctxt (block : Layer1.header) - ~(predecessor : Layer1.header) = - let open Lwt_result_syntax in - let* protocols = Store.Protocols.read node_ctxt.store.protocols in - match protocols with - | Some ({proto_level; _} :: _) - when proto_level = block.header.proto_level - && block.header.proto_level = predecessor.header.proto_level -> - (* Nominal case, no protocol change. Nothing to do. *) - return_unit - | None | Some [] -> - (* No protocols information saved in the rollup node yet, initialize with - information by looking at the current head and its predecessor. - We need to figure out if a protocol upgrade happened in one of these two blocks. - *) - let* {current_protocol; next_protocol} = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (block.hash, 0)) - () - and* { - current_protocol = pred_current_protocol; - next_protocol = pred_next_protocol; - } = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (predecessor.hash, 0)) - () - in - (* The first point in the protocol list is the one regarding - [predecessor]. If it is a migration block we register the activation - level, otherwise we don't go back any further and consider it as the - first known block of the protocol. *) - let pred_proto_info = - Store.Protocols. - { - level = - (if Protocol_hash.(pred_current_protocol = pred_next_protocol) - then First_known predecessor.level - else Activation_level predecessor.level); - proto_level = predecessor.header.proto_level; - protocol = pred_next_protocol; - } - in - let protocols = - if Protocol_hash.(current_protocol = next_protocol) then - (* There is no protocol upgrade in [head], so no new point to add the protocol list. *) - [pred_proto_info] - else - (* [head] is a migration block, add the new protocol with its activation in the list. *) - let proto_info = - Store.Protocols. - { - level = Activation_level block.level; - proto_level = block.header.proto_level; - protocol = next_protocol; - } - in - [proto_info; pred_proto_info] - in - Store.Protocols.write node_ctxt.store.protocols protocols - | Some - ({proto_level = last_proto_level; _} :: previous_protocols as protocols) - -> - (* block.header.proto_level <> last_proto_level or head is a migration - block, i.e. there is a protocol change w.r.t. last registered one. *) - let is_head_migration_block = - block.header.proto_level <> predecessor.header.proto_level - in - let* proto_info = - let+ {next_protocol = protocol; _} = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (block.hash, 0)) - () - in - let level = - if is_head_migration_block then - Store.Protocols.Activation_level block.level - else First_known block.level - in - Store.Protocols. - {level; proto_level = block.header.proto_level; protocol} - in - let protocols = - if block.header.proto_level > last_proto_level then - (* Protocol upgrade, add new item to protocol list *) - proto_info :: protocols - else if block.header.proto_level < last_proto_level then ( - (* Reorganization in which a protocol migration block was - backtracked. *) - match previous_protocols with - | [] -> - (* No info further back, store what we know. *) - [proto_info] - | previous_proto :: _ -> - (* make sure that we are in the case where we backtracked the - migration block. *) - assert ( - Protocol_hash.(proto_info.protocol = previous_proto.protocol)) ; - (* Remove last stored protocol *) - previous_protocols) - else - (* block.header.proto_level = last_proto_level && is_migration_block *) - (* Reorganization where we are doing a different protocol - upgrade. Replace last stored protocol. *) - proto_info :: previous_protocols - in - Store.Protocols.write node_ctxt.store.protocols protocols - -let get_slot_header {store; _} ~published_in_block_hash slot_index = - Error.trace_lwt_result_with - "Could not retrieve slot header for slot index %a published in block %a" - Dal.Slot_index.pp - slot_index - Block_hash.pp - published_in_block_hash - @@ - let open Lwt_result_syntax in - let+ header = - Store.Dal_slots_headers.get - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - in - Sc_rollup_proto_types.Dal.Slot_header.of_octez header - -let get_all_slot_headers {store; _} ~published_in_block_hash = - let open Lwt_result_syntax in - let+ headers = - Store.Dal_slots_headers.list_values - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map Sc_rollup_proto_types.Dal.Slot_header.of_octez headers - |> List.rev - -let get_slot_indexes {store; _} ~published_in_block_hash = - let open Lwt_result_syntax in - let+ indexes = - Store.Dal_slots_headers.list_secondary_keys - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map Sc_rollup_proto_types.Dal.Slot_index.of_octez indexes |> List.rev - -let save_slot_header {store; _} ~published_in_block_hash - (slot_header : Dal.Slot.Header.t) = - Store.Dal_slots_headers.add - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key: - (Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_header.id.index) - (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) - -let find_slot_status {store; _} ~confirmed_in_block_hash slot_index = - Store.Dal_slots_statuses.find - store.irmin_store - ~primary_key:confirmed_in_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - -let list_slots_statuses {store; _} ~confirmed_in_block_hash = - let open Lwt_result_syntax in - let+ statuses = - Store.Dal_slots_statuses.list_secondary_keys_with_values - store.irmin_store - ~primary_key:confirmed_in_block_hash - in - List.rev_map - (fun (index, status) -> - (Sc_rollup_proto_types.Dal.Slot_index.of_octez index, status)) - statuses - |> List.rev - -let save_slot_status {store; _} current_block_hash slot_index status = - Store.Dal_slots_statuses.add - store.irmin_store - ~primary_key:current_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - status - -let find_confirmed_slots_history {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_history.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez res - -let save_confirmed_slots_history {store; _} block hist = - Store.Dal_confirmed_slots_history.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history.to_octez hist) - -let find_confirmed_slots_histories {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_histories.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez res - -let save_confirmed_slots_histories {store; _} block hist = - Store.Dal_confirmed_slots_histories.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez hist) - -module Internal_for_tests = struct - let create_node_context cctxt - ?(constants = Default_parameters.constants_mainnet) ~data_dir kind = - let open Lwt_result_syntax in - let l2_blocks_cache_size = Configuration.default_l2_blocks_cache_size in - let protocol_constants = - constants - |> Data_encoding.Binary.to_bytes_exn Constants.Parametric.encoding - |> Data_encoding.Binary.of_bytes_exn Constants_parametric_repr.encoding - |> Constants_repr.all_of_parametric - |> Data_encoding.Binary.to_bytes_exn Constants_repr.encoding - |> Data_encoding.Binary.of_bytes_exn Constants.encoding - in - let* lockfile = lock ~data_dir in - let* store = - Store.load - Read_write - ~l2_blocks_cache_size - Configuration.(default_storage_dir data_dir) - in - let* context = - Context.load Read_write (Configuration.default_context_dir data_dir) - in - let genesis_info = - Sc_rollup.Commitment.{level = Raw_level.root; commitment_hash = Hash.zero} - in - let l1_ctxt = Layer1.Internal_for_tests.dummy cctxt in - let lcc = - Reference.new_ - {commitment = Sc_rollup.Commitment.Hash.zero; level = Raw_level.root} - in - let lpc = Reference.new_ None in - return - { - cctxt; - dal_cctxt = None; - data_dir; - l1_ctxt; - rollup_address = Sc_rollup.Address.zero; - mode = Observer; - operators = Configuration.Operator_purpose_map.empty; - genesis_info; - lcc; - lpc; - kind; - pvm = pvm_of_kind kind; - injector_retention_period = 0; - block_finality_time = 2; - fee_parameters = Configuration.default_fee_parameters; - protocol_constants; - proto_level = 0; - loser_mode = Loser_mode.no_failures; - lockfile; - store; - context; - kernel_debug_logger = Event.kernel_debug; - finaliser = (fun () -> Lwt.return_unit); - } -end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli deleted file mode 100644 index 21b99c5872a4..000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli +++ /dev/null @@ -1,487 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 TriliTech *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** This module describes the execution context of the node. *) - -open Protocol -open Alpha_context - -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -(** Abstract type for store to force access through this module. *) -type 'a store constraint 'a = [< `Read | `Write > `Read] - -type debug_logger = string -> unit Lwt.t - -type 'a t = { - cctxt : Protocol_client_context.full; - (** Client context used by the rollup node. *) - dal_cctxt : Dal_node_client.cctxt option; - (** DAL client context to query the dal node, if the rollup node supports - the DAL. *) - data_dir : string; (** Node data dir. *) - l1_ctxt : Layer1.t; - (** Layer 1 context to fetch blocks and monitor heads, etc.*) - rollup_address : Sc_rollup.t; (** Smart rollup tracked by the rollup node. *) - mode : Configuration.mode; - (** Mode of the node, see {!Configuration.mode}. *) - operators : Configuration.operators; - (** Addresses of the rollup node operators by purposes. *) - genesis_info : Sc_rollup.Commitment.genesis_info; - (** Origination information of the smart rollup. *) - injector_retention_period : int; - (** Number of blocks the injector will keep information about included - operations. *) - block_finality_time : int; - (** Deterministic block finality time for the layer 1 protocol. *) - kind : Sc_rollup.Kind.t; (** Kind of the smart rollup. *) - pvm : (module Pvm.S); (** The PVM used by the smart rollup. *) - fee_parameters : Configuration.fee_parameters; - (** Fee parameters to use when injecting operations in layer 1. *) - protocol_constants : Constants.t; - (** Protocol constants retrieved from the Tezos node. *) - proto_level : int; - (** Protocol supported by this rollup node (represented as a protocol - level). *) - loser_mode : Loser_mode.t; - (** If different from [Loser_mode.no_failures], the rollup node - issues wrong commitments (for tests). *) - lockfile : Lwt_unix.file_descr; - (** A lock file acquired when the node starts. *) - store : 'a store; (** The store for the persistent storage. *) - context : 'a Context.index; - (** The persistent context for the rollup node. *) - lcc : ('a, lcc) Reference.t; (** Last cemented commitment and its level. *) - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; - (** The last published commitment, i.e. commitment that the operator is - staked on. *) - kernel_debug_logger : debug_logger; - (** Logger used for writing [kernel_debug] messages *) - finaliser : unit -> unit Lwt.t; - (** Aggregation of finalisers to run when the node context closes *) -} - -(** Read/write node context {!t}. *) -type rw = [`Read | `Write] t - -(** Read only node context {!t}. *) -type ro = [`Read] t - -(** [get_operator cctxt purpose] returns the public key hash for the operator - who has purpose [purpose], if any. -*) -val get_operator : - _ t -> Configuration.purpose -> Signature.Public_key_hash.t option - -(** [is_operator cctxt pkh] returns [true] if the public key hash [pkh] is an - operator for the node (for any purpose). *) -val is_operator : _ t -> Signature.Public_key_hash.t -> bool - -(** [is_accuser node_ctxt] returns [true] if the rollup node runs in accuser - mode. *) -val is_accuser : _ t -> bool - -(** [is_loser node_ctxt] returns [true] if the rollup node runs has some - failures planned. *) -val is_loser : _ t -> bool - -(** [get_fee_parameter cctxt purpose] returns the fee parameter to inject an - operation for a given [purpose]. If no specific fee parameters were - configured for this purpose, returns the default fee parameter for this - purpose. -*) -val get_fee_parameter : - _ t -> Configuration.purpose -> Injector_sigs.fee_parameter - -(** Maximum size of an L2 batch in bytes that can fit in an operation of the - protocol. *) -val protocol_max_batch_size : int - -(** [init cctxt ~data_dir mode l1_ctxt ~proto_level configuration] initializes - the rollup representation. The rollup origination level and kind are fetched - via an RPC call to the layer1 node that [cctxt] uses for RPC requests. -*) -val init : - Protocol_client_context.full -> - data_dir:string -> - ?log_kernel_debug_file:string -> - 'a Store_sigs.mode -> - Layer1.t -> - proto_level:int -> - Configuration.t -> - 'a t tzresult Lwt.t - -(** Closes the store, context and Layer 1 monitor. *) -val close : _ t -> unit tzresult Lwt.t - -(** [checkout_context node_ctxt block_hash] returns the context at block - [block_hash]. *) -val checkout_context : 'a t -> Block_hash.t -> 'a Context.t tzresult Lwt.t - -(** [metadata node_ctxt] creates a {Sc_rollup.Metadata.t} using the information - stored in [node_ctxt]. *) -val metadata : _ t -> Sc_rollup.Metadata.t - -(** Returns [true] if the rollup node supports the DAL and if DAL is enabled for - the current protocol. *) -val dal_supported : _ t -> bool - -(** [readonly node_ctxt] returns a read only version of the node context - [node_ctxt]. *) -val readonly : _ t -> ro - -(** Monad for values with delayed write effects in the node context. *) -type 'a delayed_write = ('a, rw) Delayed_write_monad.t - -(** {2 Abstraction over store} *) - -(** {3 Layer 2 blocks} *) - -(** [is_processed store hash] returns [true] if the block with [hash] has - already been processed by the daemon. *) -val is_processed : _ t -> Block_hash.t -> bool tzresult Lwt.t - -(** [get_l2_block t hash] returns the Layer 2 block known by the rollup node for - Layer 1 block [hash]. *) -val get_l2_block : _ t -> Block_hash.t -> Sc_rollup_block.t tzresult Lwt.t - -(** Same as {!get_l2_block} but returns [None] when the Layer 2 block is not - available. *) -val find_l2_block : - _ t -> Block_hash.t -> Sc_rollup_block.t option tzresult Lwt.t - -(** Same as {!get_l2_block} but retrieves the Layer 2 block by its level. *) -val get_l2_block_by_level : _ t -> int32 -> Sc_rollup_block.t tzresult Lwt.t - -(** Same as {!get_l2_block_by_level} but returns [None] when the Layer 2 block - is not available. *) -val find_l2_block_by_level : - _ t -> int32 -> Sc_rollup_block.t option tzresult Lwt.t - -(** [get_full_l2_block node_ctxt hash] returns the full L2 block for L1 block - hash [hash]. The result contains the L2 block and its content (inbox, - messages, commitment). *) -val get_full_l2_block : - _ t -> Block_hash.t -> Sc_rollup_block.full tzresult Lwt.t - -(** [save_level t head] registers the correspondences [head.level |-> - head.hash] in the store. *) -val save_level : rw -> Layer1.head -> unit tzresult Lwt.t - -(** [save_l2_head t l2_block] remembers that the [l2_block.head] is - processed. The system should not have to come back to it. *) -val save_l2_head : rw -> Sc_rollup_block.t -> unit tzresult Lwt.t - -(** [last_processed_head_opt store] returns the last processed head if it - exists. *) -val last_processed_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t - -(** [mark_finalized_head store head] remembers that the [head] is finalized. By - construction, every block whose level is smaller than [head]'s is also - finalized. *) -val mark_finalized_level : rw -> int32 -> unit tzresult Lwt.t - -(** [get_finalized_level t] returns the last finalized level. *) -val get_finalized_level : _ t -> int32 tzresult Lwt.t - -(** [get_finalized_head_opt store] returns the last finalized head if it exists. *) -val get_finalized_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t - -(** [hash_of_level node_ctxt level] returns the current block hash for a given - [level]. *) -val hash_of_level : _ t -> int32 -> Block_hash.t tzresult Lwt.t - -(** [hash_of_level_opt] is like {!hash_of_level} but returns [None] if the - [level] is not known. *) -val hash_of_level_opt : _ t -> int32 -> Block_hash.t option tzresult Lwt.t - -(** [level_of_hash node_ctxt hash] returns the level for Tezos block hash [hash] - if it is known by the Tezos Layer 1 node. *) -val level_of_hash : _ t -> Block_hash.t -> int32 tzresult Lwt.t - -(** [get_predecessor_opt state head] returns the predecessor of block [head], - when [head] is not the genesis block. *) -val get_predecessor_opt : - _ t -> Layer1.head -> Layer1.head option tzresult Lwt.t - -(** [get_predecessor state head] returns the predecessor block of [head]. *) -val get_predecessor : _ t -> Layer1.head -> Layer1.head tzresult Lwt.t - -(** Same as {!get_predecessor_opt} with headers. *) -val get_predecessor_header_opt : - _ t -> Layer1.header -> Layer1.header option tzresult Lwt.t - -(** Same as {!get_predecessor} with headers. *) -val get_predecessor_header : - _ t -> Layer1.header -> Layer1.header tzresult Lwt.t - -(** [get_tezos_reorg_for_new_head node_ctxt old_head new_head] returns the L1 - reorganization between [old_head] and [new_head]. *) -val get_tezos_reorg_for_new_head : - _ t -> - [`Head of Layer1.head | `Level of int32] -> - Layer1.head -> - Layer1.head Reorg.t tzresult Lwt.t - -(** [block_with_tick store ~max_level tick] returns [Some b] where [b] is the - last layer 2 block which contains the [tick] before [max_level]. If no such - block exists (the tick happened after [max_level], or we are too late), the - function returns [None]. *) -val block_with_tick : - _ t -> - max_level:Raw_level.t -> - Sc_rollup.Tick.t -> - Sc_rollup_block.t option tzresult Lwt.t - -(** {3 Commitments} *) - -(** [get_commitment t hash] returns the commitment with [hash] stored by the - rollup node. *) -val get_commitment : - _ t -> Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t tzresult Lwt.t - -(** Same as {!get_commitment} but returns [None] if this commitment hash is not - known by the rollup node. *) -val find_commitment : - _ t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.t option tzresult Lwt.t - -(** [commitment_exists t hash] returns [true] if the commitment with [hash] is - known (i.e. stored) by the rollup node. *) -val commitment_exists : - _ t -> Sc_rollup.Commitment.Hash.t -> bool tzresult Lwt.t - -(** [save_commitment t commitment] saves a commitment in the store an returns is - hash. *) -val save_commitment : - rw -> Sc_rollup.Commitment.t -> Sc_rollup.Commitment.Hash.t tzresult Lwt.t - -(** [commitment_published_at_level t hash] returns the levels at which the - commitment was first published and the one at which it was included by in a - Layer 1 block. It returns [None] if the commitment is not known by the - rollup node or if it was never published by the rollup node (and included on - L1). *) -val commitment_published_at_level : - _ t -> - Sc_rollup.Commitment.Hash.t -> - Store.Commitments_published_at_level.element option tzresult Lwt.t - -(** [save_commitment_published_at_level t hash levels] saves the - publication/inclusion information for a commitment with [hash]. *) -val set_commitment_published_at_level : - rw -> - Sc_rollup.Commitment.Hash.t -> - Store.Commitments_published_at_level.element -> - unit tzresult Lwt.t - -type commitment_source = Anyone | Us - -(** [commitment_was_published t hash] returns [true] if the commitment is known - as being already published on L1. The [source] indicates if we want to know - the publication status for commitments we published ourselves [`Us] or that - [`Anyone] published. *) -val commitment_was_published : - _ t -> - source:commitment_source -> - Sc_rollup.Commitment.Hash.t -> - bool tzresult Lwt.t - -(** {3 Inboxes} *) - -type messages_info = { - is_first_block : bool; - predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; -} - -(** [get_inbox t inbox_hash] retrieves the inbox whose hash is [inbox_hash] from - the rollup node's storage. *) -val get_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** Same as {!get_inbox} but returns [None] if this inbox is not known. *) -val find_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t option tzresult Lwt.t - -(** [save_inbox t inbox] remembers the [inbox] in the storage. It is associated - to its hash which is returned. *) -val save_inbox : - rw -> Sc_rollup.Inbox.t -> Sc_rollup.Inbox.Hash.t tzresult Lwt.t - -(** [inbox_of_head node_ctxt block] returns the latest inbox at the given - [block]. This function always returns [inbox] for all levels at and - after the rollup genesis. NOTE: It requires the L2 block for [block.hash] to - have been saved. *) -val inbox_of_head : _ t -> Layer1.head -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** Same as {!get_inbox} but uses the Layer 1 block hash for this inbox instead. *) -val get_inbox_by_block_hash : - _ t -> Block_hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [genesis_inbox t] is the genesis inbox for the rollup [t.sc_rollup_address]. *) -val genesis_inbox : _ t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [get_messages t witness_hash] retrieves the messages for the merkelized - payloads hash [witness_hash] stored by the rollup node. *) -val get_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info tzresult Lwt.t - -(** Same as {!get_messages} but returns [None] if the payloads hash is not known. *) -val find_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info option tzresult Lwt.t - -(** [get_num_messages t witness_hash] retrieves the number of messages for the - inbox witness [witness_hash] stored by the rollup node. *) -val get_num_messages : - _ t -> Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> int tzresult Lwt.t - -(** [save_messages t payloads_hash ~block_hash messages] associates the list of - [messages] to the [payloads_hash]. The payload hash must be computed by - calling, e.g. {!Sc_rollup.Inbox.add_all_messages}. *) -val save_messages : - rw -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - block_hash:Block_hash.t -> - Sc_rollup.Inbox_message.t list -> - unit tzresult Lwt.t - -(** Return values for {!protocol_of_level}. *) -type proto_info = { - proto_level : int; - (** Protocol level for operations of block (can be different from L1 - header value in the case of a migration block). *) - first_level_of_protocol : bool; - (** [true] if the level is the first of the protocol. *) - protocol : Protocol_hash.t; - (** Hash of the {e current} protocol for this level. *) -} - -(** [protocol_of_level t level] returns the protocol of block level [level]. *) -val protocol_of_level : _ t -> int32 -> proto_info 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]. *) -val save_protocol_info : - rw -> Layer1.header -> predecessor:Layer1.header -> unit tzresult Lwt.t - -(** {3 DAL} *) - -(** [get_slot_header t ~published_in_block_hash slot_index] returns the slot - header for the [slot_index] that was published in the provided block hash on - Layer 1. *) -val get_slot_header : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot_index.t -> - Dal.Slot.Header.t tzresult Lwt.t - -(** [get_all_slot_headers t ~published_in_block_hash] returns the slot headers - for all the slots that were published in the provided block hash on Layer - 1. *) -val get_all_slot_headers : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t list tzresult Lwt.t - -(** [get_slot_indexes t ~published_in_block_hash] returns the slot indexes whose - headers were published in the provided block hash on Layer 1. *) -val get_slot_indexes : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot_index.t list tzresult Lwt.t - -(** [save_slot_header t ~published_in_block_hash header] saves the [header] as - being published for its index in the provided block hash on Layer 1. *) -val save_slot_header : - rw -> - published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t -> - unit tzresult Lwt.t - -(** [find_slot_status t ~confirmed_in_block_hash index] returns [None] if the - slot's block is not processed yet, [Some `Unconfirmed] if the slot was not - confirmed and [Some `Confirmed] if the slot is confirmed and the associated - pages are available. *) -val find_slot_status : - _ t -> - confirmed_in_block_hash:Block_hash.t -> - Dal.Slot_index.t -> - [`Unconfirmed | `Confirmed] option tzresult Lwt.t - -(** [list_slots_statuses t ~confirmed_in_block_hash] lists the list of - slots indices with their respective statuses that are saved for the given - [confirmed_in_block_hash] *) -val list_slots_statuses : - _ t -> - confirmed_in_block_hash:Block_hash.t -> - (Dal.Slot_index.t * [`Confirmed | `Unconfirmed]) list tzresult Lwt.t - -(** [save_slot_status node_ctxt hash slot_index status] saves in - [node_ctxt.store] that [slot_index] has status [status] in the - block with hash in [node_ctxt.store]. -*) -val save_slot_status : - rw -> - Block_hash.t -> - Dal.Slot_index.t -> - [`Confirmed | `Unconfirmed] -> - unit tzresult Lwt.t - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/4636 - Missing docstrings. *) - -val find_confirmed_slots_history : - _ t -> Block_hash.t -> Dal.Slots_history.t option tzresult Lwt.t - -val save_confirmed_slots_history : - rw -> Block_hash.t -> Dal.Slots_history.t -> unit tzresult Lwt.t - -val find_confirmed_slots_histories : - _ t -> Block_hash.t -> Dal.Slots_history.History_cache.t option tzresult Lwt.t - -val save_confirmed_slots_histories : - rw -> Block_hash.t -> Dal.Slots_history.History_cache.t -> unit tzresult Lwt.t - -(**/**) - -module Internal_for_tests : sig - (** Create a node context which really stores data on disk but does not - connect to any layer 1 node. It is meant to be used in unit tests for the - rollup node functions. *) - val create_node_context : - Protocol_client_context.full -> - ?constants:Constants.Parametric.t -> - data_dir:string -> - Sc_rollup.Kind.t -> - Store_sigs.rw t tzresult Lwt.t -end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.ml index a76f94397d5e..e9a3abe628fa 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.ml @@ -24,14 +24,11 @@ (*****************************************************************************) open Node_context -open Protocol.Alpha_context let get_state_of_lcc node_ctxt = let open Lwt_result_syntax in let lcc = Reference.get node_ctxt.lcc in - let* block_hash = - Node_context.hash_of_level node_ctxt (Raw_level.to_int32 lcc.level) - in + let* block_hash = Node_context.hash_of_level node_ctxt lcc.level in let* ctxt = Node_context.checkout_context node_ctxt block_hash in let*! state = Context.PVMState.find ctxt in return state @@ -48,7 +45,7 @@ let proof_of_output node_ctxt output = *) failwith "Error producing outbox proof (no cemented state in the node)" | Some state -> ( - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! proof = PVM.produce_output_proof node_ctxt.context state output in match proof with | Ok proof -> diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.mli index 71e8c4a1f28d..1b172b048f4b 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/outbox.mli @@ -32,4 +32,4 @@ open Protocol.Alpha_context val proof_of_output : Node_context.rw -> Sc_rollup.output -> - (Sc_rollup.Commitment.Hash.t * string) tzresult Lwt.t + (Octez_smart_rollup.Commitment.Hash.t * string) tzresult Lwt.t diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.ml index e556dc6b9f31..eb26ecbd21ce 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.ml @@ -63,20 +63,20 @@ end let add_level level increment = (* We only use this function with positive increments so it is safe *) if increment < 0 then invalid_arg "Commitment.add_level negative increment" ; - Raw_level.Internal_for_tests.add level increment + Int32.add level (Int32.of_int increment) let sub_level level decrement = (* We only use this function with positive increments so it is safe *) if decrement < 0 then invalid_arg "Commitment.sub_level negative decrement" ; - Raw_level.Internal_for_tests.sub level decrement + let r = Int32.sub level (Int32.of_int decrement) in + if r < 0l then None else Some r let sc_rollup_commitment_period node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup + node_ctxt.Node_context.protocol_constants.sc_rollup .commitment_period_in_blocks let sc_rollup_challenge_window node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup - .challenge_window_in_blocks + node_ctxt.Node_context.protocol_constants.sc_rollup.challenge_window_in_blocks let next_commitment_level node_ctxt last_commitment_level = add_level last_commitment_level (sc_rollup_commitment_period node_ctxt) @@ -85,55 +85,47 @@ type state = Node_context.ro let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Lwt_result_syntax in - let* block = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 inbox_level) - in + let* block = Node_context.get_l2_block_by_level node_ctxt inbox_level in return (Sc_rollup_block.final_tick block) let build_commitment (node_ctxt : _ Node_context.t) - (prev_commitment : Sc_rollup.Commitment.Hash.t) ~prev_commitment_level - ~inbox_level ctxt = + (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) + ~prev_commitment_level ~inbox_level ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with | Some pvm_state -> Ok pvm_state | None -> error_with - "PVM state for commitment at level %a is not available" - Raw_level.pp + "PVM state for commitment at level %ld is not available" inbox_level in let*! compressed_state = PVM.state_hash pvm_state in let*! tick = PVM.get_tick pvm_state in let* prev_commitment_tick = tick_of_level node_ctxt prev_commitment_level in let distance = Z.sub (Sc_rollup.Tick.to_z tick) prev_commitment_tick in - let number_of_ticks = - distance |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value - in - let*? number_of_ticks = - match number_of_ticks with - | Some number_of_ticks -> - if number_of_ticks = Sc_rollup.Number_of_ticks.zero then - error_with "A 0-tick commitment is impossible" - else Ok number_of_ticks - | None -> error_with "Invalid number of ticks for commitment" + let number_of_ticks = Z.to_int64 distance in + let*? () = + if number_of_ticks = 0L then error_with "A 0-tick commitment is impossible" + else if number_of_ticks < 0L then + error_with "Invalid number of ticks for commitment" + else Ok () in return - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = prev_commitment; inbox_level; number_of_ticks; - compressed_state; + compressed_state = + Sc_rollup_proto_types.State_hash.to_octez compressed_state; } let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with @@ -142,29 +134,27 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = in let*! compressed_state = PVM.state_hash pvm_state in let commitment = - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = Hash.zero; inbox_level = node_ctxt.genesis_info.level; - number_of_ticks = Sc_rollup.Number_of_ticks.zero; - compressed_state; + number_of_ticks = 0L; + compressed_state = + Sc_rollup_proto_types.State_hash.to_octez compressed_state; } in (* Ensure the initial state corresponds to the one of the rollup's in the protocol. A mismatch is possible if a wrong external boot sector was provided. *) - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let+ () = fail_unless - Sc_rollup.Commitment.Hash.( + Octez_smart_rollup.Commitment.Hash.( commitment_hash = node_ctxt.genesis_info.commitment_hash) (Sc_rollup_node_errors.Invalid_genesis_state { - expected = - Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.commitment_hash; - actual = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; + expected = node_ctxt.genesis_info.commitment_hash; + actual = commitment_hash; }) in commitment @@ -172,7 +162,7 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor current_level ctxt = let open Lwt_result_syntax in - if Raw_level.(current_level = node_ctxt.genesis_info.level) then + if current_level = node_ctxt.genesis_info.level then let*! () = Commitment_event.compute_commitment current_level in let+ genesis_commitment = genesis_commitment node_ctxt ctxt in Some genesis_commitment @@ -180,7 +170,6 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let* last_commitment_hash = let+ pred = Node_context.get_l2_block node_ctxt predecessor in Sc_rollup_block.most_recent_commitment pred.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let* last_commitment = Node_context.get_commitment node_ctxt last_commitment_hash @@ -188,7 +177,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let next_commitment_level = next_commitment_level node_ctxt last_commitment.inbox_level in - if Raw_level.(current_level = next_commitment_level) then + if current_level = next_commitment_level then let*! () = Commitment_event.compute_commitment current_level in let+ commitment = build_commitment @@ -204,7 +193,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let process_head (node_ctxt : _ Node_context.t) ~predecessor Layer1.{level; header = _; _} ctxt = let open Lwt_result_syntax in - let current_level = Raw_level.of_int32_exn level in + let current_level = level in let* commitment = create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt in @@ -230,15 +219,15 @@ let missing_commitments (node_ctxt : _ Node_context.t) = let sc_rollup_challenge_window_int32 = sc_rollup_challenge_window node_ctxt |> Int32.of_int in - let rec gather acc (commitment_hash : Sc_rollup.Commitment.Hash.t) = + let rec gather acc (commitment_hash : Octez_smart_rollup.Commitment.Hash.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in let lcc = Reference.get node_ctxt.lcc in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* Commitment is before or at the LCC, we have reached the end. *) return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lpc_level) -> + | Some commitment when commitment.inbox_level <= lpc_level -> (* Commitment is before the last published one, we have also reached the end because we only publish commitments that are for the inbox of a finalized L1 block. *) @@ -266,23 +255,18 @@ let missing_commitments (node_ctxt : _ Node_context.t) = commitments that are missing. *) let commitment = Sc_rollup_block.most_recent_commitment finalized.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in gather [] commitment let publish_commitment (node_ctxt : _ Node_context.t) ~source - (commitment : Sc_rollup.Commitment.t) = + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let publish_operation = - L1_operation.Publish - { - rollup = Sc_rollup_proto_types.Address.to_octez node_ctxt.rollup_address; - commitment = Sc_rollup_proto_types.Commitment.to_octez commitment; - } + L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} in let*! () = Commitment_event.publish_commitment - (Sc_rollup.Commitment.hash_uncarbonated commitment) + (Octez_smart_rollup.Commitment.hash commitment) commitment.inbox_level in let* _hash = Injector.add_pending_operation ~source publish_operation in @@ -303,7 +287,8 @@ let on_publish_commitments (node_ctxt : state) = let* commitments = missing_commitments node_ctxt in List.iter_es (publish_commitment node_ctxt ~source) commitments -let publish_single_commitment node_ctxt (commitment : Sc_rollup.Commitment.t) = +let publish_single_commitment node_ctxt + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let operator = Node_context.get_operator node_ctxt Publish in let lcc = Reference.get node_ctxt.lcc in @@ -338,26 +323,20 @@ let earliest_cementing_level node_ctxt commitment_hash = let latest_cementable_commitment (node_ctxt : _ Node_context.t) (head : Sc_rollup_block.t) = let open Lwt_result_option_syntax in - let commitment_hash = - Sc_rollup_block.most_recent_commitment head.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez - in + let commitment_hash = Sc_rollup_block.most_recent_commitment head.header in let** commitment = Node_context.find_commitment node_ctxt commitment_hash in let** cementable_level_bound = return @@ sub_level commitment.inbox_level (sc_rollup_challenge_window node_ctxt) in let lcc = Reference.get node_ctxt.lcc in - if Raw_level.(cementable_level_bound <= lcc.level) then return_none + if cementable_level_bound <= lcc.level then return_none else let** cementable_bound_block = - Node_context.find_l2_block_by_level - node_ctxt - (Raw_level.to_int32 cementable_level_bound) + Node_context.find_l2_block_by_level node_ctxt cementable_level_bound in let cementable_commitment = Sc_rollup_block.most_recent_commitment cementable_bound_block.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in return_some cementable_commitment @@ -367,11 +346,11 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = let*& head = Node_context.last_processed_head_opt node_ctxt in let head_level = head.header.level in let lcc = Reference.get node_ctxt.lcc in - let rec gather acc (commitment_hash : Sc_rollup.Commitment.Hash.t) = + let rec gather acc (commitment_hash : Octez_smart_rollup.Commitment.Hash.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* If we have moved backward passed or at the current LCC then we have reached the end. *) return acc @@ -406,10 +385,10 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = Layer 1 node as a failsafe. *) let* green_light = Plugin.RPC.Sc_rollup.can_be_cemented - node_ctxt.cctxt + (new Protocol_client_context.wrap_full node_ctxt.cctxt) (node_ctxt.cctxt#chain, `Head 0) - node_ctxt.rollup_address - first_cementable + (Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address) + (Sc_rollup_proto_types.Commitment_hash.of_octez first_cementable) in if green_light then return cementable else return_nil @@ -417,11 +396,7 @@ let cement_commitment (node_ctxt : _ Node_context.t) ~source commitment_hash = let open Lwt_result_syntax in let cement_operation = L1_operation.Cement - { - rollup = Sc_rollup_proto_types.Address.to_octez node_ctxt.rollup_address; - commitment = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; - } + {rollup = node_ctxt.rollup_address; commitment = commitment_hash} in let* _hash = Injector.add_pending_operation ~source cement_operation in return_unit diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.mli index 79990b2198ad..36c8c655ece7 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.mli @@ -50,16 +50,14 @@ val process_head : predecessor:Block_hash.t -> Layer1.header -> Context.rw -> - Protocol.Alpha_context.Sc_rollup.Commitment.Hash.t option tzresult Lwt.t + Octez_smart_rollup.Commitment.Hash.t option tzresult Lwt.t (** [publish_single_commitment node_ctxt commitment] publishes a single [commitment] if it is missing. This function is meant to be used by the {e accuser} mode to sparingly publish commitments when it detects a conflict. *) val publish_single_commitment : - _ Node_context.t -> - Protocol.Alpha_context.Sc_rollup.Commitment.t -> - unit tzresult Lwt.t + _ Node_context.t -> Octez_smart_rollup.Commitment.t -> unit tzresult Lwt.t (** Initialize worker for publishing and cementing commitments. *) val init : _ Node_context.t -> unit tzresult Lwt.t diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml index 9409ed42d2e4..e71be750758e 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml @@ -24,78 +24,8 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +module type S = Pvm_sig.S -(** Desired module type of a PVM from the L2 node's perspective *) -module type S = sig - include - Sc_rollup.PVM.S - with type context = Context.rw_index - and type state = Context.tree - and type hash = Sc_rollup.State_hash.t - - (** Kind of the PVM (same as {!name}). *) - val kind : Sc_rollup.Kind.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) - val get_tick : state -> Sc_rollup.Tick.t Lwt.t - - (** PVM status *) - type status - - (** [get_status state] gives you the current execution status for the PVM. *) - val get_status : state -> status Lwt.t - - (** [string_of_status status] returns a string representation of [status]. *) - val string_of_status : status -> string - - (** [get_outbox outbox_level state] returns a list of outputs - available in the outbox of [state] at a given [outbox_level]. *) - val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t - - (** [eval_many ~max_steps s0] returns a state [s1] resulting from the - execution of up to [~max_steps] steps of the rollup at state [s0]. *) - val eval_many : - reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> - write_debug:Tezos_scoru_wasm.Builtins.write_debug -> - ?stop_at_snapshot:bool -> - max_steps:int64 -> - state -> - (state * int64) Lwt.t - - val new_dissection : - default_number_of_sections:int -> - start_chunk:Sc_rollup.Dissection_chunk.t -> - our_stop_chunk:Sc_rollup.Dissection_chunk.t -> - Sc_rollup.Tick.t list - - (** State storage for this PVM. *) - module State : sig - (** [empty ()] is the empty state. *) - val empty : unit -> state - - (** [find context] returns the PVM state stored in the [context], if any. *) - val find : _ Context.t -> state option Lwt.t - - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - - (** [set context state] saves the PVM state [state] in the context and - returns the updated context. Note: [set] does not perform any write on - disk, this information must be committed using {!Context.commit}. *) - val set : 'a Context.t -> state -> 'a Context.t Lwt.t - end - - (** Inspect durable state using a more specialised way of reading the - PVM state. - For example in WASM, it decodes the durable storage in the state - before reading values. - *) - module Inspect_durable_state : sig - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - end -end +let of_kind : Kind.t -> (module S) = function + | Example_arith -> (module Arith_pvm) + | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_rpc.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_rpc.ml index 06c5c60b5e51..a8d946e87b6a 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_rpc.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_rpc.ml @@ -35,6 +35,6 @@ end let no_rpc = (module No_rpc : S) let of_kind = function - | Protocol.Alpha_context.Sc_rollup.Kind.Example_arith -> no_rpc + | Kind.Example_arith -> no_rpc | Wasm_2_0_0 -> (module Wasm_2_0_0_rpc.Make_RPC (Wasm_2_0_0_pvm.Durable_state) : S) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_sig.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_sig.ml new file mode 100644 index 000000000000..178664995c5f --- /dev/null +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm_sig.ml @@ -0,0 +1,101 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022-2023 TriliTech *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** Desired module type of a PVM from the L2 node's perspective *) +module type S = sig + include + Sc_rollup.PVM.S + with type context = Context.rw_index + and type state = Context.tree + and type hash = Sc_rollup.State_hash.t + + (** Kind of the PVM. *) + val kind : Sc_rollup.Kind.t + + (** [get_tick state] gets the total tick counter for the given PVM state. *) + val get_tick : state -> Sc_rollup.Tick.t Lwt.t + + (** PVM status *) + type status + + (** [get_status state] gives you the current execution status for the PVM. *) + val get_status : state -> status Lwt.t + + (** [string_of_status status] returns a string representation of [status]. *) + val string_of_status : status -> string + + (** [get_outbox outbox_level state] returns a list of outputs + available in the outbox of [state] at a given [outbox_level]. *) + val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t + + (** [eval_many ~max_steps s0] returns a state [s1] resulting from the + execution of up to [~max_steps] steps of the rollup at state [s0]. *) + val eval_many : + reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> + write_debug:Tezos_scoru_wasm.Builtins.write_debug -> + ?stop_at_snapshot:bool -> + max_steps:int64 -> + state -> + (state * int64) Lwt.t + + val new_dissection : + default_number_of_sections:int -> + start_chunk:Sc_rollup.Dissection_chunk.t -> + our_stop_chunk:Sc_rollup.Dissection_chunk.t -> + Sc_rollup.Tick.t list + + (** State storage for this PVM. *) + module State : sig + (** [empty ()] is the empty state. *) + val empty : unit -> state + + (** [find context] returns the PVM state stored in the [context], if any. *) + val find : _ Context.t -> state option Lwt.t + + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + + (** [set context state] saves the PVM state [state] in the context and + returns the updated context. Note: [set] does not perform any write on + disk, this information must be committed using {!val:Context.commit}. *) + val set : 'a Context.t -> state -> 'a Context.t Lwt.t + end + + (** Inspect durable state using a more specialised way of reading the + PVM state. + For example in WASM, it decodes the durable storage in the state + before reading values. + *) + module Inspect_durable_state : sig + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + end +end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_coordinator.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_coordinator.ml index b841d2e7353c..5762f752126c 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_coordinator.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_coordinator.ml @@ -31,13 +31,25 @@ module Player = Refutation_player module Pkh_map = Signature.Public_key_hash.Map module Pkh_table = Signature.Public_key_hash.Table -type state = {node_ctxt : Node_context.rw; pending_opponents : unit Pkh_table.t} - -let get_conflicts cctxt head_block = - Plugin.RPC.Sc_rollup.conflicts cctxt (cctxt#chain, head_block) - -let get_ongoing_games cctxt head_block = - Plugin.RPC.Sc_rollup.ongoing_refutation_games cctxt (cctxt#chain, head_block) +type state = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + pending_opponents : unit Pkh_table.t; +} + +let get_conflicts cctxt head_block address key = + Plugin.RPC.Sc_rollup.conflicts + cctxt + (cctxt#chain, head_block) + (Sc_rollup_proto_types.Address.of_octez address) + key + +let get_ongoing_games cctxt head_block address key = + Plugin.RPC.Sc_rollup.ongoing_refutation_games + cctxt + (cctxt#chain, head_block) + (Sc_rollup_proto_types.Address.of_octez address) + key let untracked_conflicts opponent_players conflicts = List.filter @@ -72,9 +84,11 @@ let on_process Layer1.{hash; level} state = (* Not injecting refutations, don't play refutation games *) return_unit | Some self -> - let Node_context.{rollup_address; cctxt; _} = node_ctxt in + let Node_context.{rollup_address; _} = node_ctxt in (* Current conflicts in L1 *) - let* conflicts = get_conflicts cctxt head_block rollup_address self in + let* conflicts = + get_conflicts state.cctxt head_block rollup_address self + in (* Map of opponents the node is playing against to the corresponding player worker *) let opponent_players = @@ -85,7 +99,7 @@ let on_process Layer1.{hash; level} state = let new_conflicts = untracked_conflicts opponent_players conflicts in (* L1 ongoing games *) let* ongoing_games = - get_ongoing_games cctxt head_block rollup_address self + get_ongoing_games state.cctxt head_block rollup_address self in (* Map between opponents and their corresponding games *) let ongoing_game_map = make_game_map self ongoing_games in @@ -121,7 +135,10 @@ let on_process Layer1.{hash; level} state = module Types = struct type nonrec state = state - type parameters = {node_ctxt : Node_context.rw} + type parameters = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + } end module Name = struct @@ -157,8 +174,8 @@ module Handlers = struct type launch_error = error trace - let on_launch _w () Types.{node_ctxt} = - return {node_ctxt; pending_opponents = Pkh_table.create 5} + let on_launch _w () Types.{node_ctxt; cctxt} = + return {node_ctxt; cctxt; pending_opponents = Pkh_table.create 5} let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : unit tzresult Lwt.t = @@ -187,7 +204,10 @@ let worker_promise, worker_waker = Lwt.task () let init node_ctxt = let open Lwt_result_syntax in let*! () = Refutation_game_event.Coordinator.starting () in - let+ worker = Worker.launch table () {node_ctxt} (module Handlers) in + let cctxt = + new Protocol_client_context.wrap_full node_ctxt.Node_context.cctxt + in + let+ worker = Worker.launch table () {node_ctxt; cctxt} (module Handlers) in Lwt.wakeup worker_waker worker (* This is a refutation coordinator for a single scoru *) 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 c5d09dda2a1d..66f4dc534390 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 @@ -71,9 +71,7 @@ let inject_next_move node_ctxt source ~refutation ~opponent = let refute_operation = L1_operation.Refute { - rollup = - Sc_rollup_proto_types.Address.to_octez - node_ctxt.Node_context.rollup_address; + rollup = node_ctxt.Node_context.rollup_address; refutation = Sc_rollup_proto_types.Game.refutation_to_octez refutation; opponent; } @@ -122,7 +120,7 @@ let page_membership_proof params page_index slot_data = let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag (dal_params : Dal.parameters) start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! input_request = PVM.is_input_state start_state in match input_request with | Sc_rollup.(Needs_reveal (Request_dal_page page_id)) -> ( @@ -154,9 +152,16 @@ let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag pages_per_slot)) | _ -> return_none +let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = Raw_level.of_int32_exn node_ctxt.genesis_info.level in + Sc_rollup.Metadata.{address; origination_level} + let generate_proof (node_ctxt : _ Node_context.t) game start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let snapshot = game.inbox_snapshot in (* NOTE: [snapshot_level_int32] below refers to the level of the snapshotted inbox (from the skip list) which also matches [game.start_level - 1]. *) @@ -191,7 +196,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let* parametric_constants = let cctxt = node_ctxt.cctxt in Protocol.Constants_services.parametric - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, `Level snapshot_level_int32) in let dal_l1_parameters = parametric_constants.dal in @@ -215,7 +220,10 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let reveal hash = let open Lwt_syntax in let* res = - Reveals.get ~data_dir:node_ctxt.data_dir ~pvm_kind:PVM.kind ~hash + Reveals.get + ~data_dir:node_ctxt.data_dir + ~pvm_kind:(Sc_rollup_proto_types.Kind.to_octez PVM.kind) + ~hash in match res with Ok data -> return @@ Some data | Error _ -> return None @@ -224,7 +232,11 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let get_history inbox_hash = let open Lwt_syntax in - let+ inbox = Node_context.find_inbox node_ctxt inbox_hash in + let+ inbox = + Node_context.find_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash) + in match inbox with | Error err -> Format.kasprintf @@ -234,7 +246,12 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = inbox_hash pp_print_trace err - | Ok inbox -> Option.map Sc_rollup.Inbox.take_snapshot inbox + | Ok inbox -> + Option.map + (fun i -> + Sc_rollup.Inbox.take_snapshot + (Sc_rollup_proto_types.Inbox.of_octez i)) + inbox let get_payloads_history witness = Lwt.map @@ -243,7 +260,10 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = @@ let open Lwt_result_syntax in let* {is_first_block; predecessor; predecessor_timestamp; messages} = - Node_context.get_messages node_ctxt witness + Node_context.get_messages + node_ctxt + (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez + witness) in let*? hist = Inbox.payloads_history_of_messages @@ -269,7 +289,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let page_info = page_info end end in - let metadata = Node_context.metadata node_ctxt in + let metadata = metadata node_ctxt in let*! start_tick = PVM.get_tick start_state in let* proof = trace @@ -331,7 +351,7 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok let our_stop_chunk = Sc_rollup.Dissection_chunk.{state_hash = our_state_hash; tick = our_tick} in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let* dissection = Game_helpers.make_dissection ~state_of_tick @@ -458,7 +478,7 @@ let play_timeout (node_ctxt : _ Node_context.t) self stakers = let timeout_operation = L1_operation.Timeout { - rollup = Sc_rollup_proto_types.Address.to_octez node_ctxt.rollup_address; + rollup = node_ctxt.rollup_address; stakers = Sc_rollup_proto_types.Game.index_to_octez stakers; } in @@ -474,9 +494,9 @@ let timeout_reached ~self head_block node_ctxt staker1 staker2 = let Node_context.{rollup_address; cctxt; _} = node_ctxt in let* game_result = Plugin.RPC.Sc_rollup.timeout_reached - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, head_block) - rollup_address + (Sc_rollup_proto_types.Address.of_octez rollup_address) staker1 staker2 in diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game_event.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game_event.ml index ceb5ef25e148..b9231bfc5f90 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game_event.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/refutation_game_event.ml @@ -79,10 +79,10 @@ module Simple = struct {our_commitment_hash} at level {level} with staker {other} that hash \ issued commitment {their_commitment_hash}." ~level:Notice - ("our_commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) - ("other", Sc_rollup.Staker.encoding) - ("their_commitment_hash", Sc_rollup.Commitment.Hash.encoding) + ("our_commitment_hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) + ("other", Signature.Public_key_hash.encoding) + ("their_commitment_hash", Octez_smart_rollup.Commitment.Hash.encoding) let timeout_detected = declare_1 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 9e15def1223e..1a8c0a2f5564 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.ml @@ -68,7 +68,9 @@ let path data_dir pvm_name hash = let get ~data_dir ~pvm_kind ~hash = let open Lwt_result_syntax in - let filename = path data_dir (Sc_rollup.Kind.to_string pvm_kind) hash in + let filename = + path data_dir (Octez_smart_rollup.Kind.to_string pvm_kind) hash + in (* TODO: https://gitlab.com/tezos/tezos/-/issues/5296 Use DAC observer client when [filename] doesn't exist. *) let* contents = file_contents filename in 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 56950f44c8b6..f218cab75d38 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/reveals.mli @@ -68,6 +68,6 @@ type source = } *) val get : data_dir:string -> - pvm_kind:Protocol.Alpha_context.Sc_rollup.Kind.t -> + pvm_kind:Kind.t -> hash:Protocol.Sc_rollup_reveal_hash.t -> string tzresult Lwt.t 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 a13a580a5e13..d557dbeb97e5 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.ml @@ -36,7 +36,7 @@ type info_per_level = { type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; @@ -54,15 +54,14 @@ let simulate_info_per_level (node_ctxt : [`Read] Node_context.t) predecessor = let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - let*? level = Environment.wrap_tzresult @@ Raw_level.of_int32 level in let*? () = error_unless - Raw_level.(level >= node_ctxt.Node_context.genesis_info.level) + (level >= node_ctxt.Node_context.genesis_info.level) (Exn (Failure "Cannot simulate before origination level")) in - let first_inbox_level = Raw_level.succ node_ctxt.genesis_info.level in + let first_inbox_level = Int32.succ node_ctxt.genesis_info.level in let* ctxt = - if Raw_level.(level < first_inbox_level) then + if level < first_inbox_level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -70,7 +69,7 @@ let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = in let* ctxt, state = Interpreter.state_of_head node_ctxt ctxt head in let+ info_per_level = simulate_info_per_level node_ctxt hash in - let inbox_level = Raw_level.succ level in + let inbox_level = Int32.succ level in { ctxt; inbox_level; @@ -92,7 +91,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) info_per_level = _; } as sim) messages = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! state_hash = PVM.state_hash state in let*! tick = PVM.get_tick state in let eval_state = @@ -126,22 +125,15 @@ let simulate_messages (node_ctxt : Node_context.ro) sim messages = (sim.level_position = End) (Exn (Failure "Level for simulation is ended")) in - let*? messages = - let open Result_syntax in + let messages = if sim.level_position = Start then let {predecessor_timestamp; predecessor} = sim.info_per_level in - let open Sc_rollup.Inbox_message in - let* internals = - List.map_e - serialize - [ - Internal Start_of_level; - Internal (Info_per_level {predecessor_timestamp; predecessor}); - ] - |> Environment.wrap_tzresult - in - return (internals @ messages) - else return messages + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized + :: unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) + :: messages + else messages in let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim messages in ({sim with level_position = Middle}, num_ticks) @@ -153,10 +145,10 @@ let end_simulation node_ctxt sim = (sim.level_position = End) (Exn (Failure "Level for simulation is ended")) in - let*? eol = - Sc_rollup.Inbox_message.serialize - (Sc_rollup.Inbox_message.Internal End_of_level) - |> Environment.wrap_tzresult + let+ sim, num_ticks = + simulate_messages_no_checks + node_ctxt + sim + [Sc_rollup_inbox_message_repr.(unsafe_to_string end_of_level_serialized)] in - let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim [eol] in ({sim with level_position = End}, num_ticks) 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 2c0a627ffff2..ac8d8dd03624 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.mli @@ -37,7 +37,7 @@ type info_per_level = { (** Type of the state for a simulation. *) type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; @@ -58,10 +58,7 @@ val start_simulation : simulation state, the remaining fuel (when [?fuel] is provided) and the number of ticks that happened. *) val simulate_messages : - Node_context.ro -> - t -> - Sc_rollup.Inbox_message.serialized list -> - (t * Z.t) tzresult Lwt.t + Node_context.ro -> t -> string list -> (t * Z.t) tzresult Lwt.t (** [end_simulation node_ctxt sim] adds and [End_of_level] message and marks the simulation as ended. *) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/test/canary.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/test/canary.ml index 4aa0a8575fc9..69e71af0e1db 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/test/canary.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/test/canary.ml @@ -32,7 +32,7 @@ *) open Octez_smart_rollup -open Protocol.Alpha_context +open Octez_smart_rollup_node let build_chain node_ctxt ~genesis ~length = let open Lwt_result_syntax in @@ -85,15 +85,10 @@ let tests = Helpers.alcotest "canary arith" `Quick - Sc_rollup.Kind.Example_arith - ~boot_sector:"" - canary_test; - Helpers.alcotest - "canary wasm" - `Quick - Sc_rollup.Kind.Wasm_2_0_0 + Example_arith ~boot_sector:"" canary_test; + Helpers.alcotest "canary wasm" `Quick Wasm_2_0_0 ~boot_sector:"" canary_test; ] let () = diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.ml index 1bc441f7de89..6b669b98306a 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.ml @@ -39,25 +39,23 @@ let block_hash_of_level level = Block_hash.of_string_exn s let default_constants = - let constants = Default_parameters.constants_test in - let sc_rollup = - { - constants.sc_rollup with - arith_pvm_enable = true; - challenge_window_in_blocks = 4032; - commitment_period_in_blocks = 3; - } + let test_constants = + Layer1_helpers.constants_of_parametric Default_parameters.constants_test in - {constants with sc_rollup} + { + test_constants with + sc_rollup = + { + test_constants.sc_rollup with + challenge_window_in_blocks = 4032; + commitment_period_in_blocks = 3; + }; + } let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let open Lwt_result_syntax in let head = - Layer1. - { - hash = Block_hash.zero; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; - } + Layer1.{hash = Block_hash.zero; level = node_ctxt.genesis_info.level} in let* () = Node_context.save_level node_ctxt head in let predecessor = head in @@ -66,13 +64,20 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = Sc_rollup.Inbox.genesis ~predecessor_timestamp ~predecessor:predecessor.hash - node_ctxt.genesis_info.level + (Raw_level.of_int32_exn node_ctxt.genesis_info.level) + in + let* inbox_hash = + Node_context.save_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox.to_octez inbox) + in + let inbox_witness = + Sc_rollup.Inbox.current_witness inbox + |> Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez in - let* inbox_hash = Node_context.save_inbox node_ctxt inbox in - let inbox_witness = Sc_rollup.Inbox.current_witness inbox in let ctxt = Octez_smart_rollup_node.Context.empty node_ctxt.context in let num_ticks = 0L in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let initial_tick = Sc_rollup.Tick.initial in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! state = PVM.install_boot_sector initial_state boot_sector in @@ -81,26 +86,20 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let*! context_hash = Octez_smart_rollup_node.Context.commit ctxt in let commitment = Sc_rollup.Commitment.genesis_commitment - ~origination_level:node_ctxt.genesis_info.level + ~origination_level:(Raw_level.of_int32_exn node_ctxt.genesis_info.level) ~genesis_state_hash in - let* commitment_hash = Node_context.save_commitment node_ctxt commitment in - let previous_commitment_hash = - node_ctxt.genesis_info.commitment_hash - |> Sc_rollup_proto_types.Commitment_hash.to_octez - in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez inbox_witness + let* commitment_hash = + Node_context.save_commitment + node_ctxt + (Sc_rollup_proto_types.Commitment.to_octez commitment) in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in + let previous_commitment_hash = node_ctxt.genesis_info.commitment_hash in let header = Sc_rollup_block. { block_hash = head.hash; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; + level = node_ctxt.genesis_info.level; predecessor = predecessor.hash; commitment_hash = Some commitment_hash; previous_commitment_hash; @@ -146,14 +145,13 @@ let initialize_node_context ?(constants = default_constants) kind ~boot_sector = let* ctxt = Node_context.Internal_for_tests.create_node_context cctxt - ~constants + constants ~data_dir kind in let* genesis = add_l2_genesis_block ctxt ~boot_sector in let commitment_hash = WithExceptions.Option.get ~loc:__LOC__ genesis.header.commitment_hash - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let ctxt = {ctxt with genesis_info = {ctxt.genesis_info with commitment_hash}} @@ -228,10 +226,7 @@ let append_dummy_l2_chain node_ctxt ~length = in let batches = Stdlib.List.init length (fun i -> - [ - Sc_rollup.Inbox_message.External - (Z.to_bits (Z.of_int (i + head_level + 1))); - ]) + ["\001" (* External tag *) ^ Z.to_bits (Z.of_int (i + head_level + 1))]) in append_l2_blocks node_ctxt batches diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.mli index b6571220f74a..d18d3f989dd9 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/test/helpers/helpers.mli @@ -26,6 +26,7 @@ open Octez_smart_rollup open Protocol open Alpha_context +open Octez_smart_rollup_node (** {1 Helper functions to build and run unit tests for the rollup node} *) @@ -39,8 +40,8 @@ open Alpha_context context need to use this function in order to avoid file descriptor leaks. *) val with_node_context : - ?constants:Constants.Parametric.t -> - Sc_rollup.Kind.t -> + ?constants:Rollup_constants.protocol_constants -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> @@ -64,7 +65,7 @@ val add_l2_genesis_block : val append_l2_block : [`Read | `Write] Node_context.t -> ?is_first_block:bool -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup_block.t tzresult Lwt.t (** [append_l2_block node_ctxt message_batches] appends as many blocks as there @@ -72,7 +73,7 @@ val append_l2_block : messages. The portion of the chain that was added is returned. *) val append_l2_blocks : [`Read | `Write] Node_context.t -> - Sc_rollup.Inbox_message.t list list -> + string list list -> Sc_rollup_block.t list tzresult Lwt.t (** [append_dummy_l2_chain node_ctxt ~length] append [length] L2 blocks with an @@ -108,8 +109,8 @@ end val alcotest : string -> Alcotest.speed_level -> - ?constants:Constants.Parametric.t -> - Sc_rollup.Kind.t -> + ?constants:Rollup_constants.protocol_constants -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_pvm.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_pvm.ml index 58d6d46968a1..d9629dc8759a 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_pvm.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_pvm.ml @@ -123,7 +123,7 @@ end module Durable_state = Make_durable_state (Make_wrapped_tree (Wasm_2_0_0_proof_format.Tree)) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.Wasm_2_0_0PVM.Make (Make_backend) (Wasm_2_0_0_proof_format) include PVM -- GitLab From aeec1ad8a436a020773f0f1cbad2dc2b64c8eb4d Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Wed, 31 May 2023 09:00:20 +0200 Subject: [PATCH 13/15] SCORU/Node/Mumbai: Backport !8948 - SCORU/Node: custom protocol constants - SCORU/Node: custom genesis info type - SCORU/Node: save genesis inbox on disk - SCORU/Node/batcher: check config on init - SCORU/Node: remove protocol from events - SCORU/Node: interpreter and inboxes on serialized messages - SCORU/Node: remove Protocol dependency from Node_context - SCORU/Node: remove PVM first class module from node context - SCORU/Node: node Node_context outside of proto directory --- .../lib_sc_rollup_client/commands.ml | 97 +- .../sc_rollup_services.ml | 78 +- .../lib_sc_rollup_node/RPC_server.ml | 112 +- .../lib_sc_rollup_node/arith_pvm.ml | 2 +- .../lib_sc_rollup_node/batcher.ml | 58 +- .../block_directory_helpers.ml | 6 +- .../lib_sc_rollup_node/commitment_event.ml | 14 +- .../lib_sc_rollup_node/commitment_event.mli | 8 +- .../lib_sc_rollup_node/daemon.ml | 142 +- .../lib_sc_rollup_node/dal_pages_request.ml | 128 +- .../lib_sc_rollup_node/dal_pages_request.mli | 4 +- .../lib_sc_rollup_node/dal_slots_tracker.ml | 146 +- .../lib_sc_rollup_node/dal_slots_tracker.mli | 7 - .../lib_sc_rollup_node/fueled_pvm.ml | 48 +- .../lib_sc_rollup_node/inbox.ml | 67 +- .../lib_sc_rollup_node/inbox.mli | 20 +- .../lib_sc_rollup_node/interpreter.ml | 73 +- .../lib_sc_rollup_node/interpreter.mli | 2 +- .../lib_sc_rollup_node/interpreter_event.ml | 8 +- .../lib_sc_rollup_node/layer1_helpers.ml | 111 ++ .../lib_sc_rollup_node/layer1_helpers.mli | 33 + .../lib_sc_rollup_node/node_context.ml | 1283 ----------------- .../lib_sc_rollup_node/node_context.mli | 500 ------- .../lib_sc_rollup_node/outbox.ml | 7 +- .../lib_sc_rollup_node/outbox.mli | 2 +- .../lib_sc_rollup_node/publisher.ml | 121 +- .../lib_sc_rollup_node/publisher.mli | 6 +- .../lib_sc_rollup_node/pvm.ml | 78 +- .../lib_sc_rollup_node/pvm_rpc.ml | 2 +- .../lib_sc_rollup_node/pvm_sig.ml | 101 ++ .../refutation_coordinator.ml | 48 +- .../lib_sc_rollup_node/refutation_game.ml | 53 +- .../refutation_game_event.ml | 8 +- .../lib_sc_rollup_node/reveals.ml | 4 +- .../lib_sc_rollup_node/reveals.mli | 2 +- .../lib_sc_rollup_node/simulation.ml | 41 +- .../lib_sc_rollup_node/simulation.mli | 7 +- .../lib_sc_rollup_node/test/canary.ml | 11 +- .../test/helpers/helpers.ml | 69 +- .../test/helpers/helpers.mli | 13 +- .../lib_sc_rollup_node/wasm_2_0_0_pvm.ml | 2 +- 41 files changed, 898 insertions(+), 2624 deletions(-) delete mode 100644 src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml delete mode 100644 src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli create mode 100644 src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_sig.ml diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_client/commands.ml b/src/proto_016_PtMumbai/lib_sc_rollup_client/commands.ml index 0c799d3ddfc3..86e62aaa814f 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_client/commands.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_client/commands.ml @@ -102,53 +102,50 @@ let display_answer (cctxt : #Configuration.sc_client_context) : cctxt#error "@[[HTTP 403] Access denied to: %a@]@." Uri.pp cctxt#base | _ -> cctxt#error "Unexpected server answer\n%!" -let find_string json key = - match Ezjsonm.find_opt json [key] with - | Some v -> Ezjsonm.get_string v - | None -> - invalid_arg - (Printf.sprintf - "Key %S was not found in: %s" - key - (Ezjsonm.value_to_string json)) +let unparsed_transaction_encoding = + let open Data_encoding in + obj3 + (req "parameters" string) + (req "destination" Contract.originated_encoding) + (opt "entrypoint" Entrypoint.simple_encoding) -let parse_transactions transactions = - let json = Ezjsonm.from_string transactions in - let open Ezjsonm in - let open Sc_rollup.Outbox.Message in +type unparsed_batch = + (string * Protocol.Contract_hash.t * Entrypoint.t option) list + +let unparsed_batch_encoding : unparsed_batch Data_encoding.t = + Data_encoding.list unparsed_transaction_encoding + +let expand_expr expr = + let open Result_syntax in + let* expr = + Michelson_v1_parser.parse_expression expr + |> Tezos_micheline.Micheline_parser.no_parsing_error + in + return expr.expanded + +let parse_unparsed_batch json = let open Lwt_result_syntax in - Error.trace_lwt_result_with - "Failed to parse JSON transactions: %s" - transactions - @@ - let transaction json = - let destination = - find_string json "destination" |> Protocol.Contract_hash.of_b58check_exn - in - let entrypoint = - match find_opt json ["entrypoint"] with - | None -> Entrypoint.default - | Some entrypoint -> - entrypoint |> get_string |> Entrypoint.of_string_strict_exn - in - let*? parameters = - Tezos_micheline.Micheline_parser.no_parsing_error - @@ (find_string json "parameters" |> Michelson_v1_parser.parse_expression) - in - let unparsed_parameters = parameters.expanded in - return @@ {destination; entrypoint; unparsed_parameters} + let transactions = Data_encoding.Json.destruct unparsed_batch_encoding json in + let* transactions = + List.map_es + (fun (unparsed_parameters, destination, entrypoint) -> + let*? unparsed_parameters = expand_expr unparsed_parameters in + return + Sc_rollup.Outbox.Message. + { + unparsed_parameters; + destination; + entrypoint = Option.value ~default:Entrypoint.default entrypoint; + }) + transactions in - match json with - | `A messages -> - let* transactions = List.map_es transaction messages in - return @@ Atomic_transaction_batch {transactions} - | `O _ -> - let* transaction = transaction json in - return @@ Atomic_transaction_batch {transactions = [transaction]} - | _ -> - failwith - "An outbox message must be either a single transaction or a list of \ - transactions." + return (Sc_rollup.Outbox.Message.Atomic_transaction_batch {transactions}) + +let outbox_message_parameter = + Tezos_clic.parameter (fun (cctxt : #Configuration.sc_client_context) str -> + match Data_encoding.Json.from_string str with + | Ok json -> parse_unparsed_batch json + | Error reason -> cctxt#error "Invalid transaction json: %s" reason) let get_output_proof () = Tezos_clic.command @@ -163,13 +160,13 @@ let get_output_proof () = ~name:"level" ~desc:"The level of the rollup outbox where the message is available" @@ Tezos_clic.prefixes ["transferring"] - @@ Tezos_clic.string + @@ Tezos_clic.param ~name:"transactions" ~desc:"A JSON description of the transactions" + outbox_message_parameter @@ Tezos_clic.stop) - (fun () index level transactions (cctxt : #Configuration.sc_client_context) -> + (fun () index level message (cctxt : #Configuration.sc_client_context) -> let open Lwt_result_syntax in - let* message = parse_transactions transactions in let output = Protocol.Alpha_context.Sc_rollup. { @@ -192,14 +189,14 @@ let get_output_message_encoding () = ~desc:"Get output message encoding." Tezos_clic.no_options (Tezos_clic.prefixes ["encode"; "outbox"; "message"] - @@ Tezos_clic.string + @@ Tezos_clic.param ~name:"transactions" ~desc:"A JSON description of the transactions" + outbox_message_parameter @@ Tezos_clic.stop) - (fun () transactions (cctxt : #Configuration.sc_client_context) -> + (fun () message (cctxt : #Configuration.sc_client_context) -> let open Lwt_result_syntax in let open Protocol.Alpha_context.Sc_rollup.Outbox.Message in - let* message = parse_transactions transactions in let encoded_message = serialize message in (match encoded_message with | Ok encoded_message -> diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml index c4532a958aab..b6539529a288 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -52,7 +52,7 @@ type eval_result = { state_hash : Sc_rollup.State_hash.t; status : string; output : Sc_rollup.output list; - inbox_level : Raw_level.t; + inbox_level : int32; num_ticks : Z.t; insights : bytes option list; (** The simulation can ask to look at values on the state after @@ -98,8 +98,8 @@ type message_status = l1_level : int32; finalized : bool; cemented : bool; - commitment : Sc_rollup.Commitment.t; - commitment_hash : Sc_rollup.Commitment.Hash.t; + commitment : Octez_smart_rollup.Commitment.t; + commitment_hash : Octez_smart_rollup.Commitment.Hash.t; first_published_at_level : int32; published_at_level : int32; } @@ -109,13 +109,13 @@ module Encodings = struct let commitment_with_hash = obj2 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) let commitment_with_hash_and_level_infos = obj4 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (opt "first_published_at_level" int32) (opt "published_at_level" int32) @@ -141,7 +141,7 @@ module Encodings = struct ~description:"Output produced by evaluation of the messages") (req "inbox_level" - Raw_level.encoding + int32 ~description:"Level of the inbox that would contain these messages") (req "num_ticks" @@ -320,8 +320,8 @@ module Encodings = struct (req "level" int32))) (req "finalized" bool) (req "cemented" bool) - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (req "first_published_at_level" int32) (req "published_at_level" int32)) (function @@ -606,7 +606,7 @@ module Global = struct Tezos_rpc.Service.get_service ~description:"Rollup inbox for block" ~query:Tezos_rpc.Query.empty - ~output:Sc_rollup.Inbox.encoding + ~output:Octez_smart_rollup.Inbox.encoding (path / "inbox") let ticks = @@ -710,59 +710,19 @@ module Global = struct ~output:(Data_encoding.list Dal.Slot.Header.encoding) (path / "dal" / "slot_headers") - let dal_confirmed_slot_pages = + let dal_slot_status_encoding : [`Confirmed | `Unconfirmed] Data_encoding.t = + Data_encoding.string_enum + [("confirmed", `Confirmed); ("unconfirmed", `Unconfirmed)] + + let dal_processed_slots = Tezos_rpc.Service.get_service - ~description: - "Data availability confirmed & downloaded slot pages for a given \ - block hash" + ~description:"Data availability processed slots and their statuses" ~query:Tezos_rpc.Query.empty ~output: - (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3873 - Estimate size of binary encoding and add a check_size to the - encoding. *) Data_encoding.( list - @@ obj2 - (req "index" Dal.Slot_index.encoding) - (req "contents" (list Dal.Page.content_encoding))) - (path / "dal" / "confirmed_slot_pages") - - type dal_slot_page_query = {index : Dal.Slot_index.t; page : int} - - let dal_slot_page_query = - let open Tezos_rpc.Query in - let req name f = function - | None -> - raise - (Invalid (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - let invalid_parameter i = - raise (Invalid (Format.asprintf "Invalid parameter (%d)" i)) - in - query (fun raw_index raw_page -> - let index = req "index" Dal.Slot_index.of_int raw_index in - let page = req "page" (fun p -> p) raw_page in - match index with - | None -> invalid_parameter @@ Option.value ~default:0 raw_index - | Some index -> - if page < 0 then invalid_parameter page else {index; page}) - |+ opt_field "index" Tezos_rpc.Arg.int (fun q -> - Some (Dal.Slot_index.to_int q.index)) - |+ opt_field "slot_page" Tezos_rpc.Arg.int (fun q -> Some q.page) - |> seal - - let dal_slot_page = - Tezos_rpc.Service.get_service - ~description: - "Data availability downloaded slot pages for a given block hash" - ~query:dal_slot_page_query - ~output: - Data_encoding.( - obj2 - (req "result" string) - (opt "contents" Dal.Page.content_encoding)) - (path / "dal" / "slot_page") + @@ obj2 (req "index" int31) (req "status" dal_slot_status_encoding)) + (path / "dal" / "processed_slots") module Outbox = struct let level_param = diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml index 8fea1385726b..6777c7e83d39 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml @@ -47,50 +47,8 @@ module Slot_pages_map = struct include Map.Make (Dal.Slot_index) end -let get_dal_confirmed_slot_pages node_ctxt block = - let open Lwt_result_syntax in - let* slot_pages = - Node_context.list_slot_pages node_ctxt ~confirmed_in_block_hash:block - in - (* Slot pages are sorted in lexicographic order of slot index and page - number.*) - let slot_rev_pages_map = - List.fold_left - (fun map ((index, _page), page) -> - Slot_pages_map.update - index - (function None -> Some [page] | Some pages -> Some (page :: pages)) - map) - Slot_pages_map.empty - slot_pages - in - let slot_pages_map = - Slot_pages_map.map (fun pages -> List.rev pages) slot_rev_pages_map - in - return @@ Slot_pages_map.bindings slot_pages_map - -let get_dal_slot_page node_ctxt block slot_index slot_page = - let open Lwt_result_syntax in - let* processed = - Node_context.processed_slot - node_ctxt - ~confirmed_in_block_hash:block - slot_index - in - match processed with - | None -> return ("Slot page has not been downloaded", None) - | Some `Unconfirmed -> return ("Slot was not confirmed", None) - | Some `Confirmed -> ( - let* contents_opt = - Node_context.find_slot_page - node_ctxt - ~confirmed_in_block_hash:block - ~slot_index - ~page_index:slot_page - in - match contents_opt with - | None -> assert false - | Some _contents -> return ("Slot page is available", contents_opt)) +let get_dal_processed_slots node_ctxt block = + Node_context.list_slots_statuses node_ctxt ~confirmed_in_block_hash:block module Global_directory = Make_directory (struct include Sc_rollup_services.Global @@ -164,16 +122,14 @@ module Common = struct let open Lwt_result_syntax in let* l2_block = Node_context.get_l2_block node_ctxt block in let+ num_messages = - Node_context.get_num_messages - node_ctxt - (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez - l2_block.header.inbox_witness) + Node_context.get_num_messages node_ctxt l2_block.header.inbox_witness in Z.of_int num_messages let () = Global_directory.register0 Sc_rollup_services.Global.sc_rollup_address - @@ fun node_ctxt () () -> return @@ node_ctxt.rollup_address + @@ fun node_ctxt () () -> + return @@ Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address let () = Global_directory.register0 Sc_rollup_services.Global.current_tezos_head @@ -215,7 +171,7 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages ~insight_requests messages = let open Lwt_result_syntax in let open Alpha_context in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let reveal_map = match reveal_pages with | Some pages -> @@ -251,11 +207,10 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages insight_requests in let num_ticks = Z.(num_ticks_0 + num_ticks_end) in - let*! outbox = PVM.get_outbox inbox_level state in + let level = Raw_level.of_int32_exn inbox_level in + let*! outbox = PVM.get_outbox level state in let output = - List.filter - (fun Sc_rollup.{outbox_level; _} -> outbox_level = inbox_level) - outbox + List.filter (fun Sc_rollup.{outbox_level; _} -> outbox_level = level) outbox in let*! state_hash = PVM.state_hash state in let*! status = PVM.get_status state in @@ -269,7 +224,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in return tick @@ -278,7 +233,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! hash = PVM.state_hash state in return hash @@ -287,7 +242,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! current_level = PVM.get_current_level state in return current_level @@ -314,7 +269,6 @@ let () = | Some head -> let commitment_hash = Sc_rollup_block.most_recent_commitment head.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let+ commitment = Node_context.find_commitment node_ctxt commitment_hash @@ -328,9 +282,7 @@ let () = match Reference.get node_ctxt.lpc with | None -> return_none | Some commitment -> - let hash = - Alpha_context.Sc_rollup.Commitment.hash_uncarbonated commitment - in + let hash = Octez_smart_rollup.Commitment.hash commitment in (* The corresponding level in Store.Commitments.published_at_level is available only when the commitment has been published and included in a block. *) @@ -350,7 +302,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! status = PVM.get_status state in return (PVM.string_of_status status) @@ -358,42 +310,35 @@ let () = Block_directory.register0 Sc_rollup_services.Global.Block.dal_slots @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in - let* slots = + let+ slots = Node_context.get_all_slot_headers node_ctxt ~published_in_block_hash:block in - return slots - -let () = - Block_directory.register0 - Sc_rollup_services.Global.Block.dal_confirmed_slot_pages - @@ fun (node_ctxt, block) () () -> - get_dal_confirmed_slot_pages node_ctxt block + List.rev_map Sc_rollup_proto_types.Dal.Slot_header.of_octez slots |> List.rev let () = - Block_directory.register0 Sc_rollup_services.Global.Block.dal_slot_page - @@ fun (node_ctxt, block) {index; page} () -> - get_dal_slot_page node_ctxt block index page + Block_directory.register0 Sc_rollup_services.Global.Block.dal_processed_slots + @@ fun (node_ctxt, block) () () -> get_dal_processed_slots node_ctxt block let () = Outbox_directory.register0 Sc_rollup_services.Global.Block.Outbox.messages @@ fun (node_ctxt, block, outbox_level) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! outbox = PVM.get_outbox outbox_level state in return outbox let () = Proof_helpers_directory.register0 Sc_rollup_services.Global.Helpers.outbox_proof - @@ fun node_ctxt output () -> Outbox.proof_of_output node_ctxt output + @@ fun node_ctxt output () -> + let open Lwt_result_syntax in + let+ commitment, proof = Outbox.proof_of_output node_ctxt output in + (Sc_rollup_proto_types.Commitment_hash.of_octez commitment, proof) let () = Block_directory.register0 Sc_rollup_services.Global.Block.simulate @@ fun (node_ctxt, block) () {messages; reveal_pages; insight_requests} -> - let messages = - List.map Alpha_context.Sc_rollup.Inbox_message.unsafe_of_string messages - in simulate_messages node_ctxt block ~reveal_pages ~insight_requests messages let () = @@ -425,23 +370,19 @@ let commitment_level_of_inbox_level (node_ctxt : _ Node_context.t) inbox_level = let+ last_published_commitment = Reference.get node_ctxt.lpc in let commitment_period = Int32.of_int - node_ctxt.protocol_constants.parametric.sc_rollup - .commitment_period_in_blocks - in - let last_published = - Raw_level.to_int32 last_published_commitment.inbox_level + node_ctxt.protocol_constants.sc_rollup.commitment_period_in_blocks in + let last_published = last_published_commitment.inbox_level in let open Int32 in div (sub last_published inbox_level) commitment_period |> mul commitment_period |> sub last_published |> Raw_level.of_int32_exn let inbox_info_of_level (node_ctxt : _ Node_context.t) inbox_level = - let open Alpha_context in let open Lwt_result_syntax in let+ finalized_level = Node_context.get_finalized_level node_ctxt in let finalized = Compare.Int32.(inbox_level <= finalized_level) in let lcc = Reference.get node_ctxt.lcc in - let cemented = Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) in + let cemented = Compare.Int32.(inbox_level <= lcc.level) in (finalized, cemented) let () = @@ -510,7 +451,6 @@ let () = WithExceptions.Option.get ~loc:__LOC__ block.header.commitment_hash - |> Sc_rollup_proto_types.Commitment_hash.of_octez in (* Commitment computed *) let* published_at = diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/arith_pvm.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/arith_pvm.ml index 97b5b0b1aa00..0ad11390bf1c 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/arith_pvm.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/arith_pvm.ml @@ -44,7 +44,7 @@ module Arith_proof_format = .tree_proof_encoding end) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.ArithPVM.Make (Arith_proof_format) include PVM diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/batcher.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/batcher.ml index cf4199967009..fccf828b61bb 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/batcher.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/batcher.ml @@ -153,11 +153,14 @@ let produce_batches state ~only_full = let simulate node_ctxt simulation_ctxt (messages : L2_message.t list) = let open Lwt_result_syntax in let*? ext_messages = - List.map_e - (fun m -> - Sc_rollup.Inbox_message.(serialize (External (L2_message.content m)))) - messages - |> Environment.wrap_tzresult + Environment.wrap_tzresult + @@ List.map_e + (fun m -> + let open Result_syntax in + let open Sc_rollup.Inbox_message in + let+ msg = serialize @@ External (L2_message.content m) in + unsafe_to_string msg) + messages in let+ simulation_ctxt, _ticks = Simulation.simulate_messages node_ctxt simulation_ctxt ext_messages @@ -229,6 +232,38 @@ let on_new_head state head = (* Forget failing messages *) List.iter (Message_queue.remove state.messages) failing +(** Maximum size of an L2 batch in bytes that can fit in an operation of the + protocol. *) +let protocol_max_batch_size = + let open Protocol in + let open Alpha_context in + let empty_message_op : _ Operation.t = + let open Operation in + { + shell = {branch = Block_hash.zero}; + protocol_data = + { + signature = Some Signature.zero; + contents = + Single + (Manager_operation + { + source = Signature.Public_key_hash.zero; + fee = Tez.of_mutez_exn Int64.max_int; + counter = Manager_counter.Internal_for_tests.of_int max_int; + gas_limit = + Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); + storage_limit = Z.of_int max_int; + operation = Sc_rollup_add_messages {messages = [""]}; + }); + }; + } + in + Protocol.Constants_repr.max_operation_data_length + - Data_encoding.Binary.length + Operation.encoding + (Operation.pack empty_message_op) + let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = let open Lwt_syntax in let conf = @@ -238,9 +273,7 @@ let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = min_batch_size = conf.min_batch_size; max_batch_elements = conf.max_batch_elements; max_batch_size = - Option.value - conf.max_batch_size - ~default:Node_context.protocol_max_batch_size; + Option.value conf.max_batch_size ~default:protocol_max_batch_size; } in return @@ -329,8 +362,17 @@ let table = Worker.create_table Queue let worker_promise, worker_waker = Lwt.task () +let check_batcher_config Configuration.{max_batch_size; _} = + match max_batch_size with + | Some m when m > protocol_max_batch_size -> + error_with + "batcher.max_batch_size must be smaller than %d" + protocol_max_batch_size + | _ -> Ok () + let init conf ~signer node_ctxt = let open Lwt_result_syntax in + let*? () = check_batcher_config conf in let node_ctxt = Node_context.readonly node_ctxt in let+ worker = Worker.launch table () {node_ctxt; signer; conf} (module Handlers) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.ml index a4ccb383a729..e7cba968fb78 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol - (* Conveniences to construct RPC directory against a subcontext of the Node_context *) @@ -43,9 +41,7 @@ let get_finalized node_ctxt = let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> let lcc = Reference.get node_ctxt.lcc in - Node_context.hash_of_level - node_ctxt - (Alpha_context.Raw_level.to_int32 lcc.level) + Node_context.hash_of_level node_ctxt lcc.level let block_of_prefix node_ctxt block = match block with diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml index 92c014f0ab7c..c477e81f6885 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml @@ -72,8 +72,8 @@ module Simple = struct "Last cemented commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let last_published_commitment_updated = declare_2 @@ -83,8 +83,8 @@ module Simple = struct "Last published commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let compute_commitment = declare_1 @@ -92,7 +92,7 @@ module Simple = struct ~name:"sc_rollup_node_commitment_process_head" ~msg:"Computing and storing new commitment for level {level}" ~level:Notice - ("level", Raw_level.encoding) + ("level", Data_encoding.int32) let publish_commitment = declare_2 @@ -100,8 +100,8 @@ module Simple = struct ~name:"sc_rollup_node_publish_commitment" ~msg:"Publishing commitment {hash} for inbox level {level}" ~level:Notice - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let commitment_parent_is_not_lcc = declare_3 diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli index 89b337266710..5a26a50ec34f 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli @@ -51,13 +51,13 @@ val commitment_will_not_be_published : cemented commitment was updated to the given [hash] at the given inbox [level]. *) val last_cemented_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [last_published_commitment_updated hash level] emits the event that the last published commitment was updated to the given [hash] at the given inbox [level]. *) val last_published_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [commitment_parent_is_not_lcc predecessor_hash last_cemented_commitment_hash] emits the event that a commitment at the given inbox [level] is being @@ -73,12 +73,12 @@ val commitment_parent_is_not_lcc : (** [compute_commitment level] emits the event that a new commitment is being computed and stored for the block at the given [level]. *) -val compute_commitment : Raw_level.t -> unit Lwt.t +val compute_commitment : int32 -> unit Lwt.t (** [publish_commitment hash level] emits the event that a new commitment is being published. *) val publish_commitment : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** Events emmitted by the Publisher worker *) module Publisher : sig diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml index aea99805db4e..0bc4e1b6ee9c 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml @@ -32,24 +32,21 @@ open Apply_results (** Returns [Some c] if [their_commitment] is refutable where [c] is our commitment for the same inbox level. *) let is_refutable_commitment node_ctxt - (their_commitment : Sc_rollup.Commitment.t) their_commitment_hash = + (their_commitment : Octez_smart_rollup.Commitment.t) their_commitment_hash = let open Lwt_result_syntax in let* l2_block = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 their_commitment.inbox_level) + Node_context.get_l2_block_by_level node_ctxt their_commitment.inbox_level in let* our_commitment_and_hash = Option.filter_map_es (fun hash -> - let hash = Sc_rollup_proto_types.Commitment_hash.of_octez hash in let+ commitment = Node_context.find_commitment node_ctxt hash in Option.map (fun c -> (c, hash)) commitment) l2_block.header.commitment_hash in match our_commitment_and_hash with | Some (our_commitment, our_commitment_hash) - when Sc_rollup.Commitment.Hash.( + when Octez_smart_rollup.Commitment.Hash.( their_commitment_hash <> our_commitment_hash && their_commitment.predecessor = our_commitment.predecessor) -> return our_commitment_and_hash @@ -76,7 +73,7 @@ let accuser_publish_commitment_when_refutable node_ctxt ~other rollup ~level:their_commitment.inbox_level ~other in - assert (Sc_rollup.Address.(node_ctxt.rollup_address = rollup)) ; + assert (Octez_smart_rollup.Address.(node_ctxt.rollup_address = rollup)) ; Publisher.publish_single_commitment node_ctxt our_commitment (** Process an L1 SCORU operation (for the node's rollup) which is included for @@ -94,10 +91,12 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let save_lpc = match Reference.get node_ctxt.lpc with | None -> true - | Some lpc -> Raw_level.(commitment.inbox_level >= lpc.inbox_level) + | Some lpc -> + Raw_level.to_int32 commitment.inbox_level >= lpc.inbox_level in + let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in if save_lpc then Reference.set node_ctxt.lpc (Some commitment) ; - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let* () = Node_context.set_commitment_published_at_level node_ctxt @@ -110,7 +109,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let*! () = Commitment_event.last_published_commitment_updated commitment_hash - (Raw_level.of_int32_exn head.Layer1.level) + head.Layer1.level in return_unit | ( Sc_rollup_publish {commitment = their_commitment; rollup}, @@ -118,6 +117,9 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) {published_at_level; staked_hash = their_commitment_hash; _} ) -> (* Commitment published by someone else *) (* We first register the publication information *) + let their_commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez their_commitment_hash + in let* known_commitment = Node_context.commitment_exists node_ctxt their_commitment_hash in @@ -146,6 +148,10 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) in (* An accuser node will publish its commitment if the other one is refutable. *) + let rollup = Sc_rollup_proto_types.Address.to_octez rollup in + let their_commitment = + Sc_rollup_proto_types.Commitment.to_octez their_commitment + in accuser_publish_commitment_when_refutable node_ctxt ~other:source @@ -155,13 +161,11 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) | Sc_rollup_cement {commitment; _}, Sc_rollup_cement_result {inbox_level; _} -> (* Cemented commitment ---------------------------------------------- *) - let proto_inbox_level = inbox_level in - let proto_commitment = commitment in let inbox_level = Raw_level.to_int32 inbox_level in let* inbox_block = Node_context.get_l2_block_by_level node_ctxt inbox_level in - let commitment = + let commitment_hash = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in let*? () = @@ -171,19 +175,19 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) (Option.equal Octez_smart_rollup.Commitment.Hash.( = ) our_commitment_hash - (Some commitment)) + (Some commitment_hash)) (Sc_rollup_node_errors.Disagree_with_cemented - {inbox_level; ours = our_commitment_hash; on_l1 = commitment}) + {inbox_level; ours = our_commitment_hash; on_l1 = commitment_hash}) in let lcc = Reference.get node_ctxt.lcc in let*! () = - if inbox_level > Raw_level.to_int32 lcc.level then ( + if inbox_level > lcc.level then ( Reference.set node_ctxt.lcc - {commitment = proto_commitment; level = proto_inbox_level} ; + {commitment = commitment_hash; level = inbox_level} ; Commitment_event.last_cemented_commitment_updated - proto_commitment - proto_inbox_level) + commitment_hash + inbox_level) else Lwt.return_unit in return_unit @@ -218,7 +222,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) Node_context.save_slot_header node_ctxt ~published_in_block_hash:head.Layer1.hash - slot_header.header + (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header.header) in return_unit | _, _ -> @@ -237,7 +241,9 @@ let process_l1_operation (type kind) node_ctxt (head : Layer1.header) ~source | Sc_rollup_timeout {rollup; _} | Sc_rollup_execute_outbox_message {rollup; _} | Sc_rollup_recover_bond {sc_rollup = rollup; staker = _} -> - Sc_rollup.Address.(rollup = node_ctxt.Node_context.rollup_address) + Octez_smart_rollup.Address.( + Sc_rollup_proto_types.Address.to_octez rollup + = node_ctxt.Node_context.rollup_address) | Dal_publish_slot_header _ -> true | Reveal _ | Transaction _ | Origination _ | Delegation _ | Update_consensus_key _ | Register_global_constant _ | Set_deposits_limit _ @@ -303,13 +309,13 @@ let process_l1_block_operations node_ctxt (head : Layer1.header) = return_unit let before_origination (node_ctxt : _ Node_context.t) (header : Layer1.header) = - let origination_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let origination_level = node_ctxt.genesis_info.level in header.level < origination_level let previous_context (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in - if predecessor.level < Raw_level.to_int32 node_ctxt.genesis_info.level then + if predecessor.level < node_ctxt.genesis_info.level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -380,11 +386,6 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* inbox_hash, inbox, inbox_witness, messages = Inbox.process_head node_ctxt ~predecessor head in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez - inbox_witness - in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* () = when_ (Node_context.dal_supported node_ctxt) @@ fun () -> Dal_slots_tracker.process_head node_ctxt (Layer1.head_of_header head) @@ -405,25 +406,15 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* commitment_hash = Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt in - let commitment_hash = - Option.map - Sc_rollup_proto_types.Commitment_hash.to_octez - commitment_hash - in let* () = unless (catching_up && Option.is_none commitment_hash) @@ fun () -> - Inbox.same_as_layer_1 - node_ctxt - head.hash - (Sc_rollup_proto_types.Inbox.to_octez inbox) + Inbox.same_as_layer_1 node_ctxt head.hash inbox in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -432,7 +423,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -477,9 +468,7 @@ let on_layer_1_head (daemon_components : (module Daemon_components.S)) node_ctxt | None -> (* if no head has been processed yet, we want to handle all blocks since, and including, the rollup origination. *) - let origination_level = - Raw_level.to_int32 node_ctxt.genesis_info.level - in + let origination_level = node_ctxt.genesis_info.level in `Level (Int32.pred origination_level) in let stripped_head = Layer1.head_of_header head in @@ -576,15 +565,15 @@ let install_finalizer (daemon_components : (module Daemon_components.S)) let* () = Event.shutdown_node exit_status in Tezos_base_unix.Internal_event_unix.close () -let check_initial_state_hash {Node_context.cctxt; rollup_address; pvm; _} = +let check_initial_state_hash {Node_context.cctxt; rollup_address; kind; _} = let open Lwt_result_syntax in + let module PVM = (val Pvm.of_kind kind) in let* l1_reference_initial_state_hash = RPC.Sc_rollup.initial_pvm_state_hash - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, cctxt#block) - rollup_address + (Sc_rollup_proto_types.Address.of_octez rollup_address) in - let module PVM = (val pvm) in let*! s = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! l2_initial_state_hash = PVM.state_hash s in let l1_reference_initial_state_hash = @@ -647,12 +636,9 @@ let run node_ctxt configuration { cctxt = (node_ctxt.cctxt :> Client_context.full); fee_parameters = configuration.fee_parameters; - minimal_block_delay = - node_ctxt.protocol_constants.Constants.parametric - .minimal_block_delay |> Period.to_seconds; + minimal_block_delay = node_ctxt.protocol_constants.minimal_block_delay; delay_increment_per_round = - node_ctxt.protocol_constants.Constants.parametric - .delay_increment_per_round |> Period.to_seconds; + node_ctxt.protocol_constants.delay_increment_per_round; } ~data_dir:node_ctxt.data_dir ~signers @@ -686,8 +672,8 @@ let run node_ctxt configuration Metrics.Info.init_rollup_node_info ~id:configuration.sc_rollup_address ~mode:configuration.mode - ~genesis_level:(Raw_level.to_int32 node_ctxt.genesis_info.level) - ~pvm_kind:(Sc_rollup.Kind.to_string node_ctxt.kind) ; + ~genesis_level:node_ctxt.genesis_info.level + ~pvm_kind:(Octez_smart_rollup.Kind.to_string node_ctxt.kind) ; let fatal_error_exit e = Format.eprintf "%!%a@.Exiting.@." pp_print_trace e ; let*! _ = Lwt_exit.exit_and_wait 1 in @@ -745,11 +731,6 @@ module Internal_for_tests = struct head messages in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez - inbox_witness - in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* ctxt, _num_messages, num_ticks, initial_tick = Interpreter.process_head node_ctxt ctxt ~predecessor head (inbox, messages) in @@ -761,16 +742,11 @@ module Internal_for_tests = struct head ctxt in - let commitment_hash = - Option.map Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -779,7 +755,7 @@ module Internal_for_tests = struct Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -837,6 +813,25 @@ let run Layer1.fetch_tezos_shell_header l1_ctxt head.header.predecessor in let*! () = Event.received_first_block head.hash Protocol.hash in + let publisher = + Configuration.Operator_purpose_map.find + Publish + configuration.sc_rollup_node_operators + in + let* constants = Layer1_helpers.retrieve_constants cctxt + and* genesis_info = + Layer1_helpers.retrieve_genesis_info cctxt configuration.sc_rollup_address + and* lcc = + Layer1_helpers.get_last_cemented_commitment + cctxt + configuration.sc_rollup_address + and* lpc = + Option.filter_map_es + (Layer1_helpers.get_last_published_commitment + cctxt + configuration.sc_rollup_address) + publisher + and* kind = Layer1_helpers.get_kind cctxt configuration.sc_rollup_address in let* node_ctxt = Node_context.init cctxt @@ -844,6 +839,11 @@ let run ?log_kernel_debug_file Read_write l1_ctxt + constants + genesis_info + ~lcc + ~lpc + kind ~proto_level:predecessor.proto_level configuration in diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.ml index 0e0e11aae1ec..322c201aa67c 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.ml @@ -89,39 +89,26 @@ let get_slot_pages = (Dal_node_client.get_slot_pages dal_cctxt) Lwt.return -let check_confirmation_status_and_download - ({Node_context.dal_cctxt; _} as node_ctxt) ~confirmed_in_block_hash - ~published_in_block_hash index = +let download_confirmed_slot_pages ({Node_context.dal_cctxt; _} as node_ctxt) + ~published_level ~index = let open Lwt_result_syntax in - let* confirmed_in_block_level = - Node_context.level_of_hash node_ctxt confirmed_in_block_hash + let* published_in_block_hash = + Node_context.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in - let confirmed_in_head = - Layer1.{hash = confirmed_in_block_hash; level = confirmed_in_block_level} + let* header = + Node_context.get_slot_header node_ctxt ~published_in_block_hash index in - let* is_confirmed = - Dal_slots_tracker.is_slot_confirmed node_ctxt confirmed_in_head index - in - if is_confirmed then - let* {commitment; _} = - Node_context.get_slot_header node_ctxt ~published_in_block_hash index - in - let dal_cctxt = WithExceptions.Option.get ~loc:__LOC__ dal_cctxt in - (* DAL must be configured for this point to be reached *) - let* pages = get_slot_pages dal_cctxt commitment in - let save_pages node_ctxt = - Node_context.save_confirmed_slot - node_ctxt - confirmed_in_block_hash - index - pages - in - return (Delayed_write_monad.delay_write (Some pages) save_pages) - else - let save_slot node_ctxt = - Node_context.save_unconfirmed_slot node_ctxt confirmed_in_block_hash index - in - return (Delayed_write_monad.delay_write None save_slot) + let dal_cctxt = WithExceptions.Option.get ~loc:__LOC__ dal_cctxt in + (* DAL must be configured for this point to be reached *) + get_slot_pages dal_cctxt header.commitment + +let storage_invariant_broken published_level index = + failwith + "Internal error: [Node_context.find_slot_status] is supposed to have \ + registered the status of the slot %d published at level %a in the store" + index + Raw_level.pp + published_level let slot_pages ~dal_attestation_lag node_ctxt Dal.Slot.Header.{published_level; index} = @@ -132,37 +119,21 @@ let slot_pages ~dal_attestation_lag node_ctxt ~published_level node_ctxt in + let index = Sc_rollup_proto_types.Dal.Slot_index.to_octez index in let* processed = - Node_context.processed_slot node_ctxt ~confirmed_in_block_hash index + Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in match processed with - | None -> - let* published_in_block_hash = - Node_context.hash_of_level - node_ctxt - (Raw_level.to_int32 published_level) - in - check_confirmation_status_and_download - node_ctxt - ~published_in_block_hash - ~confirmed_in_block_hash - index - | Some `Unconfirmed -> return (Delayed_write_monad.no_write None) | Some `Confirmed -> let* pages = - Node_context.list_slot_pages node_ctxt ~confirmed_in_block_hash + download_confirmed_slot_pages node_ctxt ~published_level ~index in - let pages = - List.filter_map - (fun ((slot_idx, _page_idx), v) -> - if Dal.Slot_index.equal index slot_idx then Some v else None) - pages - in - return (Delayed_write_monad.no_write (Some pages)) + return (Some pages) + | Some `Unconfirmed -> return None + | None -> storage_invariant_broken published_level index let page_content ~dal_attestation_lag node_ctxt page_id = let open Lwt_result_syntax in - let open Delayed_write_monad.Lwt_result_syntax in let Dal.Page.{slot_id; page_index} = page_id in let Dal.Slot.Header.{published_level; index} = slot_id in let* confirmed_in_block_hash = @@ -171,52 +142,17 @@ let page_content ~dal_attestation_lag node_ctxt page_id = ~published_level node_ctxt in + let index = Sc_rollup_proto_types.Dal.Slot_index.to_octez index in let* processed = - Node_context.processed_slot node_ctxt ~confirmed_in_block_hash index + Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in match processed with - | None -> ( - (* In this case we know that the slot header has not been prefetched - by the rollup node. We check whether it was confirmed by looking at the - block receipt metadata, before requesting the data to the dal node. - While the current logic in `Dal_slots_tracker.donwload_and_save_slots` - guarantees that if `processed = None`, then the slot has been confirmed, - having this additional check in place ensures that we do not rely on - the logic of that function when determining the confirmation status of - a slot. *) - let* published_in_block_hash = - Node_context.hash_of_level - node_ctxt - (Raw_level.to_int32 published_level) - in - let>* pages = - check_confirmation_status_and_download - node_ctxt - ~published_in_block_hash - ~confirmed_in_block_hash - index - in - match pages with - | None -> (* Slot is not confirmed *) return None - | Some (* Slot is confirmed *) pages -> ( - match List.nth_opt pages page_index with - | Some page -> return @@ Some page - | None -> tzfail @@ Dal_invalid_page_for_slot page_id)) - | Some `Unconfirmed -> return None | Some `Confirmed -> ( - let* page_opt = - Node_context.find_slot_page - node_ctxt - ~confirmed_in_block_hash - ~slot_index:index - ~page_index + let* pages = + download_confirmed_slot_pages node_ctxt ~published_level ~index in - match page_opt with - | Some v -> return @@ Some v - | None -> - let* pages = - Node_context.list_slot_pages node_ctxt ~confirmed_in_block_hash - in - if page_index < 0 || List.compare_length_with pages page_index <= 0 - then tzfail @@ Dal_invalid_page_for_slot page_id - else tzfail @@ Dal_slot_not_found_in_store slot_id) + match List.nth_opt pages page_index with + | Some page -> return @@ Some page + | None -> tzfail @@ Dal_invalid_page_for_slot page_id) + | Some `Unconfirmed -> return None + | None -> storage_invariant_broken published_level index diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.mli index 2a9a69a71b95..3be2cdb1f5ab 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_pages_request.mli @@ -57,7 +57,7 @@ val slot_pages : dal_attestation_lag:int -> _ Node_context.t -> Dal.slot_id -> - Dal.Page.content list option Node_context.delayed_write tzresult Lwt.t + Dal.Page.content list option tzresult Lwt.t (** Retrieve the content of the page identified by the given ID from the store. @@ -73,4 +73,4 @@ val page_content : dal_attestation_lag:int -> _ Node_context.t -> Dal.Page.t -> - Dal.Page.content option Node_context.delayed_write tzresult Lwt.t + Dal.Page.content option tzresult Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.ml index 93bff8ef31e7..f7418051577f 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.ml @@ -33,7 +33,7 @@ let ancestor_hash ~number_of_levels let genesis_level = genesis_info.level in let rec go number_of_levels (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - if level < Raw_level.to_int32 genesis_level then return_none + if level < genesis_level then return_none else if number_of_levels = 0 then return_some hash else let* pred_head = Node_context.get_predecessor_opt node_ctxt head in @@ -69,9 +69,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = we reduce the lag to 1, then the slots header will never be confirmed. *) let open Lwt_result_syntax in - let lag = - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag - in + let lag = node_ctxt.Node_context.protocol_constants.dal.attestation_lag in (* we are downloading endorsemented for slots at level [level], so we need to download the data at level [level - lag]. *) @@ -108,7 +106,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = let confirmed_slots_indexes_list = List.filter (Dal.Attestation.is_attested confirmed_slots) - published_slots_indexes + (List.filter_map Dal.Slot_index.of_int published_slots_indexes) in let*? confirmed_slots_indexes = Environment.wrap_tzresult @@ -118,101 +116,64 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = in return @@ Some {published_block_hash; confirmed_slots_indexes} -let is_slot_confirmed node_ctxt (Layer1.{hash; _} as head) slot_index = - let open Lwt_result_syntax in - let* slots_info_opt = slots_info node_ctxt head in - match slots_info_opt with - | None -> tzfail @@ Layer1_services.Cannot_read_block_metadata hash - | Some {confirmed_slots_indexes; _} -> - let*? is_confirmed = - Environment.wrap_tzresult - @@ Bitset.mem confirmed_slots_indexes (Dal.Slot_index.to_int slot_index) - in - return is_confirmed - (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3884 avoid going back and forth between bitsets and lists of slot indexes. *) -let to_slot_index_list (constants : Constants.Parametric.t) bitset = - let open Result_syntax in +let to_slot_index_list (constants : Rollup_constants.protocol_constants) bitset + = let all_slots = Misc.(0 --> (constants.dal.number_of_slots - 1)) in - let+ filtered = List.filter_e (Bitset.mem bitset) all_slots in - (* Because the maximum slot index is smaller than the number_of_slots protocol - constants, and this value is smaller than the hard limit imposed for slots, - then Dal.Slot_index.to_int will always return a defined value. See - `src/proto_alpha/lib_protocol/constants_repr.ml`. - *) - List.filter_map Dal.Slot_index.of_int filtered + List.filter_e (Bitset.mem bitset) all_slots (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/4139. Use a shared storage between dal and rollup node to store slots data. *) let download_and_save_slots - ({Node_context.dal_cctxt; protocol_constants; _} as node_context) - ~current_block_hash {published_block_hash; confirmed_slots_indexes} = + ({Node_context.protocol_constants; _} as node_context) ~current_block_hash + {published_block_hash; confirmed_slots_indexes} = let open Lwt_result_syntax in let*? all_slots = - Bitset.fill ~length:protocol_constants.parametric.dal.number_of_slots + Bitset.fill ~length:protocol_constants.dal.number_of_slots |> Environment.wrap_tzresult in let*? not_confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric + @@ to_slot_index_list protocol_constants @@ Bitset.diff all_slots confirmed_slots_indexes in - let*? _confirmed = + let*? confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric confirmed_slots_indexes + @@ to_slot_index_list protocol_constants confirmed_slots_indexes in - (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/2766. - As part of the clean rollup storage workflow, we should make sure that - pages for old slots are removed from the storage when not needed anymore. - *) (* The contents of each slot index are written to a different location on disk, therefore calls to store contents for different slot indexes can be parallelized. *) let* () = List.iter_ep (fun s_slot -> - Node_context.save_unconfirmed_slot + Node_context.save_slot_status node_context current_block_hash - s_slot) + s_slot + `Unconfirmed) not_confirmed in - let* () = - [] (* Preparing for the pre-fetching logic. *) - |> List.iter_ep (fun s_slot -> - (* fails if slot_header is missing but the slot with index s_slot has been - confirmed. This scenario should not be possible. *) - let* {commitment; _} = - Node_context.get_slot_header - node_context - ~published_in_block_hash:published_block_hash - s_slot - in - (* DAL must be configured for this point to be reached *) - let dal_cctxt = WithExceptions.Option.get ~loc:__LOC__ dal_cctxt in - (* The slot with index s_slot is confirmed. We can - proceed retrieving it from the dal node and save it - in the store. *) - let* pages = Dal_node_client.get_slot_pages dal_cctxt commitment in - let* () = - Node_context.save_confirmed_slot - node_context - current_block_hash - s_slot - pages - in - let*! () = - Dal_slots_tracker_event.slot_has_been_confirmed - s_slot - published_block_hash - current_block_hash - in - return_unit) - in - return_unit + List.iter_ep + (fun s_slot -> + let* () = + Node_context.save_slot_status + node_context + current_block_hash + s_slot + `Confirmed + in + let*! () = + Dal_slots_tracker_event.slot_has_been_confirmed + (Sc_rollup_proto_types.Dal.Slot_index.of_octez s_slot) + published_block_hash + current_block_hash + in + return_unit) + confirmed module Confirmed_slots_history = struct (** [confirmed_slots_with_headers node_ctxt confirmations_info] returns the @@ -224,22 +185,27 @@ module Confirmed_slots_history = struct let*? relevant_slots_indexes = Environment.wrap_tzresult @@ to_slot_index_list - node_ctxt.Node_context.protocol_constants.parametric + node_ctxt.Node_context.protocol_constants confirmed_slots_indexes in List.map_ep (fun slot_index -> - Node_context.get_slot_header - node_ctxt - ~published_in_block_hash:published_block_hash - slot_index) + let+ h = + Node_context.get_slot_header + node_ctxt + ~published_in_block_hash:published_block_hash + slot_index + in + Sc_rollup_proto_types.Dal.Slot_header.of_octez h) relevant_slots_indexes let read_slots_history_from_l1 {Node_context.cctxt; _} block = let open Lwt_result_syntax in (* We return the empty Slots_history if DAL is not enabled. *) let* slots_list_opt = - RPC.Dal.dal_confirmed_slots_history cctxt (cctxt#chain, `Hash (block, 0)) + RPC.Dal.dal_confirmed_slots_history + (new Protocol_client_context.wrap_full cctxt) + (cctxt#chain, `Hash (block, 0)) in return @@ Option.value slots_list_opt ~default:Dal.Slots_history.genesis @@ -251,11 +217,10 @@ module Confirmed_slots_history = struct let should_process_dal_slots node_ctxt block_level = let open Node_context in let lag = - Int32.of_int - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag + Int32.of_int node_ctxt.Node_context.protocol_constants.dal.attestation_lag in let block_level = Raw_level.to_int32 block_level in - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let genesis_level = node_ctxt.genesis_info.level in Int32.(block_level >= add lag genesis_level) let dal_entry_of_block_hash node_ctxt @@ -290,23 +255,32 @@ module Confirmed_slots_history = struct block_level let slots_history_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_history node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history" - ~find:Node_context.find_confirmed_slots_history + ~find ~default:read_slots_history_from_l1 let slots_history_cache_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_histories node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history cache" - ~find:Node_context.find_confirmed_slots_histories + ~find ~default:(fun node_ctxt _block -> let num_slots = - node_ctxt.Node_context.protocol_constants.parametric.dal - .number_of_slots + node_ctxt.Node_context.protocol_constants.dal.number_of_slots in (* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3788 Put an accurate value for capacity. The value @@ -354,13 +328,13 @@ module Confirmed_slots_history = struct Node_context.save_confirmed_slots_history node_ctxt head_hash - slots_history + (Sc_rollup_proto_types.Dal.Slot_history.to_octez slots_history) in let* () = Node_context.save_confirmed_slots_histories node_ctxt head_hash - slots_cache + (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez slots_cache) in return () end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.mli index bd1f4ce76201..c05672d93a0e 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/dal_slots_tracker.mli @@ -22,8 +22,6 @@ (* DEALINGS IN THE SOFTWARE. *) (* *) (*****************************************************************************) -open Protocol -open Alpha_context (** The rollup node keeps the list of dal slots for each block it needs to process. This is to determine whether the inbox for a given block will need @@ -33,11 +31,6 @@ open Alpha_context The state of slots per block is persistent. *) -(** [is_slot_confirmed node_ctxt head slot_index] checks whether the slot - with index [slot_index] has been confirmed in [head]. *) -val is_slot_confirmed : - _ Node_context.t -> Layer1.head -> Dal.Slot_index.t -> bool tzresult Lwt.t - (** [process_head node_ctxt head] performs the following operations: {ul {li it reads the endorsements for headers published attestation_lag 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 ef191a23d269..b56a7d48c8fc 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 @@ -39,14 +39,13 @@ module type S = sig 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 : Raw_level.t; - (** Inbox level in which messages are evaluated. *) + 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 : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; (** Messages of the inbox that remain to be evaluated. *) } @@ -61,7 +60,7 @@ module type S = sig val eval_block_inbox : fuel:fuel -> _ Node_context.t -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.serialized list -> + Octez_smart_rollup.Inbox.t * string list -> pvm_state -> eval_result Node_context.delayed_write tzresult Lwt.t @@ -90,10 +89,10 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct state : pvm_state; state_hash : Sc_rollup.State_hash.t; tick : Sc_rollup.Tick.t; - inbox_level : Raw_level.t; + inbox_level : int32; message_counter_offset : int; remaining_fuel : fuel; - remaining_messages : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; } type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} @@ -119,6 +118,15 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct exception Error_wrapper of tztrace + let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = + Raw_level.of_int32_exn node_ctxt.genesis_info.level + in + Sc_rollup.Metadata.{address; origination_level} + (** [eval_until_input node_ctxt reveal_map level message_index ~fuel start_tick failing_ticks state] advances a PVM [state] until it wants more inputs or there are no more [fuel] (if [Some fuel] is @@ -130,10 +138,10 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct message_index ~fuel start_tick failing_ticks state = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in - let metadata = Node_context.metadata node_ctxt in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in + let metadata = metadata node_ctxt in let dal_attestation_lag = - node_ctxt.protocol_constants.parametric.dal.attestation_lag + node_ctxt.protocol_constants.dal.attestation_lag in let reveal_builtins = Tezos_scoru_wasm.Builtins. @@ -266,7 +274,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct | Some fuel -> go fuel (Int64.succ current_tick) failing_ticks next_state) | Needs_reveal (Request_dal_page page_id) -> ( - let>* content_opt = + let* content_opt = Dal_pages_request.page_content ~dal_attestation_lag node_ctxt @@ -306,7 +314,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct ~fuel ~failing_ticks state input = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* res = eval_until_input node_ctxt @@ -362,7 +370,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_messages ~reveal_map ~fuel node_ctxt ~message_counter_offset state inbox_level messages = let open Delayed_write_monad.Lwt_result_syntax in - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in (* Iterate the PVM state with all the messages. *) let rec feed_messages (state, fuel) message_index = function | [] -> @@ -372,9 +380,15 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct (* Consumed all fuel *) return (state, fuel, message_index - message_counter_offset, messages) | message :: messages -> ( + let payload = Sc_rollup.Inbox_message.unsafe_of_string message in let message_counter = Z.of_int message_index in let input = - Sc_rollup.{inbox_level; message_counter; payload = message} + Sc_rollup. + { + inbox_level = Raw_level.of_int32_exn inbox_level; + message_counter; + payload; + } in let failing_ticks = Loser_mode.is_failure @@ -416,9 +430,9 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct 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 node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in (* Obtain inbox and its messages for this block. *) - let inbox_level = Inbox.inbox_level inbox in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in let*! initial_tick = PVM.get_tick state in (* Evaluate all the messages for this level. *) let>* state, remaining_fuel, num_messages, remaining_messages = @@ -459,11 +473,11 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct } = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* state, remaining_fuel, num_messages, remaining_messages = match messages with | [] -> - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in let message_index = message_counter_offset - 1 in let failing_ticks = Loser_mode.is_failure diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.ml index 3b258f344e5f..704b2826b138 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.ml @@ -78,12 +78,22 @@ let get_messages Node_context.{l1_ctxt; _} head = block.operations {apply; apply_internal}) in - return (List.rev rev_messages) + let*? messages = + Environment.wrap_tzresult + @@ List.rev_map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + rev_messages + in + return messages let same_as_layer_1 node_ctxt head_hash inbox = let open Lwt_result_syntax in let head_block = `Hash (head_hash, 0) in let Node_context.{cctxt; _} = node_ctxt in + let cctxt = new Protocol_client_context.wrap_full cctxt in let* layer1_inbox = Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, head_block) in @@ -127,6 +137,15 @@ let process_messages (node_ctxt : _ Node_context.t) let predecessor_timestamp = predecessor.header.timestamp in let inbox_metrics = Metrics.Inbox.metrics in Prometheus.Gauge.set inbox_metrics.head_inbox_level @@ Int32.to_float level ; + let inbox = Sc_rollup_proto_types.Inbox.of_octez inbox in + let serialized_messages = messages in + let*? messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let* ( _messages_history, witness_hash, inbox, @@ -137,6 +156,11 @@ let process_messages (node_ctxt : _ Node_context.t) inbox messages in + let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in + let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + let witness_hash = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez witness_hash + in Metrics.Inbox.Stats.set messages_with_protocol_internal_messages ~is_internal:(function @@ -147,18 +171,24 @@ let process_messages (node_ctxt : _ Node_context.t) node_ctxt witness_hash ~block_hash:head.hash - messages + serialized_messages + in + let*? messages_with_protocol_internal_messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + messages_with_protocol_internal_messages in - let* inbox_hash = Node_context.save_inbox node_ctxt inbox in return (inbox_hash, inbox, witness_hash, messages_with_protocol_internal_messages) let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) (head : Layer1.header) = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.level >= first_inbox_level then (* We compute the inbox of this block using the inbox of its predecessor. That way, the computation of inboxes is robust to chain @@ -172,12 +202,19 @@ let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) in process_messages node_ctxt ~predecessor head collected_messages else - let* inbox = Node_context.genesis_inbox node_ctxt in - return - ( Sc_rollup.Inbox.hash inbox, - inbox, - Sc_rollup.Inbox.current_witness inbox, - [] ) + let* inbox = + Layer1_helpers.genesis_inbox + (new Protocol_client_context.wrap_full node_ctxt.cctxt) + ~genesis_level:node_ctxt.genesis_info.level + in + let Octez_smart_rollup.Inbox.{hash = witness; _} = + Octez_smart_rollup.Inbox.Skip_list.content inbox.old_levels_messages + in + let* () = + Node_context.save_messages node_ctxt witness ~block_hash:head.hash [] + in + let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + return (inbox_hash, inbox, witness, []) let start () = Inbox_event.starting () @@ -191,6 +228,12 @@ let payloads_history_of_messages ~predecessor ~predecessor_timestamp messages = ~predecessor Raw_level.root in + let* messages = + List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let+ ( payloads_history, _history, _inbox, diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.mli index 8c7ea9599a9f..a5f3a461128f 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/inbox.mli @@ -44,10 +44,10 @@ val process_head : Node_context.rw -> predecessor:Layer1.header -> Layer1.header -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t + * string list) tzresult Lwt.t @@ -75,7 +75,7 @@ val add_messages : val payloads_history_of_messages : predecessor:Block_hash.t -> predecessor_timestamp:Timestamp.time -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup.Inbox_merkelized_payload_hashes.History.t tzresult (** [same_as_layer_1 node_ctxt block node_inbox] ensures that the rollup @@ -93,11 +93,11 @@ module Internal_for_tests : sig Node_context.rw -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox_message.t list -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + string list -> + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t + * string list) tzresult Lwt.t end 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 bdcf20eef540..e85973339fe8 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.ml @@ -44,7 +44,10 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = match (operation, result) with | ( Sc_rollup_originate {kind; boot_sector; _}, Sc_rollup_originate_result {address; _} ) - when node_ctxt.rollup_address = address && node_ctxt.kind = kind -> + 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 @@ -69,7 +72,7 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let genesis_state block_hash node_ctxt ctxt = let open Lwt_result_syntax in let* boot_sector = get_boot_sector block_hash node_ctxt in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! genesis_state = PVM.install_boot_sector initial_state boot_sector in let*! ctxt = PVM.State.set ctxt genesis_state in @@ -80,9 +83,7 @@ let state_of_head node_ctxt ctxt Layer1.{hash; level} = let*! state = Context.PVMState.find ctxt in match state with | None -> - let genesis_level = - Raw_level.to_int32 node_ctxt.Node_context.genesis_info.level - in + let genesis_level = node_ctxt.Node_context.genesis_info.level in if level = genesis_level then genesis_state hash node_ctxt ctxt else tzfail (Sc_rollup_node_errors.Missing_PVM_state (hash, level)) | Some state -> return (ctxt, state) @@ -109,7 +110,9 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} } = Delayed_write_monad.apply node_ctxt eval_result in - let module PVM = (val node_ctxt.pvm) 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 (* Produce events. *) @@ -121,25 +124,17 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} (** [process_head node_ctxt ctxt ~predecessor head] runs the PVM for the given head. *) let process_head (node_ctxt : _ Node_context.t) ctxt - ~(predecessor : Layer1.header) (head : Layer1.header) (inbox, inbox_messages) - = + ~(predecessor : Layer1.header) (head : Layer1.header) inbox_and_messages = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.Layer1.level >= first_inbox_level then - let*? inbox_messages = - List.map_e Sc_rollup.Inbox_message.serialize inbox_messages - |> Environment.wrap_tzresult - in transition_pvm node_ctxt ctxt (Layer1.head_of_header predecessor) (Layer1.head_of_header head) - (inbox, inbox_messages) - else if head.Layer1.level = Raw_level.to_int32 node_ctxt.genesis_info.level - then + inbox_and_messages + else if head.Layer1.level = node_ctxt.genesis_info.level then let* ctxt, state = genesis_state head.hash node_ctxt ctxt in let*! ctxt = Context.PVMState.set ctxt state in return (ctxt, 0, 0L, Sc_rollup.Tick.initial) @@ -160,30 +155,26 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = ctxt Layer1.{hash = block.header.predecessor; level = pred_level} in - let* inbox = - Node_context.get_inbox - node_ctxt - (Sc_rollup_proto_types.Inbox_hash.of_octez block.header.inbox_hash) + let* inbox = Node_context.get_inbox node_ctxt block.header.inbox_hash in + let* {predecessor; predecessor_timestamp; messages; _} = + Node_context.get_messages node_ctxt block.header.inbox_witness in - let* {predecessor; predecessor_timestamp; messages} = - Node_context.get_messages - node_ctxt - (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez - block.header.inbox_witness) - in - let inbox_level = Sc_rollup.Inbox.inbox_level inbox in - let module PVM = (val node_ctxt.pvm) in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in let*! state_hash = PVM.state_hash state in + let*? info_per_level = + Environment.wrap_tzresult + @@ Sc_rollup_inbox_message_repr.( + serialize + (Internal (Info_per_level {predecessor; predecessor_timestamp}))) + in let messages = - Sc_rollup.Inbox_message.Internal Start_of_level - :: Internal (Info_per_level {predecessor; predecessor_timestamp}) + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized + :: unsafe_to_string info_per_level :: messages - @ [Internal End_of_level] - in - let*? messages = - List.map_e Sc_rollup.Inbox_message.serialize messages - |> Environment.wrap_tzresult + @ [unsafe_to_string end_of_level_serialized] in return Fueled_pvm.Accounted. @@ -217,8 +208,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 Raw_level.to_int32 start_state.Fueled_pvm.Accounted.inbox_level - = event.header.level -> + when start_state.Fueled_pvm.Accounted.inbox_level = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a @@ -263,11 +253,14 @@ let memo_state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) returns [None].*) 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 <= Raw_level.to_int32 level) ; + 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 44cabfbbab1e..48cff9f6ceb5 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter.mli @@ -38,7 +38,7 @@ val process_head : 'a Context.t -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.t list -> + Octez_smart_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Sc_rollup.Tick.t) tzresult Lwt.t (** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter_event.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter_event.ml index 80fab8ac3274..967bbe9094f2 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter_event.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/interpreter_event.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol.Alpha_context.Sc_rollup - module Simple = struct include Internal_event.Simple @@ -38,9 +36,9 @@ module Simple = struct "Transitioned PVM at inbox level {inbox_level} to {state_hash} at tick \ {ticks} with {num_messages} messages" ~level:Notice - ("inbox_level", Protocol.Alpha_context.Raw_level.encoding) - ("state_hash", State_hash.encoding) - ("ticks", Tick.encoding) + ("inbox_level", Data_encoding.int32) + ("state_hash", Octez_smart_rollup.State_hash.encoding) + ("ticks", Data_encoding.n) ("num_messages", Data_encoding.int31) let intended_failure = 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 8312c2584373..22da00e35549 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 @@ -52,3 +52,114 @@ let fetch_tezos_block l1_ctxt hash = Protocol.name let prefetch_tezos_blocks = Layer1.prefetch_tezos_blocks fetch extract_header + +let get_last_cemented_commitment (cctxt : Protocol_client_context.full) + rollup_address : Node_context.lcc tzresult Lwt.t = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ commitment, level = + Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level + cctxt + (cctxt#chain, `Head 0) + rollup_address + in + { + Node_context.commitment = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment; + level = Protocol.Alpha_context.Raw_level.to_int32 level; + } + +let get_last_published_commitment (cctxt : Protocol_client_context.full) + rollup_address operator = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let*! res = + Plugin.RPC.Sc_rollup.staked_on_commitment + cctxt + (cctxt#chain, `Head 0) + rollup_address + operator + in + match res with + | Error trace + when TzTrace.fold + (fun exists -> function + | Environment.Ecoproto_error + Protocol.Sc_rollup_errors.Sc_rollup_not_staked -> + true + | _ -> exists) + false + trace -> + return_none + | Error trace -> fail trace + | Ok None -> return_none + | Ok (Some (_staked_hash, staked_commitment)) -> + return_some (Sc_rollup_proto_types.Commitment.to_octez staked_commitment) + +let get_kind cctxt rollup_address = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ kind = + RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () + in + Sc_rollup_proto_types.Kind.to_octez kind + +let genesis_inbox cctxt ~genesis_level = + let open Lwt_result_syntax in + let+ inbox = + Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, `Level genesis_level) + in + Sc_rollup_proto_types.Inbox.to_octez inbox + +let constants_of_parametric + Protocol.Alpha_context.Constants.Parametric. + { + minimal_block_delay; + delay_increment_per_round; + sc_rollup = {challenge_window_in_blocks; commitment_period_in_blocks; _}; + dal = {feature_enable; attestation_lag; number_of_slots; _}; + _; + } = + let open Protocol.Alpha_context in + Rollup_constants. + { + minimal_block_delay = Period.to_seconds minimal_block_delay; + delay_increment_per_round = Period.to_seconds delay_increment_per_round; + sc_rollup = + { + challenge_window_in_blocks; + commitment_period_in_blocks; + reveal_activation_level = None; + }; + dal = {feature_enable; attestation_lag; number_of_slots}; + } + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 + The constants are retrieved from the latest tezos block. These constants can + be different from the ones used at the creation at the rollup because of a + protocol amendment that modifies some of them. This need to be fixed when the + rollup nodes will be able to handle the migration of protocol. +*) +let retrieve_constants ?(block = `Head 0) cctxt = + let open Lwt_result_syntax in + let+ {parametric; _} = + Protocol.Constants_services.all cctxt (cctxt#chain, block) + in + constants_of_parametric parametric + +let retrieve_genesis_info cctxt rollup_address = + let open Lwt_result_syntax in + let open Protocol.Alpha_context in + let+ {level; commitment_hash} = + RPC.Sc_rollup.genesis_info + cctxt + (cctxt#chain, `Head 0) + (Sc_rollup_proto_types.Address.of_octez rollup_address) + in + + Node_context. + { + level = Raw_level.to_int32 level; + commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; + } 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 3b6fc64abf0a..605c80fcbdd0 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 @@ -38,3 +38,36 @@ val fetch_tezos_block : asynchronously. NOTE: the number of blocks to prefetch must not be greater than the size of the blocks cache otherwise they will be lost. *) val prefetch_tezos_blocks : t -> head list -> unit + +val get_last_cemented_commitment : + Protocol_client_context.full -> Address.t -> Node_context.lcc tzresult Lwt.t + +val get_last_published_commitment : + Protocol_client_context.full -> + Address.t -> + Signature.public_key_hash -> + Commitment.t option tzresult Lwt.t + +val get_kind : + Protocol_client_context.full -> Address.t -> Kind.t tzresult Lwt.t + +val genesis_inbox : + Protocol_client_context.full -> + genesis_level:int32 -> + Octez_smart_rollup.Inbox.t tzresult Lwt.t + +(** Convert protocol constants to their protocol agnostic representation. *) +val constants_of_parametric : + Protocol.Alpha_context.Constants.Parametric.t -> + Rollup_constants.protocol_constants + +(** Retrieve protocol agnotic constants for the head of the chain. *) +val retrieve_constants : + ?block:Block_services.block -> + Protocol_client_context.full -> + Rollup_constants.protocol_constants tzresult Lwt.t + +val retrieve_genesis_info : + Protocol_client_context.full -> + Address.t -> + Node_context.genesis_info tzresult Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml deleted file mode 100644 index 448e71450071..000000000000 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml +++ /dev/null @@ -1,1283 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 TriliTech *) -(* 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 - -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -type 'a store = 'a Store.t - -type debug_logger = string -> unit Lwt.t - -type 'a t = { - cctxt : Protocol_client_context.full; - dal_cctxt : Dal_node_client.cctxt option; - data_dir : string; - l1_ctxt : Layer1.t; - rollup_address : Sc_rollup.t; - mode : Configuration.mode; - operators : Configuration.operators; - genesis_info : Sc_rollup.Commitment.genesis_info; - injector_retention_period : int; - block_finality_time : int; - kind : Sc_rollup.Kind.t; - pvm : (module Pvm.S); - fee_parameters : Configuration.fee_parameters; - protocol_constants : Constants.t; - proto_level : int; - loser_mode : Loser_mode.t; - lockfile : Lwt_unix.file_descr; - store : 'a store; - context : 'a Context.index; - lcc : ('a, lcc) Reference.t; - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; - kernel_debug_logger : debug_logger; - finaliser : unit -> unit Lwt.t; -} - -type rw = [`Read | `Write] t - -type ro = [`Read] t - -let () = - if - Tezos_crypto.Hashed.Smart_rollup_address.size - <> Protocol.Alpha_context.Sc_rollup.Address.size - then - Format.ksprintf - Stdlib.failwith - "Protocol %s is not compatible with rollup addresses of size %d" - Protocol.name - Tezos_crypto.Hashed.Smart_rollup_address.size - -let get_operator node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.operators - -let is_operator node_ctxt pkh = - Configuration.Operator_purpose_map.exists - (fun _ operator -> Tezos_crypto.Signature.Public_key_hash.(operator = pkh)) - node_ctxt.operators - -let is_accuser {mode; _} = mode = Accuser - -let is_loser {loser_mode; _} = loser_mode <> Loser_mode.no_failures - -let get_fee_parameter node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.fee_parameters - |> Option.value ~default:(Configuration.default_fee_parameter ~purpose ()) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 - The constants are retrieved from the latest tezos block. These constants can - be different from the ones used at the creation at the rollup because of a - protocol amendment that modifies some of them. This need to be fixed when the - rollup nodes will be able to handle the migration of protocol. -*) -let retrieve_constants cctxt = - Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) - -let get_last_cemented_commitment (cctxt : Protocol_client_context.full) - rollup_address = - let open Lwt_result_syntax in - let+ commitment, level = - Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level - cctxt - (cctxt#chain, `Head 0) - rollup_address - in - {commitment; level} - -let get_last_published_commitment (cctxt : Protocol_client_context.full) - rollup_address operator = - let open Lwt_result_syntax in - let*! res = - Plugin.RPC.Sc_rollup.staked_on_commitment - cctxt - (cctxt#chain, `Head 0) - rollup_address - operator - in - match res with - | Error trace - when TzTrace.fold - (fun exists -> function - | Environment.Ecoproto_error Sc_rollup_errors.Sc_rollup_not_staked - -> - true - | _ -> exists) - false - trace -> - return_none - | Error trace -> fail trace - | Ok None -> return_none - | Ok (Some (_staked_hash, staked_commitment)) -> return_some staked_commitment - -let lock ~data_dir = - let lockfile_path = Filename.concat data_dir "lock" in - let lock_aux ~data_dir = - let open Lwt_result_syntax in - let*! () = Event.acquiring_lock () in - let*! () = Lwt_utils_unix.create_dir data_dir in - let* lockfile = - protect @@ fun () -> - Lwt_unix.openfile - lockfile_path - [Unix.O_CREAT; O_RDWR; O_CLOEXEC; O_SYNC] - 0o644 - |> Lwt_result.ok - in - let* () = - protect ~on_error:(fun err -> - let*! () = Lwt_unix.close lockfile in - fail err) - @@ fun () -> - let*! () = Lwt_unix.lockf lockfile Unix.F_LOCK 0 in - return_unit - in - return lockfile - in - trace (Sc_rollup_node_errors.Could_not_acquire_lock lockfile_path) - @@ lock_aux ~data_dir - -let unlock {lockfile; _} = - Lwt.finalize - (fun () -> Lwt_unix.lockf lockfile Unix.F_ULOCK 0) - (fun () -> Lwt_unix.close lockfile) - -let make_kernel_logger ?log_kernel_debug_file data_dir = - let open Lwt_syntax in - let path = - match log_kernel_debug_file with - | None -> Filename.concat data_dir "kernel.log" - | Some path -> path - in - let+ fd = - Lwt_unix.openfile path Lwt_unix.[O_WRONLY; O_CREAT; O_APPEND] 0o0644 - in - Lwt_io.of_fd ~close:(fun () -> Lwt_unix.close fd) ~mode:Lwt_io.Output fd - -let pvm_of_kind : Protocol.Alpha_context.Sc_rollup.Kind.t -> (module Pvm.S) = - function - | Example_arith -> (module Arith_pvm) - | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) - -let check_fee_parameters Configuration.{fee_parameters; _} = - let check_value purpose name compare to_string mempool_default value = - if compare mempool_default value > 0 then - error_with - "Bad configuration fee_parameter.%s for %s. It must be at least %s for \ - operations of the injector to be propagated." - name - (Configuration.string_of_purpose purpose) - (to_string mempool_default) - else Ok () - in - let check purpose - { - Injector_sigs.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee = _; - fee_cap = _; - burn_cap = _; - } = - let open Result_syntax in - let+ () = - check_value - purpose - "minimal_fees" - Int64.compare - Int64.to_string - (Tez.to_mutez Plugin.Mempool.default_minimal_fees) - minimal_fees.mutez - and+ () = - check_value - purpose - "minimal_nanotez_per_byte" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_byte - minimal_nanotez_per_byte - and+ () = - check_value - purpose - "minimal_nanotez_per_gas_unit" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_gas_unit - minimal_nanotez_per_gas_unit - in - () - in - Configuration.Operator_purpose_map.iter_e check fee_parameters - -let protocol_max_batch_size = - let empty_message_op : _ Operation.t = - let open Protocol in - let open Alpha_context in - let open Operation in - { - shell = {branch = Block_hash.zero}; - protocol_data = - { - signature = Some Signature.zero; - contents = - Single - (Manager_operation - { - source = Signature.Public_key_hash.zero; - fee = Tez.of_mutez_exn Int64.max_int; - counter = Manager_counter.Internal_for_tests.of_int max_int; - gas_limit = - Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); - storage_limit = Z.of_int max_int; - operation = Sc_rollup_add_messages {messages = [""]}; - }); - }; - } - in - Protocol.Constants_repr.max_operation_data_length - - Data_encoding.Binary.length - Operation.encoding - (Operation.pack empty_message_op) - -let check_batcher_config Configuration.{batcher = {max_batch_size; _}; _} = - match max_batch_size with - | Some m when m > protocol_max_batch_size -> - error_with - "batcher.max_batch_size must be smaller than %d" - protocol_max_batch_size - | _ -> Ok () - -let check_config config = - let open Result_syntax in - let+ () = check_fee_parameters config and+ () = check_batcher_config config in - () - -let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file - mode l1_ctxt ~proto_level - Configuration.( - { - sc_rollup_address; - sc_rollup_node_operators = operators; - mode = operating_mode; - fee_parameters; - loser_mode; - l2_blocks_cache_size; - dal_node_endpoint; - _; - } as configuration) = - let open Lwt_result_syntax in - let*? () = check_config configuration in - let* lockfile = lock ~data_dir in - let* () = - Store_migration.maybe_run_migration - ~storage_dir:(Configuration.default_storage_dir data_dir) - in - let dal_cctxt = - Option.map Dal_node_client.make_unix_cctxt dal_node_endpoint - in - let* store = - Store.load - mode - ~l2_blocks_cache_size - Configuration.(default_storage_dir data_dir) - in - let* context = - Context.load mode (Configuration.default_context_dir data_dir) - in - let* () = - Context.Rollup.check_or_set_address mode context sc_rollup_address - in - let publisher = Configuration.Operator_purpose_map.find Publish operators in - let rollup_address = - (* Convert to protocol rollup address *) - Sc_rollup_proto_types.Address.of_octez sc_rollup_address - in - let* protocol_constants = retrieve_constants cctxt - and* lcc = get_last_cemented_commitment cctxt rollup_address - and* lpc = - Option.filter_map_es - (get_last_published_commitment cctxt rollup_address) - publisher - and* kind = - RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () - and* genesis_info = - RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, cctxt#block) rollup_address - in - let*! () = - Event.rollup_exists - ~addr:sc_rollup_address - ~kind:(Sc_rollup_proto_types.Kind.to_octez kind) - in - let*! () = - if dal_cctxt = None && protocol_constants.parametric.dal.feature_enable then - Event.warn_dal_enabled_no_node () - else Lwt.return_unit - in - let*! kernel_debug_logger, kernel_debug_finaliser = - let open Lwt_syntax in - let kernel_debug = Event.kernel_debug in - if configuration.log_kernel_debug then - let+ chan = make_kernel_logger ?log_kernel_debug_file data_dir in - let kernel_debug msg = - let* () = Lwt_io.write chan msg in - let* () = Lwt_io.flush chan in - let* () = kernel_debug msg in - return_unit - in - (kernel_debug, fun () -> Lwt_io.close chan) - else return (kernel_debug, fun () -> return_unit) - in - return - { - cctxt; - dal_cctxt; - data_dir; - l1_ctxt; - rollup_address; - mode = operating_mode; - operators; - genesis_info; - lcc = Reference.new_ lcc; - lpc = Reference.new_ lpc; - kind; - pvm = pvm_of_kind kind; - injector_retention_period = 0; - block_finality_time = 2; - fee_parameters; - protocol_constants; - proto_level; - loser_mode; - lockfile; - store; - context; - kernel_debug_logger; - finaliser = kernel_debug_finaliser; - } - -let close ({cctxt; store; context; l1_ctxt; finaliser; _} as node_ctxt) = - let open Lwt_result_syntax in - let message = cctxt#message in - let*! () = message "Running finaliser@." in - let*! () = finaliser () in - let*! () = message "Shutting down L1@." in - let*! () = Layer1.shutdown l1_ctxt in - let*! () = message "Closing context@." in - let*! () = Context.close context in - let*! () = message "Closing store@." in - let* () = Store.close store in - let*! () = message "Releasing lock@." in - let*! () = unlock node_ctxt in - return_unit - -let checkout_context node_ctxt block_hash = - let open Lwt_result_syntax in - let* l2_header = - Store.L2_blocks.header node_ctxt.store.l2_blocks block_hash - in - let*? context_hash = - match l2_header with - | None -> - error (Sc_rollup_node_errors.Cannot_checkout_context (block_hash, None)) - | Some {context; _} -> ok context - in - let*! ctxt = Context.checkout node_ctxt.context context_hash in - match ctxt with - | None -> - tzfail - (Sc_rollup_node_errors.Cannot_checkout_context - (block_hash, Some context_hash)) - | Some ctxt -> return ctxt - -let metadata node_ctxt = - let address = node_ctxt.rollup_address in - let origination_level = node_ctxt.genesis_info.Sc_rollup.Commitment.level in - Sc_rollup.Metadata.{address; origination_level} - -let dal_supported node_ctxt = - node_ctxt.dal_cctxt <> None - && node_ctxt.protocol_constants.parametric.dal.feature_enable - -let readonly (node_ctxt : _ t) = - { - node_ctxt with - store = Store.readonly node_ctxt.store; - context = Context.readonly node_ctxt.context; - lcc = Reference.readonly node_ctxt.lcc; - lpc = Reference.readonly node_ctxt.lpc; - } - -type 'a delayed_write = ('a, rw) Delayed_write_monad.t - -(** Abstraction over store *) - -module Lwt_result_option_syntax = struct - let ( let** ) a f = - let open Lwt_result_syntax in - let* a in - match a with None -> return_none | Some a -> f a -end - -let hash_of_level_opt {store; cctxt; _} level = - let open Lwt_result_syntax in - let* hash = Store.Levels_to_hashes.find store.levels_to_hashes level in - match hash with - | Some hash -> return_some hash - | None -> - let*! hash = - Tezos_shell_services.Shell_services.Blocks.hash - cctxt - ~chain:cctxt#chain - ~block:(`Level level) - () - in - return (Result.to_option hash) - -let hash_of_level node_ctxt level = - let open Lwt_result_syntax in - let* hash = hash_of_level_opt node_ctxt level in - match hash with - | Some h -> return h - | None -> failwith "Cannot retrieve hash of level %ld" level - -let level_of_hash {l1_ctxt; store; _} hash = - let open Lwt_result_syntax in - let* l2_header = Store.L2_blocks.header store.l2_blocks hash in - match l2_header with - | Some {level; _} -> return level - | None -> - let+ {level; _} = Layer1.fetch_tezos_shell_header l1_ctxt hash in - level - -let save_level {store; _} Layer1.{hash; level} = - Store.Levels_to_hashes.add store.levels_to_hashes level hash - -let save_l2_head {store; _} (head : Sc_rollup_block.t) = - let open Lwt_result_syntax in - let head_info = {head with header = (); content = ()} in - let* () = - Store.L2_blocks.append - store.l2_blocks - ~key:head.header.block_hash - ~header:head.header - ~value:head_info - in - Store.L2_head.write store.l2_head head - -let is_processed {store; _} head = Store.L2_blocks.mem store.l2_blocks head - -let last_processed_head_opt {store; _} = Store.L2_head.read store.l2_head - -let mark_finalized_level {store; _} level = - Store.Last_finalized_level.write store.last_finalized_level level - -let get_finalized_level {store; _} = - let open Lwt_result_syntax in - let+ level = Store.Last_finalized_level.read store.last_finalized_level in - Option.value level ~default:0l - -let get_l2_block {store; _} block_hash = - let open Lwt_result_syntax in - let* block = Store.L2_blocks.read store.l2_blocks block_hash in - match block with - | None -> - failwith "Could not retrieve L2 block for %a" Block_hash.pp block_hash - | Some (info, header) -> return {info with Sc_rollup_block.header} - -let find_l2_block {store; _} block_hash = - let open Lwt_result_syntax in - let+ block = Store.L2_blocks.read store.l2_blocks block_hash in - Option.map (fun (info, header) -> {info with Sc_rollup_block.header}) block - -let get_l2_block_by_level node_ctxt level = - let open Lwt_result_syntax in - Error.trace_lwt_result_with "Could not retrieve L2 block at level %ld" level - @@ let* block_hash = hash_of_level node_ctxt level in - get_l2_block node_ctxt block_hash - -let find_l2_block_by_level node_ctxt level = - let open Lwt_result_syntax in - let* block_hash = hash_of_level_opt node_ctxt level in - match block_hash with - | None -> return_none - | Some block_hash -> find_l2_block node_ctxt block_hash - -let get_finalized_head_opt node_ctxt = - let open Lwt_result_syntax in - let* level = - Store.Last_finalized_level.read node_ctxt.store.last_finalized_level - in - match level with - | None -> return_none - | Some level -> find_l2_block_by_level node_ctxt level - -let head_of_block_level (hash, level) = {Layer1.hash; level} - -let block_level_of_head Layer1.{hash; level} = (hash, level) - -let get_l2_block_predecessor node_ctxt hash = - let open Lwt_result_syntax in - let+ header = Store.L2_blocks.header node_ctxt.store.l2_blocks hash in - Option.map - (fun {Sc_rollup_block.predecessor; level; _} -> - (predecessor, Int32.pred level)) - header - -let get_predecessor_opt node_ctxt (hash, level) = - let open Lwt_result_syntax in - let* pred = get_l2_block_predecessor node_ctxt hash in - match pred with - | Some p -> return_some p - | None -> - (* [head] is not already known in the L2 chain *) - Layer1.get_predecessor_opt node_ctxt.l1_ctxt (hash, level) - -let get_predecessor node_ctxt (hash, level) = - let open Lwt_result_syntax in - let* pred = get_l2_block_predecessor node_ctxt hash in - match pred with - | Some p -> return p - | None -> - (* [head] is not already known in the L2 chain *) - Layer1.get_predecessor node_ctxt.l1_ctxt (hash, level) - -let header_of_hash node_ctxt hash = - let open Lwt_result_syntax in - let+ header = Layer1.fetch_tezos_shell_header node_ctxt.l1_ctxt hash in - {Layer1.hash; level = header.level; header} - -let header_of_head node_ctxt Layer1.{hash; level = _} = - header_of_hash node_ctxt hash - -let get_tezos_reorg_for_new_head node_ctxt old_head new_head = - let open Lwt_result_syntax in - let old_head = - match old_head with - | `Level l -> `Level l - | `Head Layer1.{hash; level} -> `Head (hash, level) - in - let+ reorg = - Layer1.get_tezos_reorg_for_new_head - node_ctxt.l1_ctxt - ~get_old_predecessor:(get_predecessor node_ctxt) - old_head - (block_level_of_head new_head) - in - Reorg.map head_of_block_level reorg - -let get_predecessor_opt node_ctxt head = - let open Lwt_result_syntax in - let+ res = get_predecessor_opt node_ctxt (block_level_of_head head) in - Option.map head_of_block_level res - -let get_predecessor node_ctxt head = - let open Lwt_result_syntax in - let+ res = get_predecessor node_ctxt (block_level_of_head head) in - head_of_block_level res - -let get_predecessor_header_opt node_ctxt head = - let open Lwt_result_syntax in - let* res = get_predecessor_opt node_ctxt (Layer1.head_of_header head) in - Option.map_es (header_of_head node_ctxt) res - -let get_predecessor_header node_ctxt head = - let open Lwt_result_syntax in - let* res = get_predecessor node_ctxt (Layer1.head_of_header head) in - header_of_head node_ctxt res - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/4128 - Unit test the function tick_search. *) - -(** Returns the block that is right before [tick]. [big_step_blocks] is used to - first look for a block before the [tick] *) -let tick_search ~big_step_blocks node_ctxt head tick = - let open Lwt_result_syntax in - if Z.Compare.(head.Sc_rollup_block.initial_tick <= tick) then - if Z.Compare.(Sc_rollup_block.final_tick head < tick) then - (* The head block does not contain the tick *) - return_none - else - (* The starting block contains the tick we want, we are done. *) - return_some head - else - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - let rec find_big_step (end_block : Sc_rollup_block.t) = - let start_level = - Int32.sub end_block.header.level (Int32.of_int big_step_blocks) - in - let start_level = - if start_level < genesis_level then genesis_level else start_level - in - let* start_block = get_l2_block_by_level node_ctxt start_level in - if Z.Compare.(start_block.initial_tick <= tick) then - return (start_block, end_block) - else find_big_step start_block - in - let block_level Sc_rollup_block.{header = {level; _}; _} = - Int32.to_int level - in - let rec dicho start_block end_block = - (* Precondition: - [start_block <> end_block => - end_block.initial_tick > tick >= start_block.initial_tick] *) - let start_level = block_level start_block in - let end_level = block_level end_block in - if end_level - start_level <= 1 then - (* We have found the interval where the tick happened *) - return_some start_block - else - let middle_level = start_level + ((end_level - start_level) / 2) in - let* block_middle = - get_l2_block_by_level node_ctxt (Int32.of_int middle_level) - in - if Z.Compare.(block_middle.initial_tick <= tick) then - dicho block_middle end_block - else dicho start_block block_middle - in - (* First linear approximation *) - let* start_block, end_block = find_big_step head in - (* Then do dichotomy on interval [start_block; end_block] *) - dicho start_block end_block - -let block_with_tick ({store; _} as node_ctxt) ~max_level tick = - let open Lwt_result_syntax in - let open Lwt_result_option_syntax in - Error.trace_lwt_result_with - "Could not retrieve block with tick %a" - Sc_rollup.Tick.pp - tick - @@ let** head = Store.L2_head.read store.l2_head in - (* We start by taking big steps of 4096 blocks for the first - approximation. This means we need at most 20 big steps to start a - dichotomy on a 4096 blocks interval (at most 12 steps). We could take - the refutation period as the big_step_blocks to do a dichotomy on the - full space but we anticipate refutation to happen most of the time close - to the head. *) - let max_level = Raw_level.to_int32 max_level in - let** head = - if head.header.level <= max_level then return_some head - else find_l2_block_by_level node_ctxt max_level - in - tick_search ~big_step_blocks:4096 node_ctxt head (Sc_rollup.Tick.to_z tick) - -let find_octez_commitment {store; _} commitment_hash = - let open Lwt_result_syntax in - let+ commitment = Store.Commitments.read store.commitments commitment_hash in - Option.map fst commitment - -let find_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let+ commitment = find_octez_commitment node_ctxt commitment_hash in - Option.map Sc_rollup_proto_types.Commitment.of_octez commitment - -let get_octez_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let* commitment = find_octez_commitment node_ctxt commitment_hash in - match commitment with - | None -> - failwith - "Could not retrieve commitment %a" - Octez_smart_rollup.Commitment.Hash.pp - commitment_hash - | Some i -> return i - -let get_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let* commitment = find_commitment node_ctxt commitment_hash in - match commitment with - | None -> - failwith - "Could not retrieve commitment %a" - Sc_rollup.Commitment.Hash.pp - commitment_hash - | Some i -> return i - -let commitment_exists {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in - Store.Commitments.mem store.commitments hash - -let save_commitment {store; _} commitment = - let open Lwt_result_syntax in - let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in - let hash = Octez_smart_rollup.Commitment.hash commitment in - let+ () = - Store.Commitments.append store.commitments ~key:hash ~value:commitment - in - Sc_rollup_proto_types.Commitment_hash.of_octez hash - -let commitment_published_at_level {store; _} commitment = - let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in - Store.Commitments_published_at_level.find - store.commitments_published_at_level - commitment - -let set_commitment_published_at_level {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in - Store.Commitments_published_at_level.add - store.commitments_published_at_level - hash - -type commitment_source = Anyone | Us - -let commitment_was_published {store; _} ~source commitment_hash = - let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - match source with - | Anyone -> - Store.Commitments_published_at_level.mem - store.commitments_published_at_level - commitment_hash - | Us -> ( - let+ info = - Store.Commitments_published_at_level.find - store.commitments_published_at_level - commitment_hash - in - match info with - | Some {published_at_level = Some _; _} -> true - | _ -> false) - -let find_octez_inbox {store; _} inbox_hash = - let open Lwt_result_syntax in - let+ inbox = Store.Inboxes.read store.inboxes inbox_hash in - Option.map fst inbox - -let find_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in - let+ inbox = find_octez_inbox node_ctxt inbox_hash in - Option.map Sc_rollup_proto_types.Inbox.of_octez inbox - -let get_octez_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let* inbox = find_octez_inbox node_ctxt inbox_hash in - match inbox with - | None -> - failwith - "Could not retrieve inbox %a" - Octez_smart_rollup.Inbox.Hash.pp - inbox_hash - | Some i -> return i - -let get_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let* inbox = find_inbox node_ctxt inbox_hash in - match inbox with - | None -> - failwith "Could not retrieve inbox %a" Sc_rollup.Inbox.Hash.pp inbox_hash - | Some i -> return i - -let save_inbox {store; _} inbox = - let open Lwt_result_syntax in - let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in - let hash = Octez_smart_rollup.Inbox.hash inbox in - let+ () = Store.Inboxes.append store.inboxes ~key:hash ~value:inbox in - Sc_rollup_proto_types.Inbox_hash.of_octez hash - -let find_inbox_by_block_hash ({store; _} as node_ctxt) block_hash = - let open Lwt_result_syntax in - let* header = Store.L2_blocks.header store.l2_blocks block_hash in - match header with - | None -> return_none - | Some {inbox_hash; _} -> - find_inbox - node_ctxt - (Sc_rollup_proto_types.Inbox_hash.of_octez inbox_hash) - -let genesis_inbox node_ctxt = - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - Plugin.RPC.Sc_rollup.inbox - node_ctxt.cctxt - (node_ctxt.cctxt#chain, `Level genesis_level) - -let inbox_of_head node_ctxt Layer1.{hash = block_hash; level = block_level} = - let open Lwt_result_syntax in - let* possible_inbox = find_inbox_by_block_hash node_ctxt block_hash in - (* Pre-condition: forall l. (l > genesis_level) => inbox[l] <> None. *) - match possible_inbox with - | None -> - (* The inbox exists for each tezos block the rollup should care about. - That is, every block after the origination level. We then join - the bandwagon and build the inbox on top of the protocol's inbox - at the end of the origination level. *) - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - if block_level = genesis_level then genesis_inbox node_ctxt - else if block_level > genesis_level then - (* Invariant broken, the inbox for this level should exist. *) - failwith - "The inbox for block hash %a (level = %ld) is missing." - Block_hash.pp - block_hash - block_level - else - (* The rollup node should not care about levels before the genesis - level. *) - failwith - "Asking for the inbox before the genesis level (i.e. %ld), out of \ - the scope of the rollup's node" - block_level - | Some inbox -> return inbox - -let get_inbox_by_block_hash node_ctxt hash = - let open Lwt_result_syntax in - let* level = level_of_hash node_ctxt hash in - inbox_of_head node_ctxt {hash; level} - -type messages_info = { - predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; -} - -let find_messages node_ctxt messages_hash = - let open Lwt_result_syntax in - let messages_hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez messages_hash - in - let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in - match msg with - | None -> return_none - | Some (messages, block_hash) -> - let* header = header_of_hash node_ctxt block_hash in - let* pred_header = header_of_hash node_ctxt header.header.predecessor in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e - (fun m -> - Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string m)) - messages - in - return_some - { - predecessor = pred_header.hash; - predecessor_timestamp = pred_header.header.timestamp; - messages; - } - -let get_messages_aux find pp node_ctxt hash = - let open Lwt_result_syntax in - let* res = find node_ctxt hash in - match res with - | None -> - failwith - "Could not retrieve messages with payloads merkelized hash %a" - pp - hash - | Some res -> return res - -let get_messages node_ctxt = - get_messages_aux - find_messages - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.pp - node_ctxt - -let get_messages_without_proto_messages node_ctxt = - get_messages_aux - (fun node_ctxt messages_hash -> - let open Lwt_result_syntax in - let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in - match msg with - | None -> return_none - | Some (messages, _block_hash) -> return_some messages) - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp - node_ctxt - -let get_num_messages {store; _} hash = - let open Lwt_result_syntax in - let hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez hash - in - let* msg = Store.Messages.read store.messages hash in - match msg with - | None -> - failwith - "Could not retrieve number of messages for inbox witness %a" - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp - hash - | Some (messages, _block_hash) -> return (List.length messages) - -let save_messages {store; _} key ~block_hash messages = - let open Lwt_result_syntax in - let key = Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez key in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e - (fun m -> - let open Result_syntax in - let+ m = Sc_rollup.Inbox_message.serialize m in - Sc_rollup.Inbox_message.unsafe_to_string m) - messages - in - Store.Messages.append store.messages ~key ~header:block_hash ~value:messages - -let get_full_l2_block node_ctxt block_hash = - let open Lwt_result_syntax in - let* block = get_l2_block node_ctxt block_hash in - let* inbox = get_octez_inbox node_ctxt block.header.inbox_hash - and* messages = - get_messages_without_proto_messages node_ctxt block.header.inbox_witness - and* commitment = - Option.map_es (get_octez_commitment node_ctxt) block.header.commitment_hash - in - return {block with content = {Sc_rollup_block.inbox; messages; commitment}} - -type proto_info = { - proto_level : int; - first_level_of_protocol : bool; - protocol : Protocol_hash.t; -} - -let protocol_of_level node_ctxt level = - let open Lwt_result_syntax in - assert (level >= Raw_level.to_int32 node_ctxt.genesis_info.level) ; - let* protocols = Store.Protocols.read node_ctxt.store.protocols in - let*? protocols = - match protocols with - | None | Some [] -> - error_with "Cannot infer protocol for level %ld: no protocol info" level - | Some protos -> Ok protos - in - let rec find = function - | [] -> - error_with "Cannot infer protocol for level %ld: no information" level - | {Store.Protocols.level = p_level; proto_level; protocol} :: protos -> ( - (* Latest protocols appear first in the list *) - match p_level with - | First_known l when level >= l -> - Ok {protocol; proto_level; first_level_of_protocol = false} - | Activation_level l when level > l -> - (* The block at the activation level is of the previous protocol, so - we are in the protocol that was activated at [l] only when the - level we query is after [l]. *) - Ok - { - protocol; - proto_level; - first_level_of_protocol = level = Int32.succ l; - } - | _ -> (find [@tailcall]) protos) - in - Lwt.return (find protocols) - -let save_protocol_info node_ctxt (block : Layer1.header) - ~(predecessor : Layer1.header) = - let open Lwt_result_syntax in - let* protocols = Store.Protocols.read node_ctxt.store.protocols in - match protocols with - | Some ({proto_level; _} :: _) - when proto_level = block.header.proto_level - && block.header.proto_level = predecessor.header.proto_level -> - (* Nominal case, no protocol change. Nothing to do. *) - return_unit - | None | Some [] -> - (* No protocols information saved in the rollup node yet, initialize with - information by looking at the current head and its predecessor. - We need to figure out if a protocol upgrade happened in one of these two blocks. - *) - let* {current_protocol; next_protocol} = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (block.hash, 0)) - () - and* { - current_protocol = pred_current_protocol; - next_protocol = pred_next_protocol; - } = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (predecessor.hash, 0)) - () - in - (* The first point in the protocol list is the one regarding - [predecessor]. If it is a migration block we register the activation - level, otherwise we don't go back any further and consider it as the - first known block of the protocol. *) - let pred_proto_info = - Store.Protocols. - { - level = - (if Protocol_hash.(pred_current_protocol = pred_next_protocol) - then First_known predecessor.level - else Activation_level predecessor.level); - proto_level = predecessor.header.proto_level; - protocol = pred_next_protocol; - } - in - let protocols = - if Protocol_hash.(current_protocol = next_protocol) then - (* There is no protocol upgrade in [head], so no new point to add the protocol list. *) - [pred_proto_info] - else - (* [head] is a migration block, add the new protocol with its activation in the list. *) - let proto_info = - Store.Protocols. - { - level = Activation_level block.level; - proto_level = block.header.proto_level; - protocol = next_protocol; - } - in - [proto_info; pred_proto_info] - in - Store.Protocols.write node_ctxt.store.protocols protocols - | Some - ({proto_level = last_proto_level; _} :: previous_protocols as protocols) - -> - (* block.header.proto_level <> last_proto_level or head is a migration - block, i.e. there is a protocol change w.r.t. last registered one. *) - let is_head_migration_block = - block.header.proto_level <> predecessor.header.proto_level - in - let* proto_info = - let+ {next_protocol = protocol; _} = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (block.hash, 0)) - () - in - let level = - if is_head_migration_block then - Store.Protocols.Activation_level block.level - else First_known block.level - in - Store.Protocols. - {level; proto_level = block.header.proto_level; protocol} - in - let protocols = - if block.header.proto_level > last_proto_level then - (* Protocol upgrade, add new item to protocol list *) - proto_info :: protocols - else if block.header.proto_level < last_proto_level then ( - (* Reorganization in which a protocol migration block was - backtracked. *) - match previous_protocols with - | [] -> - (* No info further back, store what we know. *) - [proto_info] - | previous_proto :: _ -> - (* make sure that we are in the case where we backtracked the - migration block. *) - assert ( - Protocol_hash.(proto_info.protocol = previous_proto.protocol)) ; - (* Remove last stored protocol *) - previous_protocols) - else - (* block.header.proto_level = last_proto_level && is_migration_block *) - (* Reorganization where we are doing a different protocol - upgrade. Replace last stored protocol. *) - proto_info :: previous_protocols - in - Store.Protocols.write node_ctxt.store.protocols protocols - -let get_slot_header {store; _} ~published_in_block_hash slot_index = - Error.trace_lwt_result_with - "Could not retrieve slot header for slot index %a published in block %a" - Dal.Slot_index.pp - slot_index - Block_hash.pp - published_in_block_hash - @@ - let open Lwt_result_syntax in - let+ header = - Store.Dal_slots_headers.get - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key:(Dal.Slot_index.to_int slot_index) - in - Sc_rollup_proto_types.Dal.Slot_header.of_octez header - -let get_all_slot_headers {store; _} ~published_in_block_hash = - let open Lwt_result_syntax in - let+ headers = - Store.Dal_slots_headers.list_values - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map Sc_rollup_proto_types.Dal.Slot_header.of_octez headers - |> List.rev - -let get_slot_indexes {store; _} ~published_in_block_hash = - let open Lwt_result_syntax in - let+ indexes = - Store.Dal_slots_headers.list_secondary_keys - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map Sc_rollup_proto_types.Dal.Slot_index.of_octez indexes |> List.rev - -let save_slot_header {store; _} ~published_in_block_hash - (slot_header : Dal.Slot.Header.t) = - Store.Dal_slots_headers.add - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key: - (Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_header.id.index) - (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) - -let processed_slot {store; _} ~confirmed_in_block_hash slot_index = - Store.Dal_slots_statuses.find - store.irmin_store - ~primary_key:confirmed_in_block_hash - ~secondary_key:(Dal.Slot_index.to_int slot_index) - -let list_slot_pages {store; _} ~confirmed_in_block_hash = - let open Lwt_result_syntax in - let+ slot_pages = - Store.Dal_slot_pages.list_secondary_keys_with_values - store.irmin_store - ~primary_key:confirmed_in_block_hash - in - List.rev_map - (fun ((slot_index, page_index), content) -> - ( (Sc_rollup_proto_types.Dal.Slot_index.of_octez slot_index, page_index), - content )) - slot_pages - |> List.rev - -let find_slot_page {store; _} ~confirmed_in_block_hash ~slot_index ~page_index = - Store.Dal_slot_pages.find - store.irmin_store - ~primary_key:confirmed_in_block_hash - ~secondary_key: - (Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index, page_index) - -let save_unconfirmed_slot {store; _} current_block_hash slot_index = - (* No page is actually saved *) - Store.Dal_slots_statuses.add - store.irmin_store - ~primary_key:current_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - `Unconfirmed - -let save_confirmed_slot {store; _} current_block_hash slot_index pages = - (* Adding multiple entries with the same primary key amounts to updating the - contents of an in-memory map, hence pages must be added sequentially. *) - let open Lwt_result_syntax in - let* () = - List.iteri_es - (fun page_number page -> - Store.Dal_slot_pages.add - store.irmin_store - ~primary_key:current_block_hash - ~secondary_key: - ( Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index, - page_number ) - page) - pages - in - Store.Dal_slots_statuses.add - store.irmin_store - ~primary_key:current_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - `Confirmed - -let find_confirmed_slots_history {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_history.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez res - -let save_confirmed_slots_history {store; _} block hist = - Store.Dal_confirmed_slots_history.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history.to_octez hist) - -let find_confirmed_slots_histories {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_histories.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez res - -let save_confirmed_slots_histories {store; _} block hist = - Store.Dal_confirmed_slots_histories.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez hist) - -module Internal_for_tests = struct - let create_node_context cctxt - ?(constants = Default_parameters.constants_mainnet) ~data_dir kind = - let open Lwt_result_syntax in - let l2_blocks_cache_size = Configuration.default_l2_blocks_cache_size in - let protocol_constants = - constants - |> Data_encoding.Binary.to_bytes_exn Constants.Parametric.encoding - |> Data_encoding.Binary.of_bytes_exn Constants_parametric_repr.encoding - |> Constants_repr.all_of_parametric - |> Data_encoding.Binary.to_bytes_exn Constants_repr.encoding - |> Data_encoding.Binary.of_bytes_exn Constants.encoding - in - let* lockfile = lock ~data_dir in - let* store = - Store.load - Read_write - ~l2_blocks_cache_size - Configuration.(default_storage_dir data_dir) - in - let* context = - Context.load Read_write (Configuration.default_context_dir data_dir) - in - let genesis_info = - Sc_rollup.Commitment.{level = Raw_level.root; commitment_hash = Hash.zero} - in - let l1_ctxt = Layer1.Internal_for_tests.dummy cctxt in - let lcc = - Reference.new_ - {commitment = Sc_rollup.Commitment.Hash.zero; level = Raw_level.root} - in - let lpc = Reference.new_ None in - return - { - cctxt; - dal_cctxt = None; - data_dir; - l1_ctxt; - rollup_address = Sc_rollup.Address.zero; - mode = Observer; - operators = Configuration.Operator_purpose_map.empty; - genesis_info; - lcc; - lpc; - kind; - pvm = pvm_of_kind kind; - injector_retention_period = 0; - block_finality_time = 2; - fee_parameters = Configuration.default_fee_parameters; - protocol_constants; - proto_level = 0; - loser_mode = Loser_mode.no_failures; - lockfile; - store; - context; - kernel_debug_logger = Event.kernel_debug; - finaliser = (fun () -> Lwt.return_unit); - } -end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli deleted file mode 100644 index 4eace29c4523..000000000000 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli +++ /dev/null @@ -1,500 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 TriliTech *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** This module describes the execution context of the node. *) - -open Protocol -open Alpha_context - -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -(** Abstract type for store to force access through this module. *) -type 'a store constraint 'a = [< `Read | `Write > `Read] - -type debug_logger = string -> unit Lwt.t - -type 'a t = { - cctxt : Protocol_client_context.full; - (** Client context used by the rollup node. *) - dal_cctxt : Dal_node_client.cctxt option; - (** DAL client context to query the dal node, if the rollup node supports - the DAL. *) - data_dir : string; (** Node data dir. *) - l1_ctxt : Layer1.t; - (** Layer 1 context to fetch blocks and monitor heads, etc.*) - rollup_address : Sc_rollup.t; (** Smart rollup tracked by the rollup node. *) - mode : Configuration.mode; - (** Mode of the node, see {!Configuration.mode}. *) - operators : Configuration.operators; - (** Addresses of the rollup node operators by purposes. *) - genesis_info : Sc_rollup.Commitment.genesis_info; - (** Origination information of the smart rollup. *) - injector_retention_period : int; - (** Number of blocks the injector will keep information about included - operations. *) - block_finality_time : int; - (** Deterministic block finality time for the layer 1 protocol. *) - kind : Sc_rollup.Kind.t; (** Kind of the smart rollup. *) - pvm : (module Pvm.S); (** The PVM used by the smart rollup. *) - fee_parameters : Configuration.fee_parameters; - (** Fee parameters to use when injecting operations in layer 1. *) - protocol_constants : Constants.t; - (** Protocol constants retrieved from the Tezos node. *) - proto_level : int; - (** Protocol supported by this rollup node (represented as a protocol - level). *) - loser_mode : Loser_mode.t; - (** If different from [Loser_mode.no_failures], the rollup node - issues wrong commitments (for tests). *) - lockfile : Lwt_unix.file_descr; - (** A lock file acquired when the node starts. *) - store : 'a store; (** The store for the persistent storage. *) - context : 'a Context.index; - (** The persistent context for the rollup node. *) - lcc : ('a, lcc) Reference.t; (** Last cemented commitment and its level. *) - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; - (** The last published commitment, i.e. commitment that the operator is - staked on. *) - kernel_debug_logger : debug_logger; - (** Logger used for writing [kernel_debug] messages *) - finaliser : unit -> unit Lwt.t; - (** Aggregation of finalisers to run when the node context closes *) -} - -(** Read/write node context {!t}. *) -type rw = [`Read | `Write] t - -(** Read only node context {!t}. *) -type ro = [`Read] t - -(** [get_operator cctxt purpose] returns the public key hash for the operator - who has purpose [purpose], if any. -*) -val get_operator : - _ t -> - Configuration.purpose -> - Tezos_crypto.Signature.Public_key_hash.t option - -(** [is_operator cctxt pkh] returns [true] if the public key hash [pkh] is an - operator for the node (for any purpose). *) -val is_operator : _ t -> Tezos_crypto.Signature.Public_key_hash.t -> bool - -(** [is_accuser node_ctxt] returns [true] if the rollup node runs in accuser - mode. *) -val is_accuser : _ t -> bool - -(** [is_loser node_ctxt] returns [true] if the rollup node runs has some - failures planned. *) -val is_loser : _ t -> bool - -(** [get_fee_parameter cctxt purpose] returns the fee parameter to inject an - operation for a given [purpose]. If no specific fee parameters were - configured for this purpose, returns the default fee parameter for this - purpose. -*) -val get_fee_parameter : - _ t -> Configuration.purpose -> Injector_sigs.fee_parameter - -(** Maximum size of an L2 batch in bytes that can fit in an operation of the - protocol. *) -val protocol_max_batch_size : int - -(** [init cctxt ~data_dir mode l1_ctxt ~proto_level configuration] initializes - the rollup representation. The rollup origination level and kind are fetched - via an RPC call to the layer1 node that [cctxt] uses for RPC requests. -*) -val init : - Protocol_client_context.full -> - data_dir:string -> - ?log_kernel_debug_file:string -> - 'a Store_sigs.mode -> - Layer1.t -> - proto_level:int -> - Configuration.t -> - 'a t tzresult Lwt.t - -(** Closes the store, context and Layer 1 monitor. *) -val close : _ t -> unit tzresult Lwt.t - -(** [checkout_context node_ctxt block_hash] returns the context at block - [block_hash]. *) -val checkout_context : 'a t -> Block_hash.t -> 'a Context.t tzresult Lwt.t - -(** [metadata node_ctxt] creates a {Sc_rollup.Metadata.t} using the information - stored in [node_ctxt]. *) -val metadata : _ t -> Sc_rollup.Metadata.t - -(** Returns [true] if the rollup node supports the DAL and if DAL is enabled for - the current protocol. *) -val dal_supported : _ t -> bool - -(** [readonly node_ctxt] returns a read only version of the node context - [node_ctxt]. *) -val readonly : _ t -> ro - -(** Monad for values with delayed write effects in the node context. *) -type 'a delayed_write = ('a, rw) Delayed_write_monad.t - -(** {2 Abstraction over store} *) - -(** {3 Layer 2 blocks} *) - -(** [is_processed store hash] returns [true] if the block with [hash] has - already been processed by the daemon. *) -val is_processed : _ t -> Block_hash.t -> bool tzresult Lwt.t - -(** [get_l2_block t hash] returns the Layer 2 block known by the rollup node for - Layer 1 block [hash]. *) -val get_l2_block : _ t -> Block_hash.t -> Sc_rollup_block.t tzresult Lwt.t - -(** Same as {!get_l2_block} but returns [None] when the Layer 2 block is not - available. *) -val find_l2_block : - _ t -> Block_hash.t -> Sc_rollup_block.t option tzresult Lwt.t - -(** Same as {!get_l2_block} but retrieves the Layer 2 block by its level. *) -val get_l2_block_by_level : _ t -> int32 -> Sc_rollup_block.t tzresult Lwt.t - -(** Same as {!get_l2_block_by_level} but returns [None] when the Layer 2 block - is not available. *) -val find_l2_block_by_level : - _ t -> int32 -> Sc_rollup_block.t option tzresult Lwt.t - -(** [get_full_l2_block node_ctxt hash] returns the full L2 block for L1 block - hash [hash]. The result contains the L2 block and its content (inbox, - messages, commitment). *) -val get_full_l2_block : - _ t -> Block_hash.t -> Sc_rollup_block.full tzresult Lwt.t - -(** [save_level t head] registers the correspondences [head.level |-> - head.hash] in the store. *) -val save_level : rw -> Layer1.head -> unit tzresult Lwt.t - -(** [save_l2_head t l2_block] remembers that the [l2_block.head] is - processed. The system should not have to come back to it. *) -val save_l2_head : rw -> Sc_rollup_block.t -> unit tzresult Lwt.t - -(** [last_processed_head_opt store] returns the last processed head if it - exists. *) -val last_processed_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t - -(** [mark_finalized_head store head] remembers that the [head] is finalized. By - construction, every block whose level is smaller than [head]'s is also - finalized. *) -val mark_finalized_level : rw -> int32 -> unit tzresult Lwt.t - -(** [get_finalized_level t] returns the last finalized level. *) -val get_finalized_level : _ t -> int32 tzresult Lwt.t - -(** [get_finalized_head_opt store] returns the last finalized head if it exists. *) -val get_finalized_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t - -(** [hash_of_level node_ctxt level] returns the current block hash for a given - [level]. *) -val hash_of_level : _ t -> int32 -> Block_hash.t tzresult Lwt.t - -(** [hash_of_level_opt] is like {!hash_of_level} but returns [None] if the - [level] is not known. *) -val hash_of_level_opt : _ t -> int32 -> Block_hash.t option tzresult Lwt.t - -(** [level_of_hash node_ctxt hash] returns the level for Tezos block hash [hash] - if it is known by the Tezos Layer 1 node. *) -val level_of_hash : _ t -> Block_hash.t -> int32 tzresult Lwt.t - -(** [get_predecessor_opt state head] returns the predecessor of block [head], - when [head] is not the genesis block. *) -val get_predecessor_opt : - _ t -> Layer1.head -> Layer1.head option tzresult Lwt.t - -(** [get_predecessor state head] returns the predecessor block of [head]. *) -val get_predecessor : _ t -> Layer1.head -> Layer1.head tzresult Lwt.t - -(** Same as {!get_predecessor_opt} with headers. *) -val get_predecessor_header_opt : - _ t -> Layer1.header -> Layer1.header option tzresult Lwt.t - -(** Same as {!get_predecessor} with headers. *) -val get_predecessor_header : - _ t -> Layer1.header -> Layer1.header tzresult Lwt.t - -(** [get_tezos_reorg_for_new_head node_ctxt old_head new_head] returns the L1 - reorganization between [old_head] and [new_head]. *) -val get_tezos_reorg_for_new_head : - _ t -> - [`Head of Layer1.head | `Level of int32] -> - Layer1.head -> - Layer1.head Reorg.t tzresult Lwt.t - -(** [block_with_tick store ~max_level tick] returns [Some b] where [b] is the - last layer 2 block which contains the [tick] before [max_level]. If no such - block exists (the tick happened after [max_level], or we are too late), the - function returns [None]. *) -val block_with_tick : - _ t -> - max_level:Raw_level.t -> - Sc_rollup.Tick.t -> - Sc_rollup_block.t option tzresult Lwt.t - -(** {3 Commitments} *) - -(** [get_commitment t hash] returns the commitment with [hash] stored by the - rollup node. *) -val get_commitment : - _ t -> Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t tzresult Lwt.t - -(** Same as {!get_commitment} but returns [None] if this commitment hash is not - known by the rollup node. *) -val find_commitment : - _ t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.t option tzresult Lwt.t - -(** [commitment_exists t hash] returns [true] if the commitment with [hash] is - known (i.e. stored) by the rollup node. *) -val commitment_exists : - _ t -> Sc_rollup.Commitment.Hash.t -> bool tzresult Lwt.t - -(** [save_commitment t commitment] saves a commitment in the store an returns is - hash. *) -val save_commitment : - rw -> Sc_rollup.Commitment.t -> Sc_rollup.Commitment.Hash.t tzresult Lwt.t - -(** [commitment_published_at_level t hash] returns the levels at which the - commitment was first published and the one at which it was included by in a - Layer 1 block. It returns [None] if the commitment is not known by the - rollup node or if it was never published by the rollup node (and included on - L1). *) -val commitment_published_at_level : - _ t -> - Sc_rollup.Commitment.Hash.t -> - Store.Commitments_published_at_level.element option tzresult Lwt.t - -(** [save_commitment_published_at_level t hash levels] saves the - publication/inclusion information for a commitment with [hash]. *) -val set_commitment_published_at_level : - rw -> - Sc_rollup.Commitment.Hash.t -> - Store.Commitments_published_at_level.element -> - unit tzresult Lwt.t - -type commitment_source = Anyone | Us - -(** [commitment_was_published t hash] returns [true] if the commitment is known - as being already published on L1. The [source] indicates if we want to know - the publication status for commitments we published ourselves [`Us] or that - [`Anyone] published. *) -val commitment_was_published : - _ t -> - source:commitment_source -> - Sc_rollup.Commitment.Hash.t -> - bool tzresult Lwt.t - -(** {3 Inboxes} *) - -type messages_info = { - predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; -} - -(** [get_inbox t inbox_hash] retrieves the inbox whose hash is [inbox_hash] from - the rollup node's storage. *) -val get_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** Same as {!get_inbox} but returns [None] if this inbox is not known. *) -val find_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t option tzresult Lwt.t - -(** [save_inbox t inbox] remembers the [inbox] in the storage. It is associated - to its hash which is returned. *) -val save_inbox : - rw -> Sc_rollup.Inbox.t -> Sc_rollup.Inbox.Hash.t tzresult Lwt.t - -(** [inbox_of_head node_ctxt block] returns the latest inbox at the given - [block]. This function always returns [inbox] for all levels at and - after the rollup genesis. NOTE: It requires the L2 block for [block.hash] to - have been saved. *) -val inbox_of_head : _ t -> Layer1.head -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** Same as {!get_inbox} but uses the Layer 1 block hash for this inbox instead. *) -val get_inbox_by_block_hash : - _ t -> Block_hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [genesis_inbox t] is the genesis inbox for the rollup [t.sc_rollup_address]. *) -val genesis_inbox : _ t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [get_messages t witness_hash] retrieves the messages for the merkelized - payloads hash [witness_hash] stored by the rollup node. *) -val get_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info tzresult Lwt.t - -(** Same as {!get_messages} but returns [None] if the payloads hash is not known. *) -val find_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info option tzresult Lwt.t - -(** [get_num_messages t witness_hash] retrieves the number of messages for the - inbox witness [witness_hash] stored by the rollup node. *) -val get_num_messages : - _ t -> Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> int tzresult Lwt.t - -(** [save_messages t payloads_hash ~block_hash messages] associates the list of - [messages] to the [payloads_hash]. The payload hash must be computed by - calling, e.g. {!Sc_rollup.Inbox.add_all_messages}. *) -val save_messages : - rw -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - block_hash:Block_hash.t -> - Sc_rollup.Inbox_message.t list -> - unit tzresult Lwt.t - -(** Return values for {!protocol_of_level}. *) -type proto_info = { - proto_level : int; - (** Protocol level for operations of block (can be different from L1 - header value in the case of a migration block). *) - first_level_of_protocol : bool; - (** [true] if the level is the first of the protocol. *) - protocol : Protocol_hash.t; - (** Hash of the {e current} protocol for this level. *) -} - -(** [protocol_of_level t level] returns the protocol of block level [level]. *) -val protocol_of_level : _ t -> int32 -> proto_info 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]. *) -val save_protocol_info : - rw -> Layer1.header -> predecessor:Layer1.header -> unit tzresult Lwt.t - -(** {3 DAL} *) - -(** [get_slot_header t ~published_in_block_hash slot_index] returns the slot - header for the [slot_index] that was published in the provided block hash on - Layer 1. *) -val get_slot_header : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot_index.t -> - Dal.Slot.Header.t tzresult Lwt.t - -(** [get_all_slot_headers t ~published_in_block_hash] returns the slot headers - for all the slots that were published in the provided block hash on Layer - 1. *) -val get_all_slot_headers : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t list tzresult Lwt.t - -(** [get_slot_indexes t ~published_in_block_hash] returns the slot indexes whose - headers were published in the provided block hash on Layer 1. *) -val get_slot_indexes : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot_index.t list tzresult Lwt.t - -(** [save_slot_header t ~published_in_block_hash header] saves the [header] as - being published for its index in the provided block hash on Layer 1. *) -val save_slot_header : - rw -> - published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t -> - unit tzresult Lwt.t - -(** [processed_slot t ~confirmed_in_block_hash index] returns [None] if the slot - pages was never processed nor downloaded, [Some `Unconfirmed] if the slot - was not confirmed and [Some `Confirmed] if the slot is confirmed and the - associated pages are available. *) -val processed_slot : - _ t -> - confirmed_in_block_hash:Block_hash.t -> - Dal.Slot_index.t -> - [`Unconfirmed | `Confirmed] option tzresult Lwt.t - -(** [list_slot_pages t ~confirmed_in_block_hash] lists all slots and their pages - that were confirmed and stored by the rollup node for - [confirmed_in_block_hash]. *) -val list_slot_pages : - _ t -> - confirmed_in_block_hash:Block_hash.t -> - ((Dal.Slot_index.t * int) * bytes) list tzresult Lwt.t - -(** [find_slot_page t ~confirmed_in_block_hash slot_index page_index] retrieves - a pages (with index [page_index]) for a slot [slot_index] that was confirmed - in the provided block hash. It returns [None] if the slot was not processed - or if the page index is out of bounds. *) -val find_slot_page : - _ t -> - confirmed_in_block_hash:Block_hash.t -> - slot_index:Dal.Slot_index.t -> - page_index:int -> - bytes option tzresult Lwt.t - -(** [save_unconfirmed_slot node_ctxt hash slot_index] saves in [node_ctxt.store] - that [slot_index] is unconfirmed in the block with hash in [node_ctxt.store]. -*) -val save_unconfirmed_slot : - rw -> Block_hash.t -> Dal.Slot_index.t -> unit tzresult Lwt.t - -(** [save_confirmed_slot node_ctxt hash slot_index] saves in [node_ctxt.store] - that [slot_index] is confirmed in the block with hashin [node_ctxt.store]. - The contents of the slot are set to [pages] in [node_ctxt.store]. *) -val save_confirmed_slot : - rw -> Block_hash.t -> Dal.Slot_index.t -> bytes list -> unit tzresult Lwt.t - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/4636 - Missing docstrings. *) - -val find_confirmed_slots_history : - _ t -> Block_hash.t -> Dal.Slots_history.t option tzresult Lwt.t - -val save_confirmed_slots_history : - rw -> Block_hash.t -> Dal.Slots_history.t -> unit tzresult Lwt.t - -val find_confirmed_slots_histories : - _ t -> Block_hash.t -> Dal.Slots_history.History_cache.t option tzresult Lwt.t - -val save_confirmed_slots_histories : - rw -> Block_hash.t -> Dal.Slots_history.History_cache.t -> unit tzresult Lwt.t - -(**/**) - -module Internal_for_tests : sig - (** Create a node context which really stores data on disk but does not - connect to any layer 1 node. It is meant to be used in unit tests for the - rollup node functions. *) - val create_node_context : - Protocol_client_context.full -> - ?constants:Constants.Parametric.t -> - data_dir:string -> - Sc_rollup.Kind.t -> - Store_sigs.rw t tzresult Lwt.t -end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml index a76f94397d5e..e9a3abe628fa 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml @@ -24,14 +24,11 @@ (*****************************************************************************) open Node_context -open Protocol.Alpha_context let get_state_of_lcc node_ctxt = let open Lwt_result_syntax in let lcc = Reference.get node_ctxt.lcc in - let* block_hash = - Node_context.hash_of_level node_ctxt (Raw_level.to_int32 lcc.level) - in + let* block_hash = Node_context.hash_of_level node_ctxt lcc.level in let* ctxt = Node_context.checkout_context node_ctxt block_hash in let*! state = Context.PVMState.find ctxt in return state @@ -48,7 +45,7 @@ let proof_of_output node_ctxt output = *) failwith "Error producing outbox proof (no cemented state in the node)" | Some state -> ( - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! proof = PVM.produce_output_proof node_ctxt.context state output in match proof with | Ok proof -> diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.mli index 71e8c4a1f28d..1b172b048f4b 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.mli @@ -32,4 +32,4 @@ open Protocol.Alpha_context val proof_of_output : Node_context.rw -> Sc_rollup.output -> - (Sc_rollup.Commitment.Hash.t * string) tzresult Lwt.t + (Octez_smart_rollup.Commitment.Hash.t * string) tzresult Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.ml index e556dc6b9f31..eb26ecbd21ce 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.ml @@ -63,20 +63,20 @@ end let add_level level increment = (* We only use this function with positive increments so it is safe *) if increment < 0 then invalid_arg "Commitment.add_level negative increment" ; - Raw_level.Internal_for_tests.add level increment + Int32.add level (Int32.of_int increment) let sub_level level decrement = (* We only use this function with positive increments so it is safe *) if decrement < 0 then invalid_arg "Commitment.sub_level negative decrement" ; - Raw_level.Internal_for_tests.sub level decrement + let r = Int32.sub level (Int32.of_int decrement) in + if r < 0l then None else Some r let sc_rollup_commitment_period node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup + node_ctxt.Node_context.protocol_constants.sc_rollup .commitment_period_in_blocks let sc_rollup_challenge_window node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup - .challenge_window_in_blocks + node_ctxt.Node_context.protocol_constants.sc_rollup.challenge_window_in_blocks let next_commitment_level node_ctxt last_commitment_level = add_level last_commitment_level (sc_rollup_commitment_period node_ctxt) @@ -85,55 +85,47 @@ type state = Node_context.ro let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Lwt_result_syntax in - let* block = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 inbox_level) - in + let* block = Node_context.get_l2_block_by_level node_ctxt inbox_level in return (Sc_rollup_block.final_tick block) let build_commitment (node_ctxt : _ Node_context.t) - (prev_commitment : Sc_rollup.Commitment.Hash.t) ~prev_commitment_level - ~inbox_level ctxt = + (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) + ~prev_commitment_level ~inbox_level ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with | Some pvm_state -> Ok pvm_state | None -> error_with - "PVM state for commitment at level %a is not available" - Raw_level.pp + "PVM state for commitment at level %ld is not available" inbox_level in let*! compressed_state = PVM.state_hash pvm_state in let*! tick = PVM.get_tick pvm_state in let* prev_commitment_tick = tick_of_level node_ctxt prev_commitment_level in let distance = Z.sub (Sc_rollup.Tick.to_z tick) prev_commitment_tick in - let number_of_ticks = - distance |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value - in - let*? number_of_ticks = - match number_of_ticks with - | Some number_of_ticks -> - if number_of_ticks = Sc_rollup.Number_of_ticks.zero then - error_with "A 0-tick commitment is impossible" - else Ok number_of_ticks - | None -> error_with "Invalid number of ticks for commitment" + let number_of_ticks = Z.to_int64 distance in + let*? () = + if number_of_ticks = 0L then error_with "A 0-tick commitment is impossible" + else if number_of_ticks < 0L then + error_with "Invalid number of ticks for commitment" + else Ok () in return - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = prev_commitment; inbox_level; number_of_ticks; - compressed_state; + compressed_state = + Sc_rollup_proto_types.State_hash.to_octez compressed_state; } let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with @@ -142,29 +134,27 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = in let*! compressed_state = PVM.state_hash pvm_state in let commitment = - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = Hash.zero; inbox_level = node_ctxt.genesis_info.level; - number_of_ticks = Sc_rollup.Number_of_ticks.zero; - compressed_state; + number_of_ticks = 0L; + compressed_state = + Sc_rollup_proto_types.State_hash.to_octez compressed_state; } in (* Ensure the initial state corresponds to the one of the rollup's in the protocol. A mismatch is possible if a wrong external boot sector was provided. *) - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let+ () = fail_unless - Sc_rollup.Commitment.Hash.( + Octez_smart_rollup.Commitment.Hash.( commitment_hash = node_ctxt.genesis_info.commitment_hash) (Sc_rollup_node_errors.Invalid_genesis_state { - expected = - Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.commitment_hash; - actual = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; + expected = node_ctxt.genesis_info.commitment_hash; + actual = commitment_hash; }) in commitment @@ -172,7 +162,7 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor current_level ctxt = let open Lwt_result_syntax in - if Raw_level.(current_level = node_ctxt.genesis_info.level) then + if current_level = node_ctxt.genesis_info.level then let*! () = Commitment_event.compute_commitment current_level in let+ genesis_commitment = genesis_commitment node_ctxt ctxt in Some genesis_commitment @@ -180,7 +170,6 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let* last_commitment_hash = let+ pred = Node_context.get_l2_block node_ctxt predecessor in Sc_rollup_block.most_recent_commitment pred.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let* last_commitment = Node_context.get_commitment node_ctxt last_commitment_hash @@ -188,7 +177,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let next_commitment_level = next_commitment_level node_ctxt last_commitment.inbox_level in - if Raw_level.(current_level = next_commitment_level) then + if current_level = next_commitment_level then let*! () = Commitment_event.compute_commitment current_level in let+ commitment = build_commitment @@ -204,7 +193,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let process_head (node_ctxt : _ Node_context.t) ~predecessor Layer1.{level; header = _; _} ctxt = let open Lwt_result_syntax in - let current_level = Raw_level.of_int32_exn level in + let current_level = level in let* commitment = create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt in @@ -230,15 +219,15 @@ let missing_commitments (node_ctxt : _ Node_context.t) = let sc_rollup_challenge_window_int32 = sc_rollup_challenge_window node_ctxt |> Int32.of_int in - let rec gather acc (commitment_hash : Sc_rollup.Commitment.Hash.t) = + let rec gather acc (commitment_hash : Octez_smart_rollup.Commitment.Hash.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in let lcc = Reference.get node_ctxt.lcc in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* Commitment is before or at the LCC, we have reached the end. *) return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lpc_level) -> + | Some commitment when commitment.inbox_level <= lpc_level -> (* Commitment is before the last published one, we have also reached the end because we only publish commitments that are for the inbox of a finalized L1 block. *) @@ -266,23 +255,18 @@ let missing_commitments (node_ctxt : _ Node_context.t) = commitments that are missing. *) let commitment = Sc_rollup_block.most_recent_commitment finalized.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in gather [] commitment let publish_commitment (node_ctxt : _ Node_context.t) ~source - (commitment : Sc_rollup.Commitment.t) = + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let publish_operation = - L1_operation.Publish - { - rollup = Sc_rollup_proto_types.Address.to_octez node_ctxt.rollup_address; - commitment = Sc_rollup_proto_types.Commitment.to_octez commitment; - } + L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} in let*! () = Commitment_event.publish_commitment - (Sc_rollup.Commitment.hash_uncarbonated commitment) + (Octez_smart_rollup.Commitment.hash commitment) commitment.inbox_level in let* _hash = Injector.add_pending_operation ~source publish_operation in @@ -303,7 +287,8 @@ let on_publish_commitments (node_ctxt : state) = let* commitments = missing_commitments node_ctxt in List.iter_es (publish_commitment node_ctxt ~source) commitments -let publish_single_commitment node_ctxt (commitment : Sc_rollup.Commitment.t) = +let publish_single_commitment node_ctxt + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let operator = Node_context.get_operator node_ctxt Publish in let lcc = Reference.get node_ctxt.lcc in @@ -338,26 +323,20 @@ let earliest_cementing_level node_ctxt commitment_hash = let latest_cementable_commitment (node_ctxt : _ Node_context.t) (head : Sc_rollup_block.t) = let open Lwt_result_option_syntax in - let commitment_hash = - Sc_rollup_block.most_recent_commitment head.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez - in + let commitment_hash = Sc_rollup_block.most_recent_commitment head.header in let** commitment = Node_context.find_commitment node_ctxt commitment_hash in let** cementable_level_bound = return @@ sub_level commitment.inbox_level (sc_rollup_challenge_window node_ctxt) in let lcc = Reference.get node_ctxt.lcc in - if Raw_level.(cementable_level_bound <= lcc.level) then return_none + if cementable_level_bound <= lcc.level then return_none else let** cementable_bound_block = - Node_context.find_l2_block_by_level - node_ctxt - (Raw_level.to_int32 cementable_level_bound) + Node_context.find_l2_block_by_level node_ctxt cementable_level_bound in let cementable_commitment = Sc_rollup_block.most_recent_commitment cementable_bound_block.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in return_some cementable_commitment @@ -367,11 +346,11 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = let*& head = Node_context.last_processed_head_opt node_ctxt in let head_level = head.header.level in let lcc = Reference.get node_ctxt.lcc in - let rec gather acc (commitment_hash : Sc_rollup.Commitment.Hash.t) = + let rec gather acc (commitment_hash : Octez_smart_rollup.Commitment.Hash.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* If we have moved backward passed or at the current LCC then we have reached the end. *) return acc @@ -406,10 +385,10 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = Layer 1 node as a failsafe. *) let* green_light = Plugin.RPC.Sc_rollup.can_be_cemented - node_ctxt.cctxt + (new Protocol_client_context.wrap_full node_ctxt.cctxt) (node_ctxt.cctxt#chain, `Head 0) - node_ctxt.rollup_address - first_cementable + (Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address) + (Sc_rollup_proto_types.Commitment_hash.of_octez first_cementable) in if green_light then return cementable else return_nil @@ -417,11 +396,7 @@ let cement_commitment (node_ctxt : _ Node_context.t) ~source commitment_hash = let open Lwt_result_syntax in let cement_operation = L1_operation.Cement - { - rollup = Sc_rollup_proto_types.Address.to_octez node_ctxt.rollup_address; - commitment = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; - } + {rollup = node_ctxt.rollup_address; commitment = commitment_hash} in let* _hash = Injector.add_pending_operation ~source cement_operation in return_unit diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.mli index 79990b2198ad..36c8c655ece7 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.mli @@ -50,16 +50,14 @@ val process_head : predecessor:Block_hash.t -> Layer1.header -> Context.rw -> - Protocol.Alpha_context.Sc_rollup.Commitment.Hash.t option tzresult Lwt.t + Octez_smart_rollup.Commitment.Hash.t option tzresult Lwt.t (** [publish_single_commitment node_ctxt commitment] publishes a single [commitment] if it is missing. This function is meant to be used by the {e accuser} mode to sparingly publish commitments when it detects a conflict. *) val publish_single_commitment : - _ Node_context.t -> - Protocol.Alpha_context.Sc_rollup.Commitment.t -> - unit tzresult Lwt.t + _ Node_context.t -> Octez_smart_rollup.Commitment.t -> unit tzresult Lwt.t (** Initialize worker for publishing and cementing commitments. *) val init : _ Node_context.t -> unit tzresult Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml index 9409ed42d2e4..e71be750758e 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml @@ -24,78 +24,8 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +module type S = Pvm_sig.S -(** Desired module type of a PVM from the L2 node's perspective *) -module type S = sig - include - Sc_rollup.PVM.S - with type context = Context.rw_index - and type state = Context.tree - and type hash = Sc_rollup.State_hash.t - - (** Kind of the PVM (same as {!name}). *) - val kind : Sc_rollup.Kind.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) - val get_tick : state -> Sc_rollup.Tick.t Lwt.t - - (** PVM status *) - type status - - (** [get_status state] gives you the current execution status for the PVM. *) - val get_status : state -> status Lwt.t - - (** [string_of_status status] returns a string representation of [status]. *) - val string_of_status : status -> string - - (** [get_outbox outbox_level state] returns a list of outputs - available in the outbox of [state] at a given [outbox_level]. *) - val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t - - (** [eval_many ~max_steps s0] returns a state [s1] resulting from the - execution of up to [~max_steps] steps of the rollup at state [s0]. *) - val eval_many : - reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> - write_debug:Tezos_scoru_wasm.Builtins.write_debug -> - ?stop_at_snapshot:bool -> - max_steps:int64 -> - state -> - (state * int64) Lwt.t - - val new_dissection : - default_number_of_sections:int -> - start_chunk:Sc_rollup.Dissection_chunk.t -> - our_stop_chunk:Sc_rollup.Dissection_chunk.t -> - Sc_rollup.Tick.t list - - (** State storage for this PVM. *) - module State : sig - (** [empty ()] is the empty state. *) - val empty : unit -> state - - (** [find context] returns the PVM state stored in the [context], if any. *) - val find : _ Context.t -> state option Lwt.t - - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - - (** [set context state] saves the PVM state [state] in the context and - returns the updated context. Note: [set] does not perform any write on - disk, this information must be committed using {!Context.commit}. *) - val set : 'a Context.t -> state -> 'a Context.t Lwt.t - end - - (** Inspect durable state using a more specialised way of reading the - PVM state. - For example in WASM, it decodes the durable storage in the state - before reading values. - *) - module Inspect_durable_state : sig - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - end -end +let of_kind : Kind.t -> (module S) = function + | Example_arith -> (module Arith_pvm) + | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_rpc.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_rpc.ml index 06c5c60b5e51..a8d946e87b6a 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_rpc.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_rpc.ml @@ -35,6 +35,6 @@ end let no_rpc = (module No_rpc : S) let of_kind = function - | Protocol.Alpha_context.Sc_rollup.Kind.Example_arith -> no_rpc + | Kind.Example_arith -> no_rpc | Wasm_2_0_0 -> (module Wasm_2_0_0_rpc.Make_RPC (Wasm_2_0_0_pvm.Durable_state) : S) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_sig.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_sig.ml new file mode 100644 index 000000000000..178664995c5f --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm_sig.ml @@ -0,0 +1,101 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022-2023 TriliTech *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** Desired module type of a PVM from the L2 node's perspective *) +module type S = sig + include + Sc_rollup.PVM.S + with type context = Context.rw_index + and type state = Context.tree + and type hash = Sc_rollup.State_hash.t + + (** Kind of the PVM. *) + val kind : Sc_rollup.Kind.t + + (** [get_tick state] gets the total tick counter for the given PVM state. *) + val get_tick : state -> Sc_rollup.Tick.t Lwt.t + + (** PVM status *) + type status + + (** [get_status state] gives you the current execution status for the PVM. *) + val get_status : state -> status Lwt.t + + (** [string_of_status status] returns a string representation of [status]. *) + val string_of_status : status -> string + + (** [get_outbox outbox_level state] returns a list of outputs + available in the outbox of [state] at a given [outbox_level]. *) + val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t + + (** [eval_many ~max_steps s0] returns a state [s1] resulting from the + execution of up to [~max_steps] steps of the rollup at state [s0]. *) + val eval_many : + reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> + write_debug:Tezos_scoru_wasm.Builtins.write_debug -> + ?stop_at_snapshot:bool -> + max_steps:int64 -> + state -> + (state * int64) Lwt.t + + val new_dissection : + default_number_of_sections:int -> + start_chunk:Sc_rollup.Dissection_chunk.t -> + our_stop_chunk:Sc_rollup.Dissection_chunk.t -> + Sc_rollup.Tick.t list + + (** State storage for this PVM. *) + module State : sig + (** [empty ()] is the empty state. *) + val empty : unit -> state + + (** [find context] returns the PVM state stored in the [context], if any. *) + val find : _ Context.t -> state option Lwt.t + + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + + (** [set context state] saves the PVM state [state] in the context and + returns the updated context. Note: [set] does not perform any write on + disk, this information must be committed using {!val:Context.commit}. *) + val set : 'a Context.t -> state -> 'a Context.t Lwt.t + end + + (** Inspect durable state using a more specialised way of reading the + PVM state. + For example in WASM, it decodes the durable storage in the state + before reading values. + *) + module Inspect_durable_state : sig + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + end +end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_coordinator.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_coordinator.ml index b841d2e7353c..5762f752126c 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_coordinator.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_coordinator.ml @@ -31,13 +31,25 @@ module Player = Refutation_player module Pkh_map = Signature.Public_key_hash.Map module Pkh_table = Signature.Public_key_hash.Table -type state = {node_ctxt : Node_context.rw; pending_opponents : unit Pkh_table.t} - -let get_conflicts cctxt head_block = - Plugin.RPC.Sc_rollup.conflicts cctxt (cctxt#chain, head_block) - -let get_ongoing_games cctxt head_block = - Plugin.RPC.Sc_rollup.ongoing_refutation_games cctxt (cctxt#chain, head_block) +type state = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + pending_opponents : unit Pkh_table.t; +} + +let get_conflicts cctxt head_block address key = + Plugin.RPC.Sc_rollup.conflicts + cctxt + (cctxt#chain, head_block) + (Sc_rollup_proto_types.Address.of_octez address) + key + +let get_ongoing_games cctxt head_block address key = + Plugin.RPC.Sc_rollup.ongoing_refutation_games + cctxt + (cctxt#chain, head_block) + (Sc_rollup_proto_types.Address.of_octez address) + key let untracked_conflicts opponent_players conflicts = List.filter @@ -72,9 +84,11 @@ let on_process Layer1.{hash; level} state = (* Not injecting refutations, don't play refutation games *) return_unit | Some self -> - let Node_context.{rollup_address; cctxt; _} = node_ctxt in + let Node_context.{rollup_address; _} = node_ctxt in (* Current conflicts in L1 *) - let* conflicts = get_conflicts cctxt head_block rollup_address self in + let* conflicts = + get_conflicts state.cctxt head_block rollup_address self + in (* Map of opponents the node is playing against to the corresponding player worker *) let opponent_players = @@ -85,7 +99,7 @@ let on_process Layer1.{hash; level} state = let new_conflicts = untracked_conflicts opponent_players conflicts in (* L1 ongoing games *) let* ongoing_games = - get_ongoing_games cctxt head_block rollup_address self + get_ongoing_games state.cctxt head_block rollup_address self in (* Map between opponents and their corresponding games *) let ongoing_game_map = make_game_map self ongoing_games in @@ -121,7 +135,10 @@ let on_process Layer1.{hash; level} state = module Types = struct type nonrec state = state - type parameters = {node_ctxt : Node_context.rw} + type parameters = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + } end module Name = struct @@ -157,8 +174,8 @@ module Handlers = struct type launch_error = error trace - let on_launch _w () Types.{node_ctxt} = - return {node_ctxt; pending_opponents = Pkh_table.create 5} + let on_launch _w () Types.{node_ctxt; cctxt} = + return {node_ctxt; cctxt; pending_opponents = Pkh_table.create 5} let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : unit tzresult Lwt.t = @@ -187,7 +204,10 @@ let worker_promise, worker_waker = Lwt.task () let init node_ctxt = let open Lwt_result_syntax in let*! () = Refutation_game_event.Coordinator.starting () in - let+ worker = Worker.launch table () {node_ctxt} (module Handlers) in + let cctxt = + new Protocol_client_context.wrap_full node_ctxt.Node_context.cctxt + in + let+ worker = Worker.launch table () {node_ctxt; cctxt} (module Handlers) in Lwt.wakeup worker_waker worker (* This is a refutation coordinator for a single scoru *) 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 3f0ca7c18fd7..a823250a21b3 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 @@ -71,9 +71,7 @@ let inject_next_move node_ctxt source ~refutation ~opponent = let refute_operation = L1_operation.Refute { - rollup = - Sc_rollup_proto_types.Address.to_octez - node_ctxt.Node_context.rollup_address; + rollup = node_ctxt.Node_context.rollup_address; refutation = Sc_rollup_proto_types.Game.refutation_to_octez refutation; opponent; } @@ -122,7 +120,7 @@ let page_membership_proof params page_index slot_data = let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag (dal_params : Dal.parameters) start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! input_request = PVM.is_input_state start_state in match input_request with | Sc_rollup.(Needs_reveal (Request_dal_page page_id)) -> ( @@ -130,7 +128,6 @@ let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag let* pages = Dal_pages_request.slot_pages ~dal_attestation_lag node_ctxt slot_id in - let* pages = Delayed_write_monad.apply node_ctxt pages in match pages with | None -> return_none (* The slot is not confirmed. *) | Some pages -> ( @@ -155,9 +152,16 @@ let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag pages_per_slot)) | _ -> return_none +let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = Raw_level.of_int32_exn node_ctxt.genesis_info.level in + Sc_rollup.Metadata.{address; origination_level} + let generate_proof (node_ctxt : _ Node_context.t) game start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let snapshot = game.inbox_snapshot in (* NOTE: [snapshot_level_int32] below refers to the level of the snapshotted inbox (from the skip list) which also matches [game.start_level - 1]. *) @@ -192,7 +196,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let* parametric_constants = let cctxt = node_ctxt.cctxt in Protocol.Constants_services.parametric - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, `Level snapshot_level_int32) in let dal_l1_parameters = parametric_constants.dal in @@ -216,7 +220,10 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let reveal hash = let open Lwt_syntax in let* res = - Reveals.get ~data_dir:node_ctxt.data_dir ~pvm_kind:PVM.kind ~hash + Reveals.get + ~data_dir:node_ctxt.data_dir + ~pvm_kind:(Sc_rollup_proto_types.Kind.to_octez PVM.kind) + ~hash in match res with Ok data -> return @@ Some data | Error _ -> return None @@ -225,7 +232,11 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let get_history inbox_hash = let open Lwt_syntax in - let+ inbox = Node_context.find_inbox node_ctxt inbox_hash in + let+ inbox = + Node_context.find_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash) + in match inbox with | Error err -> Format.kasprintf @@ -235,7 +246,12 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = inbox_hash pp_print_trace err - | Ok inbox -> Option.map Sc_rollup.Inbox.take_snapshot inbox + | Ok inbox -> + Option.map + (fun i -> + Sc_rollup.Inbox.take_snapshot + (Sc_rollup_proto_types.Inbox.of_octez i)) + inbox let get_payloads_history witness = Lwt.map @@ -243,8 +259,11 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = ~error:(Format.kasprintf Stdlib.failwith "%a" pp_print_trace)) @@ let open Lwt_result_syntax in - let* {predecessor; predecessor_timestamp; messages} = - Node_context.get_messages node_ctxt witness + let* {predecessor; predecessor_timestamp; messages; _} = + Node_context.get_messages + node_ctxt + (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez + witness) in let*? hist = Inbox.payloads_history_of_messages @@ -269,7 +288,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let page_info = page_info end end in - let metadata = Node_context.metadata node_ctxt in + let metadata = metadata node_ctxt in let*! start_tick = PVM.get_tick start_state in let* proof = trace @@ -331,7 +350,7 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok let our_stop_chunk = Sc_rollup.Dissection_chunk.{state_hash = our_state_hash; tick = our_tick} in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let* dissection = Game_helpers.make_dissection ~state_of_tick @@ -458,7 +477,7 @@ let play_timeout (node_ctxt : _ Node_context.t) self stakers = let timeout_operation = L1_operation.Timeout { - rollup = Sc_rollup_proto_types.Address.to_octez node_ctxt.rollup_address; + rollup = node_ctxt.rollup_address; stakers = Sc_rollup_proto_types.Game.index_to_octez stakers; } in @@ -474,9 +493,9 @@ let timeout_reached ~self head_block node_ctxt staker1 staker2 = let Node_context.{rollup_address; cctxt; _} = node_ctxt in let* game_result = Plugin.RPC.Sc_rollup.timeout_reached - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, head_block) - rollup_address + (Sc_rollup_proto_types.Address.of_octez rollup_address) staker1 staker2 in diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game_event.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game_event.ml index 8b9e57ace16d..e12ea5dbc4c3 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game_event.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/refutation_game_event.ml @@ -79,10 +79,10 @@ module Simple = struct {our_commitment_hash} at level {level} with staker {other} that hash \ issued commitment {their_commitment_hash}." ~level:Notice - ("our_commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) - ("other", Sc_rollup.Staker.encoding) - ("their_commitment_hash", Sc_rollup.Commitment.Hash.encoding) + ("our_commitment_hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) + ("other", Signature.Public_key_hash.encoding) + ("their_commitment_hash", Octez_smart_rollup.Commitment.Hash.encoding) let timeout_detected = declare_1 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 b3aa7aaab693..a64538301d1c 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.ml @@ -77,7 +77,9 @@ let path data_dir pvm_name hash = let get ~data_dir ~pvm_kind ~hash = let open Lwt_result_syntax in - let filename = path data_dir (Sc_rollup.Kind.to_string pvm_kind) hash in + let filename = + path data_dir (Octez_smart_rollup.Kind.to_string pvm_kind) hash + in (* TODO: https://gitlab.com/tezos/tezos/-/issues/5296 Use DAC observer client when [filename] doesn't exist. *) let* contents = file_contents filename in 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 56950f44c8b6..f218cab75d38 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/reveals.mli @@ -68,6 +68,6 @@ type source = } *) val get : data_dir:string -> - pvm_kind:Protocol.Alpha_context.Sc_rollup.Kind.t -> + pvm_kind:Kind.t -> hash:Protocol.Sc_rollup_reveal_hash.t -> string tzresult Lwt.t 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 a13a580a5e13..ae34e8b10bc3 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.ml @@ -36,7 +36,7 @@ type info_per_level = { type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; @@ -54,15 +54,14 @@ let simulate_info_per_level (node_ctxt : [`Read] Node_context.t) predecessor = let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - let*? level = Environment.wrap_tzresult @@ Raw_level.of_int32 level in let*? () = error_unless - Raw_level.(level >= node_ctxt.Node_context.genesis_info.level) + (level >= node_ctxt.Node_context.genesis_info.level) (Exn (Failure "Cannot simulate before origination level")) in - let first_inbox_level = Raw_level.succ node_ctxt.genesis_info.level in + let first_inbox_level = Int32.succ node_ctxt.genesis_info.level in let* ctxt = - if Raw_level.(level < first_inbox_level) then + if level < first_inbox_level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -70,7 +69,7 @@ let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = in let* ctxt, state = Interpreter.state_of_head node_ctxt ctxt head in let+ info_per_level = simulate_info_per_level node_ctxt hash in - let inbox_level = Raw_level.succ level in + let inbox_level = Int32.succ level in { ctxt; inbox_level; @@ -92,7 +91,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) info_per_level = _; } as sim) messages = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! state_hash = PVM.state_hash state in let*! tick = PVM.get_tick state in let eval_state = @@ -130,17 +129,15 @@ let simulate_messages (node_ctxt : Node_context.ro) sim messages = let open Result_syntax in if sim.level_position = Start then let {predecessor_timestamp; predecessor} = sim.info_per_level in - let open Sc_rollup.Inbox_message in - let* internals = - List.map_e - serialize - [ - Internal Start_of_level; - Internal (Info_per_level {predecessor_timestamp; predecessor}); - ] - |> Environment.wrap_tzresult + let open Sc_rollup_inbox_message_repr in + let+ info_per_level = + Environment.wrap_tzresult + @@ serialize + (Internal (Info_per_level {predecessor; predecessor_timestamp})) in - return (internals @ messages) + unsafe_to_string start_of_level_serialized + :: unsafe_to_string info_per_level + :: messages else return messages in let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim messages in @@ -153,10 +150,10 @@ let end_simulation node_ctxt sim = (sim.level_position = End) (Exn (Failure "Level for simulation is ended")) in - let*? eol = - Sc_rollup.Inbox_message.serialize - (Sc_rollup.Inbox_message.Internal End_of_level) - |> Environment.wrap_tzresult + let+ sim, num_ticks = + simulate_messages_no_checks + node_ctxt + sim + [Sc_rollup_inbox_message_repr.(unsafe_to_string end_of_level_serialized)] in - let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim [eol] in ({sim with level_position = End}, num_ticks) 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 2c0a627ffff2..ac8d8dd03624 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.mli @@ -37,7 +37,7 @@ type info_per_level = { (** Type of the state for a simulation. *) type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; @@ -58,10 +58,7 @@ val start_simulation : simulation state, the remaining fuel (when [?fuel] is provided) and the number of ticks that happened. *) val simulate_messages : - Node_context.ro -> - t -> - Sc_rollup.Inbox_message.serialized list -> - (t * Z.t) tzresult Lwt.t + Node_context.ro -> t -> string list -> (t * Z.t) tzresult Lwt.t (** [end_simulation node_ctxt sim] adds and [End_of_level] message and marks the simulation as ended. *) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/test/canary.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/test/canary.ml index ea4cfb044d4b..2a25cc888ad0 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/test/canary.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/test/canary.ml @@ -32,7 +32,7 @@ *) open Octez_smart_rollup -open Protocol.Alpha_context +open Octez_smart_rollup_node let build_chain node_ctxt ~genesis ~length = let open Lwt_result_syntax in @@ -85,15 +85,10 @@ let tests = Helpers.alcotest "canary arith" `Quick - Sc_rollup.Kind.Example_arith - ~boot_sector:"" - canary_test; - Helpers.alcotest - "canary wasm" - `Quick - Sc_rollup.Kind.Wasm_2_0_0 + Example_arith ~boot_sector:"" canary_test; + Helpers.alcotest "canary wasm" `Quick Wasm_2_0_0 ~boot_sector:"" canary_test; ] let () = diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.ml index 504a1a82122a..123d317b3cf3 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.ml @@ -39,25 +39,23 @@ let block_hash_of_level level = Block_hash.of_string_exn s let default_constants = - let constants = Default_parameters.constants_test in - let sc_rollup = - { - constants.sc_rollup with - arith_pvm_enable = true; - challenge_window_in_blocks = 4032; - commitment_period_in_blocks = 3; - } + let test_constants = + Layer1_helpers.constants_of_parametric Default_parameters.constants_test in - {constants with sc_rollup} + { + test_constants with + sc_rollup = + { + test_constants.sc_rollup with + challenge_window_in_blocks = 4032; + commitment_period_in_blocks = 3; + }; + } let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let open Lwt_result_syntax in let head = - Layer1. - { - hash = Block_hash.zero; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; - } + Layer1.{hash = Block_hash.zero; level = node_ctxt.genesis_info.level} in let* () = Node_context.save_level node_ctxt head in let predecessor = head in @@ -67,13 +65,20 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = @@ Sc_rollup.Inbox.genesis ~predecessor_timestamp ~predecessor:predecessor.hash - node_ctxt.genesis_info.level + (Raw_level.of_int32_exn node_ctxt.genesis_info.level) + in + let* inbox_hash = + Node_context.save_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox.to_octez inbox) + in + let inbox_witness = + Sc_rollup.Inbox.current_witness inbox + |> Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez in - let* inbox_hash = Node_context.save_inbox node_ctxt inbox in - let inbox_witness = Sc_rollup.Inbox.current_witness inbox in let ctxt = Octez_smart_rollup_node.Context.empty node_ctxt.context in let num_ticks = 0L in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let initial_tick = Sc_rollup.Tick.initial in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! state = PVM.install_boot_sector initial_state boot_sector in @@ -82,26 +87,20 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let*! context_hash = Octez_smart_rollup_node.Context.commit ctxt in let commitment = Sc_rollup.Commitment.genesis_commitment - ~origination_level:node_ctxt.genesis_info.level + ~origination_level:(Raw_level.of_int32_exn node_ctxt.genesis_info.level) ~genesis_state_hash in - let* commitment_hash = Node_context.save_commitment node_ctxt commitment in - let previous_commitment_hash = - node_ctxt.genesis_info.commitment_hash - |> Sc_rollup_proto_types.Commitment_hash.to_octez - in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez inbox_witness + let* commitment_hash = + Node_context.save_commitment + node_ctxt + (Sc_rollup_proto_types.Commitment.to_octez commitment) in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in + let previous_commitment_hash = node_ctxt.genesis_info.commitment_hash in let header = Sc_rollup_block. { block_hash = head.hash; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; + level = node_ctxt.genesis_info.level; predecessor = predecessor.hash; commitment_hash = Some commitment_hash; previous_commitment_hash; @@ -147,14 +146,13 @@ let initialize_node_context ?(constants = default_constants) kind ~boot_sector = let* ctxt = Node_context.Internal_for_tests.create_node_context cctxt - ~constants + constants ~data_dir kind in let* genesis = add_l2_genesis_block ctxt ~boot_sector in let commitment_hash = WithExceptions.Option.get ~loc:__LOC__ genesis.header.commitment_hash - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let ctxt = {ctxt with genesis_info = {ctxt.genesis_info with commitment_hash}} @@ -227,10 +225,7 @@ let append_dummy_l2_chain node_ctxt ~length = in let batches = Stdlib.List.init length (fun i -> - [ - Sc_rollup.Inbox_message.External - (Z.to_bits (Z.of_int (i + head_level + 1))); - ]) + ["\001" (* External tag *) ^ Z.to_bits (Z.of_int (i + head_level + 1))]) in append_l2_blocks node_ctxt batches diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.mli index 1fc9332c2e92..ec6a9a4f3f19 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/test/helpers/helpers.mli @@ -26,6 +26,7 @@ open Octez_smart_rollup open Protocol open Alpha_context +open Octez_smart_rollup_node (** {1 Helper functions to build and run unit tests for the rollup node} *) @@ -39,8 +40,8 @@ open Alpha_context context need to use this function in order to avoid file descriptor leaks. *) val with_node_context : - ?constants:Constants.Parametric.t -> - Sc_rollup.Kind.t -> + ?constants:Rollup_constants.protocol_constants -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> @@ -63,7 +64,7 @@ val add_l2_genesis_block : and is returned. *) val append_l2_block : [`Read | `Write] Node_context.t -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup_block.t tzresult Lwt.t (** [append_l2_block node_ctxt message_batches] appends as many blocks as there @@ -71,7 +72,7 @@ val append_l2_block : messages. The portion of the chain that was added is returned. *) val append_l2_blocks : [`Read | `Write] Node_context.t -> - Sc_rollup.Inbox_message.t list list -> + string list list -> Sc_rollup_block.t list tzresult Lwt.t (** [append_dummy_l2_chain node_ctxt ~length] append [length] L2 blocks with an @@ -107,8 +108,8 @@ end val alcotest : string -> Alcotest.speed_level -> - ?constants:Constants.Parametric.t -> - Sc_rollup.Kind.t -> + ?constants:Rollup_constants.protocol_constants -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_pvm.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_pvm.ml index 3f7d14535184..99a16db5eb4d 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_pvm.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_pvm.ml @@ -126,7 +126,7 @@ end module Durable_state = Make_durable_state (Make_wrapped_tree (Wasm_2_0_0_proof_format.Tree)) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.Wasm_2_0_0PVM.Make (Make_backend) (Wasm_2_0_0_proof_format) include PVM -- GitLab From 163d2d588cfa8fa8af118dc09119dcc035a7c586 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Wed, 31 May 2023 09:00:20 +0200 Subject: [PATCH 14/15] SCORU/Node/Oxford: Backport !8948 - SCORU/Node: custom protocol constants - SCORU/Node: custom genesis info type - SCORU/Node: save genesis inbox on disk - SCORU/Node/batcher: check config on init - SCORU/Node: remove protocol from events - SCORU/Node: interpreter and inboxes on serialized messages - SCORU/Node: remove Protocol dependency from Node_context - SCORU/Node: remove PVM first class module from node context - SCORU/Node: node Node_context outside of proto directory --- .../sc_rollup_services.ml | 26 +- .../lib_sc_rollup_node/RPC_server.ml | 55 +- .../lib_sc_rollup_node/arith_pvm.ml | 2 +- .../lib_sc_rollup_node/batcher.ml | 58 +- .../block_directory_helpers.ml | 6 +- .../lib_sc_rollup_node/commitment_event.ml | 14 +- .../lib_sc_rollup_node/commitment_event.mli | 8 +- .../lib_sc_rollup_node/daemon.ml | 135 +- .../lib_sc_rollup_node/dal_pages_request.ml | 9 +- .../lib_sc_rollup_node/dal_slots_tracker.ml | 72 +- .../lib_sc_rollup_node/fueled_pvm.ml | 46 +- .../lib_sc_rollup_node/inbox.ml | 68 +- .../lib_sc_rollup_node/inbox.mli | 20 +- .../lib_sc_rollup_node/interpreter.ml | 71 +- .../lib_sc_rollup_node/interpreter.mli | 2 +- .../lib_sc_rollup_node/interpreter_event.ml | 8 +- .../lib_sc_rollup_node/layer1_helpers.ml | 107 ++ .../lib_sc_rollup_node/layer1_helpers.mli | 33 + .../lib_sc_rollup_node/node_context.ml | 1261 ----------------- .../lib_sc_rollup_node/node_context.mli | 492 ------- .../lib_sc_rollup_node/outbox.ml | 7 +- .../lib_sc_rollup_node/outbox.mli | 2 +- .../lib_sc_rollup_node/publisher.ml | 108 +- .../lib_sc_rollup_node/publisher.mli | 6 +- .../lib_sc_rollup_node/pvm.ml | 78 +- .../lib_sc_rollup_node/pvm_rpc.ml | 2 +- .../lib_sc_rollup_node/pvm_sig.ml | 101 ++ .../refutation_coordinator.ml | 48 +- .../lib_sc_rollup_node/refutation_game.ml | 41 +- .../refutation_game_event.ml | 8 +- .../lib_sc_rollup_node/reveals.ml | 4 +- .../lib_sc_rollup_node/reveals.mli | 2 +- .../lib_sc_rollup_node/simulation.ml | 44 +- .../lib_sc_rollup_node/simulation.mli | 7 +- .../lib_sc_rollup_node/test/canary.ml | 11 +- .../test/helpers/helpers.ml | 58 +- .../test/helpers/helpers.mli | 13 +- .../lib_sc_rollup_node/wasm_2_0_0_pvm.ml | 2 +- 38 files changed, 769 insertions(+), 2266 deletions(-) delete mode 100644 src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml delete mode 100644 src/proto_018_Proxford/lib_sc_rollup_node/node_context.mli create mode 100644 src/proto_018_Proxford/lib_sc_rollup_node/pvm_sig.ml diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml index 62664a971c3a..b6539529a288 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -52,7 +52,7 @@ type eval_result = { state_hash : Sc_rollup.State_hash.t; status : string; output : Sc_rollup.output list; - inbox_level : Raw_level.t; + inbox_level : int32; num_ticks : Z.t; insights : bytes option list; (** The simulation can ask to look at values on the state after @@ -98,8 +98,8 @@ type message_status = l1_level : int32; finalized : bool; cemented : bool; - commitment : Sc_rollup.Commitment.t; - commitment_hash : Sc_rollup.Commitment.Hash.t; + commitment : Octez_smart_rollup.Commitment.t; + commitment_hash : Octez_smart_rollup.Commitment.Hash.t; first_published_at_level : int32; published_at_level : int32; } @@ -109,13 +109,13 @@ module Encodings = struct let commitment_with_hash = obj2 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) let commitment_with_hash_and_level_infos = obj4 - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (opt "first_published_at_level" int32) (opt "published_at_level" int32) @@ -141,7 +141,7 @@ module Encodings = struct ~description:"Output produced by evaluation of the messages") (req "inbox_level" - Raw_level.encoding + int32 ~description:"Level of the inbox that would contain these messages") (req "num_ticks" @@ -320,8 +320,8 @@ module Encodings = struct (req "level" int32))) (req "finalized" bool) (req "cemented" bool) - (req "commitment" Sc_rollup.Commitment.encoding) - (req "hash" Sc_rollup.Commitment.Hash.encoding) + (req "commitment" Octez_smart_rollup.Commitment.encoding) + (req "hash" Octez_smart_rollup.Commitment.Hash.encoding) (req "first_published_at_level" int32) (req "published_at_level" int32)) (function @@ -606,7 +606,7 @@ module Global = struct Tezos_rpc.Service.get_service ~description:"Rollup inbox for block" ~query:Tezos_rpc.Query.empty - ~output:Sc_rollup.Inbox.encoding + ~output:Octez_smart_rollup.Inbox.encoding (path / "inbox") let ticks = @@ -721,9 +721,7 @@ module Global = struct ~output: Data_encoding.( list - @@ obj2 - (req "index" Dal.Slot_index.encoding) - (req "status" dal_slot_status_encoding)) + @@ obj2 (req "index" int31) (req "status" dal_slot_status_encoding)) (path / "dal" / "processed_slots") module Outbox = struct diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml b/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml index 6f049377dd2b..6777c7e83d39 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml @@ -122,16 +122,14 @@ module Common = struct let open Lwt_result_syntax in let* l2_block = Node_context.get_l2_block node_ctxt block in let+ num_messages = - Node_context.get_num_messages - node_ctxt - (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez - l2_block.header.inbox_witness) + Node_context.get_num_messages node_ctxt l2_block.header.inbox_witness in Z.of_int num_messages let () = Global_directory.register0 Sc_rollup_services.Global.sc_rollup_address - @@ fun node_ctxt () () -> return @@ node_ctxt.rollup_address + @@ fun node_ctxt () () -> + return @@ Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address let () = Global_directory.register0 Sc_rollup_services.Global.current_tezos_head @@ -173,7 +171,7 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages ~insight_requests messages = let open Lwt_result_syntax in let open Alpha_context in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let reveal_map = match reveal_pages with | Some pages -> @@ -209,11 +207,10 @@ let simulate_messages (node_ctxt : Node_context.ro) block ~reveal_pages insight_requests in let num_ticks = Z.(num_ticks_0 + num_ticks_end) in - let*! outbox = PVM.get_outbox inbox_level state in + let level = Raw_level.of_int32_exn inbox_level in + let*! outbox = PVM.get_outbox level state in let output = - List.filter - (fun Sc_rollup.{outbox_level; _} -> outbox_level = inbox_level) - outbox + List.filter (fun Sc_rollup.{outbox_level; _} -> outbox_level = level) outbox in let*! state_hash = PVM.state_hash state in let*! status = PVM.get_status state in @@ -227,7 +224,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in return tick @@ -236,7 +233,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! hash = PVM.state_hash state in return hash @@ -245,7 +242,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! current_level = PVM.get_current_level state in return current_level @@ -272,7 +269,6 @@ let () = | Some head -> let commitment_hash = Sc_rollup_block.most_recent_commitment head.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let+ commitment = Node_context.find_commitment node_ctxt commitment_hash @@ -286,9 +282,7 @@ let () = match Reference.get node_ctxt.lpc with | None -> return_none | Some commitment -> - let hash = - Alpha_context.Sc_rollup.Commitment.hash_uncarbonated commitment - in + let hash = Octez_smart_rollup.Commitment.hash commitment in (* The corresponding level in Store.Commitments.published_at_level is available only when the commitment has been published and included in a block. *) @@ -308,7 +302,7 @@ let () = @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! status = PVM.get_status state in return (PVM.string_of_status status) @@ -316,10 +310,10 @@ let () = Block_directory.register0 Sc_rollup_services.Global.Block.dal_slots @@ fun (node_ctxt, block) () () -> let open Lwt_result_syntax in - let* slots = + let+ slots = Node_context.get_all_slot_headers node_ctxt ~published_in_block_hash:block in - return slots + List.rev_map Sc_rollup_proto_types.Dal.Slot_header.of_octez slots |> List.rev let () = Block_directory.register0 Sc_rollup_services.Global.Block.dal_processed_slots @@ -330,21 +324,21 @@ let () = @@ fun (node_ctxt, block, outbox_level) () () -> let open Lwt_result_syntax in let* state = get_state node_ctxt block in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! outbox = PVM.get_outbox outbox_level state in return outbox let () = Proof_helpers_directory.register0 Sc_rollup_services.Global.Helpers.outbox_proof - @@ fun node_ctxt output () -> Outbox.proof_of_output node_ctxt output + @@ fun node_ctxt output () -> + let open Lwt_result_syntax in + let+ commitment, proof = Outbox.proof_of_output node_ctxt output in + (Sc_rollup_proto_types.Commitment_hash.of_octez commitment, proof) let () = Block_directory.register0 Sc_rollup_services.Global.Block.simulate @@ fun (node_ctxt, block) () {messages; reveal_pages; insight_requests} -> - let messages = - List.map Alpha_context.Sc_rollup.Inbox_message.unsafe_of_string messages - in simulate_messages node_ctxt block ~reveal_pages ~insight_requests messages let () = @@ -376,23 +370,19 @@ let commitment_level_of_inbox_level (node_ctxt : _ Node_context.t) inbox_level = let+ last_published_commitment = Reference.get node_ctxt.lpc in let commitment_period = Int32.of_int - node_ctxt.protocol_constants.parametric.sc_rollup - .commitment_period_in_blocks - in - let last_published = - Raw_level.to_int32 last_published_commitment.inbox_level + node_ctxt.protocol_constants.sc_rollup.commitment_period_in_blocks in + let last_published = last_published_commitment.inbox_level in let open Int32 in div (sub last_published inbox_level) commitment_period |> mul commitment_period |> sub last_published |> Raw_level.of_int32_exn let inbox_info_of_level (node_ctxt : _ Node_context.t) inbox_level = - let open Alpha_context in let open Lwt_result_syntax in let+ finalized_level = Node_context.get_finalized_level node_ctxt in let finalized = Compare.Int32.(inbox_level <= finalized_level) in let lcc = Reference.get node_ctxt.lcc in - let cemented = Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) in + let cemented = Compare.Int32.(inbox_level <= lcc.level) in (finalized, cemented) let () = @@ -461,7 +451,6 @@ let () = WithExceptions.Option.get ~loc:__LOC__ block.header.commitment_hash - |> Sc_rollup_proto_types.Commitment_hash.of_octez in (* Commitment computed *) let* published_at = diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/arith_pvm.ml b/src/proto_018_Proxford/lib_sc_rollup_node/arith_pvm.ml index 97b5b0b1aa00..0ad11390bf1c 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/arith_pvm.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/arith_pvm.ml @@ -44,7 +44,7 @@ module Arith_proof_format = .tree_proof_encoding end) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.ArithPVM.Make (Arith_proof_format) include PVM diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/batcher.ml b/src/proto_018_Proxford/lib_sc_rollup_node/batcher.ml index cf4199967009..fccf828b61bb 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/batcher.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/batcher.ml @@ -153,11 +153,14 @@ let produce_batches state ~only_full = let simulate node_ctxt simulation_ctxt (messages : L2_message.t list) = let open Lwt_result_syntax in let*? ext_messages = - List.map_e - (fun m -> - Sc_rollup.Inbox_message.(serialize (External (L2_message.content m)))) - messages - |> Environment.wrap_tzresult + Environment.wrap_tzresult + @@ List.map_e + (fun m -> + let open Result_syntax in + let open Sc_rollup.Inbox_message in + let+ msg = serialize @@ External (L2_message.content m) in + unsafe_to_string msg) + messages in let+ simulation_ctxt, _ticks = Simulation.simulate_messages node_ctxt simulation_ctxt ext_messages @@ -229,6 +232,38 @@ let on_new_head state head = (* Forget failing messages *) List.iter (Message_queue.remove state.messages) failing +(** Maximum size of an L2 batch in bytes that can fit in an operation of the + protocol. *) +let protocol_max_batch_size = + let open Protocol in + let open Alpha_context in + let empty_message_op : _ Operation.t = + let open Operation in + { + shell = {branch = Block_hash.zero}; + protocol_data = + { + signature = Some Signature.zero; + contents = + Single + (Manager_operation + { + source = Signature.Public_key_hash.zero; + fee = Tez.of_mutez_exn Int64.max_int; + counter = Manager_counter.Internal_for_tests.of_int max_int; + gas_limit = + Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); + storage_limit = Z.of_int max_int; + operation = Sc_rollup_add_messages {messages = [""]}; + }); + }; + } + in + Protocol.Constants_repr.max_operation_data_length + - Data_encoding.Binary.length + Operation.encoding + (Operation.pack empty_message_op) + let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = let open Lwt_syntax in let conf = @@ -238,9 +273,7 @@ let init_batcher_state node_ctxt ~signer (conf : Configuration.batcher) = min_batch_size = conf.min_batch_size; max_batch_elements = conf.max_batch_elements; max_batch_size = - Option.value - conf.max_batch_size - ~default:Node_context.protocol_max_batch_size; + Option.value conf.max_batch_size ~default:protocol_max_batch_size; } in return @@ -329,8 +362,17 @@ let table = Worker.create_table Queue let worker_promise, worker_waker = Lwt.task () +let check_batcher_config Configuration.{max_batch_size; _} = + match max_batch_size with + | Some m when m > protocol_max_batch_size -> + error_with + "batcher.max_batch_size must be smaller than %d" + protocol_max_batch_size + | _ -> Ok () + let init conf ~signer node_ctxt = let open Lwt_result_syntax in + let*? () = check_batcher_config conf in let node_ctxt = Node_context.readonly node_ctxt in let+ worker = Worker.launch table () {node_ctxt; signer; conf} (module Handlers) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_018_Proxford/lib_sc_rollup_node/block_directory_helpers.ml index a4ccb383a729..e7cba968fb78 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/block_directory_helpers.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/block_directory_helpers.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol - (* Conveniences to construct RPC directory against a subcontext of the Node_context *) @@ -43,9 +41,7 @@ let get_finalized node_ctxt = let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> let lcc = Reference.get node_ctxt.lcc in - Node_context.hash_of_level - node_ctxt - (Alpha_context.Raw_level.to_int32 lcc.level) + Node_context.hash_of_level node_ctxt lcc.level let block_of_prefix node_ctxt block = match block with diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.ml b/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.ml index 92c014f0ab7c..c477e81f6885 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.ml @@ -72,8 +72,8 @@ module Simple = struct "Last cemented commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let last_published_commitment_updated = declare_2 @@ -83,8 +83,8 @@ module Simple = struct "Last published commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let compute_commitment = declare_1 @@ -92,7 +92,7 @@ module Simple = struct ~name:"sc_rollup_node_commitment_process_head" ~msg:"Computing and storing new commitment for level {level}" ~level:Notice - ("level", Raw_level.encoding) + ("level", Data_encoding.int32) let publish_commitment = declare_2 @@ -100,8 +100,8 @@ module Simple = struct ~name:"sc_rollup_node_publish_commitment" ~msg:"Publishing commitment {hash} for inbox level {level}" ~level:Notice - ("hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) + ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) let commitment_parent_is_not_lcc = declare_3 diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.mli b/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.mli index 89b337266710..5a26a50ec34f 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.mli @@ -51,13 +51,13 @@ val commitment_will_not_be_published : cemented commitment was updated to the given [hash] at the given inbox [level]. *) val last_cemented_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [last_published_commitment_updated hash level] emits the event that the last published commitment was updated to the given [hash] at the given inbox [level]. *) val last_published_commitment_updated : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** [commitment_parent_is_not_lcc predecessor_hash last_cemented_commitment_hash] emits the event that a commitment at the given inbox [level] is being @@ -73,12 +73,12 @@ val commitment_parent_is_not_lcc : (** [compute_commitment level] emits the event that a new commitment is being computed and stored for the block at the given [level]. *) -val compute_commitment : Raw_level.t -> unit Lwt.t +val compute_commitment : int32 -> unit Lwt.t (** [publish_commitment hash level] emits the event that a new commitment is being published. *) val publish_commitment : - Sc_rollup.Commitment.Hash.t -> Raw_level.t -> unit Lwt.t + Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t (** Events emmitted by the Publisher worker *) module Publisher : sig diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml index 6ba66bd96b1e..a5e7d3e91585 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml @@ -32,24 +32,21 @@ open Apply_results (** Returns [Some c] if [their_commitment] is refutable where [c] is our commitment for the same inbox level. *) let is_refutable_commitment node_ctxt - (their_commitment : Sc_rollup.Commitment.t) their_commitment_hash = + (their_commitment : Octez_smart_rollup.Commitment.t) their_commitment_hash = let open Lwt_result_syntax in let* l2_block = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 their_commitment.inbox_level) + Node_context.get_l2_block_by_level node_ctxt their_commitment.inbox_level in let* our_commitment_and_hash = Option.filter_map_es (fun hash -> - let hash = Sc_rollup_proto_types.Commitment_hash.of_octez hash in let+ commitment = Node_context.find_commitment node_ctxt hash in Option.map (fun c -> (c, hash)) commitment) l2_block.header.commitment_hash in match our_commitment_and_hash with | Some (our_commitment, our_commitment_hash) - when Sc_rollup.Commitment.Hash.( + when Octez_smart_rollup.Commitment.Hash.( their_commitment_hash <> our_commitment_hash && their_commitment.predecessor = our_commitment.predecessor) -> return our_commitment_and_hash @@ -76,7 +73,7 @@ let accuser_publish_commitment_when_refutable node_ctxt ~other rollup ~level:their_commitment.inbox_level ~other in - assert (Sc_rollup.Address.(node_ctxt.rollup_address = rollup)) ; + assert (Octez_smart_rollup.Address.(node_ctxt.rollup_address = rollup)) ; Publisher.publish_single_commitment node_ctxt our_commitment (** Process an L1 SCORU operation (for the node's rollup) which is included @@ -94,10 +91,12 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let save_lpc = match Reference.get node_ctxt.lpc with | None -> true - | Some lpc -> Raw_level.(commitment.inbox_level >= lpc.inbox_level) + | Some lpc -> + Raw_level.to_int32 commitment.inbox_level >= lpc.inbox_level in + let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in if save_lpc then Reference.set node_ctxt.lpc (Some commitment) ; - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let* () = Node_context.set_commitment_published_at_level node_ctxt @@ -110,7 +109,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) let*! () = Commitment_event.last_published_commitment_updated commitment_hash - (Raw_level.of_int32_exn head.Layer1.level) + head.Layer1.level in return_unit | ( Sc_rollup_publish {commitment = their_commitment; rollup}, @@ -118,6 +117,9 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) {published_at_level; staked_hash = their_commitment_hash; _} ) -> (* Commitment published by someone else *) (* We first register the publication information *) + let their_commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez their_commitment_hash + in let* known_commitment = Node_context.commitment_exists node_ctxt their_commitment_hash in @@ -146,6 +148,9 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) in (* An accuser node will publish its commitment if the other one is refutable. *) + let their_commitment = + Sc_rollup_proto_types.Commitment.to_octez their_commitment + in accuser_publish_commitment_when_refutable node_ctxt ~other:source @@ -155,8 +160,6 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) | ( Sc_rollup_cement _, Sc_rollup_cement_result {inbox_level; commitment_hash; _} ) -> (* Cemented commitment ---------------------------------------------- *) - let proto_inbox_level = inbox_level in - let proto_commitment_hash = commitment_hash in let inbox_level = Raw_level.to_int32 inbox_level in let commitment_hash = Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash @@ -177,13 +180,13 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) in let lcc = Reference.get node_ctxt.lcc in let*! () = - if inbox_level > Raw_level.to_int32 lcc.level then ( + if inbox_level > lcc.level then ( Reference.set node_ctxt.lcc - {commitment = proto_commitment_hash; level = proto_inbox_level} ; + {commitment = commitment_hash; level = inbox_level} ; Commitment_event.last_cemented_commitment_updated - proto_commitment_hash - proto_inbox_level) + commitment_hash + inbox_level) else Lwt.return_unit in return_unit @@ -218,7 +221,7 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) Node_context.save_slot_header node_ctxt ~published_in_block_hash:head.Layer1.hash - slot_header + (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) in return_unit | _, _ -> @@ -237,7 +240,9 @@ let process_l1_operation (type kind) node_ctxt (head : Layer1.header) ~source | Sc_rollup_timeout {rollup; _} | Sc_rollup_execute_outbox_message {rollup; _} | Sc_rollup_recover_bond {sc_rollup = rollup; staker = _} -> - Sc_rollup.Address.(rollup = node_ctxt.Node_context.rollup_address) + Octez_smart_rollup.Address.( + Sc_rollup_proto_types.Address.to_octez rollup + = node_ctxt.Node_context.rollup_address) | Dal_publish_slot_header _ -> true | Reveal _ | Transaction _ | Origination _ | Delegation _ | Update_consensus_key _ | Register_global_constant _ @@ -299,13 +304,13 @@ let process_l1_block_operations node_ctxt (head : Layer1.header) = return_unit let before_origination (node_ctxt : _ Node_context.t) (header : Layer1.header) = - let origination_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let origination_level = node_ctxt.genesis_info.level in header.level < origination_level let previous_context (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in - if predecessor.level < Raw_level.to_int32 node_ctxt.genesis_info.level then + if predecessor.level < node_ctxt.genesis_info.level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -376,11 +381,6 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* inbox_hash, inbox, inbox_witness, messages = Inbox.process_head node_ctxt ~predecessor head in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez - inbox_witness - in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* () = when_ (Node_context.dal_supported node_ctxt) @@ fun () -> Dal_slots_tracker.process_head node_ctxt (Layer1.head_of_header head) @@ -401,25 +401,15 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* commitment_hash = Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt in - let commitment_hash = - Option.map - Sc_rollup_proto_types.Commitment_hash.to_octez - commitment_hash - in let* () = unless (catching_up && Option.is_none commitment_hash) @@ fun () -> - Inbox.same_as_layer_1 - node_ctxt - head.hash - (Sc_rollup_proto_types.Inbox.to_octez inbox) + Inbox.same_as_layer_1 node_ctxt head.hash inbox in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -428,7 +418,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -474,9 +464,7 @@ let on_layer_1_head (daemon_components : (module Daemon_components.S)) node_ctxt | None -> (* if no head has been processed yet, we want to handle all blocks since, and including, the rollup origination. *) - let origination_level = - Raw_level.to_int32 node_ctxt.genesis_info.level - in + let origination_level = node_ctxt.genesis_info.level in `Level (Int32.pred origination_level) in let stripped_head = Layer1.head_of_header head in @@ -573,14 +561,14 @@ let install_finalizer (daemon_components : (module Daemon_components.S)) let* () = Event.shutdown_node exit_status in Tezos_base_unix.Internal_event_unix.close () -let check_initial_state_hash {Node_context.cctxt; rollup_address; pvm; _} = +let check_initial_state_hash {Node_context.cctxt; rollup_address; kind; _} = let open Lwt_result_syntax in - let module PVM = (val pvm) in + let module PVM = (val Pvm.of_kind kind) in let* l1_reference_initial_state_hash = RPC.Sc_rollup.initial_pvm_state_hash - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, cctxt#block) - rollup_address + (Sc_rollup_proto_types.Address.of_octez rollup_address) in let*! s = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! l2_initial_state_hash = PVM.state_hash s in @@ -639,12 +627,9 @@ let run node_ctxt configuration { cctxt = (node_ctxt.cctxt :> Client_context.full); fee_parameters = configuration.fee_parameters; - minimal_block_delay = - node_ctxt.protocol_constants.Constants.parametric - .minimal_block_delay |> Period.to_seconds; + minimal_block_delay = node_ctxt.protocol_constants.minimal_block_delay; delay_increment_per_round = - node_ctxt.protocol_constants.Constants.parametric - .delay_increment_per_round |> Period.to_seconds; + node_ctxt.protocol_constants.delay_increment_per_round; } ~data_dir:node_ctxt.data_dir ~signers @@ -678,8 +663,8 @@ let run node_ctxt configuration Metrics.Info.init_rollup_node_info ~id:configuration.sc_rollup_address ~mode:configuration.mode - ~genesis_level:(Raw_level.to_int32 node_ctxt.genesis_info.level) - ~pvm_kind:(Sc_rollup.Kind.to_string node_ctxt.kind) ; + ~genesis_level:node_ctxt.genesis_info.level + ~pvm_kind:(Octez_smart_rollup.Kind.to_string node_ctxt.kind) ; let fatal_error_exit e = Format.eprintf "%!%a@.Exiting.@." pp_print_trace e ; let*! _ = Lwt_exit.exit_and_wait 1 in @@ -739,11 +724,6 @@ module Internal_for_tests = struct head messages in - let inbox_witness = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez - inbox_witness - in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* ctxt, _num_messages, num_ticks, initial_tick = Interpreter.process_head node_ctxt ctxt ~predecessor head (inbox, messages) in @@ -755,16 +735,11 @@ module Internal_for_tests = struct head ctxt in - let commitment_hash = - Option.map Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let level = Raw_level.of_int32_exn head.level in + let level = head.level in let* previous_commitment_hash = - if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then + if level = node_ctxt.genesis_info.level then (* Previous commitment for rollup genesis is itself. *) - return - (Sc_rollup_proto_types.Commitment_hash.to_octez - node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) + return node_ctxt.genesis_info.commitment_hash else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -773,7 +748,7 @@ module Internal_for_tests = struct Sc_rollup_block. { block_hash = head.hash; - level = head.level; + level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -831,6 +806,25 @@ let run Layer1.fetch_tezos_shell_header l1_ctxt head.header.predecessor in let*! () = Event.received_first_block head.hash Protocol.hash in + let publisher = + Configuration.Operator_purpose_map.find + Publish + configuration.sc_rollup_node_operators + in + let* constants = Layer1_helpers.retrieve_constants cctxt + and* genesis_info = + Layer1_helpers.retrieve_genesis_info cctxt configuration.sc_rollup_address + and* lcc = + Layer1_helpers.get_last_cemented_commitment + cctxt + configuration.sc_rollup_address + and* lpc = + Option.filter_map_es + (Layer1_helpers.get_last_published_commitment + cctxt + configuration.sc_rollup_address) + publisher + and* kind = Layer1_helpers.get_kind cctxt configuration.sc_rollup_address in let* node_ctxt = Node_context.init cctxt @@ -838,6 +832,11 @@ let run ?log_kernel_debug_file Read_write l1_ctxt + constants + genesis_info + ~lcc + ~lpc + kind ~proto_level:predecessor.proto_level configuration in diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/dal_pages_request.ml b/src/proto_018_Proxford/lib_sc_rollup_node/dal_pages_request.ml index 5744e9f67728..f95fc6e4b0e0 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/dal_pages_request.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/dal_pages_request.ml @@ -95,18 +95,17 @@ let download_confirmed_slot_pages ({Node_context.dal_cctxt; _} as node_ctxt) let* published_in_block_hash = Node_context.hash_of_level node_ctxt (Raw_level.to_int32 published_level) in - let* {commitment; _} = + let* header = Node_context.get_slot_header node_ctxt ~published_in_block_hash index in let dal_cctxt = WithExceptions.Option.get ~loc:__LOC__ dal_cctxt in (* DAL must be configured for this point to be reached *) - get_slot_pages dal_cctxt commitment + get_slot_pages dal_cctxt header.commitment let storage_invariant_broken published_level index = failwith "Internal error: [Node_context.find_slot_status] is supposed to have \ - registered the status of the slot %a published at level %a in the store" - Dal.Slot_index.pp + registered the status of the slot %d published at level %a in the store" index Raw_level.pp published_level @@ -120,6 +119,7 @@ let slot_pages ~dal_attestation_lag node_ctxt ~published_level node_ctxt in + let index = Dal.Slot_index.to_int index in let* processed = Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in @@ -142,6 +142,7 @@ let page_content ~dal_attestation_lag node_ctxt page_id = ~published_level node_ctxt in + let index = Dal.Slot_index.to_int index in let* processed = Node_context.find_slot_status node_ctxt ~confirmed_in_block_hash index in diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml b/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml index 2def15b77f98..45da0efc367c 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml @@ -32,7 +32,7 @@ let ancestor_hash ~number_of_levels let genesis_level = genesis_info.level in let rec go number_of_levels (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - if level < Raw_level.to_int32 genesis_level then return_none + if level < genesis_level then return_none else if number_of_levels = 0 then return_some hash else let* pred_head = Node_context.get_predecessor_opt node_ctxt head in @@ -68,9 +68,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = we reduce the lag to 1, then the slots header will never be confirmed. *) let open Lwt_result_syntax in - let lag = - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag - in + let lag = node_ctxt.Node_context.protocol_constants.dal.attestation_lag in (* we are downloading endorsemented for slots at level [level], so we need to download the data at level [level - lag]. *) @@ -107,7 +105,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = let confirmed_slots_indexes_list = List.filter (Dal.Attestation.is_attested confirmed_slots) - published_slots_indexes + (List.filter_map Dal.Slot_index.of_int_opt published_slots_indexes) in let*? confirmed_slots_indexes = Environment.wrap_tzresult @@ -119,16 +117,10 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3884 avoid going back and forth between bitsets and lists of slot indexes. *) -let to_slot_index_list (constants : Constants.Parametric.t) bitset = - let open Result_syntax in +let to_slot_index_list (constants : Rollup_constants.protocol_constants) bitset + = let all_slots = Misc.(0 --> (constants.dal.number_of_slots - 1)) in - let+ filtered = List.filter_e (Bitset.mem bitset) all_slots in - (* Because the maximum slot index is smaller than the number_of_slots protocol - constants, and this value is smaller than the hard limit imposed for slots, - then Dal.Slot_index.to_int will always return a defined value. See - `src/proto_alpha/lib_protocol/constants_repr.ml`. - *) - List.filter_map Dal.Slot_index.of_int_opt filtered + List.filter_e (Bitset.mem bitset) all_slots (* DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/4139. Use a shared storage between dal and rollup node to store slots data. @@ -139,17 +131,17 @@ let download_and_save_slots {published_block_hash; confirmed_slots_indexes} = let open Lwt_result_syntax in let*? all_slots = - Bitset.fill ~length:protocol_constants.parametric.dal.number_of_slots + Bitset.fill ~length:protocol_constants.dal.number_of_slots |> Environment.wrap_tzresult in let*? not_confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric + @@ to_slot_index_list protocol_constants @@ Bitset.diff all_slots confirmed_slots_indexes in let*? confirmed = Environment.wrap_tzresult - @@ to_slot_index_list protocol_constants.parametric confirmed_slots_indexes + @@ to_slot_index_list protocol_constants confirmed_slots_indexes in (* The contents of each slot index are written to a different location on disk, therefore calls to store contents for different slot indexes can @@ -173,6 +165,9 @@ let download_and_save_slots s_slot `Confirmed in + let*? s_slot = + Environment.wrap_tzresult @@ Dal.Slot_index.of_int s_slot + in let*! () = Dal_slots_tracker_event.slot_has_been_confirmed s_slot @@ -192,22 +187,27 @@ module Confirmed_slots_history = struct let*? relevant_slots_indexes = Environment.wrap_tzresult @@ to_slot_index_list - node_ctxt.Node_context.protocol_constants.parametric + node_ctxt.Node_context.protocol_constants confirmed_slots_indexes in List.map_ep (fun slot_index -> - Node_context.get_slot_header - node_ctxt - ~published_in_block_hash:published_block_hash - slot_index) + let+ h = + Node_context.get_slot_header + node_ctxt + ~published_in_block_hash:published_block_hash + slot_index + in + Sc_rollup_proto_types.Dal.Slot_header.of_octez h) relevant_slots_indexes let read_slots_history_from_l1 {Node_context.cctxt; _} block = let open Lwt_result_syntax in (* We return the empty Slots_history if DAL is not enabled. *) let* slots_list_opt = - RPC.Dal.dal_confirmed_slots_history cctxt (cctxt#chain, `Hash (block, 0)) + RPC.Dal.dal_confirmed_slots_history + (new Protocol_client_context.wrap_full cctxt) + (cctxt#chain, `Hash (block, 0)) in return @@ Option.value slots_list_opt ~default:Dal.Slots_history.genesis @@ -219,11 +219,10 @@ module Confirmed_slots_history = struct let should_process_dal_slots node_ctxt block_level = let open Node_context in let lag = - Int32.of_int - node_ctxt.Node_context.protocol_constants.parametric.dal.attestation_lag + Int32.of_int node_ctxt.Node_context.protocol_constants.dal.attestation_lag in let block_level = Raw_level.to_int32 block_level in - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in + let genesis_level = node_ctxt.genesis_info.level in Int32.(block_level >= add lag genesis_level) let dal_entry_of_block_hash node_ctxt @@ -258,23 +257,32 @@ module Confirmed_slots_history = struct block_level let slots_history_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_history node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history" - ~find:Node_context.find_confirmed_slots_history + ~find ~default:read_slots_history_from_l1 let slots_history_cache_of_hash node_ctxt block = + let find node_ctxt block = + let open Lwt_result_syntax in + let+ hist = Node_context.find_confirmed_slots_histories node_ctxt block in + Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez hist + in dal_entry_of_block_hash node_ctxt block ~entry_kind:"slots history cache" - ~find:Node_context.find_confirmed_slots_histories + ~find ~default:(fun node_ctxt _block -> let num_slots = - node_ctxt.Node_context.protocol_constants.parametric.dal - .number_of_slots + node_ctxt.Node_context.protocol_constants.dal.number_of_slots in (* FIXME/DAL: https://gitlab.com/tezos/tezos/-/issues/3788 Put an accurate value for capacity. The value @@ -322,13 +330,13 @@ module Confirmed_slots_history = struct Node_context.save_confirmed_slots_history node_ctxt head_hash - slots_history + (Sc_rollup_proto_types.Dal.Slot_history.to_octez slots_history) in let* () = Node_context.save_confirmed_slots_histories node_ctxt head_hash - slots_cache + (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez slots_cache) in return () end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/fueled_pvm.ml b/src/proto_018_Proxford/lib_sc_rollup_node/fueled_pvm.ml index 3c0739cf40d6..dba3f265a6ff 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/fueled_pvm.ml @@ -39,14 +39,13 @@ module type S = sig 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 : Raw_level.t; - (** Inbox level in which messages are evaluated. *) + 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 : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; (** Messages of the inbox that remain to be evaluated. *) } @@ -61,7 +60,7 @@ module type S = sig val eval_block_inbox : fuel:fuel -> _ Node_context.t -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.serialized list -> + Octez_smart_rollup.Inbox.t * string list -> pvm_state -> eval_result Node_context.delayed_write tzresult Lwt.t @@ -90,10 +89,10 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct state : pvm_state; state_hash : Sc_rollup.State_hash.t; tick : Sc_rollup.Tick.t; - inbox_level : Raw_level.t; + inbox_level : int32; message_counter_offset : int; remaining_fuel : fuel; - remaining_messages : Sc_rollup.Inbox_message.serialized list; + remaining_messages : string list; } type eval_result = {state : eval_state; num_ticks : Z.t; num_messages : int} @@ -119,6 +118,15 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct exception Error_wrapper of tztrace + let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = + Raw_level.of_int32_exn node_ctxt.genesis_info.level + in + Sc_rollup.Metadata.{address; origination_level} + (** [eval_until_input node_ctxt reveal_map level message_index ~fuel start_tick failing_ticks state] advances a PVM [state] until it wants more inputs or there are no more [fuel] (if [Some fuel] is @@ -130,10 +138,10 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct message_index ~fuel start_tick failing_ticks state = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in - let metadata = Node_context.metadata node_ctxt in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in + let metadata = metadata node_ctxt in let dal_attestation_lag = - node_ctxt.protocol_constants.parametric.dal.attestation_lag + node_ctxt.protocol_constants.dal.attestation_lag in let reveal_builtins = Tezos_scoru_wasm.Builtins. @@ -307,7 +315,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct ~fuel ~failing_ticks state input = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* res = eval_until_input node_ctxt @@ -363,7 +371,7 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct let eval_messages ~reveal_map ~fuel node_ctxt ~message_counter_offset state inbox_level messages = let open Delayed_write_monad.Lwt_result_syntax in - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in (* Iterate the PVM state with all the messages. *) let rec feed_messages (state, fuel) message_index = function | [] -> @@ -373,9 +381,15 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct (* Consumed all fuel *) return (state, fuel, message_index - message_counter_offset, messages) | message :: messages -> ( + let payload = Sc_rollup.Inbox_message.unsafe_of_string message in let message_counter = Z.of_int message_index in let input = - Sc_rollup.{inbox_level; message_counter; payload = message} + Sc_rollup. + { + inbox_level = Raw_level.of_int32_exn inbox_level; + message_counter; + payload; + } in let failing_ticks = Loser_mode.is_failure @@ -417,9 +431,9 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct 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 node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in (* Obtain inbox and its messages for this block. *) - let inbox_level = Inbox.inbox_level inbox in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in let*! initial_tick = PVM.get_tick state in (* Evaluate all the messages for this level. *) let>* state, remaining_fuel, num_messages, remaining_messages = @@ -460,11 +474,11 @@ module Make_fueled (F : Fuel.S) : S with type fuel = F.t = struct } = let open Lwt_result_syntax in let open Delayed_write_monad.Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let>* state, remaining_fuel, num_messages, remaining_messages = match messages with | [] -> - let level = Raw_level.to_int32 inbox_level |> Int32.to_int in + let level = Int32.to_int inbox_level in let message_index = message_counter_offset - 1 in let failing_ticks = Loser_mode.is_failure diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml b/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml index a99e1218bca8..621a72a12b02 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml @@ -78,12 +78,22 @@ let get_messages Node_context.{l1_ctxt; _} head = block.operations {apply; apply_internal}) in - return (List.rev rev_messages) + let*? messages = + Environment.wrap_tzresult + @@ List.rev_map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + rev_messages + in + return messages let same_as_layer_1 node_ctxt head_hash inbox = let open Lwt_result_syntax in let head_block = `Hash (head_hash, 0) in let Node_context.{cctxt; _} = node_ctxt in + let cctxt = new Protocol_client_context.wrap_full cctxt in let* layer1_inbox = Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, head_block) in @@ -129,6 +139,15 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block let predecessor_timestamp = predecessor.header.timestamp in let inbox_metrics = Metrics.Inbox.metrics in Prometheus.Gauge.set inbox_metrics.head_inbox_level @@ Int32.to_float level ; + let inbox = Sc_rollup_proto_types.Inbox.of_octez inbox in + let serialized_messages = messages in + let*? messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let* ( _messages_history, witness_hash, inbox, @@ -140,6 +159,11 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block inbox messages in + let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in + let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + let witness_hash = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez witness_hash + in Metrics.Inbox.Stats.set messages_with_protocol_internal_messages ~is_internal:(function @@ -150,18 +174,24 @@ let process_messages (node_ctxt : _ Node_context.t) ~is_first_block node_ctxt witness_hash ~block_hash:head.hash - messages + serialized_messages + in + let*? messages_with_protocol_internal_messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + let open Result_syntax in + let+ msg = Sc_rollup.Inbox_message.serialize msg in + Sc_rollup.Inbox_message.unsafe_to_string msg) + messages_with_protocol_internal_messages in - let* inbox_hash = Node_context.save_inbox node_ctxt inbox in return (inbox_hash, inbox, witness_hash, messages_with_protocol_internal_messages) let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) (head : Layer1.header) = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.level >= first_inbox_level then (* We compute the inbox of this block using the inbox of its predecessor. That way, the computation of inboxes is robust to chain @@ -182,12 +212,19 @@ let process_head (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) head collected_messages else - let* inbox = Node_context.genesis_inbox node_ctxt in - return - ( Sc_rollup.Inbox.hash inbox, - inbox, - Sc_rollup.Inbox.current_witness inbox, - [] ) + let* inbox = + Layer1_helpers.genesis_inbox + (new Protocol_client_context.wrap_full node_ctxt.cctxt) + ~genesis_level:node_ctxt.genesis_info.level + in + let Octez_smart_rollup.Inbox.{hash = witness; _} = + Octez_smart_rollup.Inbox.Skip_list.content inbox.old_levels_messages + in + let* () = + Node_context.save_messages node_ctxt witness ~block_hash:head.hash [] + in + let* inbox_hash = Node_context.save_inbox node_ctxt inbox in + return (inbox_hash, inbox, witness, []) let start () = Inbox_event.starting () @@ -198,6 +235,13 @@ let payloads_history_of_messages ~is_first_block ~predecessor (* The inbox is not necessary to compute the payloads *) Sc_rollup.Inbox.genesis ~predecessor_timestamp ~predecessor Raw_level.root in + let* messages = + Environment.wrap_tzresult + @@ List.map_e + (fun msg -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string msg)) + messages + in let+ ( payloads_history, _history, _inbox, diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/inbox.mli b/src/proto_018_Proxford/lib_sc_rollup_node/inbox.mli index fed5e0503071..915b87728b2a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/inbox.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/inbox.mli @@ -44,10 +44,10 @@ val process_head : Node_context.rw -> predecessor:Layer1.header -> Layer1.header -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t + * string list) tzresult Lwt.t @@ -79,7 +79,7 @@ val payloads_history_of_messages : is_first_block:bool -> predecessor:Block_hash.t -> predecessor_timestamp:Timestamp.time -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup.Inbox_merkelized_payload_hashes.History.t tzresult (** [same_as_layer_1 node_ctxt block node_inbox] ensures that the rollup @@ -98,11 +98,11 @@ module Internal_for_tests : sig is_first_block:bool -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox_message.t list -> - (Sc_rollup.Inbox.Hash.t - * Sc_rollup.Inbox.t - * Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - * Sc_rollup.Inbox_message.t list) + string list -> + (Octez_smart_rollup.Inbox.Hash.t + * Octez_smart_rollup.Inbox.t + * Merkelized_payload_hashes_hash.t + * string list) tzresult Lwt.t end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml index 77143300570d..b306b2badaea 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml @@ -44,7 +44,10 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = match (operation, result) with | ( Sc_rollup_originate {kind; boot_sector; _}, Sc_rollup_originate_result {address; _} ) - when node_ctxt.rollup_address = address && node_ctxt.kind = kind -> + 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 @@ -71,7 +74,7 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = match node_ctxt.boot_sector_file with | None -> get_boot_sector block_hash node_ctxt | Some boot_sector_file -> - let module PVM = (val node_ctxt.pvm) in + 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 @@ -87,7 +90,7 @@ let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let genesis_state block_hash node_ctxt ctxt = let open Lwt_result_syntax in let* boot_sector = get_boot_sector block_hash node_ctxt in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! genesis_state = PVM.install_boot_sector initial_state boot_sector in let*! ctxt = PVM.State.set ctxt genesis_state in @@ -98,9 +101,7 @@ let state_of_head node_ctxt ctxt Layer1.{hash; level} = let*! state = Context.PVMState.find ctxt in match state with | None -> - let genesis_level = - Raw_level.to_int32 node_ctxt.Node_context.genesis_info.level - in + let genesis_level = node_ctxt.Node_context.genesis_info.level in if level = genesis_level then genesis_state hash node_ctxt ctxt else tzfail (Sc_rollup_node_errors.Missing_PVM_state (hash, level)) | Some state -> return (ctxt, state) @@ -127,7 +128,9 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} } = Delayed_write_monad.apply node_ctxt eval_result in - let module PVM = (val node_ctxt.pvm) 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 (* Produce events. *) @@ -139,25 +142,17 @@ let transition_pvm node_ctxt ctxt predecessor Layer1.{hash = _; _} (** [process_head node_ctxt ctxt ~predecessor head] runs the PVM for the given head. *) let process_head (node_ctxt : _ Node_context.t) ctxt - ~(predecessor : Layer1.header) (head : Layer1.header) (inbox, inbox_messages) - = + ~(predecessor : Layer1.header) (head : Layer1.header) inbox_and_messages = let open Lwt_result_syntax in - let first_inbox_level = - Raw_level.to_int32 node_ctxt.genesis_info.level |> Int32.succ - in + let first_inbox_level = node_ctxt.genesis_info.level |> Int32.succ in if head.Layer1.level >= first_inbox_level then - let*? inbox_messages = - List.map_e Sc_rollup.Inbox_message.serialize inbox_messages - |> Environment.wrap_tzresult - in transition_pvm node_ctxt ctxt (Layer1.head_of_header predecessor) (Layer1.head_of_header head) - (inbox, inbox_messages) - else if head.Layer1.level = Raw_level.to_int32 node_ctxt.genesis_info.level - then + inbox_and_messages + else if head.Layer1.level = node_ctxt.genesis_info.level then let* ctxt, state = genesis_state head.hash node_ctxt ctxt in let*! ctxt = Context.PVMState.set ctxt state in return (ctxt, 0, 0L, Sc_rollup.Tick.initial) @@ -178,35 +173,25 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = ctxt Layer1.{hash = block.header.predecessor; level = pred_level} in - let* inbox = - Node_context.get_inbox - node_ctxt - (Sc_rollup_proto_types.Inbox_hash.of_octez block.header.inbox_hash) - in + let* inbox = Node_context.get_inbox node_ctxt block.header.inbox_hash in let* {is_first_block; predecessor; predecessor_timestamp; messages} = - Node_context.get_messages - node_ctxt - (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez - block.header.inbox_witness) + Node_context.get_messages node_ctxt block.header.inbox_witness in - let inbox_level = Sc_rollup.Inbox.inbox_level inbox in - let module PVM = (val node_ctxt.pvm) in + let inbox_level = Octez_smart_rollup.Inbox.inbox_level inbox in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! tick = PVM.get_tick state in let*! state_hash = PVM.state_hash state in let messages = - let open Sc_rollup.Inbox_message in - Internal Start_of_level + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized :: (if is_first_block then - [Internal Sc_rollup.Inbox_message.protocol_migration_internal_message] + [unsafe_to_string Raw_context.protocol_migration_serialized_message] else []) - @ Internal (Info_per_level {predecessor; predecessor_timestamp}) + @ unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) :: messages - @ [Internal End_of_level] - in - let*? messages = - List.map_e Sc_rollup.Inbox_message.serialize messages - |> Environment.wrap_tzresult + @ [unsafe_to_string end_of_level_serialized] in return Fueled_pvm.Accounted. @@ -240,8 +225,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 Raw_level.to_int32 start_state.Fueled_pvm.Accounted.inbox_level - = event.header.level -> + when start_state.Fueled_pvm.Accounted.inbox_level = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a @@ -286,11 +270,14 @@ let memo_state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) returns [None].*) 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 <= Raw_level.to_int32 level) ; + 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_018_Proxford/lib_sc_rollup_node/interpreter.mli b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.mli index 44cabfbbab1e..48cff9f6ceb5 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.mli @@ -38,7 +38,7 @@ val process_head : 'a Context.t -> predecessor:Layer1.header -> Layer1.header -> - Sc_rollup.Inbox.t * Sc_rollup.Inbox_message.t list -> + Octez_smart_rollup.Inbox.t * string list -> ('a Context.t * int * int64 * Sc_rollup.Tick.t) tzresult Lwt.t (** [state_of_tick node_ctxt ?start_state tick level] returns [Some (state, diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/interpreter_event.ml b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter_event.ml index 80fab8ac3274..967bbe9094f2 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/interpreter_event.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter_event.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol.Alpha_context.Sc_rollup - module Simple = struct include Internal_event.Simple @@ -38,9 +36,9 @@ module Simple = struct "Transitioned PVM at inbox level {inbox_level} to {state_hash} at tick \ {ticks} with {num_messages} messages" ~level:Notice - ("inbox_level", Protocol.Alpha_context.Raw_level.encoding) - ("state_hash", State_hash.encoding) - ("ticks", Tick.encoding) + ("inbox_level", Data_encoding.int32) + ("state_hash", Octez_smart_rollup.State_hash.encoding) + ("ticks", Data_encoding.n) ("num_messages", Data_encoding.int31) let intended_failure = diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.ml b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.ml index 8312c2584373..12b477a68c83 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.ml @@ -52,3 +52,110 @@ let fetch_tezos_block l1_ctxt hash = Protocol.name let prefetch_tezos_blocks = Layer1.prefetch_tezos_blocks fetch extract_header + +let get_last_cemented_commitment (cctxt : Protocol_client_context.full) + rollup_address : Node_context.lcc tzresult Lwt.t = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ commitment, level = + Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level + cctxt + (cctxt#chain, `Head 0) + rollup_address + in + { + Node_context.commitment = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment; + level = Protocol.Alpha_context.Raw_level.to_int32 level; + } + +let get_last_published_commitment (cctxt : Protocol_client_context.full) + rollup_address operator = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let*! res = + Plugin.RPC.Sc_rollup.staked_on_commitment + cctxt + (cctxt#chain, `Head 0) + rollup_address + operator + in + match res with + | Error trace + when TzTrace.fold + (fun exists -> function + | Environment.Ecoproto_error + Protocol.Sc_rollup_errors.Sc_rollup_not_staked -> + true + | _ -> exists) + false + trace -> + return_none + | Error trace -> fail trace + | Ok None -> return_none + | Ok (Some (_staked_hash, staked_commitment)) -> + return_some (Sc_rollup_proto_types.Commitment.to_octez staked_commitment) + +let get_kind cctxt rollup_address = + let open Lwt_result_syntax in + let rollup_address = Sc_rollup_proto_types.Address.of_octez rollup_address in + let+ kind = + RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () + in + Sc_rollup_proto_types.Kind.to_octez kind + +let genesis_inbox cctxt ~genesis_level = + let open Lwt_result_syntax in + let+ inbox = + Plugin.RPC.Sc_rollup.inbox cctxt (cctxt#chain, `Level genesis_level) + in + Sc_rollup_proto_types.Inbox.to_octez inbox + +let constants_of_parametric + Protocol.Alpha_context.Constants.Parametric. + { + minimal_block_delay; + delay_increment_per_round; + sc_rollup = {challenge_window_in_blocks; commitment_period_in_blocks; _}; + dal = {feature_enable; attestation_lag; number_of_slots; _}; + _; + } = + let open Protocol.Alpha_context in + Rollup_constants. + { + minimal_block_delay = Period.to_seconds minimal_block_delay; + delay_increment_per_round = Period.to_seconds delay_increment_per_round; + sc_rollup = + { + challenge_window_in_blocks; + commitment_period_in_blocks; + reveal_activation_level = None; + }; + dal = {feature_enable; attestation_lag; number_of_slots}; + } + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 + The constants are retrieved from the latest tezos block. These constants can + be different from the ones used at the creation at the rollup because of a + protocol amendment that modifies some of them. This need to be fixed when the + rollup nodes will be able to handle the migration of protocol. +*) +let retrieve_constants ?(block = `Head 0) cctxt = + let open Lwt_result_syntax in + let+ {parametric; _} = + Protocol.Constants_services.all cctxt (cctxt#chain, block) + in + constants_of_parametric parametric + +let retrieve_genesis_info cctxt rollup_address = + let open Lwt_result_syntax in + let open Protocol.Alpha_context in + let+ {level; commitment_hash} = + RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, `Head 0) rollup_address + in + Node_context. + { + level = Raw_level.to_int32 level; + commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash; + } diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.mli b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.mli index 3b6fc64abf0a..605c80fcbdd0 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.mli @@ -38,3 +38,36 @@ val fetch_tezos_block : asynchronously. NOTE: the number of blocks to prefetch must not be greater than the size of the blocks cache otherwise they will be lost. *) val prefetch_tezos_blocks : t -> head list -> unit + +val get_last_cemented_commitment : + Protocol_client_context.full -> Address.t -> Node_context.lcc tzresult Lwt.t + +val get_last_published_commitment : + Protocol_client_context.full -> + Address.t -> + Signature.public_key_hash -> + Commitment.t option tzresult Lwt.t + +val get_kind : + Protocol_client_context.full -> Address.t -> Kind.t tzresult Lwt.t + +val genesis_inbox : + Protocol_client_context.full -> + genesis_level:int32 -> + Octez_smart_rollup.Inbox.t tzresult Lwt.t + +(** Convert protocol constants to their protocol agnostic representation. *) +val constants_of_parametric : + Protocol.Alpha_context.Constants.Parametric.t -> + Rollup_constants.protocol_constants + +(** Retrieve protocol agnotic constants for the head of the chain. *) +val retrieve_constants : + ?block:Block_services.block -> + Protocol_client_context.full -> + Rollup_constants.protocol_constants tzresult Lwt.t + +val retrieve_genesis_info : + Protocol_client_context.full -> + Address.t -> + Node_context.genesis_info tzresult Lwt.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml b/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml deleted file mode 100644 index 757c35a0aa3e..000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml +++ /dev/null @@ -1,1261 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 TriliTech *) -(* 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 - -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -type 'a store = 'a Store.t - -type debug_logger = string -> unit Lwt.t - -type 'a t = { - cctxt : Protocol_client_context.full; - dal_cctxt : Dal_node_client.cctxt option; - dac_client : Dac_observer_client.t option; - data_dir : string; - l1_ctxt : Layer1.t; - rollup_address : Sc_rollup.t; - boot_sector_file : string option; - mode : Configuration.mode; - operators : Configuration.operators; - genesis_info : Sc_rollup.Commitment.genesis_info; - injector_retention_period : int; - block_finality_time : int; - kind : Sc_rollup.Kind.t; - pvm : (module Pvm.S); - fee_parameters : Configuration.fee_parameters; - protocol_constants : Constants.t; - proto_level : int; - loser_mode : Loser_mode.t; - lockfile : Lwt_unix.file_descr; - store : 'a store; - context : 'a Context.index; - lcc : ('a, lcc) Reference.t; - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; - kernel_debug_logger : debug_logger; - finaliser : unit -> unit Lwt.t; -} - -type rw = [`Read | `Write] t - -type ro = [`Read] t - -let get_operator node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.operators - -let is_operator node_ctxt pkh = - Configuration.Operator_purpose_map.exists - (fun _ operator -> Signature.Public_key_hash.(operator = pkh)) - node_ctxt.operators - -let is_accuser {mode; _} = mode = Accuser - -let is_loser {loser_mode; _} = loser_mode <> Loser_mode.no_failures - -let get_fee_parameter node_ctxt purpose = - Configuration.Operator_purpose_map.find purpose node_ctxt.fee_parameters - |> Option.value ~default:(Configuration.default_fee_parameter ~purpose ()) - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/2901 - The constants are retrieved from the latest tezos block. These constants can - be different from the ones used at the creation at the rollup because of a - protocol amendment that modifies some of them. This need to be fixed when the - rollup nodes will be able to handle the migration of protocol. -*) -let retrieve_constants cctxt = - Protocol.Constants_services.all cctxt (cctxt#chain, cctxt#block) - -let get_last_cemented_commitment (cctxt : Protocol_client_context.full) - rollup_address = - let open Lwt_result_syntax in - let+ commitment, level = - Plugin.RPC.Sc_rollup.last_cemented_commitment_hash_with_level - cctxt - (cctxt#chain, `Head 0) - rollup_address - in - {commitment; level} - -let get_last_published_commitment (cctxt : Protocol_client_context.full) - rollup_address operator = - let open Lwt_result_syntax in - let*! res = - Plugin.RPC.Sc_rollup.staked_on_commitment - cctxt - (cctxt#chain, `Head 0) - rollup_address - operator - in - match res with - | Error trace - when TzTrace.fold - (fun exists -> function - | Environment.Ecoproto_error Sc_rollup_errors.Sc_rollup_not_staked - -> - true - | _ -> exists) - false - trace -> - return_none - | Error trace -> fail trace - | Ok None -> return_none - | Ok (Some (_staked_hash, staked_commitment)) -> return_some staked_commitment - -let lock ~data_dir = - let lockfile_path = Filename.concat data_dir "lock" in - let lock_aux ~data_dir = - let open Lwt_result_syntax in - let*! () = Event.acquiring_lock () in - let*! () = Lwt_utils_unix.create_dir data_dir in - let* lockfile = - protect @@ fun () -> - Lwt_unix.openfile - lockfile_path - [Unix.O_CREAT; O_RDWR; O_CLOEXEC; O_SYNC] - 0o644 - |> Lwt_result.ok - in - let* () = - protect ~on_error:(fun err -> - let*! () = Lwt_unix.close lockfile in - fail err) - @@ fun () -> - let*! () = Lwt_unix.lockf lockfile Unix.F_LOCK 0 in - return_unit - in - return lockfile - in - trace (Sc_rollup_node_errors.Could_not_acquire_lock lockfile_path) - @@ lock_aux ~data_dir - -let unlock {lockfile; _} = - Lwt.finalize - (fun () -> Lwt_unix.lockf lockfile Unix.F_ULOCK 0) - (fun () -> Lwt_unix.close lockfile) - -let make_kernel_logger ?log_kernel_debug_file data_dir = - let open Lwt_syntax in - let path = - match log_kernel_debug_file with - | None -> Filename.concat data_dir "kernel.log" - | Some path -> path - in - let+ fd = - Lwt_unix.openfile path Lwt_unix.[O_WRONLY; O_CREAT; O_APPEND] 0o0644 - in - Lwt_io.of_fd ~close:(fun () -> Lwt_unix.close fd) ~mode:Lwt_io.Output fd - -let pvm_of_kind : Protocol.Alpha_context.Sc_rollup.Kind.t -> (module Pvm.S) = - function - | Example_arith -> (module Arith_pvm) - | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) - -let check_fee_parameters Configuration.{fee_parameters; _} = - let check_value purpose name compare to_string mempool_default value = - if compare mempool_default value > 0 then - error_with - "Bad configuration fee_parameter.%s for %s. It must be at least %s for \ - operations of the injector to be propagated." - name - (Configuration.string_of_purpose purpose) - (to_string mempool_default) - else Ok () - in - let check purpose - { - Injector_sigs.minimal_fees; - minimal_nanotez_per_byte; - minimal_nanotez_per_gas_unit; - force_low_fee = _; - fee_cap = _; - burn_cap = _; - } = - let open Result_syntax in - let+ () = - check_value - purpose - "minimal_fees" - Int64.compare - Int64.to_string - (Tez.to_mutez Plugin.Mempool.default_minimal_fees) - minimal_fees.mutez - and+ () = - check_value - purpose - "minimal_nanotez_per_byte" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_byte - minimal_nanotez_per_byte - and+ () = - check_value - purpose - "minimal_nanotez_per_gas_unit" - Q.compare - Q.to_string - Plugin.Mempool.default_minimal_nanotez_per_gas_unit - minimal_nanotez_per_gas_unit - in - () - in - Configuration.Operator_purpose_map.iter_e check fee_parameters - -let protocol_max_batch_size = - let empty_message_op : _ Operation.t = - let open Protocol in - let open Alpha_context in - let open Operation in - { - shell = {branch = Block_hash.zero}; - protocol_data = - { - signature = Some Signature.zero; - contents = - Single - (Manager_operation - { - source = Signature.Public_key_hash.zero; - fee = Tez.of_mutez_exn Int64.max_int; - counter = Manager_counter.Internal_for_tests.of_int max_int; - gas_limit = - Gas.Arith.integral_of_int_exn ((max_int - 1) / 1000); - storage_limit = Z.of_int max_int; - operation = Sc_rollup_add_messages {messages = [""]}; - }); - }; - } - in - Protocol.Constants_repr.max_operation_data_length - - Data_encoding.Binary.length - Operation.encoding_with_legacy_attestation_name - (Operation.pack empty_message_op) - -let check_batcher_config Configuration.{batcher = {max_batch_size; _}; _} = - match max_batch_size with - | Some m when m > protocol_max_batch_size -> - error_with - "batcher.max_batch_size must be smaller than %d" - protocol_max_batch_size - | _ -> Ok () - -let check_config config = - let open Result_syntax in - let+ () = check_fee_parameters config and+ () = check_batcher_config config in - () - -let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file - mode l1_ctxt ~proto_level - Configuration.( - { - sc_rollup_address = rollup_address; - sc_rollup_node_operators = operators; - boot_sector_file; - mode = operating_mode; - fee_parameters; - loser_mode; - l2_blocks_cache_size; - dal_node_endpoint; - _; - } as configuration) = - let open Lwt_result_syntax in - let*? () = check_config configuration in - let* lockfile = lock ~data_dir in - let* () = - Store_migration.maybe_run_migration - ~storage_dir:(Configuration.default_storage_dir data_dir) - in - let dal_cctxt = - Option.map Dal_node_client.make_unix_cctxt dal_node_endpoint - in - let* store = - Store.load - mode - ~l2_blocks_cache_size - Configuration.(default_storage_dir data_dir) - in - let* context = - Context.load mode (Configuration.default_context_dir data_dir) - in - let* () = Context.Rollup.check_or_set_address mode context rollup_address in - let publisher = Configuration.Operator_purpose_map.find Publish operators in - let* protocol_constants = retrieve_constants cctxt - and* lcc = get_last_cemented_commitment cctxt rollup_address - and* lpc = - Option.filter_map_es - (get_last_published_commitment cctxt rollup_address) - publisher - and* kind = - RPC.Sc_rollup.kind cctxt (cctxt#chain, cctxt#block) rollup_address () - and* genesis_info = - RPC.Sc_rollup.genesis_info cctxt (cctxt#chain, cctxt#block) rollup_address - in - let*! () = - Event.rollup_exists - ~addr:rollup_address - ~kind:(Sc_rollup_proto_types.Kind.to_octez kind) - in - let*! () = - if dal_cctxt = None && protocol_constants.parametric.dal.feature_enable then - Event.warn_dal_enabled_no_node () - else Lwt.return_unit - in - let* dac_client = - Option.map_es - (fun observer_endpoint -> - Dac_observer_client.init - { - observer_endpoint; - reveal_data_dir = - Filename.concat data_dir (Sc_rollup.Kind.to_string kind); - timeout_seconds = configuration.dac_timeout; - }) - configuration.dac_observer_endpoint - in - let*! kernel_debug_logger, kernel_debug_finaliser = - let open Lwt_syntax in - let kernel_debug = Event.kernel_debug in - if configuration.log_kernel_debug then - let+ chan = make_kernel_logger ?log_kernel_debug_file data_dir in - let kernel_debug msg = - let* () = Lwt_io.write chan msg in - let* () = Lwt_io.flush chan in - let* () = kernel_debug msg in - return_unit - in - (kernel_debug, fun () -> Lwt_io.close chan) - else return (kernel_debug, fun () -> return_unit) - in - return - { - cctxt; - dal_cctxt; - dac_client; - data_dir; - l1_ctxt; - rollup_address; - boot_sector_file; - mode = operating_mode; - operators; - genesis_info; - lcc = Reference.new_ lcc; - lpc = Reference.new_ lpc; - kind; - pvm = pvm_of_kind kind; - injector_retention_period = 0; - block_finality_time = 2; - fee_parameters; - protocol_constants; - proto_level; - loser_mode; - lockfile; - store; - context; - kernel_debug_logger; - finaliser = kernel_debug_finaliser; - } - -let close ({cctxt; store; context; l1_ctxt; finaliser; _} as node_ctxt) = - let open Lwt_result_syntax in - let message = cctxt#message in - let*! () = message "Running finaliser@." in - let*! () = finaliser () in - let*! () = message "Shutting down L1@." in - let*! () = Layer1.shutdown l1_ctxt in - let*! () = message "Closing context@." in - let*! () = Context.close context in - let*! () = message "Closing store@." in - let* () = Store.close store in - let*! () = message "Releasing lock@." in - let*! () = unlock node_ctxt in - return_unit - -let checkout_context node_ctxt block_hash = - let open Lwt_result_syntax in - let* l2_header = - Store.L2_blocks.header node_ctxt.store.l2_blocks block_hash - in - let*? context_hash = - match l2_header with - | None -> - error (Sc_rollup_node_errors.Cannot_checkout_context (block_hash, None)) - | Some {context; _} -> ok context - in - let*! ctxt = Context.checkout node_ctxt.context context_hash in - match ctxt with - | None -> - tzfail - (Sc_rollup_node_errors.Cannot_checkout_context - (block_hash, Some context_hash)) - | Some ctxt -> return ctxt - -let metadata node_ctxt = - let address = node_ctxt.rollup_address in - let origination_level = node_ctxt.genesis_info.Sc_rollup.Commitment.level in - Sc_rollup.Metadata.{address; origination_level} - -let dal_supported node_ctxt = - node_ctxt.dal_cctxt <> None - && node_ctxt.protocol_constants.parametric.dal.feature_enable - -let readonly (node_ctxt : _ t) = - { - node_ctxt with - store = Store.readonly node_ctxt.store; - context = Context.readonly node_ctxt.context; - lcc = Reference.readonly node_ctxt.lcc; - lpc = Reference.readonly node_ctxt.lpc; - } - -type 'a delayed_write = ('a, rw) Delayed_write_monad.t - -(** Abstraction over store *) - -module Lwt_result_option_syntax = struct - let ( let** ) a f = - let open Lwt_result_syntax in - let* a in - match a with None -> return_none | Some a -> f a -end - -let hash_of_level_opt {store; cctxt; _} level = - let open Lwt_result_syntax in - let* hash = Store.Levels_to_hashes.find store.levels_to_hashes level in - match hash with - | Some hash -> return_some hash - | None -> - let*! hash = - Tezos_shell_services.Shell_services.Blocks.hash - cctxt - ~chain:cctxt#chain - ~block:(`Level level) - () - in - return (Result.to_option hash) - -let hash_of_level node_ctxt level = - let open Lwt_result_syntax in - let* hash = hash_of_level_opt node_ctxt level in - match hash with - | Some h -> return h - | None -> failwith "Cannot retrieve hash of level %ld" level - -let level_of_hash {l1_ctxt; store; _} hash = - let open Lwt_result_syntax in - let* l2_header = Store.L2_blocks.header store.l2_blocks hash in - match l2_header with - | Some {level; _} -> return level - | None -> - let+ {level; _} = Layer1.fetch_tezos_shell_header l1_ctxt hash in - level - -let save_level {store; _} Layer1.{hash; level} = - Store.Levels_to_hashes.add store.levels_to_hashes level hash - -let save_l2_head {store; _} (head : Sc_rollup_block.t) = - let open Lwt_result_syntax in - let head_info = {head with header = (); content = ()} in - let* () = - Store.L2_blocks.append - store.l2_blocks - ~key:head.header.block_hash - ~header:head.header - ~value:head_info - in - Store.L2_head.write store.l2_head head - -let is_processed {store; _} head = Store.L2_blocks.mem store.l2_blocks head - -let last_processed_head_opt {store; _} = Store.L2_head.read store.l2_head - -let mark_finalized_level {store; _} level = - Store.Last_finalized_level.write store.last_finalized_level level - -let get_finalized_level {store; _} = - let open Lwt_result_syntax in - let+ level = Store.Last_finalized_level.read store.last_finalized_level in - Option.value level ~default:0l - -let get_l2_block {store; _} block_hash = - let open Lwt_result_syntax in - let* block = Store.L2_blocks.read store.l2_blocks block_hash in - match block with - | None -> - failwith "Could not retrieve L2 block for %a" Block_hash.pp block_hash - | Some (info, header) -> return {info with Sc_rollup_block.header} - -let find_l2_block {store; _} block_hash = - let open Lwt_result_syntax in - let+ block = Store.L2_blocks.read store.l2_blocks block_hash in - Option.map (fun (info, header) -> {info with Sc_rollup_block.header}) block - -let get_l2_block_by_level node_ctxt level = - let open Lwt_result_syntax in - Error.trace_lwt_result_with "Could not retrieve L2 block at level %ld" level - @@ let* block_hash = hash_of_level node_ctxt level in - get_l2_block node_ctxt block_hash - -let find_l2_block_by_level node_ctxt level = - let open Lwt_result_syntax in - let* block_hash = hash_of_level_opt node_ctxt level in - match block_hash with - | None -> return_none - | Some block_hash -> find_l2_block node_ctxt block_hash - -let get_finalized_head_opt node_ctxt = - let open Lwt_result_syntax in - let* level = - Store.Last_finalized_level.read node_ctxt.store.last_finalized_level - in - match level with - | None -> return_none - | Some level -> find_l2_block_by_level node_ctxt level - -let head_of_block_level (hash, level) = {Layer1.hash; level} - -let block_level_of_head Layer1.{hash; level} = (hash, level) - -let get_l2_block_predecessor node_ctxt hash = - let open Lwt_result_syntax in - let+ header = Store.L2_blocks.header node_ctxt.store.l2_blocks hash in - Option.map - (fun {Sc_rollup_block.predecessor; level; _} -> - (predecessor, Int32.pred level)) - header - -let get_predecessor_opt node_ctxt (hash, level) = - let open Lwt_result_syntax in - let* pred = get_l2_block_predecessor node_ctxt hash in - match pred with - | Some p -> return_some p - | None -> - (* [head] is not already known in the L2 chain *) - Layer1.get_predecessor_opt node_ctxt.l1_ctxt (hash, level) - -let get_predecessor node_ctxt (hash, level) = - let open Lwt_result_syntax in - let* pred = get_l2_block_predecessor node_ctxt hash in - match pred with - | Some p -> return p - | None -> - (* [head] is not already known in the L2 chain *) - Layer1.get_predecessor node_ctxt.l1_ctxt (hash, level) - -let header_of_hash node_ctxt hash = - let open Lwt_result_syntax in - let+ header = Layer1.fetch_tezos_shell_header node_ctxt.l1_ctxt hash in - {Layer1.hash; level = header.level; header} - -let header_of_head node_ctxt Layer1.{hash; level = _} = - header_of_hash node_ctxt hash - -let get_tezos_reorg_for_new_head node_ctxt old_head new_head = - let open Lwt_result_syntax in - let old_head = - match old_head with - | `Level l -> `Level l - | `Head Layer1.{hash; level} -> `Head (hash, level) - in - let+ reorg = - Layer1.get_tezos_reorg_for_new_head - node_ctxt.l1_ctxt - ~get_old_predecessor:(get_predecessor node_ctxt) - old_head - (block_level_of_head new_head) - in - Reorg.map head_of_block_level reorg - -let get_predecessor_opt node_ctxt head = - let open Lwt_result_syntax in - let+ res = get_predecessor_opt node_ctxt (block_level_of_head head) in - Option.map head_of_block_level res - -let get_predecessor node_ctxt head = - let open Lwt_result_syntax in - let+ res = get_predecessor node_ctxt (block_level_of_head head) in - head_of_block_level res - -let get_predecessor_header_opt node_ctxt head = - let open Lwt_result_syntax in - let* res = get_predecessor_opt node_ctxt (Layer1.head_of_header head) in - Option.map_es (header_of_head node_ctxt) res - -let get_predecessor_header node_ctxt head = - let open Lwt_result_syntax in - let* res = get_predecessor node_ctxt (Layer1.head_of_header head) in - header_of_head node_ctxt res - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/4128 - Unit test the function tick_search. *) - -(** Returns the block that is right before [tick]. [big_step_blocks] is used to - first look for a block before the [tick] *) -let tick_search ~big_step_blocks node_ctxt head tick = - let open Lwt_result_syntax in - if Z.Compare.(head.Sc_rollup_block.initial_tick <= tick) then - if Z.Compare.(Sc_rollup_block.final_tick head < tick) then - (* The head block does not contain the tick *) - return_none - else - (* The starting block contains the tick we want, we are done. *) - return_some head - else - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - let rec find_big_step (end_block : Sc_rollup_block.t) = - let start_level = - Int32.sub end_block.header.level (Int32.of_int big_step_blocks) - in - let start_level = - if start_level < genesis_level then genesis_level else start_level - in - let* start_block = get_l2_block_by_level node_ctxt start_level in - if Z.Compare.(start_block.initial_tick <= tick) then - return (start_block, end_block) - else find_big_step start_block - in - let block_level Sc_rollup_block.{header = {level; _}; _} = - Int32.to_int level - in - let rec dicho start_block end_block = - (* Precondition: - [start_block <> end_block => - end_block.initial_tick > tick >= start_block.initial_tick] *) - let start_level = block_level start_block in - let end_level = block_level end_block in - if end_level - start_level <= 1 then - (* We have found the interval where the tick happened *) - return_some start_block - else - let middle_level = start_level + ((end_level - start_level) / 2) in - let* block_middle = - get_l2_block_by_level node_ctxt (Int32.of_int middle_level) - in - if Z.Compare.(block_middle.initial_tick <= tick) then - dicho block_middle end_block - else dicho start_block block_middle - in - (* First linear approximation *) - let* start_block, end_block = find_big_step head in - (* Then do dichotomy on interval [start_block; end_block] *) - dicho start_block end_block - -let block_with_tick ({store; _} as node_ctxt) ~max_level tick = - let open Lwt_result_syntax in - let open Lwt_result_option_syntax in - Error.trace_lwt_result_with - "Could not retrieve block with tick %a" - Sc_rollup.Tick.pp - tick - @@ let** head = Store.L2_head.read store.l2_head in - (* We start by taking big steps of 4096 blocks for the first - approximation. This means we need at most 20 big steps to start a - dichotomy on a 4096 blocks interval (at most 12 steps). We could take - the refutation period as the big_step_blocks to do a dichotomy on the - full space but we anticipate refutation to happen most of the time close - to the head. *) - let max_level = Raw_level.to_int32 max_level in - let** head = - if head.header.level <= max_level then return_some head - else find_l2_block_by_level node_ctxt max_level - in - tick_search ~big_step_blocks:4096 node_ctxt head (Sc_rollup.Tick.to_z tick) - -let find_octez_commitment {store; _} commitment_hash = - let open Lwt_result_syntax in - let+ commitment = Store.Commitments.read store.commitments commitment_hash in - Option.map fst commitment - -let find_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - let+ commitment = find_octez_commitment node_ctxt commitment_hash in - Option.map Sc_rollup_proto_types.Commitment.of_octez commitment - -let get_octez_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let* commitment = find_octez_commitment node_ctxt commitment_hash in - match commitment with - | None -> - failwith - "Could not retrieve commitment %a" - Octez_smart_rollup.Commitment.Hash.pp - commitment_hash - | Some i -> return i - -let get_commitment node_ctxt commitment_hash = - let open Lwt_result_syntax in - let* commitment = find_commitment node_ctxt commitment_hash in - match commitment with - | None -> - failwith - "Could not retrieve commitment %a" - Sc_rollup.Commitment.Hash.pp - commitment_hash - | Some i -> return i - -let commitment_exists {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in - Store.Commitments.mem store.commitments hash - -let save_commitment {store; _} commitment = - let open Lwt_result_syntax in - let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in - let hash = Octez_smart_rollup.Commitment.hash commitment in - let+ () = - Store.Commitments.append store.commitments ~key:hash ~value:commitment - in - Sc_rollup_proto_types.Commitment_hash.of_octez hash - -let commitment_published_at_level {store; _} commitment = - let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in - Store.Commitments_published_at_level.find - store.commitments_published_at_level - commitment - -let set_commitment_published_at_level {store; _} hash = - let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in - Store.Commitments_published_at_level.add - store.commitments_published_at_level - hash - -type commitment_source = Anyone | Us - -let commitment_was_published {store; _} ~source commitment_hash = - let open Lwt_result_syntax in - let commitment_hash = - Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash - in - match source with - | Anyone -> - Store.Commitments_published_at_level.mem - store.commitments_published_at_level - commitment_hash - | Us -> ( - let+ info = - Store.Commitments_published_at_level.find - store.commitments_published_at_level - commitment_hash - in - match info with - | Some {published_at_level = Some _; _} -> true - | _ -> false) - -let find_octez_inbox {store; _} inbox_hash = - let open Lwt_result_syntax in - let+ inbox = Store.Inboxes.read store.inboxes inbox_hash in - Option.map fst inbox - -let find_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in - let+ inbox = find_octez_inbox node_ctxt inbox_hash in - Option.map Sc_rollup_proto_types.Inbox.of_octez inbox - -let get_octez_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let* inbox = find_octez_inbox node_ctxt inbox_hash in - match inbox with - | None -> - failwith - "Could not retrieve inbox %a" - Octez_smart_rollup.Inbox.Hash.pp - inbox_hash - | Some i -> return i - -let get_inbox node_ctxt inbox_hash = - let open Lwt_result_syntax in - let* inbox = find_inbox node_ctxt inbox_hash in - match inbox with - | None -> - failwith "Could not retrieve inbox %a" Sc_rollup.Inbox.Hash.pp inbox_hash - | Some i -> return i - -let save_inbox {store; _} inbox = - let open Lwt_result_syntax in - let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in - let hash = Octez_smart_rollup.Inbox.hash inbox in - let+ () = Store.Inboxes.append store.inboxes ~key:hash ~value:inbox in - Sc_rollup_proto_types.Inbox_hash.of_octez hash - -let find_inbox_by_block_hash ({store; _} as node_ctxt) block_hash = - let open Lwt_result_syntax in - let* header = Store.L2_blocks.header store.l2_blocks block_hash in - match header with - | None -> return_none - | Some {inbox_hash; _} -> - find_inbox - node_ctxt - (Sc_rollup_proto_types.Inbox_hash.of_octez inbox_hash) - -let genesis_inbox node_ctxt = - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - Plugin.RPC.Sc_rollup.inbox - node_ctxt.cctxt - (node_ctxt.cctxt#chain, `Level genesis_level) - -let inbox_of_head node_ctxt Layer1.{hash = block_hash; level = block_level} = - let open Lwt_result_syntax in - let* possible_inbox = find_inbox_by_block_hash node_ctxt block_hash in - (* Pre-condition: forall l. (l > genesis_level) => inbox[l] <> None. *) - match possible_inbox with - | None -> - (* The inbox exists for each tezos block the rollup should care about. - That is, every block after the origination level. We then join - the bandwagon and build the inbox on top of the protocol's inbox - at the end of the origination level. *) - let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in - if block_level = genesis_level then genesis_inbox node_ctxt - else if block_level > genesis_level then - (* Invariant broken, the inbox for this level should exist. *) - failwith - "The inbox for block hash %a (level = %ld) is missing." - Block_hash.pp - block_hash - block_level - else - (* The rollup node should not care about levels before the genesis - level. *) - failwith - "Asking for the inbox before the genesis level (i.e. %ld), out of \ - the scope of the rollup's node" - block_level - | Some inbox -> return inbox - -let get_inbox_by_block_hash node_ctxt hash = - let open Lwt_result_syntax in - let* level = level_of_hash node_ctxt hash in - inbox_of_head node_ctxt {hash; level} - -type messages_info = { - is_first_block : bool; - predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; -} - -let find_messages node_ctxt messages_hash = - let open Lwt_result_syntax in - let messages_hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez messages_hash - in - let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in - match msg with - | None -> return_none - | Some (messages, block_hash) -> - let* header = header_of_hash node_ctxt block_hash in - let* pred_header = header_of_hash node_ctxt header.header.predecessor in - let* grand_parent_header = - header_of_hash node_ctxt pred_header.header.predecessor - in - let is_first_block = - pred_header.header.proto_level <> grand_parent_header.header.proto_level - in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e - (fun m -> - Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string m)) - messages - in - return_some - { - is_first_block; - predecessor = pred_header.hash; - predecessor_timestamp = pred_header.header.timestamp; - messages; - } - -let get_messages_aux find pp node_ctxt hash = - let open Lwt_result_syntax in - let* res = find node_ctxt hash in - match res with - | None -> - failwith - "Could not retrieve messages with payloads merkelized hash %a" - pp - hash - | Some res -> return res - -let get_messages node_ctxt = - get_messages_aux - find_messages - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.pp - node_ctxt - -let get_messages_without_proto_messages node_ctxt = - get_messages_aux - (fun node_ctxt messages_hash -> - let open Lwt_result_syntax in - let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in - match msg with - | None -> return_none - | Some (messages, _block_hash) -> return_some messages) - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp - node_ctxt - -let get_num_messages {store; _} hash = - let open Lwt_result_syntax in - let hash = - Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez hash - in - let* msg = Store.Messages.read store.messages hash in - match msg with - | None -> - failwith - "Could not retrieve number of messages for inbox witness %a" - Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp - hash - | Some (messages, _block_hash) -> return (List.length messages) - -let save_messages {store; _} key ~block_hash messages = - let open Lwt_result_syntax in - let key = Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez key in - let*? messages = - Environment.wrap_tzresult - @@ List.map_e Sc_rollup.Inbox_message.serialize messages - in - Store.Messages.append - store.messages - ~key - ~header:block_hash - ~value:(messages :> string list) - -let get_full_l2_block node_ctxt block_hash = - let open Lwt_result_syntax in - let* block = get_l2_block node_ctxt block_hash in - let* inbox = get_octez_inbox node_ctxt block.header.inbox_hash - and* messages = - get_messages_without_proto_messages node_ctxt block.header.inbox_witness - and* commitment = - Option.map_es (get_octez_commitment node_ctxt) block.header.commitment_hash - in - return {block with content = {Sc_rollup_block.inbox; messages; commitment}} - -type proto_info = { - proto_level : int; - first_level_of_protocol : bool; - protocol : Protocol_hash.t; -} - -let protocol_of_level node_ctxt level = - let open Lwt_result_syntax in - assert (level >= Raw_level.to_int32 node_ctxt.genesis_info.level) ; - let* protocols = Store.Protocols.read node_ctxt.store.protocols in - let*? protocols = - match protocols with - | None | Some [] -> - error_with "Cannot infer protocol for level %ld: no protocol info" level - | Some protos -> Ok protos - in - let rec find = function - | [] -> - error_with "Cannot infer protocol for level %ld: no information" level - | {Store.Protocols.level = p_level; proto_level; protocol} :: protos -> ( - (* Latest protocols appear first in the list *) - match p_level with - | First_known l when level >= l -> - Ok {protocol; proto_level; first_level_of_protocol = false} - | Activation_level l when level > l -> - (* The block at the activation level is of the previous protocol, so - we are in the protocol that was activated at [l] only when the - level we query is after [l]. *) - Ok - { - protocol; - proto_level; - first_level_of_protocol = level = Int32.succ l; - } - | _ -> (find [@tailcall]) protos) - in - Lwt.return (find protocols) - -let save_protocol_info node_ctxt (block : Layer1.header) - ~(predecessor : Layer1.header) = - let open Lwt_result_syntax in - let* protocols = Store.Protocols.read node_ctxt.store.protocols in - match protocols with - | Some ({proto_level; _} :: _) - when proto_level = block.header.proto_level - && block.header.proto_level = predecessor.header.proto_level -> - (* Nominal case, no protocol change. Nothing to do. *) - return_unit - | None | Some [] -> - (* No protocols information saved in the rollup node yet, initialize with - information by looking at the current head and its predecessor. - We need to figure out if a protocol upgrade happened in one of these two blocks. - *) - let* {current_protocol; next_protocol} = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (block.hash, 0)) - () - and* { - current_protocol = pred_current_protocol; - next_protocol = pred_next_protocol; - } = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (predecessor.hash, 0)) - () - in - (* The first point in the protocol list is the one regarding - [predecessor]. If it is a migration block we register the activation - level, otherwise we don't go back any further and consider it as the - first known block of the protocol. *) - let pred_proto_info = - Store.Protocols. - { - level = - (if Protocol_hash.(pred_current_protocol = pred_next_protocol) - then First_known predecessor.level - else Activation_level predecessor.level); - proto_level = predecessor.header.proto_level; - protocol = pred_next_protocol; - } - in - let protocols = - if Protocol_hash.(current_protocol = next_protocol) then - (* There is no protocol upgrade in [head], so no new point to add the protocol list. *) - [pred_proto_info] - else - (* [head] is a migration block, add the new protocol with its activation in the list. *) - let proto_info = - Store.Protocols. - { - level = Activation_level block.level; - proto_level = block.header.proto_level; - protocol = next_protocol; - } - in - [proto_info; pred_proto_info] - in - Store.Protocols.write node_ctxt.store.protocols protocols - | Some - ({proto_level = last_proto_level; _} :: previous_protocols as protocols) - -> - (* block.header.proto_level <> last_proto_level or head is a migration - block, i.e. there is a protocol change w.r.t. last registered one. *) - let is_head_migration_block = - block.header.proto_level <> predecessor.header.proto_level - in - let* proto_info = - let+ {next_protocol = protocol; _} = - Tezos_shell_services.Shell_services.Blocks.protocols - node_ctxt.cctxt - ~block:(`Hash (block.hash, 0)) - () - in - let level = - if is_head_migration_block then - Store.Protocols.Activation_level block.level - else First_known block.level - in - Store.Protocols. - {level; proto_level = block.header.proto_level; protocol} - in - let protocols = - if block.header.proto_level > last_proto_level then - (* Protocol upgrade, add new item to protocol list *) - proto_info :: protocols - else if block.header.proto_level < last_proto_level then ( - (* Reorganization in which a protocol migration block was - backtracked. *) - match previous_protocols with - | [] -> - (* No info further back, store what we know. *) - [proto_info] - | previous_proto :: _ -> - (* make sure that we are in the case where we backtracked the - migration block. *) - assert ( - Protocol_hash.(proto_info.protocol = previous_proto.protocol)) ; - (* Remove last stored protocol *) - previous_protocols) - else - (* block.header.proto_level = last_proto_level && is_migration_block *) - (* Reorganization where we are doing a different protocol - upgrade. Replace last stored protocol. *) - proto_info :: previous_protocols - in - Store.Protocols.write node_ctxt.store.protocols protocols - -let get_slot_header {store; _} ~published_in_block_hash slot_index = - Error.trace_lwt_result_with - "Could not retrieve slot header for slot index %a published in block %a" - Dal.Slot_index.pp - slot_index - Block_hash.pp - published_in_block_hash - @@ - let open Lwt_result_syntax in - let+ header = - Store.Dal_slots_headers.get - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - in - Sc_rollup_proto_types.Dal.Slot_header.of_octez header - -let get_all_slot_headers {store; _} ~published_in_block_hash = - let open Lwt_result_syntax in - let+ headers = - Store.Dal_slots_headers.list_values - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map Sc_rollup_proto_types.Dal.Slot_header.of_octez headers - |> List.rev - -let get_slot_indexes {store; _} ~published_in_block_hash = - let open Lwt_result_syntax in - let+ indexes = - Store.Dal_slots_headers.list_secondary_keys - store.irmin_store - ~primary_key:published_in_block_hash - in - List.rev_map Sc_rollup_proto_types.Dal.Slot_index.of_octez indexes |> List.rev - -let save_slot_header {store; _} ~published_in_block_hash - (slot_header : Dal.Slot.Header.t) = - Store.Dal_slots_headers.add - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key: - (Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_header.id.index) - (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) - -let find_slot_status {store; _} ~confirmed_in_block_hash slot_index = - Store.Dal_slots_statuses.find - store.irmin_store - ~primary_key:confirmed_in_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - -let list_slots_statuses {store; _} ~confirmed_in_block_hash = - let open Lwt_result_syntax in - let+ statuses = - Store.Dal_slots_statuses.list_secondary_keys_with_values - store.irmin_store - ~primary_key:confirmed_in_block_hash - in - List.rev_map - (fun (index, status) -> - (Sc_rollup_proto_types.Dal.Slot_index.of_octez index, status)) - statuses - |> List.rev - -let save_slot_status {store; _} current_block_hash slot_index status = - Store.Dal_slots_statuses.add - store.irmin_store - ~primary_key:current_block_hash - ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) - status - -let find_confirmed_slots_history {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_history.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez res - -let save_confirmed_slots_history {store; _} block hist = - Store.Dal_confirmed_slots_history.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history.to_octez hist) - -let find_confirmed_slots_histories {store; _} block = - let open Lwt_result_syntax in - let+ res = Store.Dal_confirmed_slots_histories.find store.irmin_store block in - Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez res - -let save_confirmed_slots_histories {store; _} block hist = - Store.Dal_confirmed_slots_histories.add - store.irmin_store - block - (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez hist) - -module Internal_for_tests = struct - let create_node_context cctxt - ?(constants = Default_parameters.constants_mainnet) ~data_dir kind = - let open Lwt_result_syntax in - let l2_blocks_cache_size = Configuration.default_l2_blocks_cache_size in - let protocol_constants = - constants - |> Data_encoding.Binary.to_bytes_exn Constants.Parametric.encoding - |> Data_encoding.Binary.of_bytes_exn Constants_parametric_repr.encoding - |> Constants_repr.all_of_parametric - |> Data_encoding.Binary.to_bytes_exn Constants_repr.encoding - |> Data_encoding.Binary.of_bytes_exn Constants.encoding - in - let* lockfile = lock ~data_dir in - let* store = - Store.load - Read_write - ~l2_blocks_cache_size - Configuration.(default_storage_dir data_dir) - in - let* context = - Context.load Read_write (Configuration.default_context_dir data_dir) - in - let genesis_info = - Sc_rollup.Commitment.{level = Raw_level.root; commitment_hash = Hash.zero} - in - let l1_ctxt = Layer1.Internal_for_tests.dummy cctxt in - let lcc = - Reference.new_ - {commitment = Sc_rollup.Commitment.Hash.zero; level = Raw_level.root} - in - let lpc = Reference.new_ None in - return - { - cctxt; - dal_cctxt = None; - dac_client = None; - data_dir; - l1_ctxt; - rollup_address = Sc_rollup.Address.zero; - boot_sector_file = None; - mode = Observer; - operators = Configuration.Operator_purpose_map.empty; - genesis_info; - lcc; - lpc; - kind; - pvm = pvm_of_kind kind; - injector_retention_period = 0; - block_finality_time = 2; - fee_parameters = Configuration.default_fee_parameters; - protocol_constants; - proto_level = 0; - loser_mode = Loser_mode.no_failures; - lockfile; - store; - context; - kernel_debug_logger = Event.kernel_debug; - finaliser = (fun () -> Lwt.return_unit); - } -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.mli b/src/proto_018_Proxford/lib_sc_rollup_node/node_context.mli deleted file mode 100644 index ae996303fb00..000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.mli +++ /dev/null @@ -1,492 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 TriliTech *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** This module describes the execution context of the node. *) - -open Protocol -open Alpha_context - -type lcc = {commitment : Sc_rollup.Commitment.Hash.t; level : Raw_level.t} - -(** Abstract type for store to force access through this module. *) -type 'a store constraint 'a = [< `Read | `Write > `Read] - -type debug_logger = string -> unit Lwt.t - -type 'a t = { - cctxt : Protocol_client_context.full; - (** Client context used by the rollup node. *) - dal_cctxt : Dal_node_client.cctxt option; - (** DAL client context to query the dal node, if the rollup node supports - the DAL. *) - dac_client : Dac_observer_client.t option; - (** DAC observer client to optionally pull in preimages *) - data_dir : string; (** Node data dir. *) - l1_ctxt : Layer1.t; - (** Layer 1 context to fetch blocks and monitor heads, etc.*) - rollup_address : Sc_rollup.t; (** Smart rollup tracked by the rollup node. *) - boot_sector_file : string option; - (** Optional path to the boot sector file. Useful only if the smart - rollup was bootstrapped and not originated. *) - mode : Configuration.mode; - (** Mode of the node, see {!Configuration.mode}. *) - operators : Configuration.operators; - (** Addresses of the rollup node operators by purposes. *) - genesis_info : Sc_rollup.Commitment.genesis_info; - (** Origination information of the smart rollup. *) - injector_retention_period : int; - (** Number of blocks the injector will keep information about included - operations. *) - block_finality_time : int; - (** Deterministic block finality time for the layer 1 protocol. *) - kind : Sc_rollup.Kind.t; (** Kind of the smart rollup. *) - pvm : (module Pvm.S); (** The PVM used by the smart rollup. *) - fee_parameters : Configuration.fee_parameters; - (** Fee parameters to use when injecting operations in layer 1. *) - protocol_constants : Constants.t; - (** Protocol constants retrieved from the Tezos node. *) - proto_level : int; - (** Protocol supported by this rollup node (represented as a protocol - level). *) - loser_mode : Loser_mode.t; - (** If different from [Loser_mode.no_failures], the rollup node - issues wrong commitments (for tests). *) - lockfile : Lwt_unix.file_descr; - (** A lock file acquired when the node starts. *) - store : 'a store; (** The store for the persistent storage. *) - context : 'a Context.index; - (** The persistent context for the rollup node. *) - lcc : ('a, lcc) Reference.t; (** Last cemented commitment and its level. *) - lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; - (** The last published commitment, i.e. commitment that the operator is - staked on. *) - kernel_debug_logger : debug_logger; - (** Logger used for writing [kernel_debug] messages *) - finaliser : unit -> unit Lwt.t; - (** Aggregation of finalisers to run when the node context closes *) -} - -(** Read/write node context {!t}. *) -type rw = [`Read | `Write] t - -(** Read only node context {!t}. *) -type ro = [`Read] t - -(** [get_operator cctxt purpose] returns the public key hash for the operator - who has purpose [purpose], if any. -*) -val get_operator : - _ t -> Configuration.purpose -> Signature.Public_key_hash.t option - -(** [is_operator cctxt pkh] returns [true] if the public key hash [pkh] is an - operator for the node (for any purpose). *) -val is_operator : _ t -> Signature.Public_key_hash.t -> bool - -(** [is_accuser node_ctxt] returns [true] if the rollup node runs in accuser - mode. *) -val is_accuser : _ t -> bool - -(** [is_loser node_ctxt] returns [true] if the rollup node runs has some - failures planned. *) -val is_loser : _ t -> bool - -(** [get_fee_parameter cctxt purpose] returns the fee parameter to inject an - operation for a given [purpose]. If no specific fee parameters were - configured for this purpose, returns the default fee parameter for this - purpose. -*) -val get_fee_parameter : - _ t -> Configuration.purpose -> Injector_sigs.fee_parameter - -(** Maximum size of an L2 batch in bytes that can fit in an operation of the - protocol. *) -val protocol_max_batch_size : int - -(** [init cctxt ~data_dir mode l1_ctxt ~proto_level configuration] initializes - the rollup representation. The rollup origination level and kind are fetched - via an RPC call to the layer1 node that [cctxt] uses for RPC requests. -*) -val init : - Protocol_client_context.full -> - data_dir:string -> - ?log_kernel_debug_file:string -> - 'a Store_sigs.mode -> - Layer1.t -> - proto_level:int -> - Configuration.t -> - 'a t tzresult Lwt.t - -(** Closes the store, context and Layer 1 monitor. *) -val close : _ t -> unit tzresult Lwt.t - -(** [checkout_context node_ctxt block_hash] returns the context at block - [block_hash]. *) -val checkout_context : 'a t -> Block_hash.t -> 'a Context.t tzresult Lwt.t - -(** [metadata node_ctxt] creates a {!Sc_rollup.Metadata.t} using the information - stored in [node_ctxt]. *) -val metadata : _ t -> Sc_rollup.Metadata.t - -(** Returns [true] if the rollup node supports the DAL and if DAL is enabled for - the current protocol. *) -val dal_supported : _ t -> bool - -(** [readonly node_ctxt] returns a read only version of the node context - [node_ctxt]. *) -val readonly : _ t -> ro - -(** Monad for values with delayed write effects in the node context. *) -type 'a delayed_write = ('a, rw) Delayed_write_monad.t - -(** {2 Abstraction over store} *) - -(** {3 Layer 2 blocks} *) - -(** [is_processed store hash] returns [true] if the block with [hash] has - already been processed by the daemon. *) -val is_processed : _ t -> Block_hash.t -> bool tzresult Lwt.t - -(** [get_l2_block t hash] returns the Layer 2 block known by the rollup node for - Layer 1 block [hash]. *) -val get_l2_block : _ t -> Block_hash.t -> Sc_rollup_block.t tzresult Lwt.t - -(** Same as {!get_l2_block} but returns [None] when the Layer 2 block is not - available. *) -val find_l2_block : - _ t -> Block_hash.t -> Sc_rollup_block.t option tzresult Lwt.t - -(** Same as {!get_l2_block} but retrieves the Layer 2 block by its level. *) -val get_l2_block_by_level : _ t -> int32 -> Sc_rollup_block.t tzresult Lwt.t - -(** Same as {!get_l2_block_by_level} but returns [None] when the Layer 2 block - is not available. *) -val find_l2_block_by_level : - _ t -> int32 -> Sc_rollup_block.t option tzresult Lwt.t - -(** [get_full_l2_block node_ctxt hash] returns the full L2 block for L1 block - hash [hash]. The result contains the L2 block and its content (inbox, - messages, commitment). *) -val get_full_l2_block : - _ t -> Block_hash.t -> Sc_rollup_block.full tzresult Lwt.t - -(** [save_level t head] registers the correspondences [head.level |-> - head.hash] in the store. *) -val save_level : rw -> Layer1.head -> unit tzresult Lwt.t - -(** [save_l2_head t l2_block] remembers that the [l2_block.head] is - processed. The system should not have to come back to it. *) -val save_l2_head : rw -> Sc_rollup_block.t -> unit tzresult Lwt.t - -(** [last_processed_head_opt store] returns the last processed head if it - exists. *) -val last_processed_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t - -(** [mark_finalized_head store head] remembers that the [head] is finalized. By - construction, every block whose level is smaller than [head]'s is also - finalized. *) -val mark_finalized_level : rw -> int32 -> unit tzresult Lwt.t - -(** [get_finalized_level t] returns the last finalized level. *) -val get_finalized_level : _ t -> int32 tzresult Lwt.t - -(** [get_finalized_head_opt store] returns the last finalized head if it exists. *) -val get_finalized_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t - -(** [hash_of_level node_ctxt level] returns the current block hash for a given - [level]. *) -val hash_of_level : _ t -> int32 -> Block_hash.t tzresult Lwt.t - -(** [hash_of_level_opt] is like {!hash_of_level} but returns [None] if the - [level] is not known. *) -val hash_of_level_opt : _ t -> int32 -> Block_hash.t option tzresult Lwt.t - -(** [level_of_hash node_ctxt hash] returns the level for Tezos block hash [hash] - if it is known by the Tezos Layer 1 node. *) -val level_of_hash : _ t -> Block_hash.t -> int32 tzresult Lwt.t - -(** [get_predecessor_opt state head] returns the predecessor of block [head], - when [head] is not the genesis block. *) -val get_predecessor_opt : - _ t -> Layer1.head -> Layer1.head option tzresult Lwt.t - -(** [get_predecessor state head] returns the predecessor block of [head]. *) -val get_predecessor : _ t -> Layer1.head -> Layer1.head tzresult Lwt.t - -(** Same as {!get_predecessor_opt} with headers. *) -val get_predecessor_header_opt : - _ t -> Layer1.header -> Layer1.header option tzresult Lwt.t - -(** Same as {!get_predecessor} with headers. *) -val get_predecessor_header : - _ t -> Layer1.header -> Layer1.header tzresult Lwt.t - -(** [get_tezos_reorg_for_new_head node_ctxt old_head new_head] returns the L1 - reorganization between [old_head] and [new_head]. *) -val get_tezos_reorg_for_new_head : - _ t -> - [`Head of Layer1.head | `Level of int32] -> - Layer1.head -> - Layer1.head Reorg.t tzresult Lwt.t - -(** [block_with_tick store ~max_level tick] returns [Some b] where [b] is the - last layer 2 block which contains the [tick] before [max_level]. If no such - block exists (the tick happened after [max_level], or we are too late), the - function returns [None]. *) -val block_with_tick : - _ t -> - max_level:Raw_level.t -> - Sc_rollup.Tick.t -> - Sc_rollup_block.t option tzresult Lwt.t - -(** {3 Commitments} *) - -(** [get_commitment t hash] returns the commitment with [hash] stored by the - rollup node. *) -val get_commitment : - _ t -> Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t tzresult Lwt.t - -(** Same as {!get_commitment} but returns [None] if this commitment hash is not - known by the rollup node. *) -val find_commitment : - _ t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.t option tzresult Lwt.t - -(** [commitment_exists t hash] returns [true] if the commitment with [hash] is - known (i.e. stored) by the rollup node. *) -val commitment_exists : - _ t -> Sc_rollup.Commitment.Hash.t -> bool tzresult Lwt.t - -(** [save_commitment t commitment] saves a commitment in the store an returns is - hash. *) -val save_commitment : - rw -> Sc_rollup.Commitment.t -> Sc_rollup.Commitment.Hash.t tzresult Lwt.t - -(** [commitment_published_at_level t hash] returns the levels at which the - commitment was first published and the one at which it was included by in a - Layer 1 block. It returns [None] if the commitment is not known by the - rollup node or if it was never published by the rollup node (and included on - L1). *) -val commitment_published_at_level : - _ t -> - Sc_rollup.Commitment.Hash.t -> - Store.Commitments_published_at_level.element option tzresult Lwt.t - -(** [save_commitment_published_at_level t hash levels] saves the - publication/inclusion information for a commitment with [hash]. *) -val set_commitment_published_at_level : - rw -> - Sc_rollup.Commitment.Hash.t -> - Store.Commitments_published_at_level.element -> - unit tzresult Lwt.t - -type commitment_source = Anyone | Us - -(** [commitment_was_published t hash] returns [true] if the commitment is known - as being already published on L1. The [source] indicates if we want to know - the publication status for commitments we published ourselves [`Us] or that - [`Anyone] published. *) -val commitment_was_published : - _ t -> - source:commitment_source -> - Sc_rollup.Commitment.Hash.t -> - bool tzresult Lwt.t - -(** {3 Inboxes} *) - -type messages_info = { - is_first_block : bool; - predecessor : Block_hash.t; - predecessor_timestamp : Timestamp.t; - messages : Sc_rollup.Inbox_message.t list; -} - -(** [get_inbox t inbox_hash] retrieves the inbox whose hash is [inbox_hash] from - the rollup node's storage. *) -val get_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** Same as {!get_inbox} but returns [None] if this inbox is not known. *) -val find_inbox : - _ t -> Sc_rollup.Inbox.Hash.t -> Sc_rollup.Inbox.t option tzresult Lwt.t - -(** [save_inbox t inbox] remembers the [inbox] in the storage. It is associated - to its hash which is returned. *) -val save_inbox : - rw -> Sc_rollup.Inbox.t -> Sc_rollup.Inbox.Hash.t tzresult Lwt.t - -(** [inbox_of_head node_ctxt block] returns the latest inbox at the given - [block]. This function always returns [inbox] for all levels at and - after the rollup genesis. NOTE: It requires the L2 block for [block.hash] to - have been saved. *) -val inbox_of_head : _ t -> Layer1.head -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** Same as {!get_inbox} but uses the Layer 1 block hash for this inbox instead. *) -val get_inbox_by_block_hash : - _ t -> Block_hash.t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [genesis_inbox t] is the genesis inbox for the rollup [t.sc_rollup_address]. *) -val genesis_inbox : _ t -> Sc_rollup.Inbox.t tzresult Lwt.t - -(** [get_messages t witness_hash] retrieves the messages for the merkelized - payloads hash [witness_hash] stored by the rollup node. *) -val get_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info tzresult Lwt.t - -(** Same as {!get_messages} but returns [None] if the payloads hash is not known. *) -val find_messages : - _ t -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - messages_info option tzresult Lwt.t - -(** [get_num_messages t witness_hash] retrieves the number of messages for the - inbox witness [witness_hash] stored by the rollup node. *) -val get_num_messages : - _ t -> Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> int tzresult Lwt.t - -(** [save_messages t payloads_hash ~block_hash messages] associates the list of - [messages] to the [payloads_hash]. The payload hash must be computed by - calling, e.g. {!Sc_rollup.Inbox.add_all_messages}. *) -val save_messages : - rw -> - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t -> - block_hash:Block_hash.t -> - Sc_rollup.Inbox_message.t list -> - unit tzresult Lwt.t - -(** Return values for {!protocol_of_level}. *) -type proto_info = { - proto_level : int; - (** Protocol level for operations of block (can be different from L1 - header value in the case of a migration block). *) - first_level_of_protocol : bool; - (** [true] if the level is the first of the protocol. *) - protocol : Protocol_hash.t; - (** Hash of the {e current} protocol for this level. *) -} - -(** [protocol_of_level t level] returns the protocol of block level [level]. *) -val protocol_of_level : _ t -> int32 -> proto_info 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]. *) -val save_protocol_info : - rw -> Layer1.header -> predecessor:Layer1.header -> unit tzresult Lwt.t - -(** {3 DAL} *) - -(** [get_slot_header t ~published_in_block_hash slot_index] returns the slot - header for the [slot_index] that was published in the provided block hash on - Layer 1. *) -val get_slot_header : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot_index.t -> - Dal.Slot.Header.t tzresult Lwt.t - -(** [get_all_slot_headers t ~published_in_block_hash] returns the slot headers - for all the slots that were published in the provided block hash on Layer - 1. *) -val get_all_slot_headers : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t list tzresult Lwt.t - -(** [get_slot_indexes t ~published_in_block_hash] returns the slot indexes whose - headers were published in the provided block hash on Layer 1. *) -val get_slot_indexes : - _ t -> - published_in_block_hash:Block_hash.t -> - Dal.Slot_index.t list tzresult Lwt.t - -(** [save_slot_header t ~published_in_block_hash header] saves the [header] as - being published for its index in the provided block hash on Layer 1. *) -val save_slot_header : - rw -> - published_in_block_hash:Block_hash.t -> - Dal.Slot.Header.t -> - unit tzresult Lwt.t - -(** [find_slot_status t ~confirmed_in_block_hash index] returns [None] if the - slot's block is not processed yet, [Some `Unconfirmed] if the slot was not - confirmed and [Some `Confirmed] if the slot is confirmed and the associated - pages are available. *) -val find_slot_status : - _ t -> - confirmed_in_block_hash:Block_hash.t -> - Dal.Slot_index.t -> - [`Unconfirmed | `Confirmed] option tzresult Lwt.t - -(** [list_slots_statuses t ~confirmed_in_block_hash] lists the list of - slots indices with their respective statuses that are saved for the given - [confirmed_in_block_hash] *) -val list_slots_statuses : - _ t -> - confirmed_in_block_hash:Block_hash.t -> - (Dal.Slot_index.t * [`Confirmed | `Unconfirmed]) list tzresult Lwt.t - -(** [save_slot_status node_ctxt hash slot_index status] saves in - [node_ctxt.store] that [slot_index] has status [status] in the - block with hash in [node_ctxt.store]. -*) -val save_slot_status : - rw -> - Block_hash.t -> - Dal.Slot_index.t -> - [`Confirmed | `Unconfirmed] -> - unit tzresult Lwt.t - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/4636 - Missing docstrings. *) - -val find_confirmed_slots_history : - _ t -> Block_hash.t -> Dal.Slots_history.t option tzresult Lwt.t - -val save_confirmed_slots_history : - rw -> Block_hash.t -> Dal.Slots_history.t -> unit tzresult Lwt.t - -val find_confirmed_slots_histories : - _ t -> Block_hash.t -> Dal.Slots_history.History_cache.t option tzresult Lwt.t - -val save_confirmed_slots_histories : - rw -> Block_hash.t -> Dal.Slots_history.History_cache.t -> unit tzresult Lwt.t - -(**/**) - -module Internal_for_tests : sig - (** Create a node context which really stores data on disk but does not - connect to any layer 1 node. It is meant to be used in unit tests for the - rollup node functions. *) - val create_node_context : - Protocol_client_context.full -> - ?constants:Constants.Parametric.t -> - data_dir:string -> - Sc_rollup.Kind.t -> - Store_sigs.rw t tzresult Lwt.t -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/outbox.ml b/src/proto_018_Proxford/lib_sc_rollup_node/outbox.ml index a76f94397d5e..e9a3abe628fa 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/outbox.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/outbox.ml @@ -24,14 +24,11 @@ (*****************************************************************************) open Node_context -open Protocol.Alpha_context let get_state_of_lcc node_ctxt = let open Lwt_result_syntax in let lcc = Reference.get node_ctxt.lcc in - let* block_hash = - Node_context.hash_of_level node_ctxt (Raw_level.to_int32 lcc.level) - in + let* block_hash = Node_context.hash_of_level node_ctxt lcc.level in let* ctxt = Node_context.checkout_context node_ctxt block_hash in let*! state = Context.PVMState.find ctxt in return state @@ -48,7 +45,7 @@ let proof_of_output node_ctxt output = *) failwith "Error producing outbox proof (no cemented state in the node)" | Some state -> ( - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! proof = PVM.produce_output_proof node_ctxt.context state output in match proof with | Ok proof -> diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/outbox.mli b/src/proto_018_Proxford/lib_sc_rollup_node/outbox.mli index 71e8c4a1f28d..1b172b048f4b 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/outbox.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/outbox.mli @@ -32,4 +32,4 @@ open Protocol.Alpha_context val proof_of_output : Node_context.rw -> Sc_rollup.output -> - (Sc_rollup.Commitment.Hash.t * string) tzresult Lwt.t + (Octez_smart_rollup.Commitment.Hash.t * string) tzresult Lwt.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml b/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml index d2ad6afc0248..f984a811cfc9 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml @@ -63,20 +63,20 @@ end let add_level level increment = (* We only use this function with positive increments so it is safe *) if increment < 0 then invalid_arg "Commitment.add_level negative increment" ; - Raw_level.Internal_for_tests.add level increment + Int32.add level (Int32.of_int increment) let sub_level level decrement = (* We only use this function with positive increments so it is safe *) if decrement < 0 then invalid_arg "Commitment.sub_level negative decrement" ; - Raw_level.Internal_for_tests.sub level decrement + let r = Int32.sub level (Int32.of_int decrement) in + if r < 0l then None else Some r let sc_rollup_commitment_period node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup + node_ctxt.Node_context.protocol_constants.sc_rollup .commitment_period_in_blocks let sc_rollup_challenge_window node_ctxt = - node_ctxt.Node_context.protocol_constants.parametric.sc_rollup - .challenge_window_in_blocks + node_ctxt.Node_context.protocol_constants.sc_rollup.challenge_window_in_blocks let next_commitment_level node_ctxt last_commitment_level = add_level last_commitment_level (sc_rollup_commitment_period node_ctxt) @@ -85,55 +85,47 @@ type state = Node_context.ro let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Lwt_result_syntax in - let* block = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 inbox_level) - in + let* block = Node_context.get_l2_block_by_level node_ctxt inbox_level in return (Sc_rollup_block.final_tick block) let build_commitment (node_ctxt : _ Node_context.t) - (prev_commitment : Sc_rollup.Commitment.Hash.t) ~prev_commitment_level - ~inbox_level ctxt = + (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) + ~prev_commitment_level ~inbox_level ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with | Some pvm_state -> Ok pvm_state | None -> error_with - "PVM state for commitment at level %a is not available" - Raw_level.pp + "PVM state for commitment at level %ld is not available" inbox_level in let*! compressed_state = PVM.state_hash pvm_state in let*! tick = PVM.get_tick pvm_state in let* prev_commitment_tick = tick_of_level node_ctxt prev_commitment_level in let distance = Z.sub (Sc_rollup.Tick.to_z tick) prev_commitment_tick in - let number_of_ticks = - distance |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value - in - let*? number_of_ticks = - match number_of_ticks with - | Some number_of_ticks -> - if number_of_ticks = Sc_rollup.Number_of_ticks.zero then - error_with "A 0-tick commitment is impossible" - else Ok number_of_ticks - | None -> error_with "Invalid number of ticks for commitment" + let number_of_ticks = Z.to_int64 distance in + let*? () = + if number_of_ticks = 0L then error_with "A 0-tick commitment is impossible" + else if number_of_ticks < 0L then + error_with "Invalid number of ticks for commitment" + else Ok () in return - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = prev_commitment; inbox_level; number_of_ticks; - compressed_state; + compressed_state = + Sc_rollup_proto_types.State_hash.to_octez compressed_state; } let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! pvm_state = PVM.State.find ctxt in let*? pvm_state = match pvm_state with @@ -142,21 +134,22 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = in let*! compressed_state = PVM.state_hash pvm_state in let commitment = - Sc_rollup.Commitment. + Octez_smart_rollup.Commitment. { predecessor = Hash.zero; inbox_level = node_ctxt.genesis_info.level; - number_of_ticks = Sc_rollup.Number_of_ticks.zero; - compressed_state; + number_of_ticks = 0L; + compressed_state = + Sc_rollup_proto_types.State_hash.to_octez compressed_state; } in (* Ensure the initial state corresponds to the one of the rollup's in the protocol. A mismatch is possible if a wrong external boot sector was provided. *) - let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in let+ () = fail_unless - Sc_rollup.Commitment.Hash.( + Octez_smart_rollup.Commitment.Hash.( commitment_hash = node_ctxt.genesis_info.commitment_hash) (Sc_rollup_node_errors.Invalid_genesis_state { @@ -169,7 +162,7 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor current_level ctxt = let open Lwt_result_syntax in - if Raw_level.(current_level = node_ctxt.genesis_info.level) then + if current_level = node_ctxt.genesis_info.level then let*! () = Commitment_event.compute_commitment current_level in let+ genesis_commitment = genesis_commitment node_ctxt ctxt in Some genesis_commitment @@ -177,7 +170,6 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let* last_commitment_hash = let+ pred = Node_context.get_l2_block node_ctxt predecessor in Sc_rollup_block.most_recent_commitment pred.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in let* last_commitment = Node_context.get_commitment node_ctxt last_commitment_hash @@ -185,7 +177,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let next_commitment_level = next_commitment_level node_ctxt last_commitment.inbox_level in - if Raw_level.(current_level = next_commitment_level) then + if current_level = next_commitment_level then let*! () = Commitment_event.compute_commitment current_level in let+ commitment = build_commitment @@ -201,7 +193,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let process_head (node_ctxt : _ Node_context.t) ~predecessor Layer1.{level; header = _; _} ctxt = let open Lwt_result_syntax in - let current_level = Raw_level.of_int32_exn level in + let current_level = level in let* commitment = create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt in @@ -227,15 +219,15 @@ let missing_commitments (node_ctxt : _ Node_context.t) = let sc_rollup_challenge_window_int32 = sc_rollup_challenge_window node_ctxt |> Int32.of_int in - let rec gather acc (commitment_hash : Sc_rollup.Commitment.Hash.t) = + let rec gather acc (commitment_hash : Octez_smart_rollup.Commitment.Hash.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in let lcc = Reference.get node_ctxt.lcc in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* Commitment is before or at the LCC, we have reached the end. *) return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lpc_level) -> + | Some commitment when commitment.inbox_level <= lpc_level -> (* Commitment is before the last published one, we have also reached the end because we only publish commitments that are for the inbox of a finalized L1 block. *) @@ -263,23 +255,18 @@ let missing_commitments (node_ctxt : _ Node_context.t) = commitments that are missing. *) let commitment = Sc_rollup_block.most_recent_commitment finalized.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in gather [] commitment let publish_commitment (node_ctxt : _ Node_context.t) ~source - (commitment : Sc_rollup.Commitment.t) = + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let publish_operation = - L1_operation.Publish - { - rollup = node_ctxt.rollup_address; - commitment = Sc_rollup_proto_types.Commitment.to_octez commitment; - } + L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} in let*! () = Commitment_event.publish_commitment - (Sc_rollup.Commitment.hash_uncarbonated commitment) + (Octez_smart_rollup.Commitment.hash commitment) commitment.inbox_level in let* _hash = Injector.add_pending_operation ~source publish_operation in @@ -300,7 +287,8 @@ let on_publish_commitments (node_ctxt : state) = let* commitments = missing_commitments node_ctxt in List.iter_es (publish_commitment node_ctxt ~source) commitments -let publish_single_commitment node_ctxt (commitment : Sc_rollup.Commitment.t) = +let publish_single_commitment node_ctxt + (commitment : Octez_smart_rollup.Commitment.t) = let open Lwt_result_syntax in let operator = Node_context.get_operator node_ctxt Publish in let lcc = Reference.get node_ctxt.lcc in @@ -335,26 +323,20 @@ let earliest_cementing_level node_ctxt commitment_hash = let latest_cementable_commitment (node_ctxt : _ Node_context.t) (head : Sc_rollup_block.t) = let open Lwt_result_option_syntax in - let commitment_hash = - Sc_rollup_block.most_recent_commitment head.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez - in + let commitment_hash = Sc_rollup_block.most_recent_commitment head.header in let** commitment = Node_context.find_commitment node_ctxt commitment_hash in let** cementable_level_bound = return @@ sub_level commitment.inbox_level (sc_rollup_challenge_window node_ctxt) in let lcc = Reference.get node_ctxt.lcc in - if Raw_level.(cementable_level_bound <= lcc.level) then return_none + if cementable_level_bound <= lcc.level then return_none else let** cementable_bound_block = - Node_context.find_l2_block_by_level - node_ctxt - (Raw_level.to_int32 cementable_level_bound) + Node_context.find_l2_block_by_level node_ctxt cementable_level_bound in let cementable_commitment = Sc_rollup_block.most_recent_commitment cementable_bound_block.header - |> Sc_rollup_proto_types.Commitment_hash.of_octez in return_some cementable_commitment @@ -364,11 +346,11 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = let*& head = Node_context.last_processed_head_opt node_ctxt in let head_level = head.header.level in let lcc = Reference.get node_ctxt.lcc in - let rec gather acc (commitment_hash : Sc_rollup.Commitment.Hash.t) = + let rec gather acc (commitment_hash : Octez_smart_rollup.Commitment.Hash.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in match commitment with | None -> return acc - | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> + | Some commitment when commitment.inbox_level <= lcc.level -> (* If we have moved backward passed or at the current LCC then we have reached the end. *) return acc @@ -403,10 +385,10 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = Layer 1 node as a failsafe. *) let* green_light = Plugin.RPC.Sc_rollup.can_be_cemented - node_ctxt.cctxt + (new Protocol_client_context.wrap_full node_ctxt.cctxt) (node_ctxt.cctxt#chain, `Head 0) - node_ctxt.rollup_address - first_cementable + (Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address) + (Sc_rollup_proto_types.Commitment_hash.of_octez first_cementable) in if green_light then return cementable else return_nil diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.mli b/src/proto_018_Proxford/lib_sc_rollup_node/publisher.mli index 79990b2198ad..36c8c655ece7 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/publisher.mli @@ -50,16 +50,14 @@ val process_head : predecessor:Block_hash.t -> Layer1.header -> Context.rw -> - Protocol.Alpha_context.Sc_rollup.Commitment.Hash.t option tzresult Lwt.t + Octez_smart_rollup.Commitment.Hash.t option tzresult Lwt.t (** [publish_single_commitment node_ctxt commitment] publishes a single [commitment] if it is missing. This function is meant to be used by the {e accuser} mode to sparingly publish commitments when it detects a conflict. *) val publish_single_commitment : - _ Node_context.t -> - Protocol.Alpha_context.Sc_rollup.Commitment.t -> - unit tzresult Lwt.t + _ Node_context.t -> Octez_smart_rollup.Commitment.t -> unit tzresult Lwt.t (** Initialize worker for publishing and cementing commitments. *) val init : _ Node_context.t -> unit tzresult Lwt.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/pvm.ml b/src/proto_018_Proxford/lib_sc_rollup_node/pvm.ml index 178664995c5f..e71be750758e 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/pvm.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/pvm.ml @@ -24,78 +24,8 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +module type S = Pvm_sig.S -(** Desired module type of a PVM from the L2 node's perspective *) -module type S = sig - include - Sc_rollup.PVM.S - with type context = Context.rw_index - and type state = Context.tree - and type hash = Sc_rollup.State_hash.t - - (** Kind of the PVM. *) - val kind : Sc_rollup.Kind.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) - val get_tick : state -> Sc_rollup.Tick.t Lwt.t - - (** PVM status *) - type status - - (** [get_status state] gives you the current execution status for the PVM. *) - val get_status : state -> status Lwt.t - - (** [string_of_status status] returns a string representation of [status]. *) - val string_of_status : status -> string - - (** [get_outbox outbox_level state] returns a list of outputs - available in the outbox of [state] at a given [outbox_level]. *) - val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t - - (** [eval_many ~max_steps s0] returns a state [s1] resulting from the - execution of up to [~max_steps] steps of the rollup at state [s0]. *) - val eval_many : - reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> - write_debug:Tezos_scoru_wasm.Builtins.write_debug -> - ?stop_at_snapshot:bool -> - max_steps:int64 -> - state -> - (state * int64) Lwt.t - - val new_dissection : - default_number_of_sections:int -> - start_chunk:Sc_rollup.Dissection_chunk.t -> - our_stop_chunk:Sc_rollup.Dissection_chunk.t -> - Sc_rollup.Tick.t list - - (** State storage for this PVM. *) - module State : sig - (** [empty ()] is the empty state. *) - val empty : unit -> state - - (** [find context] returns the PVM state stored in the [context], if any. *) - val find : _ Context.t -> state option Lwt.t - - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - - (** [set context state] saves the PVM state [state] in the context and - returns the updated context. Note: [set] does not perform any write on - disk, this information must be committed using {!val:Context.commit}. *) - val set : 'a Context.t -> state -> 'a Context.t Lwt.t - end - - (** Inspect durable state using a more specialised way of reading the - PVM state. - For example in WASM, it decodes the durable storage in the state - before reading values. - *) - module Inspect_durable_state : sig - (** [lookup state path] returns the data stored for the path [path] in the - PVM state [state]. *) - val lookup : state -> string list -> bytes option Lwt.t - end -end +let of_kind : Kind.t -> (module S) = function + | Example_arith -> (module Arith_pvm) + | Wasm_2_0_0 -> (module Wasm_2_0_0_pvm) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/pvm_rpc.ml b/src/proto_018_Proxford/lib_sc_rollup_node/pvm_rpc.ml index 06c5c60b5e51..a8d946e87b6a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/pvm_rpc.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/pvm_rpc.ml @@ -35,6 +35,6 @@ end let no_rpc = (module No_rpc : S) let of_kind = function - | Protocol.Alpha_context.Sc_rollup.Kind.Example_arith -> no_rpc + | Kind.Example_arith -> no_rpc | Wasm_2_0_0 -> (module Wasm_2_0_0_rpc.Make_RPC (Wasm_2_0_0_pvm.Durable_state) : S) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/pvm_sig.ml b/src/proto_018_Proxford/lib_sc_rollup_node/pvm_sig.ml new file mode 100644 index 000000000000..178664995c5f --- /dev/null +++ b/src/proto_018_Proxford/lib_sc_rollup_node/pvm_sig.ml @@ -0,0 +1,101 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022-2023 TriliTech *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol +open Alpha_context + +(** Desired module type of a PVM from the L2 node's perspective *) +module type S = sig + include + Sc_rollup.PVM.S + with type context = Context.rw_index + and type state = Context.tree + and type hash = Sc_rollup.State_hash.t + + (** Kind of the PVM. *) + val kind : Sc_rollup.Kind.t + + (** [get_tick state] gets the total tick counter for the given PVM state. *) + val get_tick : state -> Sc_rollup.Tick.t Lwt.t + + (** PVM status *) + type status + + (** [get_status state] gives you the current execution status for the PVM. *) + val get_status : state -> status Lwt.t + + (** [string_of_status status] returns a string representation of [status]. *) + val string_of_status : status -> string + + (** [get_outbox outbox_level state] returns a list of outputs + available in the outbox of [state] at a given [outbox_level]. *) + val get_outbox : Raw_level.t -> state -> Sc_rollup.output list Lwt.t + + (** [eval_many ~max_steps s0] returns a state [s1] resulting from the + execution of up to [~max_steps] steps of the rollup at state [s0]. *) + val eval_many : + reveal_builtins:Tezos_scoru_wasm.Builtins.reveals -> + write_debug:Tezos_scoru_wasm.Builtins.write_debug -> + ?stop_at_snapshot:bool -> + max_steps:int64 -> + state -> + (state * int64) Lwt.t + + val new_dissection : + default_number_of_sections:int -> + start_chunk:Sc_rollup.Dissection_chunk.t -> + our_stop_chunk:Sc_rollup.Dissection_chunk.t -> + Sc_rollup.Tick.t list + + (** State storage for this PVM. *) + module State : sig + (** [empty ()] is the empty state. *) + val empty : unit -> state + + (** [find context] returns the PVM state stored in the [context], if any. *) + val find : _ Context.t -> state option Lwt.t + + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + + (** [set context state] saves the PVM state [state] in the context and + returns the updated context. Note: [set] does not perform any write on + disk, this information must be committed using {!val:Context.commit}. *) + val set : 'a Context.t -> state -> 'a Context.t Lwt.t + end + + (** Inspect durable state using a more specialised way of reading the + PVM state. + For example in WASM, it decodes the durable storage in the state + before reading values. + *) + module Inspect_durable_state : sig + (** [lookup state path] returns the data stored for the path [path] in the + PVM state [state]. *) + val lookup : state -> string list -> bytes option Lwt.t + end +end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_coordinator.ml b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_coordinator.ml index b841d2e7353c..5762f752126c 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_coordinator.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_coordinator.ml @@ -31,13 +31,25 @@ module Player = Refutation_player module Pkh_map = Signature.Public_key_hash.Map module Pkh_table = Signature.Public_key_hash.Table -type state = {node_ctxt : Node_context.rw; pending_opponents : unit Pkh_table.t} - -let get_conflicts cctxt head_block = - Plugin.RPC.Sc_rollup.conflicts cctxt (cctxt#chain, head_block) - -let get_ongoing_games cctxt head_block = - Plugin.RPC.Sc_rollup.ongoing_refutation_games cctxt (cctxt#chain, head_block) +type state = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + pending_opponents : unit Pkh_table.t; +} + +let get_conflicts cctxt head_block address key = + Plugin.RPC.Sc_rollup.conflicts + cctxt + (cctxt#chain, head_block) + (Sc_rollup_proto_types.Address.of_octez address) + key + +let get_ongoing_games cctxt head_block address key = + Plugin.RPC.Sc_rollup.ongoing_refutation_games + cctxt + (cctxt#chain, head_block) + (Sc_rollup_proto_types.Address.of_octez address) + key let untracked_conflicts opponent_players conflicts = List.filter @@ -72,9 +84,11 @@ let on_process Layer1.{hash; level} state = (* Not injecting refutations, don't play refutation games *) return_unit | Some self -> - let Node_context.{rollup_address; cctxt; _} = node_ctxt in + let Node_context.{rollup_address; _} = node_ctxt in (* Current conflicts in L1 *) - let* conflicts = get_conflicts cctxt head_block rollup_address self in + let* conflicts = + get_conflicts state.cctxt head_block rollup_address self + in (* Map of opponents the node is playing against to the corresponding player worker *) let opponent_players = @@ -85,7 +99,7 @@ let on_process Layer1.{hash; level} state = let new_conflicts = untracked_conflicts opponent_players conflicts in (* L1 ongoing games *) let* ongoing_games = - get_ongoing_games cctxt head_block rollup_address self + get_ongoing_games state.cctxt head_block rollup_address self in (* Map between opponents and their corresponding games *) let ongoing_game_map = make_game_map self ongoing_games in @@ -121,7 +135,10 @@ let on_process Layer1.{hash; level} state = module Types = struct type nonrec state = state - type parameters = {node_ctxt : Node_context.rw} + type parameters = { + node_ctxt : Node_context.rw; + cctxt : Protocol_client_context.full; + } end module Name = struct @@ -157,8 +174,8 @@ module Handlers = struct type launch_error = error trace - let on_launch _w () Types.{node_ctxt} = - return {node_ctxt; pending_opponents = Pkh_table.create 5} + let on_launch _w () Types.{node_ctxt; cctxt} = + return {node_ctxt; cctxt; pending_opponents = Pkh_table.create 5} let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : unit tzresult Lwt.t = @@ -187,7 +204,10 @@ let worker_promise, worker_waker = Lwt.task () let init node_ctxt = let open Lwt_result_syntax in let*! () = Refutation_game_event.Coordinator.starting () in - let+ worker = Worker.launch table () {node_ctxt} (module Handlers) in + let cctxt = + new Protocol_client_context.wrap_full node_ctxt.Node_context.cctxt + in + let+ worker = Worker.launch table () {node_ctxt; cctxt} (module Handlers) in Lwt.wakeup worker_waker worker (* This is a refutation coordinator for a single scoru *) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml index d62b831205cf..54f08d2ba8e3 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml @@ -120,7 +120,7 @@ let page_membership_proof params page_index slot_data = let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag (dal_params : Dal.parameters) start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! input_request = PVM.is_input_state start_state in match input_request with | Sc_rollup.(Needs_reveal (Request_dal_page page_id)) -> ( @@ -152,9 +152,16 @@ let page_info_from_pvm_state (node_ctxt : _ Node_context.t) ~dal_attestation_lag pages_per_slot)) | _ -> return_none +let metadata (node_ctxt : _ Node_context.t) = + let address = + Sc_rollup_proto_types.Address.of_octez node_ctxt.rollup_address + in + let origination_level = Raw_level.of_int32_exn node_ctxt.genesis_info.level in + Sc_rollup.Metadata.{address; origination_level} + let generate_proof (node_ctxt : _ Node_context.t) game start_state = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let snapshot = game.inbox_snapshot in (* NOTE: [snapshot_level_int32] below refers to the level of the snapshotted inbox (from the skip list) which also matches [game.start_level - 1]. *) @@ -189,7 +196,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let* parametric_constants = let cctxt = node_ctxt.cctxt in Protocol.Constants_services.parametric - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, `Level snapshot_level_int32) in let dal_l1_parameters = parametric_constants.dal in @@ -216,7 +223,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = Reveals.get ?dac_client:node_ctxt.dac_client ~data_dir:node_ctxt.data_dir - ~pvm_kind:PVM.kind + ~pvm_kind:(Sc_rollup_proto_types.Kind.to_octez PVM.kind) hash in match res with Ok data -> return @@ Some data | Error _ -> return None @@ -226,7 +233,11 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let get_history inbox_hash = let open Lwt_syntax in - let+ inbox = Node_context.find_inbox node_ctxt inbox_hash in + let+ inbox = + Node_context.find_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash) + in match inbox with | Error err -> Format.kasprintf @@ -236,7 +247,12 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = inbox_hash pp_print_trace err - | Ok inbox -> Option.map Sc_rollup.Inbox.take_snapshot inbox + | Ok inbox -> + Option.map + (fun i -> + Sc_rollup.Inbox.take_snapshot + (Sc_rollup_proto_types.Inbox.of_octez i)) + inbox let get_payloads_history witness = Lwt.map @@ -245,7 +261,10 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = @@ let open Lwt_result_syntax in let* {is_first_block; predecessor; predecessor_timestamp; messages} = - Node_context.get_messages node_ctxt witness + Node_context.get_messages + node_ctxt + (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez + witness) in let*? hist = Inbox.payloads_history_of_messages @@ -271,7 +290,7 @@ let generate_proof (node_ctxt : _ Node_context.t) game start_state = let page_info = page_info end end in - let metadata = Node_context.metadata node_ctxt in + let metadata = metadata node_ctxt in let*! start_tick = PVM.get_tick start_state in let* proof = trace @@ -333,7 +352,7 @@ let new_dissection ~opponent ~default_number_of_sections node_ctxt last_level ok let our_stop_chunk = Sc_rollup.Dissection_chunk.{state_hash = our_state_hash; tick = our_tick} in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let* dissection = Game_helpers.make_dissection ~state_of_tick @@ -476,9 +495,9 @@ let timeout_reached ~self head_block node_ctxt staker1 staker2 = let Node_context.{rollup_address; cctxt; _} = node_ctxt in let* game_result = Plugin.RPC.Sc_rollup.timeout_reached - cctxt + (new Protocol_client_context.wrap_full cctxt) (cctxt#chain, head_block) - rollup_address + (Sc_rollup_proto_types.Address.of_octez rollup_address) staker1 staker2 in diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game_event.ml b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game_event.ml index ceb5ef25e148..b9231bfc5f90 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game_event.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game_event.ml @@ -79,10 +79,10 @@ module Simple = struct {our_commitment_hash} at level {level} with staker {other} that hash \ issued commitment {their_commitment_hash}." ~level:Notice - ("our_commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("level", Raw_level.encoding) - ("other", Sc_rollup.Staker.encoding) - ("their_commitment_hash", Sc_rollup.Commitment.Hash.encoding) + ("our_commitment_hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) + ("other", Signature.Public_key_hash.encoding) + ("their_commitment_hash", Octez_smart_rollup.Commitment.Hash.encoding) let timeout_detected = declare_1 diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/reveals.ml b/src/proto_018_Proxford/lib_sc_rollup_node/reveals.ml index 77d6937abfc0..e3efc65ed384 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/reveals.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/reveals.ml @@ -73,7 +73,9 @@ let proto_hash_to_dac_hash ((module Plugin) : Dac_plugin.t) proto_reveal_hash = let get ?dac_client ~data_dir ~pvm_kind hash = let open Lwt_result_syntax in let* contents = - let filename = path data_dir (Sc_rollup.Kind.to_string pvm_kind) hash in + let filename = + path data_dir (Octez_smart_rollup.Kind.to_string pvm_kind) hash + in let* file_contents = file_contents filename in match file_contents with | Some contents -> return contents diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/reveals.mli b/src/proto_018_Proxford/lib_sc_rollup_node/reveals.mli index 921b0e6b027b..921e2869adf9 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/reveals.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/reveals.mli @@ -69,6 +69,6 @@ type source = val get : ?dac_client:Dac_observer_client.t -> data_dir:string -> - pvm_kind:Protocol.Alpha_context.Sc_rollup.Kind.t -> + pvm_kind:Kind.t -> Protocol.Sc_rollup_reveal_hash.t -> string tzresult Lwt.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml b/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml index a13a580a5e13..d557dbeb97e5 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml @@ -36,7 +36,7 @@ type info_per_level = { type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; @@ -54,15 +54,14 @@ let simulate_info_per_level (node_ctxt : [`Read] Node_context.t) predecessor = let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = let open Lwt_result_syntax in - let*? level = Environment.wrap_tzresult @@ Raw_level.of_int32 level in let*? () = error_unless - Raw_level.(level >= node_ctxt.Node_context.genesis_info.level) + (level >= node_ctxt.Node_context.genesis_info.level) (Exn (Failure "Cannot simulate before origination level")) in - let first_inbox_level = Raw_level.succ node_ctxt.genesis_info.level in + let first_inbox_level = Int32.succ node_ctxt.genesis_info.level in let* ctxt = - if Raw_level.(level < first_inbox_level) then + if level < first_inbox_level then (* This is before we have interpreted the boot sector, so we start with an empty context in genesis *) return (Context.empty node_ctxt.context) @@ -70,7 +69,7 @@ let start_simulation node_ctxt ~reveal_map (Layer1.{hash; level} as head) = in let* ctxt, state = Interpreter.state_of_head node_ctxt ctxt head in let+ info_per_level = simulate_info_per_level node_ctxt hash in - let inbox_level = Raw_level.succ level in + let inbox_level = Int32.succ level in { ctxt; inbox_level; @@ -92,7 +91,7 @@ let simulate_messages_no_checks (node_ctxt : Node_context.ro) info_per_level = _; } as sim) messages = let open Lwt_result_syntax in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let*! state_hash = PVM.state_hash state in let*! tick = PVM.get_tick state in let eval_state = @@ -126,22 +125,15 @@ let simulate_messages (node_ctxt : Node_context.ro) sim messages = (sim.level_position = End) (Exn (Failure "Level for simulation is ended")) in - let*? messages = - let open Result_syntax in + let messages = if sim.level_position = Start then let {predecessor_timestamp; predecessor} = sim.info_per_level in - let open Sc_rollup.Inbox_message in - let* internals = - List.map_e - serialize - [ - Internal Start_of_level; - Internal (Info_per_level {predecessor_timestamp; predecessor}); - ] - |> Environment.wrap_tzresult - in - return (internals @ messages) - else return messages + let open Sc_rollup_inbox_message_repr in + unsafe_to_string start_of_level_serialized + :: unsafe_to_string + (info_per_level_serialized ~predecessor ~predecessor_timestamp) + :: messages + else messages in let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim messages in ({sim with level_position = Middle}, num_ticks) @@ -153,10 +145,10 @@ let end_simulation node_ctxt sim = (sim.level_position = End) (Exn (Failure "Level for simulation is ended")) in - let*? eol = - Sc_rollup.Inbox_message.serialize - (Sc_rollup.Inbox_message.Internal End_of_level) - |> Environment.wrap_tzresult + let+ sim, num_ticks = + simulate_messages_no_checks + node_ctxt + sim + [Sc_rollup_inbox_message_repr.(unsafe_to_string end_of_level_serialized)] in - let+ sim, num_ticks = simulate_messages_no_checks node_ctxt sim [eol] in ({sim with level_position = End}, num_ticks) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/simulation.mli b/src/proto_018_Proxford/lib_sc_rollup_node/simulation.mli index 2c0a627ffff2..ac8d8dd03624 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/simulation.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/simulation.mli @@ -37,7 +37,7 @@ type info_per_level = { (** Type of the state for a simulation. *) type t = { ctxt : Context.ro; - inbox_level : Raw_level.t; + inbox_level : int32; state : Context.tree; reveal_map : string Sc_rollup_reveal_hash.Map.t option; nb_messages_inbox : int; @@ -58,10 +58,7 @@ val start_simulation : simulation state, the remaining fuel (when [?fuel] is provided) and the number of ticks that happened. *) val simulate_messages : - Node_context.ro -> - t -> - Sc_rollup.Inbox_message.serialized list -> - (t * Z.t) tzresult Lwt.t + Node_context.ro -> t -> string list -> (t * Z.t) tzresult Lwt.t (** [end_simulation node_ctxt sim] adds and [End_of_level] message and marks the simulation as ended. *) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml b/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml index 66b9d6ef3a9c..894d2e304ee5 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml @@ -32,7 +32,7 @@ *) open Octez_smart_rollup -open Protocol.Alpha_context +open Octez_smart_rollup_node let build_chain node_ctxt ~genesis ~length = let open Lwt_result_syntax in @@ -85,15 +85,10 @@ let tests = Helpers.alcotest "canary arith" `Quick - Sc_rollup.Kind.Example_arith - ~boot_sector:"" - canary_test; - Helpers.alcotest - "canary wasm" - `Quick - Sc_rollup.Kind.Wasm_2_0_0 + Example_arith ~boot_sector:"" canary_test; + Helpers.alcotest "canary wasm" `Quick Wasm_2_0_0 ~boot_sector:"" canary_test; ] let () = diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml index e888c6b40313..6b669b98306a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml @@ -39,25 +39,23 @@ let block_hash_of_level level = Block_hash.of_string_exn s let default_constants = - let constants = Default_parameters.constants_test in - let sc_rollup = - { - constants.sc_rollup with - arith_pvm_enable = true; - challenge_window_in_blocks = 4032; - commitment_period_in_blocks = 3; - } + let test_constants = + Layer1_helpers.constants_of_parametric Default_parameters.constants_test in - {constants with sc_rollup} + { + test_constants with + sc_rollup = + { + test_constants.sc_rollup with + challenge_window_in_blocks = 4032; + commitment_period_in_blocks = 3; + }; + } let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let open Lwt_result_syntax in let head = - Layer1. - { - hash = Block_hash.zero; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; - } + Layer1.{hash = Block_hash.zero; level = node_ctxt.genesis_info.level} in let* () = Node_context.save_level node_ctxt head in let predecessor = head in @@ -66,13 +64,20 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = Sc_rollup.Inbox.genesis ~predecessor_timestamp ~predecessor:predecessor.hash - node_ctxt.genesis_info.level + (Raw_level.of_int32_exn node_ctxt.genesis_info.level) + in + let* inbox_hash = + Node_context.save_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox.to_octez inbox) + in + let inbox_witness = + Sc_rollup.Inbox.current_witness inbox + |> Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez in - let* inbox_hash = Node_context.save_inbox node_ctxt inbox in - let inbox_witness = Sc_rollup.Inbox.current_witness inbox in let ctxt = Octez_smart_rollup_node.Context.empty node_ctxt.context in let num_ticks = 0L in - let module PVM = (val node_ctxt.pvm) in + let module PVM = (val Pvm.of_kind node_ctxt.kind) in let initial_tick = Sc_rollup.Tick.initial in let*! initial_state = PVM.initial_state ~empty:(PVM.State.empty ()) in let*! state = PVM.install_boot_sector initial_state boot_sector in @@ -81,16 +86,20 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let*! context_hash = Octez_smart_rollup_node.Context.commit ctxt in let commitment = Sc_rollup.Commitment.genesis_commitment - ~origination_level:node_ctxt.genesis_info.level + ~origination_level:(Raw_level.of_int32_exn node_ctxt.genesis_info.level) ~genesis_state_hash in - let* commitment_hash = Node_context.save_commitment node_ctxt commitment in + let* commitment_hash = + Node_context.save_commitment + node_ctxt + (Sc_rollup_proto_types.Commitment.to_octez commitment) + in let previous_commitment_hash = node_ctxt.genesis_info.commitment_hash in let header = Sc_rollup_block. { block_hash = head.hash; - level = Raw_level.to_int32 node_ctxt.genesis_info.level; + level = node_ctxt.genesis_info.level; predecessor = predecessor.hash; commitment_hash = Some commitment_hash; previous_commitment_hash; @@ -136,7 +145,7 @@ let initialize_node_context ?(constants = default_constants) kind ~boot_sector = let* ctxt = Node_context.Internal_for_tests.create_node_context cctxt - ~constants + constants ~data_dir kind in @@ -217,10 +226,7 @@ let append_dummy_l2_chain node_ctxt ~length = in let batches = Stdlib.List.init length (fun i -> - [ - Sc_rollup.Inbox_message.External - (Z.to_bits (Z.of_int (i + head_level + 1))); - ]) + ["\001" (* External tag *) ^ Z.to_bits (Z.of_int (i + head_level + 1))]) in append_l2_blocks node_ctxt batches diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli index b6571220f74a..d18d3f989dd9 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli @@ -26,6 +26,7 @@ open Octez_smart_rollup open Protocol open Alpha_context +open Octez_smart_rollup_node (** {1 Helper functions to build and run unit tests for the rollup node} *) @@ -39,8 +40,8 @@ open Alpha_context context need to use this function in order to avoid file descriptor leaks. *) val with_node_context : - ?constants:Constants.Parametric.t -> - Sc_rollup.Kind.t -> + ?constants:Rollup_constants.protocol_constants -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> @@ -64,7 +65,7 @@ val add_l2_genesis_block : val append_l2_block : [`Read | `Write] Node_context.t -> ?is_first_block:bool -> - Sc_rollup.Inbox_message.t list -> + string list -> Sc_rollup_block.t tzresult Lwt.t (** [append_l2_block node_ctxt message_batches] appends as many blocks as there @@ -72,7 +73,7 @@ val append_l2_block : messages. The portion of the chain that was added is returned. *) val append_l2_blocks : [`Read | `Write] Node_context.t -> - Sc_rollup.Inbox_message.t list list -> + string list list -> Sc_rollup_block.t list tzresult Lwt.t (** [append_dummy_l2_chain node_ctxt ~length] append [length] L2 blocks with an @@ -108,8 +109,8 @@ end val alcotest : string -> Alcotest.speed_level -> - ?constants:Constants.Parametric.t -> - Sc_rollup.Kind.t -> + ?constants:Rollup_constants.protocol_constants -> + Octez_smart_rollup.Kind.t -> boot_sector:string -> ([`Read | `Write] Node_context.t -> genesis:Sc_rollup_block.t -> diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/wasm_2_0_0_pvm.ml b/src/proto_018_Proxford/lib_sc_rollup_node/wasm_2_0_0_pvm.ml index 58d6d46968a1..d9629dc8759a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/wasm_2_0_0_pvm.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/wasm_2_0_0_pvm.ml @@ -123,7 +123,7 @@ end module Durable_state = Make_durable_state (Make_wrapped_tree (Wasm_2_0_0_proof_format.Tree)) -module Impl : Pvm.S = struct +module Impl : Pvm_sig.S = struct module PVM = Sc_rollup.Wasm_2_0_0PVM.Make (Make_backend) (Wasm_2_0_0_proof_format) include PVM -- GitLab From b76eb7f95fc2992fe03f23351c7dee5953deec19 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 29 Jun 2023 10:08:16 +0200 Subject: [PATCH 15/15] Doc: remove obsolete odoc patches --- docs/odoc_protocols.patch | 70 --------------------------------------- 1 file changed, 70 deletions(-) diff --git a/docs/odoc_protocols.patch b/docs/odoc_protocols.patch index 90c1bd01ce10..8393ba320edc 100644 --- a/docs/odoc_protocols.patch +++ b/docs/odoc_protocols.patch @@ -287,41 +287,6 @@ index 2a9a69a71b..f7247a51e3 100644 supposed to be confirmed and [pages] correspond to the pages of the slot. Otherwise [None] is returned. -diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli -index 411710c5b7..a62117b545 100644 ---- a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli -+++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli -@@ -137,7 +137,7 @@ val close : _ t -> unit tzresult Lwt.t - [block_hash]. *) - val checkout_context : 'a t -> Block_hash.t -> 'a Context.t tzresult Lwt.t - --(** [metadata node_ctxt] creates a {Sc_rollup.Metadata.t} using the information -+(** [metadata node_ctxt] creates a {!Sc_rollup.Metadata.t} using the information - stored in [node_ctxt]. *) - val metadata : _ t -> Sc_rollup.Metadata.t - -diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml -index ca8e5769b9..90a3c81f2f 100644 ---- a/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml -+++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/pvm.ml -@@ -34,7 +34,7 @@ module type S = sig - with type context = Context.rw_index - and type hash = Sc_rollup.State_hash.t - -- (** Kind of the PVM (same as {!name}). *) -+ (** Kind of the PVM. *) - val kind : Sc_rollup.Kind.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) -@@ -88,7 +88,7 @@ module type S = sig - - (** [set context state] saves the PVM state [state] in the context and - returns the updated context. Note: [set] does not perform any write on -- disk, this information must be committed using {!Context.commit}. *) -+ disk, this information must be committed using {!val:Context.commit}. *) - val set : 'a Context.t -> state -> 'a Context.t Lwt.t - end - end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/dal_pages_request.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/dal_pages_request.mli index 3be2cdb1f5..f27d737fbc 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/dal_pages_request.mli @@ -348,38 +313,3 @@ index a723ad47e5..29caafad18 100644 val add_messages : is_migration_block:bool -> predecessor_timestamp:Timestamp.time -> -diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli -index 713cf00c65..2e1b6d51d9 100644 ---- a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli -+++ b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli -@@ -135,7 +135,7 @@ val close : _ t -> unit tzresult Lwt.t - [block_hash]. *) - val checkout_context : 'a t -> Block_hash.t -> 'a Context.t tzresult Lwt.t - --(** [metadata node_ctxt] creates a {Sc_rollup.Metadata.t} using the information -+(** [metadata node_ctxt] creates a {!Sc_rollup.Metadata.t} using the information - stored in [node_ctxt]. *) - val metadata : _ t -> Sc_rollup.Metadata.t - -diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml -index ca8e5769b9..90a3c81f2f 100644 ---- a/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml -+++ b/src/proto_017_PtNairob/lib_sc_rollup_node/pvm.ml -@@ -34,7 +34,7 @@ module type S = sig - with type context = Context.rw_index - and type hash = Sc_rollup.State_hash.t - -- (** Kind of the PVM (same as {!name}). *) -+ (** Kind of the PVM. *) - val kind : Sc_rollup.Kind.t - - (** [get_tick state] gets the total tick counter for the given PVM state. *) -@@ -88,7 +88,7 @@ module type S = sig - - (** [set context state] saves the PVM state [state] in the context and - returns the updated context. Note: [set] does not perform any write on -- disk, this information must be committed using {!Context.commit}. *) -+ disk, this information must be committed using {!val:Context.commit}. *) - val set : 'a Context.t -> state -> 'a Context.t Lwt.t - end - end -- GitLab