diff --git a/docs/odoc_protocols.patch b/docs/odoc_protocols.patch index 90c1bd01ce10cd3057968aa95dc7758357b3cc04..8393ba320edc347ca098230fc6963210ff8bef72 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 diff --git a/manifest/main.ml b/manifest/main.ml index e410db9d4cb8479234d545b36856f736b1fe8e4a..911045aac376ae5c06ad1baee3dc676987a9eb05 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 db2390f3e97b11b02daa681a69a4690dbc4b415c..12c31d0dcd7bcfdfe2cc596eec7d73f393cc4469 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_injector/injector_functor.ml b/src/lib_injector/injector_functor.ml index cc5fb99770baca0fdd28983bc97cd6b072ccbcc8..2aa820d2f7a7942a9553aec5990578d74b0d9eef 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 bccf22b5fab4257b135f598552621425ce64c9ed..cab16c94984731886974c409cb301a807e327996 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 282069b5a7037c8e80033e13e369d6bbaba208ae..5c53b3c9fa25bd1005c8cc15d059b8e66b158c08 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 a3caa29d14621f203a9c48f50ae501b67247fa0f..1ab160a081f541bbb1184923fe7fbaa87457516c 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/lib_scoru_sequencer/rpc_server.ml b/src/lib_scoru_sequencer/rpc_server.ml index 597802619e5b76f6d29404cc755698a6c933c8ec..8f3e6bd134bf2457a819661360f3249bfacbec2d 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/lib_scoru_sequencer/seq_batcher.ml b/src/lib_scoru_sequencer/seq_batcher.ml index 471804b7940e6407f95bf8b466b8796a09cd4108..dcaa70d5661f42645eefd5bc5acfb8388e4d2954 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) @@ -147,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 @@ -205,8 +204,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/lib_smart_rollup/rollup_constants.ml b/src/lib_smart_rollup/rollup_constants.ml new file mode 100644 index 0000000000000000000000000000000000000000..72826294237346dba394cbbb91d3384811f67043 --- /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/lib_smart_rollup_node/dune b/src/lib_smart_rollup_node/dune index ae2cce70ad79b6defb412285bad0d9b8a6beeda7..d57b6e625ece68011e0c39ffd2028eb47ed2de0b 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 diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml b/src/lib_smart_rollup_node/node_context.ml similarity index 69% rename from src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml rename to src/lib_smart_rollup_node/node_context.ml index 757c35a0aa3e0f18d54ca0626836ff54f66d1204..2e34b972c4d6bf323d508aa50b2ad08b5526be6a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml +++ b/src/lib_smart_rollup_node/node_context.ml @@ -24,39 +24,37 @@ (* *) (*****************************************************************************) -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 : 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 : Sc_rollup.Commitment.genesis_info; + genesis_info : genesis_info; injector_retention_period : int; block_finality_time : int; - kind : Sc_rollup.Kind.t; - pvm : (module Pvm.S); + kind : Kind.t; 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; 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; } @@ -81,51 +79,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 - 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 = @@ -150,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; _} = @@ -170,106 +123,9 @@ 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 - | 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 +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; @@ -283,7 +139,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 @@ -302,25 +157,9 @@ 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* 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 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 + if dal_cctxt = None && protocol_constants.dal.feature_enable then Event.warn_dal_enabled_no_node () else Lwt.return_unit in @@ -330,8 +169,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 @@ -352,7 +190,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; @@ -365,7 +203,6 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file lcc = Reference.new_ lcc; lpc = Reference.new_ lpc; kind; - pvm = pvm_of_kind kind; injector_retention_period = 0; block_finality_time = 2; fee_parameters; @@ -400,27 +237,22 @@ 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 -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 + node_ctxt.dal_cctxt <> None && node_ctxt.protocol_constants.dal.feature_enable let readonly (node_ctxt : _ t) = { @@ -624,7 +456,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) @@ -668,7 +500,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 @@ -677,37 +509,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 @@ -715,31 +527,27 @@ 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 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 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 @@ -748,9 +556,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 @@ -766,20 +571,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 @@ -788,50 +587,30 @@ 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 = 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) + | 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 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 = 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 + 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." @@ -855,15 +634,12 @@ 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 = 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 @@ -876,13 +652,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; @@ -903,10 +672,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 @@ -916,30 +682,21 @@ 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 = 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 + 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 @@ -949,11 +706,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}} @@ -965,7 +722,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 @@ -1107,110 +864,67 @@ let save_protocol_info node_ctxt (block : Layer1.header) 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 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; _} ~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 + Store.Dal_slots_headers.list_values + store.irmin_store + ~primary_key:published_in_block_hash 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 + 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; _} ~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 + 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 - ?(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 @@ -1221,23 +935,18 @@ module Internal_for_tests = struct 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 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; @@ -1245,7 +954,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_018_Proxford/lib_sc_rollup_node/node_context.mli b/src/lib_smart_rollup_node/node_context.mli similarity index 84% rename from src/proto_018_Proxford/lib_sc_rollup_node/node_context.mli rename to src/lib_smart_rollup_node/node_context.mli index ae996303fb0085bbff2d57b106b13a269e7d2f5b..0b4fcc19c5a60ef61240276eb8761a1bd2b1d942 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.mli +++ b/src/lib_smart_rollup_node/node_context.mli @@ -26,10 +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 : Commitment.Hash.t} (** Abstract type for store to force access through this module. *) type 'a store constraint 'a = [< `Read | `Write > `Read] @@ -37,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. *) @@ -47,26 +45,25 @@ 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. *) 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 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. *) + kind : Kind.t; (** Kind of 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 @@ -80,7 +77,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; @@ -121,20 +118,22 @@ 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 ~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 -> + #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 @@ -146,10 +145,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 @@ -256,34 +251,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 +279,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 +297,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 +392,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 +400,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 +414,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 +450,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 +468,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 -> - ?constants:Constants.Parametric.t -> + #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_016_PtMumbai/lib_sc_rollup_client/commands.ml b/src/proto_016_PtMumbai/lib_sc_rollup_client/commands.ml index 0c799d3ddfc3144a7c44c8fba63f096bbfe93593..86e62aaa814f7fdd28b5bb2136da40f5a9bbc654 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 c4532a958aab2cd37eabb01023ce2f82f0de0828..b6539529a2883aa9a2b71d44ee6f55c89d0c5cc5 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 8fea1385726b2808bf0ba19420dddcafdb20d863..6777c7e83d39edc98ee24941407aff192c47e7a7 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 97b5b0b1aa0064efaa3a8180681cbccc281ca0ff..0ad11390bf1c0c12ad87b43ef518369dfbf0df69 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 cf41999670092d19794e9cd9c70067cb5ffaa3f8..fccf828b61bb86d458e2de869bdaa3bc6650fdd9 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 a4ccb383a729f3407e0c9fc943fec33844276c84..e7cba968fb7846f2015ab1fc7bea518fffbe2197 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 92c014f0ab7c27c4598f452eb8ce8bb50e5d4347..c477e81f688533cc7920fef3d68a5bb1a1ece77b 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 89b337266710ca554b6cadb31a84abb9b1798503..5a26a50ec34fed8a10cec72d6eefc8b89161dcfe 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 f7bd8ddc57bf3347da36da3da1ac0637e92ccdf3..0bc4e1b6ee9c14e51e360f39fceed6a6d31816f8 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 @@ -714,9 +700,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 @@ -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 0e0e11aae1ecd0d78a5a36fc15a732d4bab6d1fc..322c201aa67c24b6d1cd6656d3158ff2f96df55c 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 2a9a69a71b9512d5bd065aa109e8b9a7e9e6d287..3be2cdb1f5ab1628d7820090609fef1cff84bf2e 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 93bff8ef31e7efb263769d6eaddb3756bff69398..f7418051577f803269d84b13d05c635791c8da32 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 bd1f4ce7620128e5a0d2b9a63c9214074239b8d2..c05672d93a0e21dbe29c76bd3f43d7e00ffbf37c 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 ef191a23d26905da70b924adf0fd31ca55401276..b56a7d48c8fccb0e6df2008e80a2bd59c16daff1 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 3b258f344e5f722ab2c729fedfbb2febe99a9ef1..704b2826b13826d8137df685c89f80ba2d928eb8 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 8c7ea9599a9f115d1feb74a8fea92e8d6b712f8a..a5f3a461128fa733595df1cce03d8b4b3bd7a7e3 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 bdcf20eef54075daa0b94582e4d2d58b05147ddd..e85973339fe871ed2ce51e9381bc15d26322f4e0 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 44cabfbbab1e7d564386550f94f7278925b1c6b5..48cff9f6ceb5366c4bcdb7a69b922fd390102b24 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 80fab8ac3274387359c9aad5045bc31948f183af..967bbe9094f25a4d5839b38009fe0cdc5ae3feae 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 8312c25843735023a287a1287b424eb69e6e2757..22da00e3554946644ff9f9d75695d87b4ca1aa4d 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 3b6fc64abf0ad9e4548664e3a949b88e3e2551b2..605c80fcbdd0757210fabb5b06a5ca6edbb02154 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 448e714500716c154f804b508f78b818b511b00f..0000000000000000000000000000000000000000 --- 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 4eace29c4523f02684e24942750eb8f582264650..0000000000000000000000000000000000000000 --- 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 a76f94397d5eaedbc4ae6eb799037ba332b2e109..e9a3abe628faa75517ba81bea83d1f94caeab28e 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 71e8c4a1f28d89c0785ba0ff44c135ca348f2cd7..1b172b048f4bf0d42754a89042015496762105bf 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 e556dc6b9f31684d3062c51adf1fa4604e28530e..eb26ecbd21ce1cefcaf3e8a7f75804a585c6ce96 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 79990b2198adf503ced40b2879027cc9716feca1..36c8c655ece7b53e98e476ec2084f46ca714ebc3 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 9409ed42d2e44a75e184bcb6a61a7de7a545a721..e71be750758edf1e6726b41040229f55aa64ea88 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 06c5c60b5e517cc12112a481db38bc048e25e533..a8d946e87b6a15af7525c522a0b49af712f1599c 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 0000000000000000000000000000000000000000..178664995c5f30ce3cd80dc678f206573379e26b --- /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 b841d2e7353cf7745460a674d880c99784af655e..5762f752126c9814d1d882e6a540ca5c81085dec 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 3f0ca7c18fd7623c6c89e7672551c4bb43d061a3..a823250a21b3770417a5aaebc233ca4bcc5bb3c0 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 8b9e57ace16d827302921a4a74019051353b1434..e12ea5dbc4c3a6248e222f41ff3a72bc8fdf3f5f 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 b3aa7aaab6930e6ac57c89eb9624660e28fec76d..a64538301d1c0bdbd758c72496ba9daa8b41ac33 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 56950f44c8b61cb8d2a56895a93e4c4be7735ad9..f218cab75d38acd05a0acc9cdbd3d4e91edc3d03 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/sc_rollup_injector.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_injector.ml index 1e60a17330cd7db216fdfab23f9584d7b70768cd..3c99b84bf38e42a9a52c5fc1259249ffa6ee7481 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_016_PtMumbai/lib_sc_rollup_node/simulation.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/simulation.ml index a13a580a5e13fc4b64f146066ec77d784688b77b..ae34e8b10bc3109c7de2abeefa1261c627c226c4 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 2c0a627ffff2e270f685d100548566637127d4b2..ac8d8dd036249ecc7567d4dc7b952bd691ec4675 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 ea4cfb044d4b22ecaa41ba85559efcb5bc5ffda6..2a25cc888ad020ea5c6c36d1c247a2e535a88f61 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 504a1a82122af16442d2283b4ead04dfc7ef804d..123d317b3cf3a2f26a2636ba677aa53ddc391284 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 1fc9332c2e92e2e864e7163b2804698aa30157a0..ec6a9a4f3f195542736136ad79b51f40092a1ac5 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 3f7d14535184a7b9b2d88c424a35dedaf416c2cd..99a16db5eb4d0d647835d7d1449bdf01007e88b4 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 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 62664a971c3a37a5e7bca2e095468d650bbf3d6a..b6539529a2883aa9a2b71d44ee6f55c89d0c5cc5 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 6f049377dd2ba8ec9eeb7d6876646a1497c070c0..6777c7e83d39edc98ee24941407aff192c47e7a7 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 97b5b0b1aa0064efaa3a8180681cbccc281ca0ff..0ad11390bf1c0c12ad87b43ef518369dfbf0df69 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 cf41999670092d19794e9cd9c70067cb5ffaa3f8..fccf828b61bb86d458e2de869bdaa3bc6650fdd9 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 a4ccb383a729f3407e0c9fc943fec33844276c84..e7cba968fb7846f2015ab1fc7bea518fffbe2197 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 92c014f0ab7c27c4598f452eb8ce8bb50e5d4347..c477e81f688533cc7920fef3d68a5bb1a1ece77b 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 89b337266710ca554b6cadb31a84abb9b1798503..5a26a50ec34fed8a10cec72d6eefc8b89161dcfe 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 dc949dac91c4d6e186188f422d7828319674412d..003433875727dcb59567f51eab2e9534f085cd45 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 @@ -705,9 +691,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 @@ -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 5744e9f67728e3593ce0c9b163be93ea558fdd4c..f95fc6e4b0e04ad1762fb4a8dd056c95dd743212 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 ced86b18711fdb30acf89937ac8f6334c9940159..e8f011e00c7faf12a61b25ef68af96ef69089d00 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 573d866ace87be2f9c0d812febfe6c2e313fd8de..b56a7d48c8fccb0e6df2008e80a2bd59c16daff1 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 37458f1e0432d170d441d07be56ecd15047c0d37..7715bd437a89c5ba5460476533caca9aa85cec4b 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 cd78e43783e4e11b9c26df1065d7d6b0690583da..88a64b03897247443c53172954a87616d3979c12 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 bb64d5d879b609c11cc5a860722ba7c2d6da4951..dee1f6fdb114975a20babde498d670a0ed0b255d 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 44cabfbbab1e7d564386550f94f7278925b1c6b5..48cff9f6ceb5366c4bcdb7a69b922fd390102b24 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 80fab8ac3274387359c9aad5045bc31948f183af..967bbe9094f25a4d5839b38009fe0cdc5ae3feae 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 8312c25843735023a287a1287b424eb69e6e2757..f15e34e99d15fe5a8c6514b1f2510f0126525ad9 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 3b6fc64abf0ad9e4548664e3a949b88e3e2551b2..605c80fcbdd0757210fabb5b06a5ca6edbb02154 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 920de832a917c81e1f9e2a41f38006a6eac1111f..0000000000000000000000000000000000000000 --- 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 21b99c5872a4cff1667609ff222663e26442ae04..0000000000000000000000000000000000000000 --- 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 a76f94397d5eaedbc4ae6eb799037ba332b2e109..e9a3abe628faa75517ba81bea83d1f94caeab28e 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 71e8c4a1f28d89c0785ba0ff44c135ca348f2cd7..1b172b048f4bf0d42754a89042015496762105bf 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 e556dc6b9f31684d3062c51adf1fa4604e28530e..eb26ecbd21ce1cefcaf3e8a7f75804a585c6ce96 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 79990b2198adf503ced40b2879027cc9716feca1..36c8c655ece7b53e98e476ec2084f46ca714ebc3 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 9409ed42d2e44a75e184bcb6a61a7de7a545a721..e71be750758edf1e6726b41040229f55aa64ea88 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 06c5c60b5e517cc12112a481db38bc048e25e533..a8d946e87b6a15af7525c522a0b49af712f1599c 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 0000000000000000000000000000000000000000..178664995c5f30ce3cd80dc678f206573379e26b --- /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 b841d2e7353cf7745460a674d880c99784af655e..5762f752126c9814d1d882e6a540ca5c81085dec 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 c5d09dda2a1da8c43b0db2c3b5abe72878bfa8b8..66f4dc5343909c16745f7f662f8d1a2aba9344e9 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 ceb5ef25e148d96bfcfd688c0ea316a95452ab5a..b9231bfc5f90de13c320f966e116353f1f054c0e 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 9e15def1223eff8b2424b29b9f7f977f417c5649..1a8c0a2f556473d86c4e42e0ef461bd9ef4f73bc 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 56950f44c8b61cb8d2a56895a93e4c4be7735ad9..f218cab75d38acd05a0acc9cdbd3d4e91edc3d03 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/sc_rollup_injector.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/sc_rollup_injector.ml index 1e60a17330cd7db216fdfab23f9584d7b70768cd..3c99b84bf38e42a9a52c5fc1259249ffa6ee7481 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_017_PtNairob/lib_sc_rollup_node/simulation.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/simulation.ml index a13a580a5e13fc4b64f146066ec77d784688b77b..d557dbeb97e51c958b42fefce6686ca2a59e8d67 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 2c0a627ffff2e270f685d100548566637127d4b2..ac8d8dd036249ecc7567d4dc7b952bd691ec4675 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 4aa0a8575fc979226a21743ead462e1a91a30cf5..69e71af0e1db5fc27b121007913c891249227735 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 1bc441f7de89d82094e734236edf120bc364f046..6b669b98306a1642c001f60616f2613bb5e711cd 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 b6571220f74a7fe518c03d6ed1c25b4fb7d98451..d18d3f989dd9674262879cbab06eea2438e939ee 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 58d6d46968a1979d65e8564e9dba7923770277ec..d9629dc8759a00cfa2e1049da3336dabdf5a0418 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 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 62664a971c3a37a5e7bca2e095468d650bbf3d6a..b6539529a2883aa9a2b71d44ee6f55c89d0c5cc5 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 6f049377dd2ba8ec9eeb7d6876646a1497c070c0..6777c7e83d39edc98ee24941407aff192c47e7a7 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 97b5b0b1aa0064efaa3a8180681cbccc281ca0ff..0ad11390bf1c0c12ad87b43ef518369dfbf0df69 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 cf41999670092d19794e9cd9c70067cb5ffaa3f8..fccf828b61bb86d458e2de869bdaa3bc6650fdd9 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 a4ccb383a729f3407e0c9fc943fec33844276c84..e7cba968fb7846f2015ab1fc7bea518fffbe2197 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 92c014f0ab7c27c4598f452eb8ce8bb50e5d4347..c477e81f688533cc7920fef3d68a5bb1a1ece77b 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 89b337266710ca554b6cadb31a84abb9b1798503..5a26a50ec34fed8a10cec72d6eefc8b89161dcfe 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 042f606463dad7d17fea1c6efa9f75556328c957..a5e7d3e9158559370115e8d60d36c4687122e865 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 @@ -706,8 +691,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 @@ -738,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 @@ -754,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 @@ -772,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; @@ -830,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 @@ -837,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 5744e9f67728e3593ce0c9b163be93ea558fdd4c..f95fc6e4b0e04ad1762fb4a8dd056c95dd743212 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 2def15b77f98c583af61f088af7d62d471e78973..45da0efc367c60c1b0301bbc4de7b5ab23cb2484 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 3c0739cf40d6accd9bd5195bf912b4b645f0c05d..dba3f265a6ff7a2ced132b517c6f999d628cd590 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 a99e1218bca8f3c9da87f441236e7813ed00269e..621a72a12b023b360cad9b06347c89c8fc11f038 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 fed5e050307197bc341897206891a4f574a5cef0..915b87728b2a1f34d500ac0bd304f5355dab13ff 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 77143300570d37e02ae8c5f3acd219e5d964a4de..b306b2badaea47c610bfbc27425a7be1c88036a0 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 44cabfbbab1e7d564386550f94f7278925b1c6b5..48cff9f6ceb5366c4bcdb7a69b922fd390102b24 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 80fab8ac3274387359c9aad5045bc31948f183af..967bbe9094f25a4d5839b38009fe0cdc5ae3feae 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 8312c25843735023a287a1287b424eb69e6e2757..12b477a68c835b351054cb9d4d3c3603c12cb84e 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 3b6fc64abf0ad9e4548664e3a949b88e3e2551b2..605c80fcbdd0757210fabb5b06a5ca6edbb02154 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/outbox.ml b/src/proto_018_Proxford/lib_sc_rollup_node/outbox.ml index a76f94397d5eaedbc4ae6eb799037ba332b2e109..e9a3abe628faa75517ba81bea83d1f94caeab28e 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 71e8c4a1f28d89c0785ba0ff44c135ca348f2cd7..1b172b048f4bf0d42754a89042015496762105bf 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 d2ad6afc0248e57c179dcd3b1188b1401b246de5..f984a811cfc91b5410dbc1dd3a9dc293833caf0b 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 79990b2198adf503ced40b2879027cc9716feca1..36c8c655ece7b53e98e476ec2084f46ca714ebc3 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 178664995c5f30ce3cd80dc678f206573379e26b..e71be750758edf1e6726b41040229f55aa64ea88 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 06c5c60b5e517cc12112a481db38bc048e25e533..a8d946e87b6a15af7525c522a0b49af712f1599c 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 0000000000000000000000000000000000000000..178664995c5f30ce3cd80dc678f206573379e26b --- /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 b841d2e7353cf7745460a674d880c99784af655e..5762f752126c9814d1d882e6a540ca5c81085dec 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 d62b831205cfdeeb1ca9f61122377eeb62b9344a..54f08d2ba8e3a913c7f007e04a7731338b13df20 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 ceb5ef25e148d96bfcfd688c0ea316a95452ab5a..b9231bfc5f90de13c320f966e116353f1f054c0e 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 77d6937abfc0f422545f85c6b6300f1e835c6d8c..e3efc65ed3848bf6dcd2127e23af62ea1ff391ab 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 921b0e6b027bb7cb62e6f873bb3d889bcd5a066a..921e2869adf91dbd279e5f84888fe64c40786815 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/sc_rollup_injector.ml b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml index 15950e96c941fa9fb87e7dcbe77d5a56ee7f3651..b88c8e74322a34a906417559751a97a959bc2f5c 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_018_Proxford/lib_sc_rollup_node/simulation.ml b/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml index a13a580a5e13fc4b64f146066ec77d784688b77b..d557dbeb97e51c958b42fefce6686ca2a59e8d67 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 2c0a627ffff2e270f685d100548566637127d4b2..ac8d8dd036249ecc7567d4dc7b952bd691ec4675 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 66b9d6ef3a9cbeac214cd1ff19d35137fe43fb56..894d2e304ee57633386895544c996aaeb898a0a6 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 e888c6b40313f6e550b8a8b8c8698e0d9a9c3501..6b669b98306a1642c001f60616f2613bb5e711cd 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 b6571220f74a7fe518c03d6ed1c25b4fb7d98451..d18d3f989dd9674262879cbab06eea2438e939ee 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 58d6d46968a1979d65e8564e9dba7923770277ec..d9629dc8759a00cfa2e1049da3336dabdf5a0418 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 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 daef0157af637cce7402f472023e0a2ef2eeb4cb..b85e403c010d93097efde9b1ca0b5b6e28161177 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 b20fa0dcd218f365adbaf9da177ce99a53e6353e..e1426d860a988de2c9006e7f0604c107560be539 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_layer2/sc_rollup_services.ml b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml index 62664a971c3a37a5e7bca2e095468d650bbf3d6a..b6539529a2883aa9a2b71d44ee6f55c89d0c5cc5 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 9f429eed2452e8b9c8b1f3379d499b75eb6517ad..5227b3609bb125efb84fa96792059bacb04dd4a2 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 -> @@ -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. @@ -237,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 @@ -246,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 @@ -255,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 @@ -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. *) @@ -318,31 +312,30 @@ 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* 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 + let module PVM = (val Pvm.of_kind node_ctxt.kind) in + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5871 + Use constants for correct protocol. *) + let is_reveal_enabled = + node_ctxt.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 @@ -353,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 @@ -365,9 +358,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 () = @@ -399,23 +389,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 () = 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 4466bff7a1159a8795f84cbb097aeb8965ca0387..5f9cfa0bf2898ce3c80a8a0012e3717a7e0523a5 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/batcher.ml b/src/proto_alpha/lib_sc_rollup_node/batcher.ml index cf41999670092d19794e9cd9c70067cb5ffaa3f8..eaf5b902f150afe2068cc7dc06fbeb32128ef284 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 @@ -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_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 +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_alpha/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml index a4ccb383a729f3407e0c9fc943fec33844276c84..e7cba968fb7846f2015ab1fc7bea518fffbe2197 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/commitment_event.ml b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml index 92c014f0ab7c27c4598f452eb8ce8bb50e5d4347..c477e81f688533cc7920fef3d68a5bb1a1ece77b 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 @@ -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_alpha/lib_sc_rollup_node/commitment_event.mli b/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli index 89b337266710ca554b6cadb31a84abb9b1798503..5a26a50ec34fed8a10cec72d6eefc8b89161dcfe 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 @@ -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_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index 042f606463dad7d17fea1c6efa9f75556328c957..bf2509aa9a8f213da6c5d12a7ad54da8f83a7523 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 @@ -110,7 +112,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}, @@ -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,13 +178,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 = proto_commitment_hash; level = inbox_level} ; Commitment_event.last_cemented_commitment_updated proto_commitment_hash - proto_inbox_level) + inbox_level) else Lwt.return_unit in return_unit @@ -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 | _, _ -> @@ -299,13 +300,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) @@ -408,18 +409,13 @@ 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 = 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 +424,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 +470,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,12 +567,12 @@ 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 in @@ -639,12 +633,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 +669,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 @@ -706,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 @@ -757,13 +749,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 @@ -772,7 +762,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; @@ -830,6 +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 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 @@ -837,6 +846,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_alpha/lib_sc_rollup_node/dal_pages_request.ml b/src/proto_alpha/lib_sc_rollup_node/dal_pages_request.ml index 5744e9f67728e3593ce0c9b163be93ea558fdd4c..322c201aa67c24b6d1cd6656d3158ff2f96df55c 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 9d73b5447eb2e7bb4a121336d43fbee1d721a009..d48444cd9513abcea90f67c41eaaee96cbd10bff 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 @@ -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]. *) @@ -104,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,17 +122,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 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 to_slot_index_list (constants : Rollup_constants.protocol_constants) bitset + = + 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. @@ -140,17 +136,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 @@ -176,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 @@ -193,22 +191,29 @@ 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 + ~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 @@ -220,11 +225,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 +263,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 +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 105475761166e8083f0a9b753290b6e4ee359885..dc3cc376a79ff31657998a97c586422e3b97dff3 100644 --- a/src/proto_alpha/lib_sc_rollup_node/fueled_pvm.ml +++ b/src/proto_alpha/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,15 +138,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 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. @@ -313,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 @@ -369,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 | [] -> @@ -379,9 +390,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 @@ -423,9 +440,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 = @@ -466,11 +483,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_alpha/lib_sc_rollup_node/inbox.ml b/src/proto_alpha/lib_sc_rollup_node/inbox.ml index a99e1218bca8f3c9da87f441236e7813ed00269e..108334f2544efcfe67468ee85b796bbff638b246 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.ml +++ b/src/proto_alpha/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, @@ -150,18 +169,29 @@ 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 + (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) 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_alpha/lib_sc_rollup_node/inbox.mli b/src/proto_alpha/lib_sc_rollup_node/inbox.mli index fed5e050307197bc341897206891a4f574a5cef0..915b87728b2a1f34d500ac0bd304f5355dab13ff 100644 --- a/src/proto_alpha/lib_sc_rollup_node/inbox.mli +++ b/src/proto_alpha/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_alpha/lib_sc_rollup_node/interpreter.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter.ml index 77143300570d37e02ae8c5f3acd219e5d964a4de..98bdca5ffbf27b30959a561f4a2e903c25a910e9 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 @@ -71,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 @@ -87,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 @@ -98,9 +99,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 +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. *) @@ -139,25 +138,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) @@ -189,24 +180,21 @@ 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 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 +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 @@ -286,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 44cabfbbab1e7d564386550f94f7278925b1c6b5..48cff9f6ceb5366c4bcdb7a69b922fd390102b24 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 -> + 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/interpreter_event.ml b/src/proto_alpha/lib_sc_rollup_node/interpreter_event.ml index 80fab8ac3274387359c9aad5045bc31948f183af..ff8f435c5f35b7445d4e4af46fbf231934455fda 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/layer1_helpers.ml b/src/proto_alpha/lib_sc_rollup_node/layer1_helpers.ml index 8312c25843735023a287a1287b424eb69e6e2757..6e8fcdf54076c6b1fdc567f62397e89398cdc4f1 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,119 @@ 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; + 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}; + } + +(* 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 3b6fc64abf0ad9e4548664e3a949b88e3e2551b2..605c80fcbdd0757210fabb5b06a5ca6edbb02154 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,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_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml deleted file mode 100644 index 39790d0df0e9cdb75387e4ad65d7af6029ac887f..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ /dev/null @@ -1,1280 +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 rollup_address = - (* 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 - 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; protocol_constants; _} ~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 - ~number_of_slots:protocol_constants.parametric.dal.number_of_slots - header - -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.parametric.dal.number_of_slots) - headers - |> List.rev - -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.parametric.dal.number_of_slots) - 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; 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.parametric.dal.number_of_slots - 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_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli deleted file mode 100644 index ae996303fb0085bbff2d57b106b13a269e7d2f5b..0000000000000000000000000000000000000000 --- a/src/proto_alpha/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_alpha/lib_sc_rollup_node/outbox.ml b/src/proto_alpha/lib_sc_rollup_node/outbox.ml index a76f94397d5eaedbc4ae6eb799037ba332b2e109..e9a3abe628faa75517ba81bea83d1f94caeab28e 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 @@ -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_alpha/lib_sc_rollup_node/outbox.mli b/src/proto_alpha/lib_sc_rollup_node/outbox.mli index 71e8c4a1f28d89c0785ba0ff44c135ca348f2cd7..1b172b048f4bf0d42754a89042015496762105bf 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 d2ad6afc0248e57c179dcd3b1188b1401b246de5..e1180ebffafcc045be416d3e71c550f79118fa82 100644 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.ml +++ b/src/proto_alpha/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,45 +85,36 @@ 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; @@ -133,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 @@ -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 = node_ctxt.genesis_info.level; - number_of_ticks = Sc_rollup.Number_of_ticks.zero; + 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 { @@ -169,7 +160,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 @@ -185,7 +176,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 +192,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 @@ -232,10 +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.(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. *) @@ -268,18 +259,14 @@ 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) + (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 @@ -345,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 @@ -368,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 @@ -403,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 79990b2198adf503ced40b2879027cc9716feca1..36c8c655ece7b53e98e476ec2084f46ca714ebc3 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.ml b/src/proto_alpha/lib_sc_rollup_node/pvm.ml index 2ae9c9f725f9ccdac56578156c3ca1d07ea18320..e71be750758edf1e6726b41040229f55aa64ea88 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_rpc.ml b/src/proto_alpha/lib_sc_rollup_node/pvm_rpc.ml index 06c5c60b5e517cc12112a481db38bc048e25e533..a8d946e87b6a15af7525c522a0b49af712f1599c 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/pvm_sig.ml b/src/proto_alpha/lib_sc_rollup_node/pvm_sig.ml new file mode 100644 index 0000000000000000000000000000000000000000..2ae9c9f725f9ccdac56578156c3ca1d07ea18320 --- /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_coordinator.ml b/src/proto_alpha/lib_sc_rollup_node/refutation_coordinator.ml index b841d2e7353cf7745460a674d880c99784af655e..d78834ff4e3418d7f2697f16a51b26243b1d2bd6 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 1595337ec7c1e2b3db3c4eeef7f79abb70db2a4c..98e174b5a65339b4b7e9c1174984ca6b5dd3b7a8 100644 --- a/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_alpha/lib_sc_rollup_node/refutation_game.ml @@ -120,10 +120,14 @@ 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 = - 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 @@ -156,9 +160,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]. *) @@ -193,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 @@ -220,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 @@ -240,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 @@ -275,7 +291,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 @@ -346,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 @@ -489,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 77d6937abfc0f422545f85c6b6300f1e835c6d8c..e3efc65ed3848bf6dcd2127e23af62ea1ff391ab 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 921b0e6b027bb7cb62e6f873bb3d889bcd5a066a..921e2869adf91dbd279e5f84888fe64c40786815 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/sc_rollup_injector.ml b/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml index 15950e96c941fa9fb87e7dcbe77d5a56ee7f3651..b88c8e74322a34a906417559751a97a959bc2f5c 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) diff --git a/src/proto_alpha/lib_sc_rollup_node/simulation.ml b/src/proto_alpha/lib_sc_rollup_node/simulation.ml index a13a580a5e13fc4b64f146066ec77d784688b77b..d557dbeb97e51c958b42fefce6686ca2a59e8d67 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; @@ -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_alpha/lib_sc_rollup_node/simulation.mli b/src/proto_alpha/lib_sc_rollup_node/simulation.mli index 2c0a627ffff2e270f685d100548566637127d4b2..ac8d8dd036249ecc7567d4dc7b952bd691ec4675 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; @@ -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_alpha/lib_sc_rollup_node/test/canary.ml b/src/proto_alpha/lib_sc_rollup_node/test/canary.ml index 5e0877462c9e55c964dc40971dfa04d7d1bcca3b..8b5b7a0cc7d9be0da5785ec2d0ea3c61daaf1529 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,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_alpha/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_alpha/lib_sc_rollup_node/test/helpers/helpers.ml index e888c6b40313f6e550b8a8b8c8698e0d9a9c3501..6aeab3d04a78f1bc3ff2ad19ccde8ca0c9e96006 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,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,17 @@ 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_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 +83,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 +142,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 +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 b6571220f74a7fe518c03d6ed1c25b4fb7d98451..d18d3f989dd9674262879cbab06eea2438e939ee 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} *) @@ -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_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 7b53be26ebdee706054dc30baa0fd6d69683635a..2d5937615019fbbd0672d0b4a7141308b1dfd279 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