diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml b/src/lib_smart_rollup_node/commitment_event.ml similarity index 85% rename from src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml rename to src/lib_smart_rollup_node/commitment_event.ml index c477e81f688533cc7920fef3d68a5bb1a1ece77b..4f87f9042d5d087cf978cab3b516a708dfa5e2cc 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml +++ b/src/lib_smart_rollup_node/commitment_event.ml @@ -23,14 +23,12 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context open Publisher_worker_types module Simple = struct include Internal_event.Simple - let section = [Protocol.name; "sc_rollup_node"; "commitment"] + let section = ["sc_rollup_node"; "commitment"] let starting = declare_0 @@ -58,11 +56,11 @@ module Simple = struct {predecessor}, inbox_level: {inbox_level}, compressed_state: \ {compressed_state}, number_of_ticks: {number_of_ticks}" ~level:Notice - ("lcc_level", Raw_level.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) + ("lcc_level", Data_encoding.int32) + ("predecessor", Commitment.Hash.encoding) + ("inbox_level", Data_encoding.int32) + ("compressed_state", State_hash.encoding) + ("number_of_ticks", Data_encoding.int64) let last_cemented_commitment_updated = declare_2 @@ -72,7 +70,7 @@ module Simple = struct "Last cemented commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("hash", Commitment.Hash.encoding) ("level", Data_encoding.int32) let last_published_commitment_updated = @@ -83,7 +81,7 @@ module Simple = struct "Last published commitment was updated to hash {hash} at inbox level \ {level}" ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("hash", Commitment.Hash.encoding) ("level", Data_encoding.int32) let compute_commitment = @@ -100,7 +98,7 @@ module Simple = struct ~name:"sc_rollup_node_publish_commitment" ~msg:"Publishing commitment {hash} for inbox level {level}" ~level:Notice - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) + ("hash", Commitment.Hash.encoding) ("level", Data_encoding.int32) let commitment_parent_is_not_lcc = @@ -114,9 +112,9 @@ module Simple = struct {lcc_hash}. This is a critical error, and the rollup node will be \ terminated." ~level:Fatal - ("level", Raw_level.encoding) - ("predecessor_hash", Sc_rollup.Commitment.Hash.encoding) - ("lcc_hash", Sc_rollup.Commitment.Hash.encoding) + ("level", Data_encoding.int32) + ("predecessor_hash", Commitment.Hash.encoding) + ("lcc_hash", Commitment.Hash.encoding) let commitment_stored = declare_5 @@ -127,11 +125,11 @@ module Simple = struct inbox_level: {inbox_level}, compressed_state: {compressed_state}, \ number_of_ticks: {number_of_ticks}" ~level:Notice - ("commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) + ("commitment_hash", Commitment.Hash.encoding) + ("predecessor", Commitment.Hash.encoding) + ("inbox_level", Data_encoding.int32) + ("compressed_state", State_hash.encoding) + ("number_of_ticks", Data_encoding.int64) module Publisher = struct let section = section @ ["publisher"] @@ -166,12 +164,10 @@ let starting = Simple.(emit starting) let stopping = Simple.(emit stopping) -open Sc_rollup.Commitment - let section = Simple.section let emit_commitment_event f commitment_hash - {predecessor; inbox_level; compressed_state; number_of_ticks} = + Commitment.{predecessor; inbox_level; compressed_state; number_of_ticks} = Simple.( emit f @@ -182,7 +178,7 @@ let emit_commitment_event f commitment_hash number_of_ticks )) let commitment_will_not_be_published lcc_level - {predecessor; inbox_level; compressed_state; number_of_ticks} = + Commitment.{predecessor; inbox_level; compressed_state; number_of_ticks} = Simple.( emit commitment_will_not_be_published diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.mli b/src/lib_smart_rollup_node/commitment_event.mli similarity index 87% rename from src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.mli rename to src/lib_smart_rollup_node/commitment_event.mli index 5a26a50ec34fed8a10cec72d6eefc8b89161dcfe..07a809a12d5b78b5558b9b9a2ba4d9526d9276f5 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.mli +++ b/src/lib_smart_rollup_node/commitment_event.mli @@ -26,7 +26,6 @@ (** This module defines functions that emit the events used for the rollup node when it is storing and publishing commitments (see {!Commitment}). *) -open Protocol.Alpha_context open Publisher_worker_types val starting : unit -> unit Lwt.t @@ -38,26 +37,22 @@ val section : string list (** [commitment_stored commitment_hash commitment] emits the event that the [commitment] was stored. *) -val commitment_stored : - Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t -> unit Lwt.t +val commitment_stored : Commitment.Hash.t -> Commitment.t -> unit Lwt.t (** [commitment_will_not_be_published level commitment] emits the event that [commitment] will not be published: its inbox level is less or equal than the last cemented commitment [level]. *) -val commitment_will_not_be_published : - Raw_level.t -> Sc_rollup.Commitment.t -> unit Lwt.t +val commitment_will_not_be_published : int32 -> Commitment.t -> unit Lwt.t (** [last_cemented_commitment_updated hash level] emits the event that the last cemented commitment was updated to the given [hash] at the given inbox [level]. *) -val last_cemented_commitment_updated : - Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t +val last_cemented_commitment_updated : 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 : - Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t +val last_published_commitment_updated : 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 @@ -66,10 +61,7 @@ val last_published_commitment_updated : [last_cemented_commitment_hash]. This is a critical error, the rollup node will be terminated. *) val commitment_parent_is_not_lcc : - Raw_level.t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.Hash.t -> - unit Lwt.t + int32 -> Commitment.Hash.t -> Commitment.Hash.t -> unit Lwt.t (** [compute_commitment level] emits the event that a new commitment is being computed and stored for the block at the given [level]. *) @@ -77,8 +69,7 @@ val compute_commitment : int32 -> unit Lwt.t (** [publish_commitment hash level] emits the event that a new commitment is being published. *) -val publish_commitment : - Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t +val publish_commitment : Commitment.Hash.t -> int32 -> unit Lwt.t (** Events emmitted by the Publisher worker *) module Publisher : sig diff --git a/src/lib_smart_rollup_node/protocol_plugin_sig.ml b/src/lib_smart_rollup_node/protocol_plugin_sig.ml index fd472fa37024074647dc511a152d24b8c124c5f7..46c78dd7fdf27d7f97dfa87d70e8252cca68f068 100644 --- a/src/lib_smart_rollup_node/protocol_plugin_sig.ml +++ b/src/lib_smart_rollup_node/protocol_plugin_sig.ml @@ -131,41 +131,6 @@ module type INTERPRETER = sig ('a Context.t * Context.tree) tzresult Lwt.t end -(** Protocol specific commitments publisher. NOTE: The publisher has to be - stopped and the new one restarted on protocol change. *) -module type PUBLISHER = sig - (** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash to be included in the commitment. *) - val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - Commitment.Hash.t option tzresult Lwt.t - - (** [init node_ctxt] initializes the worker for publishing and cementing - commitments. *) - val init : _ Node_context.t -> unit tzresult Lwt.t - - (** [publish_commitments ()] publishes the commitments that were not - yet published up to the finalized head and which are after the last - cemented commitment. *) - val publish_commitments : unit -> unit tzresult Lwt.t - - (** [cement_commitments ()] cements the commitments that can be - cemented, i.e. the commitments that are after the current last cemented - commitment and which have [sc_rollup_challenge_period] levels on top of - them since they were originally published. *) - val cement_commitments : unit -> unit tzresult Lwt.t - - (** [shutdown ()] stops the worker for publishing and cementing - commitments. *) - val shutdown : unit -> unit Lwt.t -end - (** Protocol specific refutation coordinator. NOTE: The refutation coordinator has to be stopped and the new one restarted on protocol change. *) module type REFUTATION_COORDINATOR = sig @@ -304,8 +269,6 @@ module type S = sig module Interpreter : INTERPRETER - module Publisher : PUBLISHER - module Refutation_coordinator : REFUTATION_COORDINATOR module Batcher_constants : BATCHER_CONSTANTS diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml b/src/lib_smart_rollup_node/publisher.ml similarity index 88% rename from src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml rename to src/lib_smart_rollup_node/publisher.ml index 857b3ea306fe66652a4a5bf5ff891a14cee860cd..9b2db825ddc35410a3389163f92b0dda05194fd4 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml +++ b/src/lib_smart_rollup_node/publisher.ml @@ -41,8 +41,6 @@ commitment that was not published already. *) -open Protocol -open Alpha_context open Publisher_worker_types module Lwt_result_option_syntax = struct @@ -50,6 +48,10 @@ module Lwt_result_option_syntax = struct let open Lwt_result_syntax in let* a in match a with None -> return_none | Some a -> f a + + let fail = Lwt_result_syntax.return_none + + let return x = Lwt_result_syntax.return_some x end module Lwt_result_option_list_syntax = struct @@ -89,12 +91,12 @@ let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = 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) +let build_commitment (module Plugin : Protocol_plugin_sig.S) + (node_ctxt : _ Node_context.t) (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) ~prev_commitment_level ~inbox_level ctxt = let open Lwt_result_syntax in - let module PVM = (val Pvm.of_kind node_ctxt.kind) in - let*! pvm_state = PVM.State.find ctxt in + let*! pvm_state = Context.PVMState.find ctxt in let*? pvm_state = match pvm_state with | Some pvm_state -> Ok pvm_state @@ -103,10 +105,10 @@ let build_commitment (node_ctxt : _ Node_context.t) "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*! compressed_state = Plugin.Pvm.state_hash node_ctxt.kind pvm_state in + let*! tick = Plugin.Pvm.get_tick node_ctxt.kind 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 distance = Z.sub tick prev_commitment_tick in let number_of_ticks = Z.to_int64 distance in let*? () = if number_of_ticks = 0L then error_with "A 0-tick commitment is impossible" @@ -123,16 +125,16 @@ let build_commitment (node_ctxt : _ Node_context.t) compressed_state; } -let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = +let genesis_commitment (module Plugin : Protocol_plugin_sig.S) + (node_ctxt : _ Node_context.t) ctxt = let open Lwt_result_syntax in - let module PVM = (val Pvm.of_kind node_ctxt.kind) in - let*! pvm_state = PVM.State.find ctxt in + let*! pvm_state = Context.PVMState.find ctxt in let*? pvm_state = match pvm_state with | Some pvm_state -> Ok pvm_state | None -> error_with "PVM state for genesis commitment is not available" in - let*! compressed_state = PVM.state_hash pvm_state in + let*! compressed_state = Plugin.Pvm.state_hash node_ctxt.kind pvm_state in let commitment = Octez_smart_rollup.Commitment. { @@ -150,7 +152,7 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = fail_unless Octez_smart_rollup.Commitment.Hash.( commitment_hash = node_ctxt.genesis_info.commitment_hash) - (Sc_rollup_node_errors.Invalid_genesis_state + (Rollup_node_errors.Invalid_genesis_state { expected = node_ctxt.genesis_info.commitment_hash; actual = commitment_hash; @@ -158,18 +160,17 @@ let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = in commitment -let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor - current_level ctxt = +let create_commitment_if_necessary plugin (node_ctxt : _ Node_context.t) + ~predecessor current_level ctxt = let open Lwt_result_syntax in 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 + let+ genesis_commitment = genesis_commitment plugin node_ctxt ctxt in Some genesis_commitment else 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 @@ -181,6 +182,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let*! () = Commitment_event.compute_commitment current_level in let+ commitment = build_commitment + plugin node_ctxt last_commitment_hash ~prev_commitment_level:last_commitment.inbox_level @@ -190,12 +192,17 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor Some commitment else return_none -let process_head (node_ctxt : _ Node_context.t) ~predecessor +let process_head plugin (node_ctxt : _ Node_context.t) ~predecessor Layer1.{level; header = _; _} ctxt = let open Lwt_result_syntax in let current_level = level in let* commitment = - create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt + create_commitment_if_necessary + plugin + node_ctxt + ~predecessor + current_level + ctxt in match commitment with | None -> return_none @@ -219,7 +226,7 @@ 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 : 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 @@ -255,7 +262,6 @@ 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 @@ -308,7 +314,7 @@ let earliest_cementing_level node_ctxt commitment_hash = let** {first_published_at_level; _} = Node_context.commitment_published_at_level node_ctxt commitment_hash in - return_some + return @@ Int32.add first_published_at_level (sc_rollup_challenge_window node_ctxt |> Int32.of_int) @@ -324,26 +330,22 @@ 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 + Lwt_result.return @@ sub_level commitment.inbox_level (sc_rollup_challenge_window node_ctxt) in let lcc = Reference.get node_ctxt.lcc in - if cementable_level_bound <= lcc.level then return_none + if cementable_level_bound <= lcc.level then fail else let** cementable_bound_block = 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 + return cementable_commitment let cementable_commitments (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in @@ -351,7 +353,7 @@ 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 : Commitment.Hash.t) = let* commitment = Node_context.find_commitment node_ctxt commitment_hash in match commitment with | None -> return acc @@ -382,24 +384,10 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = let*& latest_cementable_commitment = latest_cementable_commitment node_ctxt head in - let* cementable = gather [] latest_cementable_commitment in - match cementable with - | [] -> return_nil - | first_cementable :: _ -> - (* Make sure that the first commitment can be cemented according to the - Layer 1 node as a failsafe. *) - let* green_light = - Plugin.RPC.Sc_rollup.can_be_cemented - (new Protocol_client_context.wrap_full node_ctxt.cctxt) - (node_ctxt.cctxt#chain, `Head 0) - node_ctxt.rollup_address - first_cementable - in - if green_light then return cementable else return_nil + gather [] latest_cementable_commitment let cement_commitment (node_ctxt : _ Node_context.t) ~source commitment = let open Lwt_result_syntax in - let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in let cement_operation = L1_operation.Cement {rollup = node_ctxt.rollup_address; commitment} in @@ -455,7 +443,7 @@ module Handlers = struct type launch_error = error trace - let on_launch _w () Types.{node_ctxt} = return node_ctxt + let on_launch _w () Types.{node_ctxt} = Lwt_result.return node_ctxt let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : unit tzresult Lwt.t = @@ -498,17 +486,18 @@ let init node_ctxt = return_unit | Lwt.Fail exn -> (* Worker crashed, not recoverable. *) - fail [Sc_rollup_node_errors.No_publisher; Exn exn] + fail [Rollup_node_errors.No_publisher; Exn exn] | Lwt.Sleep -> (* Never started, start it. *) start node_ctxt (* This is a publisher worker for a single scoru *) let worker = + let open Result_syntax in lazy (match Lwt.state worker_promise with - | Lwt.Return worker -> ok worker - | Lwt.Fail _ | Lwt.Sleep -> error Sc_rollup_node_errors.No_publisher) + | Lwt.Return worker -> return worker + | Lwt.Fail _ | Lwt.Sleep -> tzfail Rollup_node_errors.No_publisher) let publish_commitments () = let open Lwt_result_syntax in diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.mli b/src/lib_smart_rollup_node/publisher.mli similarity index 84% rename from src/proto_018_Proxford/lib_sc_rollup_node/publisher.mli rename to src/lib_smart_rollup_node/publisher.mli index 36c8c655ece7b53e98e476ec2084f46ca714ebc3..af5afb221c72d08b3b7049fecdbf2f66201efb85 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.mli +++ b/src/lib_smart_rollup_node/publisher.mli @@ -40,34 +40,35 @@ commitment that was not published already. *) -(** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) +(** [process_head plugin node_ctxt ~predecessor head ctxt] builds a new + commitment if needed, by looking at the level of [head] and checking whether + it is a multiple of `Commitment.sc_rollup_commitment_period` levels away + from [node_ctxt.initial_level]. It uses the functionalities of [PVM] to + compute the hash of to be included in the commitment. *) val process_head : + (module Protocol_plugin_sig.S) -> Node_context.rw -> predecessor:Block_hash.t -> Layer1.header -> Context.rw -> - Octez_smart_rollup.Commitment.Hash.t option tzresult Lwt.t + 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 -> Octez_smart_rollup.Commitment.t -> unit tzresult Lwt.t + _ Node_context.t -> Commitment.t -> unit tzresult Lwt.t (** Initialize worker for publishing and cementing commitments. *) val init : _ Node_context.t -> unit tzresult Lwt.t -(** [publish_commitments node_ctxt] publishes the commitments that were not yet +(** [publish_commitments ()] publishes the commitments that were not yet published up to the finalized head and which are after the last cemented commitment. *) val publish_commitments : unit -> unit tzresult Lwt.t -(** [cement_commitments node_ctxt] cements the commitments that can be cemented, +(** [cement_commitments ()] cements the commitments that can be cemented, i.e. the commitments that are after the current last cemented commitment and which have [sc_rollup_challenge_period] levels on top of them since they were originally published. *) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.ml b/src/lib_smart_rollup_node/publisher_worker_types.ml similarity index 100% rename from src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.ml rename to src/lib_smart_rollup_node/publisher_worker_types.ml diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.mli b/src/lib_smart_rollup_node/publisher_worker_types.mli similarity index 100% rename from src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.mli rename to src/lib_smart_rollup_node/publisher_worker_types.mli diff --git a/src/lib_smart_rollup_node/rollup_node_daemon.ml b/src/lib_smart_rollup_node/rollup_node_daemon.ml index 019e5942fdc751ae145edfb63dd2d0fedf391d34..7528eef257ee9115be88efb3112697ec33bcea03 100644 --- a/src/lib_smart_rollup_node/rollup_node_daemon.ml +++ b/src/lib_smart_rollup_node/rollup_node_daemon.ml @@ -63,7 +63,7 @@ let start_workers ?(degraded = false) (configuration : Configuration.t) let module Plugin = (val plugin) in let* () = unless degraded @@ fun () -> - let* () = Plugin.Publisher.init node_ctxt in + let* () = Publisher.init node_ctxt in match Configuration.Operator_purpose_map.find Add_messages node_ctxt.operators with @@ -139,7 +139,8 @@ let process_new_head ({node_ctxt; _} as state) ~catching_up ~predecessor in let*! context_hash = Context.commit ctxt in let* commitment_hash = - Plugin.Publisher.process_head + Publisher.process_head + state.plugin node_ctxt ~predecessor:predecessor.hash head @@ -269,8 +270,8 @@ let on_layer_1_head ({node_ctxt; _} as state) (head : Layer1.header) = new_chain_prefetching in let module Plugin = (val state.plugin) in - let* () = Plugin.Publisher.publish_commitments () in - let* () = Plugin.Publisher.cement_commitments () in + let* () = Publisher.publish_commitments () in + let* () = Publisher.cement_commitments () in let*! () = Daemon_event.new_heads_processed reorg.new_chain in let* () = Plugin.Refutation_coordinator.process stripped_head in let* () = Batcher.new_head stripped_head in @@ -288,7 +289,7 @@ let degraded_refutation_mode state = let*! () = message "Shutting down Batcher@." in let*! () = Batcher.shutdown () in let*! () = message "Shutting down Commitment Publisher@." in - let*! () = Plugin.Publisher.shutdown () in + let*! () = Publisher.shutdown () in Layer1.iter_heads state.node_ctxt.l1_ctxt @@ fun head -> let* () = handle_protocol_migration ~degraded:true ~catching_up:false state head @@ -312,7 +313,7 @@ let install_finalizer state = let* () = message "Shutting down Batcher@." in let* () = Batcher.shutdown () in let* () = message "Shutting down Commitment Publisher@." in - let* () = Plugin.Publisher.shutdown () in + let* () = Publisher.shutdown () in let* () = message "Shutting down Refutation Coordinator@." in let* () = Plugin.Refutation_coordinator.shutdown () in let* (_ : unit tzresult) = Node_context.close state.node_ctxt in @@ -452,7 +453,8 @@ module Internal_for_tests = struct in let*! context_hash = Context.commit ctxt in let* commitment_hash = - Plugin.Publisher.process_head + Publisher.process_head + (module Plugin) node_ctxt ~predecessor:predecessor.Layer1.hash head 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 deleted file mode 100644 index 5a26a50ec34fed8a10cec72d6eefc8b89161dcfe..0000000000000000000000000000000000000000 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli +++ /dev/null @@ -1,97 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module defines functions that emit the events used for the rollup node - when it is storing and publishing commitments (see {!Commitment}). *) - -open Protocol.Alpha_context -open Publisher_worker_types - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** Section for commitment events. *) -val section : string list - -(** [commitment_stored commitment_hash commitment] emits the event - that the [commitment] was stored. *) -val commitment_stored : - Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [commitment_will_not_be_published level commitment] emits the event that - [commitment] will not be published: its inbox level is less or equal than - the last cemented commitment [level]. *) -val commitment_will_not_be_published : - Raw_level.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [last_cemented_commitment_updated hash level] emits the event that the last - cemented commitment was updated to the given [hash] at the given inbox - [level]. *) -val last_cemented_commitment_updated : - 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 : - 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 - published, whose parent is the last cemented commitment, but the - commitment's [predecessor_hash] differs from the - [last_cemented_commitment_hash]. - This is a critical error, the rollup node will be terminated. *) -val commitment_parent_is_not_lcc : - Raw_level.t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.Hash.t -> - unit Lwt.t - -(** [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 : int32 -> unit Lwt.t - -(** [publish_commitment hash level] emits the event that a new commitment is - being published. *) -val publish_commitment : - Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t - -(** Events emmitted by the Publisher worker *) -module Publisher : sig - (** [request_failed view status errors] emits the event that a worker - request [view] has failed with [status] after producing [errors]. *) - val request_failed : - Request.view -> - Worker_types.request_status -> - Error_monad.tztrace -> - unit Lwt.t - - (** [request_completed view status] emits the event that a worker - request [view] has been completed with [status]. *) - val request_completed : - Request.view -> Worker_types.request_status -> unit Lwt.t -end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_sig.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_sig.ml deleted file mode 100644 index af79ffb90c90b8c410334944529207e8e917b450..0000000000000000000000000000000000000000 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_sig.ml +++ /dev/null @@ -1,82 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) -module type S = sig - module PVM : Pvm.S - - (** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) - val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - Protocol.Alpha_context.Sc_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 - - (** Initialize worker for publishing and cementing commitments. *) - val init : _ Node_context.t -> unit tzresult Lwt.t - - (** [publish_commitments node_ctxt] publishes the commitments that were not - yet published up to the finalized head and which are after the last - cemented commitment. *) - val publish_commitments : unit -> unit tzresult Lwt.t - - (** [cement_commitments node_ctxt] cements the commitments that can be - cemented, i.e. the commitments that are after the current last cemented - commitment and which have [sc_rollup_challenge_period] levels on top of - them since they were originally published. *) - val cement_commitments : unit -> unit tzresult Lwt.t - - (** Stop worker for publishing and cementing commitments. *) - val shutdown : unit -> unit Lwt.t -end 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 7fe0963b96c59246b08e959271d5efc3ca61e3a1..450299936f0078b33a9f28b9a4e03d4114df7816 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml @@ -125,7 +125,12 @@ let rec process_head (daemon_components : (module Daemon_components.S)) in let*! context_hash = Context.commit ctxt in let* commitment_hash = - Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt + Publisher.process_head + (module Rollup_node_plugin.Plugin) + node_ctxt + ~predecessor:predecessor.hash + head + ctxt in let* () = unless (catching_up && Option.is_none commitment_hash) @@ fun () -> @@ -428,6 +433,7 @@ module Internal_for_tests = struct let*! context_hash = Context.commit ctxt in let* commitment_hash = Publisher.process_head + (module Rollup_node_plugin.Plugin) node_ctxt ~predecessor:predecessor.Layer1.hash head diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.ml deleted file mode 100644 index 3305d3a16b5c26c1271b8bfeb8a1b8ce36992411..0000000000000000000000000000000000000000 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.ml +++ /dev/null @@ -1,527 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM every - [Constants.sc_rollup_commitment_period_in_blocks] levels. - - Every time a finalized block is processed by the rollup node, the latter - determines whether the last commitment that the node has produced referred - to [sc_rollup.commitment_period_in_blocks] blocks earlier. For mainnet, - [sc_rollup.commitment_period_in_blocks = 30]. In this case, it computes and - stores a new commitment in a level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -open Protocol -open Alpha_context -open Publisher_worker_types - -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 - -module Lwt_result_option_list_syntax = struct - (** A small monadic combinator to return an empty list on None results. *) - let ( let*& ) x f = - let open Lwt_result_syntax in - let* x in - match x with None -> return_nil | Some x -> f x -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" ; - 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" ; - 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.current_protocol.constants.sc_rollup - .commitment_period_in_blocks - -let sc_rollup_challenge_window node_ctxt = - node_ctxt.Node_context.current_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) - -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 inbox_level in - return (Sc_rollup_block.final_tick block) - -let build_commitment (node_ctxt : _ Node_context.t) - (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) - ~prev_commitment_level ~inbox_level ctxt = - let open Lwt_result_syntax in - let module PVM = (val 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 %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 = 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 - Octez_smart_rollup.Commitment. - { - predecessor = prev_commitment; - inbox_level; - number_of_ticks; - 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 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 genesis commitment is not available" - in - let*! compressed_state = PVM.state_hash pvm_state in - let commitment = - Octez_smart_rollup.Commitment. - { - predecessor = Hash.zero; - inbox_level = node_ctxt.genesis_info.level; - 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 = Octez_smart_rollup.Commitment.hash commitment in - let+ () = - fail_unless - Octez_smart_rollup.Commitment.Hash.( - commitment_hash = node_ctxt.genesis_info.commitment_hash) - (Sc_rollup_node_errors.Invalid_genesis_state - { - expected = node_ctxt.genesis_info.commitment_hash; - actual = commitment_hash; - }) - in - commitment - -let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor - current_level ctxt = - let open Lwt_result_syntax in - 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 - else - let* last_commitment_hash = - let+ pred = Node_context.get_l2_block node_ctxt predecessor in - Sc_rollup_block.most_recent_commitment pred.header - in - let* last_commitment = - Node_context.get_commitment node_ctxt last_commitment_hash - in - let next_commitment_level = - next_commitment_level node_ctxt last_commitment.inbox_level - in - if current_level = next_commitment_level then - let*! () = Commitment_event.compute_commitment current_level in - let+ commitment = - build_commitment - node_ctxt - last_commitment_hash - ~prev_commitment_level:last_commitment.inbox_level - ~inbox_level:current_level - ctxt - in - Some commitment - else return_none - -let process_head (node_ctxt : _ Node_context.t) ~predecessor - Layer1.{level; header = _; _} ctxt = - let open Lwt_result_syntax in - let current_level = level in - let* commitment = - create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt - in - match commitment with - | None -> return_none - | Some commitment -> - let* commitment_hash = - Node_context.save_commitment node_ctxt commitment - in - return_some commitment_hash - -let missing_commitments (node_ctxt : _ Node_context.t) = - let open Lwt_result_syntax in - let lpc_level = - match Reference.get node_ctxt.lpc with - | None -> node_ctxt.genesis_info.level - | Some lpc -> lpc.inbox_level - in - let* head = Node_context.last_processed_head_opt node_ctxt in - let next_head_level = - Option.map (fun (b : Sc_rollup_block.t) -> Int32.succ b.header.level) head - in - let sc_rollup_challenge_window_int32 = - sc_rollup_challenge_window node_ctxt |> Int32.of_int - in - 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 commitment.inbox_level <= lcc.level -> - (* Commitment is before or at the LCC, we have reached the end. *) - return acc - | 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. *) - return acc - | Some commitment -> - let* published_info = - Node_context.commitment_published_at_level node_ctxt commitment_hash - in - let past_curfew = - match (published_info, next_head_level) with - | None, _ | _, None -> false - | Some {first_published_at_level; _}, Some next_head_level -> - Int32.sub next_head_level first_published_at_level - > sc_rollup_challenge_window_int32 - in - let acc = if past_curfew then acc else commitment :: acc in - (* We keep the commitment and go back to the previous one. *) - gather acc commitment.predecessor - in - let* finalized_block = Node_context.get_finalized_head_opt node_ctxt in - match finalized_block with - | None -> return_nil - | Some finalized -> - (* Start from finalized block's most recent commitment and gather all - commitments that are missing. *) - let commitment = - Sc_rollup_block.most_recent_commitment finalized.header - in - gather [] commitment - -let publish_commitment (node_ctxt : _ Node_context.t) ~source - (commitment : Octez_smart_rollup.Commitment.t) = - let open Lwt_result_syntax in - let publish_operation = - L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} - in - let*! () = - Commitment_event.publish_commitment - (Octez_smart_rollup.Commitment.hash commitment) - commitment.inbox_level - in - let* _hash = Injector.add_pending_operation ~source publish_operation in - return_unit - -let on_publish_commitments (node_ctxt : state) = - let open Lwt_result_syntax in - let operator = Node_context.get_operator node_ctxt Publish in - if Node_context.is_accuser node_ctxt then - (* Accuser does not publish all commitments *) - return_unit - else - match operator with - | None -> - (* Configured to not publish commitments *) - return_unit - | Some source -> - let* commitments = missing_commitments node_ctxt in - List.iter_es (publish_commitment node_ctxt ~source) commitments - -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 - match operator with - | None -> - (* Configured to not publish commitments *) - return_unit - | Some source -> - when_ (commitment.inbox_level > lcc.level) @@ fun () -> - publish_commitment node_ctxt ~source commitment - -(* Commitments can only be cemented after [sc_rollup_challenge_window] has - passed since they were first published. *) -let earliest_cementing_level node_ctxt commitment_hash = - let open Lwt_result_option_syntax in - let** {first_published_at_level; _} = - Node_context.commitment_published_at_level node_ctxt commitment_hash - in - return_some - @@ Int32.add - first_published_at_level - (sc_rollup_challenge_window node_ctxt |> Int32.of_int) - -(** [latest_cementable_commitment node_ctxt head] is the most recent commitment - hash that could be cemented in [head]'s successor if: - - - all its predecessors were cemented - - it would have been first published at the same level as its inbox - - It does not need to be exact but it must be an upper bound on which we can - start the search for cementable commitments. *) -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 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 cementable_level_bound <= lcc.level then return_none - else - let** cementable_bound_block = - 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 - in - return_some cementable_commitment - -let cementable_commitments (node_ctxt : _ Node_context.t) = - let open Lwt_result_syntax in - let open Lwt_result_option_list_syntax in - 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 : 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 commitment.inbox_level <= lcc.level -> - (* If we have moved backward passed or at the current LCC then we have - reached the end. *) - return acc - | Some commitment -> - let* earliest_cementing_level = - earliest_cementing_level node_ctxt commitment_hash - in - let acc = - match earliest_cementing_level with - | None -> acc - | Some earliest_cementing_level -> - if earliest_cementing_level > head_level then - (* Commitments whose cementing level are after the head's - successor won't be cementable in the next block. *) - acc - else commitment_hash :: acc - in - gather acc commitment.predecessor - in - (* We start our search from the last possible cementable commitment. This is - to avoid iterating over a large number of commitments - ([challenge_window_in_blocks / commitment_period_in_blocks], in the order - of 10^3 on mainnet). *) - let*& latest_cementable_commitment = - latest_cementable_commitment node_ctxt head - in - let* cementable = gather [] latest_cementable_commitment in - match cementable with - | [] -> return_nil - | first_cementable :: _ -> - (* Make sure that the first commitment can be cemented according to the - Layer 1 node as a failsafe. *) - let* green_light = - Plugin.RPC.Sc_rollup.can_be_cemented - (new Protocol_client_context.wrap_full node_ctxt.cctxt) - (node_ctxt.cctxt#chain, `Head 0) - (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 - -let cement_commitment (node_ctxt : _ Node_context.t) ~source commitment_hash = - let open Lwt_result_syntax in - let cement_operation = - L1_operation.Cement - {rollup = node_ctxt.rollup_address; commitment = commitment_hash} - in - let* _hash = Injector.add_pending_operation ~source cement_operation in - return_unit - -let on_cement_commitments (node_ctxt : state) = - let open Lwt_result_syntax in - let operator = Node_context.get_operator node_ctxt Cement in - match operator with - | None -> - (* Configured to not cement commitments *) - return_unit - | Some source -> - let* cementable_commitments = cementable_commitments node_ctxt in - List.iter_es (cement_commitment node_ctxt ~source) cementable_commitments - -module Types = struct - type nonrec state = state - - type parameters = {node_ctxt : Node_context.ro} -end - -module Name = struct - (* We only have a single committer in the node *) - type t = unit - - let encoding = Data_encoding.unit - - let base = Commitment_event.section @ ["publisher"] - - let pp _ _ = () - - let equal () () = true -end - -module Worker = Worker.MakeSingle (Name) (Request) (Types) - -type worker = Worker.infinite Worker.queue Worker.t - -module Handlers = struct - type self = worker - - let on_request : - type r request_error. - worker -> (r, request_error) Request.t -> (r, request_error) result Lwt.t - = - fun w request -> - let state = Worker.state w in - match request with - | Request.Publish -> protect @@ fun () -> on_publish_commitments state - | Request.Cement -> protect @@ fun () -> on_cement_commitments state - - type launch_error = error trace - - let on_launch _w () Types.{node_ctxt} = return node_ctxt - - let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : - unit tzresult Lwt.t = - let open Lwt_result_syntax in - let request_view = Request.view r in - let emit_and_return_errors errs = - let*! () = - Commitment_event.Publisher.request_failed request_view st errs - in - return_unit - in - match r with - | Request.Publish -> emit_and_return_errors errs - | Request.Cement -> emit_and_return_errors errs - - let on_completion _w r _ st = - Commitment_event.Publisher.request_completed (Request.view r) st - - let on_no_request _ = Lwt.return_unit - - let on_close _w = Lwt.return_unit -end - -let table = Worker.create_table Queue - -let worker_promise, worker_waker = Lwt.task () - -let start node_ctxt = - let open Lwt_result_syntax in - let*! () = Commitment_event.starting () in - let node_ctxt = Node_context.readonly node_ctxt in - let+ worker = Worker.launch table () {node_ctxt} (module Handlers) in - Lwt.wakeup worker_waker worker - -let init node_ctxt = - let open Lwt_result_syntax in - match Lwt.state worker_promise with - | Lwt.Return _ -> - (* Worker already started, nothing to do. *) - return_unit - | Lwt.Fail exn -> - (* Worker crashed, not recoverable. *) - fail [Sc_rollup_node_errors.No_publisher; Exn exn] - | Lwt.Sleep -> - (* Never started, start it. *) - start node_ctxt - -(* This is a publisher worker for a single scoru *) -let worker = - lazy - (match Lwt.state worker_promise with - | Lwt.Return worker -> ok worker - | Lwt.Fail _ | Lwt.Sleep -> error Sc_rollup_node_errors.No_publisher) - -let publish_commitments () = - let open Lwt_result_syntax in - let*? w = Lazy.force worker in - let*! (_pushed : bool) = Worker.Queue.push_request w Request.Publish in - return_unit - -let cement_commitments () = - let open Lwt_result_syntax in - let*? w = Lazy.force worker in - let*! (_pushed : bool) = Worker.Queue.push_request w Request.Cement in - return_unit - -let shutdown () = - let w = Lazy.force worker in - match w with - | Error _ -> - (* There is no publisher, nothing to do *) - Lwt.return_unit - | Ok w -> Worker.shutdown w diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.mli deleted file mode 100644 index 36c8c655ece7b53e98e476ec2084f46ca714ebc3..0000000000000000000000000000000000000000 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher.mli +++ /dev/null @@ -1,77 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -(** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) -val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - 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 -> 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 - -(** [publish_commitments node_ctxt] publishes the commitments that were not yet - published up to the finalized head and which are after the last cemented - commitment. *) -val publish_commitments : unit -> unit tzresult Lwt.t - -(** [cement_commitments node_ctxt] cements the commitments that can be cemented, - i.e. the commitments that are after the current last cemented commitment and - which have [sc_rollup_challenge_period] levels on top of them since they - were originally published. *) -val cement_commitments : unit -> unit tzresult Lwt.t - -(** Stop worker for publishing and cementing commitments. *) -val shutdown : unit -> unit Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml index 16ff802accefda3938a8c6fe2b5ec529b3a80337..d54d5b6674235872968376834fd8ab660cf6fbbf 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/rollup_node_plugin.ml @@ -30,7 +30,6 @@ module Plugin : Protocol_plugin_sig.S = struct module Dal_slots_tracker = Dal_slots_tracker module Inbox = Inbox module Interpreter = Interpreter - module Publisher = Publisher module Refutation_coordinator = Refutation_coordinator module Batcher_constants = Batcher_constants module Layer1_helpers = Layer1_helpers 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 deleted file mode 100644 index c477e81f688533cc7920fef3d68a5bb1a1ece77b..0000000000000000000000000000000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_event.ml +++ /dev/null @@ -1,213 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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 -open Publisher_worker_types - -module Simple = struct - include Internal_event.Simple - - let section = [Protocol.name; "sc_rollup_node"; "commitment"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_commitment_publisher_starting" - ~msg:"Starting commitment publisher for the smart rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_commitment_publisher_stopping" - ~msg:"Stopping commitment publisher for the smart rollup node" - ~level:Notice - () - - let commitment_will_not_be_published = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_will_not_be_published" - ~msg: - "Commitment will not be published: its inbox level is less or equal \ - than the last cemented commitment level {lcc_level} - predecessor: \ - {predecessor}, inbox_level: {inbox_level}, compressed_state: \ - {compressed_state}, number_of_ticks: {number_of_ticks}" - ~level:Notice - ("lcc_level", Raw_level.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - let last_cemented_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lcc_updated" - ~msg: - "Last cemented commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let last_published_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lpc_updated" - ~msg: - "Last published commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let compute_commitment = - declare_1 - ~section - ~name:"sc_rollup_node_commitment_process_head" - ~msg:"Computing and storing new commitment for level {level}" - ~level:Notice - ("level", Data_encoding.int32) - - let publish_commitment = - declare_2 - ~section - ~name:"sc_rollup_node_publish_commitment" - ~msg:"Publishing commitment {hash} for inbox level {level}" - ~level:Notice - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let commitment_parent_is_not_lcc = - declare_3 - ~section - ~name:"sc_rollup_commitment_parent_is_not_lcc" - ~msg: - "Trying to publish a commitment at inbox level {level} whose parent is \ - the last cemented commitment, but the commitment's predecessor hash \ - {predecessor_hash} differs from the last cemented commitment hash \ - {lcc_hash}. This is a critical error, and the rollup node will be \ - terminated." - ~level:Fatal - ("level", Raw_level.encoding) - ("predecessor_hash", Sc_rollup.Commitment.Hash.encoding) - ("lcc_hash", Sc_rollup.Commitment.Hash.encoding) - - let commitment_stored = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_stored" - ~msg: - "Commitment {commitment_hash} was stored - predecessor: {predecessor}, \ - inbox_level: {inbox_level}, compressed_state: {compressed_state}, \ - number_of_ticks: {number_of_ticks}" - ~level:Notice - ("commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - module Publisher = struct - let section = section @ ["publisher"] - - let request_failed = - declare_3 - ~section - ~name:"request_failed" - ~msg:"request {view} failed ({worker_status}): {errors}" - ~level:Warning - ("view", Request.encoding) - ~pp1:Request.pp - ("worker_status", Worker_types.request_status_encoding) - ~pp2:Worker_types.pp_status - ("errors", Error_monad.trace_encoding) - ~pp3:Error_monad.pp_print_trace - - let request_completed = - declare_2 - ~section - ~name:"request_completed" - ~msg:"{view} {worker_status}" - ~level:Debug - ("view", Request.encoding) - ("worker_status", Worker_types.request_status_encoding) - ~pp1:Request.pp - ~pp2:Worker_types.pp_status - end -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -open Sc_rollup.Commitment - -let section = Simple.section - -let emit_commitment_event f commitment_hash - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - f - ( commitment_hash, - predecessor, - inbox_level, - compressed_state, - number_of_ticks )) - -let commitment_will_not_be_published lcc_level - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - commitment_will_not_be_published - (lcc_level, predecessor, inbox_level, compressed_state, number_of_ticks)) - -let commitment_stored = emit_commitment_event Simple.commitment_stored - -let last_cemented_commitment_updated head level = - Simple.(emit last_cemented_commitment_updated (head, level)) - -let last_published_commitment_updated head level = - Simple.(emit last_published_commitment_updated (head, level)) - -let compute_commitment level = Simple.(emit compute_commitment level) - -let publish_commitment head level = - Simple.(emit publish_commitment (head, level)) - -let commitment_parent_is_not_lcc level predecessor_hash lcc_hash = - Simple.(emit commitment_parent_is_not_lcc (level, predecessor_hash, lcc_hash)) - -module Publisher = struct - let request_failed view worker_status errors = - Simple.(emit Publisher.request_failed (view, worker_status, errors)) - - let request_completed view worker_status = - Simple.(emit Publisher.request_completed (view, worker_status)) -end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_sig.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_sig.ml deleted file mode 100644 index af79ffb90c90b8c410334944529207e8e917b450..0000000000000000000000000000000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/commitment_sig.ml +++ /dev/null @@ -1,82 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) -module type S = sig - module PVM : Pvm.S - - (** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) - val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - Protocol.Alpha_context.Sc_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 - - (** Initialize worker for publishing and cementing commitments. *) - val init : _ Node_context.t -> unit tzresult Lwt.t - - (** [publish_commitments node_ctxt] publishes the commitments that were not - yet published up to the finalized head and which are after the last - cemented commitment. *) - val publish_commitments : unit -> unit tzresult Lwt.t - - (** [cement_commitments node_ctxt] cements the commitments that can be - cemented, i.e. the commitments that are after the current last cemented - commitment and which have [sc_rollup_challenge_period] levels on top of - them since they were originally published. *) - val cement_commitments : unit -> unit tzresult Lwt.t - - (** Stop worker for publishing and cementing commitments. *) - val shutdown : unit -> unit Lwt.t -end 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 2824fc471aa0fd83af851d751fd9a918bb56d288..8d8f840a2f321e36874741eea360d5137d2da788 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml @@ -125,7 +125,12 @@ let rec process_head (daemon_components : (module Daemon_components.S)) in let*! context_hash = Context.commit ctxt in let* commitment_hash = - Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt + Publisher.process_head + (module Rollup_node_plugin.Plugin) + node_ctxt + ~predecessor:predecessor.hash + head + ctxt in let* () = unless (catching_up && Option.is_none commitment_hash) @@ fun () -> @@ -423,6 +428,7 @@ module Internal_for_tests = struct let*! context_hash = Context.commit ctxt in let* commitment_hash = Publisher.process_head + (module Rollup_node_plugin.Plugin) node_ctxt ~predecessor:predecessor.Layer1.hash head diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.ml deleted file mode 100644 index 3305d3a16b5c26c1271b8bfeb8a1b8ce36992411..0000000000000000000000000000000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.ml +++ /dev/null @@ -1,527 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM every - [Constants.sc_rollup_commitment_period_in_blocks] levels. - - Every time a finalized block is processed by the rollup node, the latter - determines whether the last commitment that the node has produced referred - to [sc_rollup.commitment_period_in_blocks] blocks earlier. For mainnet, - [sc_rollup.commitment_period_in_blocks = 30]. In this case, it computes and - stores a new commitment in a level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -open Protocol -open Alpha_context -open Publisher_worker_types - -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 - -module Lwt_result_option_list_syntax = struct - (** A small monadic combinator to return an empty list on None results. *) - let ( let*& ) x f = - let open Lwt_result_syntax in - let* x in - match x with None -> return_nil | Some x -> f x -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" ; - 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" ; - 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.current_protocol.constants.sc_rollup - .commitment_period_in_blocks - -let sc_rollup_challenge_window node_ctxt = - node_ctxt.Node_context.current_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) - -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 inbox_level in - return (Sc_rollup_block.final_tick block) - -let build_commitment (node_ctxt : _ Node_context.t) - (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) - ~prev_commitment_level ~inbox_level ctxt = - let open Lwt_result_syntax in - let module PVM = (val 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 %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 = 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 - Octez_smart_rollup.Commitment. - { - predecessor = prev_commitment; - inbox_level; - number_of_ticks; - 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 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 genesis commitment is not available" - in - let*! compressed_state = PVM.state_hash pvm_state in - let commitment = - Octez_smart_rollup.Commitment. - { - predecessor = Hash.zero; - inbox_level = node_ctxt.genesis_info.level; - 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 = Octez_smart_rollup.Commitment.hash commitment in - let+ () = - fail_unless - Octez_smart_rollup.Commitment.Hash.( - commitment_hash = node_ctxt.genesis_info.commitment_hash) - (Sc_rollup_node_errors.Invalid_genesis_state - { - expected = node_ctxt.genesis_info.commitment_hash; - actual = commitment_hash; - }) - in - commitment - -let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor - current_level ctxt = - let open Lwt_result_syntax in - 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 - else - let* last_commitment_hash = - let+ pred = Node_context.get_l2_block node_ctxt predecessor in - Sc_rollup_block.most_recent_commitment pred.header - in - let* last_commitment = - Node_context.get_commitment node_ctxt last_commitment_hash - in - let next_commitment_level = - next_commitment_level node_ctxt last_commitment.inbox_level - in - if current_level = next_commitment_level then - let*! () = Commitment_event.compute_commitment current_level in - let+ commitment = - build_commitment - node_ctxt - last_commitment_hash - ~prev_commitment_level:last_commitment.inbox_level - ~inbox_level:current_level - ctxt - in - Some commitment - else return_none - -let process_head (node_ctxt : _ Node_context.t) ~predecessor - Layer1.{level; header = _; _} ctxt = - let open Lwt_result_syntax in - let current_level = level in - let* commitment = - create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt - in - match commitment with - | None -> return_none - | Some commitment -> - let* commitment_hash = - Node_context.save_commitment node_ctxt commitment - in - return_some commitment_hash - -let missing_commitments (node_ctxt : _ Node_context.t) = - let open Lwt_result_syntax in - let lpc_level = - match Reference.get node_ctxt.lpc with - | None -> node_ctxt.genesis_info.level - | Some lpc -> lpc.inbox_level - in - let* head = Node_context.last_processed_head_opt node_ctxt in - let next_head_level = - Option.map (fun (b : Sc_rollup_block.t) -> Int32.succ b.header.level) head - in - let sc_rollup_challenge_window_int32 = - sc_rollup_challenge_window node_ctxt |> Int32.of_int - in - 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 commitment.inbox_level <= lcc.level -> - (* Commitment is before or at the LCC, we have reached the end. *) - return acc - | 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. *) - return acc - | Some commitment -> - let* published_info = - Node_context.commitment_published_at_level node_ctxt commitment_hash - in - let past_curfew = - match (published_info, next_head_level) with - | None, _ | _, None -> false - | Some {first_published_at_level; _}, Some next_head_level -> - Int32.sub next_head_level first_published_at_level - > sc_rollup_challenge_window_int32 - in - let acc = if past_curfew then acc else commitment :: acc in - (* We keep the commitment and go back to the previous one. *) - gather acc commitment.predecessor - in - let* finalized_block = Node_context.get_finalized_head_opt node_ctxt in - match finalized_block with - | None -> return_nil - | Some finalized -> - (* Start from finalized block's most recent commitment and gather all - commitments that are missing. *) - let commitment = - Sc_rollup_block.most_recent_commitment finalized.header - in - gather [] commitment - -let publish_commitment (node_ctxt : _ Node_context.t) ~source - (commitment : Octez_smart_rollup.Commitment.t) = - let open Lwt_result_syntax in - let publish_operation = - L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} - in - let*! () = - Commitment_event.publish_commitment - (Octez_smart_rollup.Commitment.hash commitment) - commitment.inbox_level - in - let* _hash = Injector.add_pending_operation ~source publish_operation in - return_unit - -let on_publish_commitments (node_ctxt : state) = - let open Lwt_result_syntax in - let operator = Node_context.get_operator node_ctxt Publish in - if Node_context.is_accuser node_ctxt then - (* Accuser does not publish all commitments *) - return_unit - else - match operator with - | None -> - (* Configured to not publish commitments *) - return_unit - | Some source -> - let* commitments = missing_commitments node_ctxt in - List.iter_es (publish_commitment node_ctxt ~source) commitments - -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 - match operator with - | None -> - (* Configured to not publish commitments *) - return_unit - | Some source -> - when_ (commitment.inbox_level > lcc.level) @@ fun () -> - publish_commitment node_ctxt ~source commitment - -(* Commitments can only be cemented after [sc_rollup_challenge_window] has - passed since they were first published. *) -let earliest_cementing_level node_ctxt commitment_hash = - let open Lwt_result_option_syntax in - let** {first_published_at_level; _} = - Node_context.commitment_published_at_level node_ctxt commitment_hash - in - return_some - @@ Int32.add - first_published_at_level - (sc_rollup_challenge_window node_ctxt |> Int32.of_int) - -(** [latest_cementable_commitment node_ctxt head] is the most recent commitment - hash that could be cemented in [head]'s successor if: - - - all its predecessors were cemented - - it would have been first published at the same level as its inbox - - It does not need to be exact but it must be an upper bound on which we can - start the search for cementable commitments. *) -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 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 cementable_level_bound <= lcc.level then return_none - else - let** cementable_bound_block = - 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 - in - return_some cementable_commitment - -let cementable_commitments (node_ctxt : _ Node_context.t) = - let open Lwt_result_syntax in - let open Lwt_result_option_list_syntax in - 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 : 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 commitment.inbox_level <= lcc.level -> - (* If we have moved backward passed or at the current LCC then we have - reached the end. *) - return acc - | Some commitment -> - let* earliest_cementing_level = - earliest_cementing_level node_ctxt commitment_hash - in - let acc = - match earliest_cementing_level with - | None -> acc - | Some earliest_cementing_level -> - if earliest_cementing_level > head_level then - (* Commitments whose cementing level are after the head's - successor won't be cementable in the next block. *) - acc - else commitment_hash :: acc - in - gather acc commitment.predecessor - in - (* We start our search from the last possible cementable commitment. This is - to avoid iterating over a large number of commitments - ([challenge_window_in_blocks / commitment_period_in_blocks], in the order - of 10^3 on mainnet). *) - let*& latest_cementable_commitment = - latest_cementable_commitment node_ctxt head - in - let* cementable = gather [] latest_cementable_commitment in - match cementable with - | [] -> return_nil - | first_cementable :: _ -> - (* Make sure that the first commitment can be cemented according to the - Layer 1 node as a failsafe. *) - let* green_light = - Plugin.RPC.Sc_rollup.can_be_cemented - (new Protocol_client_context.wrap_full node_ctxt.cctxt) - (node_ctxt.cctxt#chain, `Head 0) - (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 - -let cement_commitment (node_ctxt : _ Node_context.t) ~source commitment_hash = - let open Lwt_result_syntax in - let cement_operation = - L1_operation.Cement - {rollup = node_ctxt.rollup_address; commitment = commitment_hash} - in - let* _hash = Injector.add_pending_operation ~source cement_operation in - return_unit - -let on_cement_commitments (node_ctxt : state) = - let open Lwt_result_syntax in - let operator = Node_context.get_operator node_ctxt Cement in - match operator with - | None -> - (* Configured to not cement commitments *) - return_unit - | Some source -> - let* cementable_commitments = cementable_commitments node_ctxt in - List.iter_es (cement_commitment node_ctxt ~source) cementable_commitments - -module Types = struct - type nonrec state = state - - type parameters = {node_ctxt : Node_context.ro} -end - -module Name = struct - (* We only have a single committer in the node *) - type t = unit - - let encoding = Data_encoding.unit - - let base = Commitment_event.section @ ["publisher"] - - let pp _ _ = () - - let equal () () = true -end - -module Worker = Worker.MakeSingle (Name) (Request) (Types) - -type worker = Worker.infinite Worker.queue Worker.t - -module Handlers = struct - type self = worker - - let on_request : - type r request_error. - worker -> (r, request_error) Request.t -> (r, request_error) result Lwt.t - = - fun w request -> - let state = Worker.state w in - match request with - | Request.Publish -> protect @@ fun () -> on_publish_commitments state - | Request.Cement -> protect @@ fun () -> on_cement_commitments state - - type launch_error = error trace - - let on_launch _w () Types.{node_ctxt} = return node_ctxt - - let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : - unit tzresult Lwt.t = - let open Lwt_result_syntax in - let request_view = Request.view r in - let emit_and_return_errors errs = - let*! () = - Commitment_event.Publisher.request_failed request_view st errs - in - return_unit - in - match r with - | Request.Publish -> emit_and_return_errors errs - | Request.Cement -> emit_and_return_errors errs - - let on_completion _w r _ st = - Commitment_event.Publisher.request_completed (Request.view r) st - - let on_no_request _ = Lwt.return_unit - - let on_close _w = Lwt.return_unit -end - -let table = Worker.create_table Queue - -let worker_promise, worker_waker = Lwt.task () - -let start node_ctxt = - let open Lwt_result_syntax in - let*! () = Commitment_event.starting () in - let node_ctxt = Node_context.readonly node_ctxt in - let+ worker = Worker.launch table () {node_ctxt} (module Handlers) in - Lwt.wakeup worker_waker worker - -let init node_ctxt = - let open Lwt_result_syntax in - match Lwt.state worker_promise with - | Lwt.Return _ -> - (* Worker already started, nothing to do. *) - return_unit - | Lwt.Fail exn -> - (* Worker crashed, not recoverable. *) - fail [Sc_rollup_node_errors.No_publisher; Exn exn] - | Lwt.Sleep -> - (* Never started, start it. *) - start node_ctxt - -(* This is a publisher worker for a single scoru *) -let worker = - lazy - (match Lwt.state worker_promise with - | Lwt.Return worker -> ok worker - | Lwt.Fail _ | Lwt.Sleep -> error Sc_rollup_node_errors.No_publisher) - -let publish_commitments () = - let open Lwt_result_syntax in - let*? w = Lazy.force worker in - let*! (_pushed : bool) = Worker.Queue.push_request w Request.Publish in - return_unit - -let cement_commitments () = - let open Lwt_result_syntax in - let*? w = Lazy.force worker in - let*! (_pushed : bool) = Worker.Queue.push_request w Request.Cement in - return_unit - -let shutdown () = - let w = Lazy.force worker in - match w with - | Error _ -> - (* There is no publisher, nothing to do *) - Lwt.return_unit - | Ok w -> Worker.shutdown w diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.mli deleted file mode 100644 index 36c8c655ece7b53e98e476ec2084f46ca714ebc3..0000000000000000000000000000000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher.mli +++ /dev/null @@ -1,77 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -(** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) -val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - 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 -> 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 - -(** [publish_commitments node_ctxt] publishes the commitments that were not yet - published up to the finalized head and which are after the last cemented - commitment. *) -val publish_commitments : unit -> unit tzresult Lwt.t - -(** [cement_commitments node_ctxt] cements the commitments that can be cemented, - i.e. the commitments that are after the current last cemented commitment and - which have [sc_rollup_challenge_period] levels on top of them since they - were originally published. *) -val cement_commitments : unit -> unit tzresult Lwt.t - -(** Stop worker for publishing and cementing commitments. *) -val shutdown : unit -> unit Lwt.t diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher_worker_types.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher_worker_types.ml deleted file mode 100644 index c10e697273e3a27772ce298eb43d33c53dde9db5..0000000000000000000000000000000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher_worker_types.ml +++ /dev/null @@ -1,57 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Request = struct - type ('a, 'b) t = - | Publish : (unit, error trace) t - | Cement : (unit, error trace) t - - type view = View : _ t -> view - - let view req = View req - - let encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Publish" - (obj1 (req "request" (constant "publish"))) - (function View Publish -> Some () | _ -> None) - (fun () -> View Publish); - case - (Tag 1) - ~title:"Cement" - (obj1 (req "request" (constant "cement"))) - (function View Cement -> Some () | _ -> None) - (fun () -> View Cement); - ] - - let pp ppf (View r) = - match r with - | Publish -> Format.pp_print_string ppf "publish" - | Cement -> Format.pp_print_string ppf "cement" -end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher_worker_types.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/publisher_worker_types.mli deleted file mode 100644 index eed1fdcad468e10c17c8bb15d651c24ab699ee0c..0000000000000000000000000000000000000000 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/publisher_worker_types.mli +++ /dev/null @@ -1,40 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Request : sig - (** Type of requests accepted by the publisher worker. *) - type ('a, 'b) t = - | Publish : (unit, error trace) t - (** Request to publish new commitments in L1. *) - | Cement : (unit, error trace) t - (** Request to cement commitments in L1. *) - - type view = View : _ t -> view - - include - Worker_intf.REQUEST - with type ('a, 'request_error) t := ('a, 'request_error) t - and type view := view -end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml index 16ff802accefda3938a8c6fe2b5ec529b3a80337..d54d5b6674235872968376834fd8ab660cf6fbbf 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/rollup_node_plugin.ml @@ -30,7 +30,6 @@ module Plugin : Protocol_plugin_sig.S = struct module Dal_slots_tracker = Dal_slots_tracker module Inbox = Inbox module Interpreter = Interpreter - module Publisher = Publisher module Refutation_coordinator = Refutation_coordinator module Batcher_constants = Batcher_constants module Layer1_helpers = Layer1_helpers 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 deleted file mode 100644 index c477e81f688533cc7920fef3d68a5bb1a1ece77b..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.ml +++ /dev/null @@ -1,213 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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 -open Publisher_worker_types - -module Simple = struct - include Internal_event.Simple - - let section = [Protocol.name; "sc_rollup_node"; "commitment"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_commitment_publisher_starting" - ~msg:"Starting commitment publisher for the smart rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_commitment_publisher_stopping" - ~msg:"Stopping commitment publisher for the smart rollup node" - ~level:Notice - () - - let commitment_will_not_be_published = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_will_not_be_published" - ~msg: - "Commitment will not be published: its inbox level is less or equal \ - than the last cemented commitment level {lcc_level} - predecessor: \ - {predecessor}, inbox_level: {inbox_level}, compressed_state: \ - {compressed_state}, number_of_ticks: {number_of_ticks}" - ~level:Notice - ("lcc_level", Raw_level.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - let last_cemented_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lcc_updated" - ~msg: - "Last cemented commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let last_published_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lpc_updated" - ~msg: - "Last published commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let compute_commitment = - declare_1 - ~section - ~name:"sc_rollup_node_commitment_process_head" - ~msg:"Computing and storing new commitment for level {level}" - ~level:Notice - ("level", Data_encoding.int32) - - let publish_commitment = - declare_2 - ~section - ~name:"sc_rollup_node_publish_commitment" - ~msg:"Publishing commitment {hash} for inbox level {level}" - ~level:Notice - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let commitment_parent_is_not_lcc = - declare_3 - ~section - ~name:"sc_rollup_commitment_parent_is_not_lcc" - ~msg: - "Trying to publish a commitment at inbox level {level} whose parent is \ - the last cemented commitment, but the commitment's predecessor hash \ - {predecessor_hash} differs from the last cemented commitment hash \ - {lcc_hash}. This is a critical error, and the rollup node will be \ - terminated." - ~level:Fatal - ("level", Raw_level.encoding) - ("predecessor_hash", Sc_rollup.Commitment.Hash.encoding) - ("lcc_hash", Sc_rollup.Commitment.Hash.encoding) - - let commitment_stored = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_stored" - ~msg: - "Commitment {commitment_hash} was stored - predecessor: {predecessor}, \ - inbox_level: {inbox_level}, compressed_state: {compressed_state}, \ - number_of_ticks: {number_of_ticks}" - ~level:Notice - ("commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - module Publisher = struct - let section = section @ ["publisher"] - - let request_failed = - declare_3 - ~section - ~name:"request_failed" - ~msg:"request {view} failed ({worker_status}): {errors}" - ~level:Warning - ("view", Request.encoding) - ~pp1:Request.pp - ("worker_status", Worker_types.request_status_encoding) - ~pp2:Worker_types.pp_status - ("errors", Error_monad.trace_encoding) - ~pp3:Error_monad.pp_print_trace - - let request_completed = - declare_2 - ~section - ~name:"request_completed" - ~msg:"{view} {worker_status}" - ~level:Debug - ("view", Request.encoding) - ("worker_status", Worker_types.request_status_encoding) - ~pp1:Request.pp - ~pp2:Worker_types.pp_status - end -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -open Sc_rollup.Commitment - -let section = Simple.section - -let emit_commitment_event f commitment_hash - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - f - ( commitment_hash, - predecessor, - inbox_level, - compressed_state, - number_of_ticks )) - -let commitment_will_not_be_published lcc_level - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - commitment_will_not_be_published - (lcc_level, predecessor, inbox_level, compressed_state, number_of_ticks)) - -let commitment_stored = emit_commitment_event Simple.commitment_stored - -let last_cemented_commitment_updated head level = - Simple.(emit last_cemented_commitment_updated (head, level)) - -let last_published_commitment_updated head level = - Simple.(emit last_published_commitment_updated (head, level)) - -let compute_commitment level = Simple.(emit compute_commitment level) - -let publish_commitment head level = - Simple.(emit publish_commitment (head, level)) - -let commitment_parent_is_not_lcc level predecessor_hash lcc_hash = - Simple.(emit commitment_parent_is_not_lcc (level, predecessor_hash, lcc_hash)) - -module Publisher = struct - let request_failed view worker_status errors = - Simple.(emit Publisher.request_failed (view, worker_status, errors)) - - let request_completed view worker_status = - Simple.(emit Publisher.request_completed (view, worker_status)) -end 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 deleted file mode 100644 index 5a26a50ec34fed8a10cec72d6eefc8b89161dcfe..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_event.mli +++ /dev/null @@ -1,97 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module defines functions that emit the events used for the rollup node - when it is storing and publishing commitments (see {!Commitment}). *) - -open Protocol.Alpha_context -open Publisher_worker_types - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** Section for commitment events. *) -val section : string list - -(** [commitment_stored commitment_hash commitment] emits the event - that the [commitment] was stored. *) -val commitment_stored : - Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [commitment_will_not_be_published level commitment] emits the event that - [commitment] will not be published: its inbox level is less or equal than - the last cemented commitment [level]. *) -val commitment_will_not_be_published : - Raw_level.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [last_cemented_commitment_updated hash level] emits the event that the last - cemented commitment was updated to the given [hash] at the given inbox - [level]. *) -val last_cemented_commitment_updated : - 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 : - 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 - published, whose parent is the last cemented commitment, but the - commitment's [predecessor_hash] differs from the - [last_cemented_commitment_hash]. - This is a critical error, the rollup node will be terminated. *) -val commitment_parent_is_not_lcc : - Raw_level.t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.Hash.t -> - unit Lwt.t - -(** [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 : int32 -> unit Lwt.t - -(** [publish_commitment hash level] emits the event that a new commitment is - being published. *) -val publish_commitment : - Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t - -(** Events emmitted by the Publisher worker *) -module Publisher : sig - (** [request_failed view status errors] emits the event that a worker - request [view] has failed with [status] after producing [errors]. *) - val request_failed : - Request.view -> - Worker_types.request_status -> - Error_monad.tztrace -> - unit Lwt.t - - (** [request_completed view status] emits the event that a worker - request [view] has been completed with [status]. *) - val request_completed : - Request.view -> Worker_types.request_status -> unit Lwt.t -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_sig.ml b/src/proto_018_Proxford/lib_sc_rollup_node/commitment_sig.ml deleted file mode 100644 index af79ffb90c90b8c410334944529207e8e917b450..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/commitment_sig.ml +++ /dev/null @@ -1,82 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) -module type S = sig - module PVM : Pvm.S - - (** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) - val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - Protocol.Alpha_context.Sc_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 - - (** Initialize worker for publishing and cementing commitments. *) - val init : _ Node_context.t -> unit tzresult Lwt.t - - (** [publish_commitments node_ctxt] publishes the commitments that were not - yet published up to the finalized head and which are after the last - cemented commitment. *) - val publish_commitments : unit -> unit tzresult Lwt.t - - (** [cement_commitments node_ctxt] cements the commitments that can be - cemented, i.e. the commitments that are after the current last cemented - commitment and which have [sc_rollup_challenge_period] levels on top of - them since they were originally published. *) - val cement_commitments : unit -> unit tzresult Lwt.t - - (** Stop worker for publishing and cementing commitments. *) - val shutdown : unit -> unit Lwt.t -end 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 9d5d77f98a8ec4385882eff492ce6fbda9fa20ff..9666e64b79806c35d5c3ec069e9fcbe6a83a1414 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml @@ -130,7 +130,12 @@ let rec process_head (daemon_components : (module Daemon_components.S)) in let*! context_hash = Context.commit ctxt in let* commitment_hash = - Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt + Publisher.process_head + (module Rollup_node_plugin.Plugin) + node_ctxt + ~predecessor:predecessor.hash + head + ctxt in let commitment_hash = Option.map @@ -440,6 +445,7 @@ module Internal_for_tests = struct let*! context_hash = Context.commit ctxt in let* commitment_hash = Publisher.process_head + (module Rollup_node_plugin.Plugin) node_ctxt ~predecessor:predecessor.Layer1.hash head diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/publisher_worker_types.ml b/src/proto_018_Proxford/lib_sc_rollup_node/publisher_worker_types.ml deleted file mode 100644 index c10e697273e3a27772ce298eb43d33c53dde9db5..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/publisher_worker_types.ml +++ /dev/null @@ -1,57 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Request = struct - type ('a, 'b) t = - | Publish : (unit, error trace) t - | Cement : (unit, error trace) t - - type view = View : _ t -> view - - let view req = View req - - let encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Publish" - (obj1 (req "request" (constant "publish"))) - (function View Publish -> Some () | _ -> None) - (fun () -> View Publish); - case - (Tag 1) - ~title:"Cement" - (obj1 (req "request" (constant "cement"))) - (function View Cement -> Some () | _ -> None) - (fun () -> View Cement); - ] - - let pp ppf (View r) = - match r with - | Publish -> Format.pp_print_string ppf "publish" - | Cement -> Format.pp_print_string ppf "cement" -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/publisher_worker_types.mli b/src/proto_018_Proxford/lib_sc_rollup_node/publisher_worker_types.mli deleted file mode 100644 index eed1fdcad468e10c17c8bb15d651c24ab699ee0c..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/publisher_worker_types.mli +++ /dev/null @@ -1,40 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Request : sig - (** Type of requests accepted by the publisher worker. *) - type ('a, 'b) t = - | Publish : (unit, error trace) t - (** Request to publish new commitments in L1. *) - | Cement : (unit, error trace) t - (** Request to cement commitments in L1. *) - - type view = View : _ t -> view - - include - Worker_intf.REQUEST - with type ('a, 'request_error) t := ('a, 'request_error) t - and type view := view -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/rollup_node_plugin.ml b/src/proto_018_Proxford/lib_sc_rollup_node/rollup_node_plugin.ml index 16ff802accefda3938a8c6fe2b5ec529b3a80337..d54d5b6674235872968376834fd8ab660cf6fbbf 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/rollup_node_plugin.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/rollup_node_plugin.ml @@ -30,7 +30,6 @@ module Plugin : Protocol_plugin_sig.S = struct module Dal_slots_tracker = Dal_slots_tracker module Inbox = Inbox module Interpreter = Interpreter - module Publisher = Publisher module Refutation_coordinator = Refutation_coordinator module Batcher_constants = Batcher_constants module Layer1_helpers = Layer1_helpers diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml deleted file mode 100644 index c477e81f688533cc7920fef3d68a5bb1a1ece77b..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml +++ /dev/null @@ -1,213 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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 -open Publisher_worker_types - -module Simple = struct - include Internal_event.Simple - - let section = [Protocol.name; "sc_rollup_node"; "commitment"] - - let starting = - declare_0 - ~section - ~name:"sc_rollup_commitment_publisher_starting" - ~msg:"Starting commitment publisher for the smart rollup node" - ~level:Notice - () - - let stopping = - declare_0 - ~section - ~name:"sc_rollup_node_commitment_publisher_stopping" - ~msg:"Stopping commitment publisher for the smart rollup node" - ~level:Notice - () - - let commitment_will_not_be_published = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_will_not_be_published" - ~msg: - "Commitment will not be published: its inbox level is less or equal \ - than the last cemented commitment level {lcc_level} - predecessor: \ - {predecessor}, inbox_level: {inbox_level}, compressed_state: \ - {compressed_state}, number_of_ticks: {number_of_ticks}" - ~level:Notice - ("lcc_level", Raw_level.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - let last_cemented_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lcc_updated" - ~msg: - "Last cemented commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let last_published_commitment_updated = - declare_2 - ~section - ~name:"sc_rollup_node_lpc_updated" - ~msg: - "Last published commitment was updated to hash {hash} at inbox level \ - {level}" - ~level:Debug - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let compute_commitment = - declare_1 - ~section - ~name:"sc_rollup_node_commitment_process_head" - ~msg:"Computing and storing new commitment for level {level}" - ~level:Notice - ("level", Data_encoding.int32) - - let publish_commitment = - declare_2 - ~section - ~name:"sc_rollup_node_publish_commitment" - ~msg:"Publishing commitment {hash} for inbox level {level}" - ~level:Notice - ("hash", Octez_smart_rollup.Commitment.Hash.encoding) - ("level", Data_encoding.int32) - - let commitment_parent_is_not_lcc = - declare_3 - ~section - ~name:"sc_rollup_commitment_parent_is_not_lcc" - ~msg: - "Trying to publish a commitment at inbox level {level} whose parent is \ - the last cemented commitment, but the commitment's predecessor hash \ - {predecessor_hash} differs from the last cemented commitment hash \ - {lcc_hash}. This is a critical error, and the rollup node will be \ - terminated." - ~level:Fatal - ("level", Raw_level.encoding) - ("predecessor_hash", Sc_rollup.Commitment.Hash.encoding) - ("lcc_hash", Sc_rollup.Commitment.Hash.encoding) - - let commitment_stored = - declare_5 - ~section - ~name:"sc_rollup_node_commitment_stored" - ~msg: - "Commitment {commitment_hash} was stored - predecessor: {predecessor}, \ - inbox_level: {inbox_level}, compressed_state: {compressed_state}, \ - number_of_ticks: {number_of_ticks}" - ~level:Notice - ("commitment_hash", Sc_rollup.Commitment.Hash.encoding) - ("predecessor", Sc_rollup.Commitment.Hash.encoding) - ("inbox_level", Raw_level.encoding) - ("compressed_state", Sc_rollup.State_hash.encoding) - ("number_of_ticks", Sc_rollup.Number_of_ticks.encoding) - - module Publisher = struct - let section = section @ ["publisher"] - - let request_failed = - declare_3 - ~section - ~name:"request_failed" - ~msg:"request {view} failed ({worker_status}): {errors}" - ~level:Warning - ("view", Request.encoding) - ~pp1:Request.pp - ("worker_status", Worker_types.request_status_encoding) - ~pp2:Worker_types.pp_status - ("errors", Error_monad.trace_encoding) - ~pp3:Error_monad.pp_print_trace - - let request_completed = - declare_2 - ~section - ~name:"request_completed" - ~msg:"{view} {worker_status}" - ~level:Debug - ("view", Request.encoding) - ("worker_status", Worker_types.request_status_encoding) - ~pp1:Request.pp - ~pp2:Worker_types.pp_status - end -end - -let starting = Simple.(emit starting) - -let stopping = Simple.(emit stopping) - -open Sc_rollup.Commitment - -let section = Simple.section - -let emit_commitment_event f commitment_hash - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - f - ( commitment_hash, - predecessor, - inbox_level, - compressed_state, - number_of_ticks )) - -let commitment_will_not_be_published lcc_level - {predecessor; inbox_level; compressed_state; number_of_ticks} = - Simple.( - emit - commitment_will_not_be_published - (lcc_level, predecessor, inbox_level, compressed_state, number_of_ticks)) - -let commitment_stored = emit_commitment_event Simple.commitment_stored - -let last_cemented_commitment_updated head level = - Simple.(emit last_cemented_commitment_updated (head, level)) - -let last_published_commitment_updated head level = - Simple.(emit last_published_commitment_updated (head, level)) - -let compute_commitment level = Simple.(emit compute_commitment level) - -let publish_commitment head level = - Simple.(emit publish_commitment (head, level)) - -let commitment_parent_is_not_lcc level predecessor_hash lcc_hash = - Simple.(emit commitment_parent_is_not_lcc (level, predecessor_hash, lcc_hash)) - -module Publisher = struct - let request_failed view worker_status errors = - Simple.(emit Publisher.request_failed (view, worker_status, errors)) - - let request_completed view worker_status = - Simple.(emit Publisher.request_completed (view, worker_status)) -end diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli b/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli deleted file mode 100644 index 5a26a50ec34fed8a10cec72d6eefc8b89161dcfe..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli +++ /dev/null @@ -1,97 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -(** This module defines functions that emit the events used for the rollup node - when it is storing and publishing commitments (see {!Commitment}). *) - -open Protocol.Alpha_context -open Publisher_worker_types - -val starting : unit -> unit Lwt.t - -val stopping : unit -> unit Lwt.t - -(** Section for commitment events. *) -val section : string list - -(** [commitment_stored commitment_hash commitment] emits the event - that the [commitment] was stored. *) -val commitment_stored : - Sc_rollup.Commitment.Hash.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [commitment_will_not_be_published level commitment] emits the event that - [commitment] will not be published: its inbox level is less or equal than - the last cemented commitment [level]. *) -val commitment_will_not_be_published : - Raw_level.t -> Sc_rollup.Commitment.t -> unit Lwt.t - -(** [last_cemented_commitment_updated hash level] emits the event that the last - cemented commitment was updated to the given [hash] at the given inbox - [level]. *) -val last_cemented_commitment_updated : - 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 : - 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 - published, whose parent is the last cemented commitment, but the - commitment's [predecessor_hash] differs from the - [last_cemented_commitment_hash]. - This is a critical error, the rollup node will be terminated. *) -val commitment_parent_is_not_lcc : - Raw_level.t -> - Sc_rollup.Commitment.Hash.t -> - Sc_rollup.Commitment.Hash.t -> - unit Lwt.t - -(** [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 : int32 -> unit Lwt.t - -(** [publish_commitment hash level] emits the event that a new commitment is - being published. *) -val publish_commitment : - Octez_smart_rollup.Commitment.Hash.t -> int32 -> unit Lwt.t - -(** Events emmitted by the Publisher worker *) -module Publisher : sig - (** [request_failed view status errors] emits the event that a worker - request [view] has failed with [status] after producing [errors]. *) - val request_failed : - Request.view -> - Worker_types.request_status -> - Error_monad.tztrace -> - unit Lwt.t - - (** [request_completed view status] emits the event that a worker - request [view] has been completed with [status]. *) - val request_completed : - Request.view -> Worker_types.request_status -> unit Lwt.t -end diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_sig.ml b/src/proto_alpha/lib_sc_rollup_node/commitment_sig.ml deleted file mode 100644 index af79ffb90c90b8c410334944529207e8e917b450..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_sig.ml +++ /dev/null @@ -1,82 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) -module type S = sig - module PVM : Pvm.S - - (** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) - val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - Protocol.Alpha_context.Sc_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 - - (** Initialize worker for publishing and cementing commitments. *) - val init : _ Node_context.t -> unit tzresult Lwt.t - - (** [publish_commitments node_ctxt] publishes the commitments that were not - yet published up to the finalized head and which are after the last - cemented commitment. *) - val publish_commitments : unit -> unit tzresult Lwt.t - - (** [cement_commitments node_ctxt] cements the commitments that can be - cemented, i.e. the commitments that are after the current last cemented - commitment and which have [sc_rollup_challenge_period] levels on top of - them since they were originally published. *) - val cement_commitments : unit -> unit tzresult Lwt.t - - (** Stop worker for publishing and cementing commitments. *) - val shutdown : unit -> unit Lwt.t -end diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index 9d5d77f98a8ec4385882eff492ce6fbda9fa20ff..9666e64b79806c35d5c3ec069e9fcbe6a83a1414 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -130,7 +130,12 @@ let rec process_head (daemon_components : (module Daemon_components.S)) in let*! context_hash = Context.commit ctxt in let* commitment_hash = - Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt + Publisher.process_head + (module Rollup_node_plugin.Plugin) + node_ctxt + ~predecessor:predecessor.hash + head + ctxt in let commitment_hash = Option.map @@ -440,6 +445,7 @@ module Internal_for_tests = struct let*! context_hash = Context.commit ctxt in let* commitment_hash = Publisher.process_head + (module Rollup_node_plugin.Plugin) node_ctxt ~predecessor:predecessor.Layer1.hash head diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.ml b/src/proto_alpha/lib_sc_rollup_node/publisher.ml deleted file mode 100644 index 857b3ea306fe66652a4a5bf5ff891a14cee860cd..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.ml +++ /dev/null @@ -1,531 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM every - [Constants.sc_rollup_commitment_period_in_blocks] levels. - - Every time a finalized block is processed by the rollup node, the latter - determines whether the last commitment that the node has produced referred - to [sc_rollup.commitment_period_in_blocks] blocks earlier. For mainnet, - [sc_rollup.commitment_period_in_blocks = 30]. In this case, it computes and - stores a new commitment in a level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -open Protocol -open Alpha_context -open Publisher_worker_types - -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 - -module Lwt_result_option_list_syntax = struct - (** A small monadic combinator to return an empty list on None results. *) - let ( let*& ) x f = - let open Lwt_result_syntax in - let* x in - match x with None -> return_nil | Some x -> f x -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" ; - 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" ; - 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.current_protocol.constants.sc_rollup - .commitment_period_in_blocks - -let sc_rollup_challenge_window node_ctxt = - node_ctxt.Node_context.current_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) - -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 inbox_level in - return (Sc_rollup_block.final_tick block) - -let build_commitment (node_ctxt : _ Node_context.t) - (prev_commitment : Octez_smart_rollup.Commitment.Hash.t) - ~prev_commitment_level ~inbox_level ctxt = - let open Lwt_result_syntax in - let module PVM = (val 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 %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 = 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 - Octez_smart_rollup.Commitment. - { - predecessor = prev_commitment; - inbox_level; - number_of_ticks; - compressed_state; - } - -let genesis_commitment (node_ctxt : _ Node_context.t) ctxt = - let open Lwt_result_syntax 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 genesis commitment is not available" - in - let*! compressed_state = PVM.state_hash pvm_state in - let commitment = - Octez_smart_rollup.Commitment. - { - predecessor = Hash.zero; - inbox_level = node_ctxt.genesis_info.level; - number_of_ticks = 0L; - compressed_state; - } - in - (* Ensure the initial state corresponds to the one of the rollup's in the - protocol. A mismatch is possible if a wrong external boot sector was - provided. *) - let commitment_hash = Octez_smart_rollup.Commitment.hash commitment in - let+ () = - fail_unless - Octez_smart_rollup.Commitment.Hash.( - commitment_hash = node_ctxt.genesis_info.commitment_hash) - (Sc_rollup_node_errors.Invalid_genesis_state - { - expected = node_ctxt.genesis_info.commitment_hash; - actual = commitment_hash; - }) - in - commitment - -let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor - current_level ctxt = - let open Lwt_result_syntax in - 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 - else - 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 - in - let next_commitment_level = - next_commitment_level node_ctxt last_commitment.inbox_level - in - if current_level = next_commitment_level then - let*! () = Commitment_event.compute_commitment current_level in - let+ commitment = - build_commitment - node_ctxt - last_commitment_hash - ~prev_commitment_level:last_commitment.inbox_level - ~inbox_level:current_level - ctxt - in - Some commitment - else return_none - -let process_head (node_ctxt : _ Node_context.t) ~predecessor - Layer1.{level; header = _; _} ctxt = - let open Lwt_result_syntax in - let current_level = level in - let* commitment = - create_commitment_if_necessary node_ctxt ~predecessor current_level ctxt - in - match commitment with - | None -> return_none - | Some commitment -> - let* commitment_hash = - Node_context.save_commitment node_ctxt commitment - in - return_some commitment_hash - -let missing_commitments (node_ctxt : _ Node_context.t) = - let open Lwt_result_syntax in - let lpc_level = - match Reference.get node_ctxt.lpc with - | None -> node_ctxt.genesis_info.level - | Some lpc -> lpc.inbox_level - in - let* head = Node_context.last_processed_head_opt node_ctxt in - let next_head_level = - Option.map (fun (b : Sc_rollup_block.t) -> Int32.succ b.header.level) head - in - 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* 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 commitment.inbox_level <= lcc.level -> - (* Commitment is before or at the LCC, we have reached the end. *) - return acc - | 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. *) - return acc - | Some commitment -> - let* published_info = - Node_context.commitment_published_at_level node_ctxt commitment_hash - in - let past_curfew = - match (published_info, next_head_level) with - | None, _ | _, None -> false - | Some {first_published_at_level; _}, Some next_head_level -> - Int32.sub next_head_level first_published_at_level - > sc_rollup_challenge_window_int32 - in - let acc = if past_curfew then acc else commitment :: acc in - (* We keep the commitment and go back to the previous one. *) - gather acc commitment.predecessor - in - let* finalized_block = Node_context.get_finalized_head_opt node_ctxt in - match finalized_block with - | None -> return_nil - | Some finalized -> - (* Start from finalized block's most recent commitment and gather all - 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 : Octez_smart_rollup.Commitment.t) = - let open Lwt_result_syntax in - let publish_operation = - L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} - in - let*! () = - Commitment_event.publish_commitment - (Octez_smart_rollup.Commitment.hash commitment) - commitment.inbox_level - in - let* _hash = Injector.add_pending_operation ~source publish_operation in - return_unit - -let on_publish_commitments (node_ctxt : state) = - let open Lwt_result_syntax in - let operator = Node_context.get_operator node_ctxt Publish in - if Node_context.is_accuser node_ctxt then - (* Accuser does not publish all commitments *) - return_unit - else - match operator with - | None -> - (* Configured to not publish commitments *) - return_unit - | Some source -> - let* commitments = missing_commitments node_ctxt in - List.iter_es (publish_commitment node_ctxt ~source) commitments - -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 - match operator with - | None -> - (* Configured to not publish commitments *) - return_unit - | Some source -> - when_ (commitment.inbox_level > lcc.level) @@ fun () -> - publish_commitment node_ctxt ~source commitment - -(* Commitments can only be cemented after [sc_rollup_challenge_window] has - passed since they were first published. *) -let earliest_cementing_level node_ctxt commitment_hash = - let open Lwt_result_option_syntax in - let** {first_published_at_level; _} = - Node_context.commitment_published_at_level node_ctxt commitment_hash - in - return_some - @@ Int32.add - first_published_at_level - (sc_rollup_challenge_window node_ctxt |> Int32.of_int) - -(** [latest_cementable_commitment node_ctxt head] is the most recent commitment - hash that could be cemented in [head]'s successor if: - - - all its predecessors were cemented - - it would have been first published at the same level as its inbox - - It does not need to be exact but it must be an upper bound on which we can - start the search for cementable commitments. *) -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 = 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 cementable_level_bound <= lcc.level then return_none - else - let** cementable_bound_block = - 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 - -let cementable_commitments (node_ctxt : _ Node_context.t) = - let open Lwt_result_syntax in - let open Lwt_result_option_list_syntax in - 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* commitment = Node_context.find_commitment node_ctxt commitment_hash in - match commitment with - | None -> return acc - | 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 - | Some commitment -> - let* earliest_cementing_level = - earliest_cementing_level node_ctxt commitment_hash - in - let acc = - match earliest_cementing_level with - | None -> acc - | Some earliest_cementing_level -> - if earliest_cementing_level > head_level then - (* Commitments whose cementing level are after the head's - successor won't be cementable in the next block. *) - acc - else commitment_hash :: acc - in - gather acc commitment.predecessor - in - (* We start our search from the last possible cementable commitment. This is - to avoid iterating over a large number of commitments - ([challenge_window_in_blocks / commitment_period_in_blocks], in the order - of 10^3 on mainnet). *) - let*& latest_cementable_commitment = - latest_cementable_commitment node_ctxt head - in - let* cementable = gather [] latest_cementable_commitment in - match cementable with - | [] -> return_nil - | first_cementable :: _ -> - (* Make sure that the first commitment can be cemented according to the - Layer 1 node as a failsafe. *) - let* green_light = - Plugin.RPC.Sc_rollup.can_be_cemented - (new Protocol_client_context.wrap_full node_ctxt.cctxt) - (node_ctxt.cctxt#chain, `Head 0) - node_ctxt.rollup_address - first_cementable - in - if green_light then return cementable else return_nil - -let cement_commitment (node_ctxt : _ Node_context.t) ~source commitment = - let open Lwt_result_syntax in - let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in - let cement_operation = - L1_operation.Cement {rollup = node_ctxt.rollup_address; commitment} - in - let* _hash = Injector.add_pending_operation ~source cement_operation in - return_unit - -let on_cement_commitments (node_ctxt : state) = - let open Lwt_result_syntax in - let operator = Node_context.get_operator node_ctxt Cement in - match operator with - | None -> - (* Configured to not cement commitments *) - return_unit - | Some source -> - let* cementable_commitments = cementable_commitments node_ctxt in - List.iter_es (cement_commitment node_ctxt ~source) cementable_commitments - -module Types = struct - type nonrec state = state - - type parameters = {node_ctxt : Node_context.ro} -end - -module Name = struct - (* We only have a single committer in the node *) - type t = unit - - let encoding = Data_encoding.unit - - let base = Commitment_event.section @ ["publisher"] - - let pp _ _ = () - - let equal () () = true -end - -module Worker = Worker.MakeSingle (Name) (Request) (Types) - -type worker = Worker.infinite Worker.queue Worker.t - -module Handlers = struct - type self = worker - - let on_request : - type r request_error. - worker -> (r, request_error) Request.t -> (r, request_error) result Lwt.t - = - fun w request -> - let state = Worker.state w in - match request with - | Request.Publish -> protect @@ fun () -> on_publish_commitments state - | Request.Cement -> protect @@ fun () -> on_cement_commitments state - - type launch_error = error trace - - let on_launch _w () Types.{node_ctxt} = return node_ctxt - - let on_error (type a b) _w st (r : (a, b) Request.t) (errs : b) : - unit tzresult Lwt.t = - let open Lwt_result_syntax in - let request_view = Request.view r in - let emit_and_return_errors errs = - let*! () = - Commitment_event.Publisher.request_failed request_view st errs - in - return_unit - in - match r with - | Request.Publish -> emit_and_return_errors errs - | Request.Cement -> emit_and_return_errors errs - - let on_completion _w r _ st = - Commitment_event.Publisher.request_completed (Request.view r) st - - let on_no_request _ = Lwt.return_unit - - let on_close _w = Lwt.return_unit -end - -let table = Worker.create_table Queue - -let worker_promise, worker_waker = Lwt.task () - -let start node_ctxt = - let open Lwt_result_syntax in - let*! () = Commitment_event.starting () in - let node_ctxt = Node_context.readonly node_ctxt in - let+ worker = Worker.launch table () {node_ctxt} (module Handlers) in - Lwt.wakeup worker_waker worker - -let init node_ctxt = - let open Lwt_result_syntax in - match Lwt.state worker_promise with - | Lwt.Return _ -> - (* Worker already started, nothing to do. *) - return_unit - | Lwt.Fail exn -> - (* Worker crashed, not recoverable. *) - fail [Sc_rollup_node_errors.No_publisher; Exn exn] - | Lwt.Sleep -> - (* Never started, start it. *) - start node_ctxt - -(* This is a publisher worker for a single scoru *) -let worker = - lazy - (match Lwt.state worker_promise with - | Lwt.Return worker -> ok worker - | Lwt.Fail _ | Lwt.Sleep -> error Sc_rollup_node_errors.No_publisher) - -let publish_commitments () = - let open Lwt_result_syntax in - let*? w = Lazy.force worker in - let*! (_pushed : bool) = Worker.Queue.push_request w Request.Publish in - return_unit - -let cement_commitments () = - let open Lwt_result_syntax in - let*? w = Lazy.force worker in - let*! (_pushed : bool) = Worker.Queue.push_request w Request.Cement in - return_unit - -let shutdown () = - let w = Lazy.force worker in - match w with - | Error _ -> - (* There is no publisher, nothing to do *) - Lwt.return_unit - | Ok w -> Worker.shutdown w diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher.mli b/src/proto_alpha/lib_sc_rollup_node/publisher.mli deleted file mode 100644 index 36c8c655ece7b53e98e476ec2084f46ca714ebc3..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/publisher.mli +++ /dev/null @@ -1,77 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 TriliTech *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -(** The rollup node stores and publishes commitments for the PVM - every `Commitment.sc_rollup_commitment_period` levels. - - Every time a finalized block is processed by the rollup node, - the latter determines whether the last commitment that the node - has produced referred to `Commitment.sc_rollup_commitment_period` blocks - earlier. In this case, it computes and stores a new commitment in a - level-indexed map. - - Stored commitments are signed by the rollup node operator - and published on the layer1 chain. To ensure that commitments - produced by the rollup node are eventually published, - storing and publishing commitments are decoupled. Every time - a new head is processed, the node tries to publish the oldest - commitment that was not published already. -*) - -(** [process_head node_ctxt ~predecessor head ctxt] builds a new commitment if - needed, by looking at the level of [head] and checking whether it is a - multiple of `Commitment.sc_rollup_commitment_period` levels away from - [node_ctxt.initial_level]. It uses the functionalities of [PVM] to compute - the hash of to be included in the commitment. *) -val process_head : - Node_context.rw -> - predecessor:Block_hash.t -> - Layer1.header -> - Context.rw -> - 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 -> 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 - -(** [publish_commitments node_ctxt] publishes the commitments that were not yet - published up to the finalized head and which are after the last cemented - commitment. *) -val publish_commitments : unit -> unit tzresult Lwt.t - -(** [cement_commitments node_ctxt] cements the commitments that can be cemented, - i.e. the commitments that are after the current last cemented commitment and - which have [sc_rollup_challenge_period] levels on top of them since they - were originally published. *) -val cement_commitments : unit -> unit tzresult Lwt.t - -(** Stop worker for publishing and cementing commitments. *) -val shutdown : unit -> unit Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.ml b/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.ml deleted file mode 100644 index c10e697273e3a27772ce298eb43d33c53dde9db5..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.ml +++ /dev/null @@ -1,57 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Request = struct - type ('a, 'b) t = - | Publish : (unit, error trace) t - | Cement : (unit, error trace) t - - type view = View : _ t -> view - - let view req = View req - - let encoding = - let open Data_encoding in - union - [ - case - (Tag 0) - ~title:"Publish" - (obj1 (req "request" (constant "publish"))) - (function View Publish -> Some () | _ -> None) - (fun () -> View Publish); - case - (Tag 1) - ~title:"Cement" - (obj1 (req "request" (constant "cement"))) - (function View Cement -> Some () | _ -> None) - (fun () -> View Cement); - ] - - let pp ppf (View r) = - match r with - | Publish -> Format.pp_print_string ppf "publish" - | Cement -> Format.pp_print_string ppf "cement" -end diff --git a/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.mli b/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.mli deleted file mode 100644 index eed1fdcad468e10c17c8bb15d651c24ab699ee0c..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.mli +++ /dev/null @@ -1,40 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* *) -(* Permission is hereby granted, free of charge, to any person obtaining a *) -(* copy of this software and associated documentation files (the "Software"),*) -(* to deal in the Software without restriction, including without limitation *) -(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) -(* and/or sell copies of the Software, and to permit persons to whom the *) -(* Software is furnished to do so, subject to the following conditions: *) -(* *) -(* The above copyright notice and this permission notice shall be included *) -(* in all copies or substantial portions of the Software. *) -(* *) -(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) -(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) -(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) -(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) -(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) -(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) -(* DEALINGS IN THE SOFTWARE. *) -(* *) -(*****************************************************************************) - -module Request : sig - (** Type of requests accepted by the publisher worker. *) - type ('a, 'b) t = - | Publish : (unit, error trace) t - (** Request to publish new commitments in L1. *) - | Cement : (unit, error trace) t - (** Request to cement commitments in L1. *) - - type view = View : _ t -> view - - include - Worker_intf.REQUEST - with type ('a, 'request_error) t := ('a, 'request_error) t - and type view := view -end diff --git a/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml b/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml index 16ff802accefda3938a8c6fe2b5ec529b3a80337..d54d5b6674235872968376834fd8ab660cf6fbbf 100644 --- a/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml +++ b/src/proto_alpha/lib_sc_rollup_node/rollup_node_plugin.ml @@ -30,7 +30,6 @@ module Plugin : Protocol_plugin_sig.S = struct module Dal_slots_tracker = Dal_slots_tracker module Inbox = Inbox module Interpreter = Interpreter - module Publisher = Publisher module Refutation_coordinator = Refutation_coordinator module Batcher_constants = Batcher_constants module Layer1_helpers = Layer1_helpers