diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml index 9e0cbc67258667656e0bcef55b7c9cc6dcc9f585..ca7cf1e405fa4f4cae73a1dac18996fc6af30599 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml @@ -82,9 +82,10 @@ module Block_directory_helpers = struct let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> + let lcc = Reference.get node_ctxt.lcc in Node_context.hash_of_level node_ctxt - (Alpha_context.Raw_level.to_int32 node_ctxt.lcc.level) + (Alpha_context.Raw_level.to_int32 lcc.level) let block_of_prefix node_ctxt block = match block with diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml index 7663077fd8a0c9eee4d54d06c95e84c27f436433..5912cfecb54afee61d6b3690093bc38844c55244 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml @@ -312,7 +312,7 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct Local_directory.register0 Sc_rollup_services.Local.last_published_commitment @@ fun node_ctxt () () -> let open Lwt_result_syntax in - match node_ctxt.lpc with + match Reference.get node_ctxt.lpc with | None -> return_none | Some commitment -> let hash = @@ -405,7 +405,7 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct = let open Alpha_context in let open Option_syntax in - let+ last_published_commitment = node_ctxt.lpc in + let+ last_published_commitment = Reference.get node_ctxt.lpc in let commitment_period = Int32.of_int node_ctxt.protocol_constants.parametric.sc_rollup @@ -428,8 +428,9 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct | Some {header = {level = finalized_level; _}; _} -> Compare.Int32.(inbox_level <= Raw_level.to_int32 finalized_level) in + let lcc = Reference.get node_ctxt.lcc in let cemented = - Compare.Int32.(inbox_level <= Raw_level.to_int32 node_ctxt.lcc.level) + Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) in (finalized, cemented) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment.ml index 4b67e37a569b499be63ecfd0ffa9e276079fbee2..f1c09fefe9d21c0a5f589dccaa1fd709cacded25 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment.ml @@ -43,6 +43,7 @@ open Protocol open Alpha_context +open Publisher_worker_types module Lwt_result_option_syntax = struct let ( let** ) a f = @@ -83,6 +84,8 @@ let next_commitment_level node_ctxt last_commitment_level = module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct module PVM = PVM + type state = Node_context.ro + let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Lwt_result_syntax in let* block = @@ -184,7 +187,7 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let missing_commitments (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in let lpc_level = - match node_ctxt.lpc with + match Reference.get node_ctxt.lpc with | None -> node_ctxt.genesis_info.level | Some lpc -> lpc.inbox_level in @@ -201,10 +204,10 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let* commitment = Node_context.find_commitment node_ctxt commitment_hash in + let lcc = Reference.get node_ctxt.lcc in match commitment with | None -> return acc - | Some commitment - when Raw_level.(commitment.inbox_level <= node_ctxt.lcc.level) -> + | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> (* Commitment is before or at the LCC, we have reached the end. *) return acc | Some commitment when Raw_level.(commitment.inbox_level <= lpc_level) -> @@ -252,7 +255,7 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let* _hash = Injector.add_pending_operation ~source publish_operation in return_unit - let publish_commitments (node_ctxt : _ Node_context.t) = + 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 @@ -271,12 +274,13 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct = 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 > node_ctxt.lcc.level) @@ fun () -> + when_ (commitment.inbox_level > lcc.level) @@ fun () -> publish_commitment node_ctxt ~source commitment (* Commitments can only be cemented after [sc_rollup_challenge_window] has @@ -306,8 +310,8 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct return @@ sub_level commitment.inbox_level (sc_rollup_challenge_window node_ctxt) in - if Raw_level.(cementable_level_bound <= node_ctxt.lcc.level) then - return_none + let lcc = Reference.get node_ctxt.lcc in + if Raw_level.(cementable_level_bound <= lcc.level) then return_none else let** cementable_bound_block = Node_context.find_l2_block_by_level @@ -324,14 +328,14 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct 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 Raw_level.(commitment.inbox_level <= node_ctxt.lcc.level) -> + | Some commitment when Raw_level.(commitment.inbox_level <= lcc.level) -> (* If we have moved backward passed or at the current LCC then we have reached the end. *) return acc @@ -382,7 +386,7 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let* _hash = Injector.add_pending_operation ~source cement_operation in return_unit - let cement_commitments node_ctxt = + 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 @@ -395,5 +399,93 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct (cement_commitment node_ctxt ~source) cementable_commitments - let start () = Commitment_event.starting () + module Publisher = struct + module Types = struct + type nonrec state = state + + type parameters = {node_ctxt : Node_context.ro} + 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 init 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 + + (* 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 + end end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml index c8bedc3424138dead92caefdbdcb9689755a86ac..7f9135d2792a16f0a870196cad9942a9f5fc33e8 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.ml @@ -25,6 +25,7 @@ open Protocol open Alpha_context +open Publisher_worker_types module Simple = struct include Internal_event.Simple @@ -120,6 +121,34 @@ module Simple = struct ("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) @@ -158,3 +187,11 @@ let 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_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli index 7ae1f155a08ae2e525817756ad99ff558982fffd..8f4baf9b0e14b40ddcdbd621c2aa831741bd4f9f 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_event.mli @@ -27,6 +27,7 @@ when it is storing and publishing commitments (see {!Commitment}). *) open Protocol.Alpha_context +open Publisher_worker_types val starting : unit -> unit Lwt.t @@ -69,3 +70,19 @@ val compute_commitment : Raw_level.t -> unit Lwt.t being published. *) val publish_commitment : Sc_rollup.Commitment.Hash.t -> Raw_level.t -> 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 index a646980a047bb063b9531ad3f49750ea4b3c8b56..96f2306dd8f084e7f35c0c07c79a5f17c21ddc4b 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_sig.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/commitment_sig.ml @@ -54,11 +54,6 @@ module type S = sig Context.rw -> Protocol.Alpha_context.Sc_rollup.Commitment.Hash.t option 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 : _ Node_context.t -> unit 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 @@ -68,13 +63,21 @@ module type S = sig Protocol.Alpha_context.Sc_rollup.Commitment.t -> unit tzresult Lwt.t - (** [cement_commitments node_ctxt] cements the commitments that can be + (** Worker for publishing and cementing commitments. *) + module Publisher : sig + 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 : _ Node_context.t -> unit tzresult Lwt.t + val cement_commitments : unit -> unit tzresult Lwt.t - (** [start ()] only emits the event that the commitment manager - for the rollup node has started. *) - val start : unit -> unit Lwt.t + val shutdown : unit -> unit Lwt.t + end 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 af086c1f6d91ad893350243b2ff1b893b60c8879..4a44c41e4c315c3ad3ce85cd659caf2900e4b2ac 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml @@ -92,11 +92,11 @@ module Make (PVM : Pvm.S) = struct when Node_context.is_operator node_ctxt source -> (* Published commitment --------------------------------------------- *) let save_lpc = - match node_ctxt.lpc with + match Reference.get node_ctxt.lpc with | None -> true | Some lpc -> Raw_level.(commitment.inbox_level >= lpc.inbox_level) in - if save_lpc then node_ctxt.lpc <- Some commitment ; + if save_lpc then Reference.set node_ctxt.lpc (Some commitment) ; let commitment_hash = Sc_rollup.Commitment.hash_uncarbonated commitment in @@ -171,9 +171,10 @@ module Make (PVM : Pvm.S) = struct on_l1 = commitment; }) in + let lcc = Reference.get node_ctxt.lcc in let*! () = - if Raw_level.(inbox_level > node_ctxt.lcc.level) then ( - node_ctxt.lcc <- {commitment; level = inbox_level} ; + if Raw_level.(inbox_level > lcc.level) then ( + Reference.set node_ctxt.lcc {commitment; level = inbox_level} ; Commitment_event.last_cemented_commitment_updated commitment inbox_level) @@ -425,8 +426,8 @@ module Make (PVM : Pvm.S) = struct in let*! () = Daemon_event.processing_heads_iteration reorg.new_chain in let* () = List.iter_es (process_head node_ctxt) reorg.new_chain in - let* () = Components.Commitment.publish_commitments node_ctxt in - let* () = Components.Commitment.cement_commitments node_ctxt in + let* () = Components.Commitment.Publisher.publish_commitments () in + let* () = Components.Commitment.Publisher.cement_commitments () in let* () = notify_injector node_ctxt new_head reorg in let*! () = Daemon_event.new_heads_processed reorg.new_chain in let* () = Components.Refutation_game.process head node_ctxt in @@ -489,6 +490,8 @@ module Make (PVM : Pvm.S) = struct let* () = Injector.shutdown () in let* () = message "Shutting down Batcher@." in let* () = Components.Batcher.shutdown () in + let* () = message "Shutting down Commitment Publisher@." in + let* () = Components.Commitment.Publisher.shutdown () in let* (_ : unit tzresult) = Node_context.close node_ctxt in let* () = Event.shutdown_node exit_status in Tezos_base_unix.Internal_event_unix.close () @@ -525,7 +528,6 @@ module Make (PVM : Pvm.S) = struct install_finalizer node_ctxt rpc_server in let*! () = Inbox.start () in - let*! () = Components.Commitment.start () in let signers = Configuration.Operator_purpose_map.bindings node_ctxt.operators |> List.fold_left @@ -551,6 +553,7 @@ module Make (PVM : Pvm.S) = struct in (operator, strategy, purposes)) in + let* () = Components.Commitment.Publisher.init node_ctxt in let* () = Injector.init node_ctxt.cctxt diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml index b47ddc695a16968d85303fe921a6833869ecf91f..c9802326b7d207ac250eb457442462f0edb1e6e7 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml @@ -47,8 +47,8 @@ type 'a t = { loser_mode : Loser_mode.t; store : 'a store; context : 'a Context.index; - mutable lcc : lcc; - mutable lpc : Sc_rollup.Commitment.t option; + lcc : ('a, lcc) Reference.t; + lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; } type rw = [`Read | `Write] t @@ -163,8 +163,8 @@ let init (cctxt : Protocol_client_context.full) ~data_dir mode mode = operating_mode; operators; genesis_info = l1_ctxt.Layer1.genesis_info; - lcc; - lpc; + lcc = Reference.new_ lcc; + lpc = Reference.new_ lpc; kind; injector_retention_period = 0; block_finality_time = 2; @@ -219,6 +219,8 @@ let readonly (node_ctxt : _ t) = node_ctxt with store = Store.readonly node_ctxt.store; context = Context.readonly node_ctxt.context; + lcc = Reference.readonly node_ctxt.lcc; + lpc = Reference.readonly node_ctxt.lpc; } type 'a delayed_write = ('a, rw) Delayed_write_monad.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli index 0cd937f0bd7f30178ad372db02e5fcb3de81eb5c..5d896e7faa78b50056f57531252f5690f5c176f2 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli @@ -65,8 +65,8 @@ type 'a t = { store : 'a store; (** The store for the persistent storage. *) context : 'a Context.index; (** The persistent context for the rollup node. *) - mutable lcc : lcc; (** Last cemented commitment and its level. *) - mutable lpc : Sc_rollup.Commitment.t option; + lcc : ('a, lcc) Reference.t; (** Last cemented commitment and its level. *) + lpc : ('a, Sc_rollup.Commitment.t option) Reference.t; (** The last published commitment, i.e. commitment that the operator is staked on. *) } diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml index 66a5a55a2425fca6949e6c27e1926e2c91866787..8b539af74ef67266f064c6cd9fcafea2518f37ab 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/outbox.ml @@ -29,10 +29,9 @@ open Protocol.Alpha_context module Make (PVM : Pvm.S) = struct let get_state_of_lcc node_ctxt = let open Lwt_result_syntax in + let lcc = Reference.get node_ctxt.lcc in let* block_hash = - Node_context.hash_of_level - node_ctxt - (Raw_level.to_int32 node_ctxt.lcc.level) + Node_context.hash_of_level node_ctxt (Raw_level.to_int32 lcc.level) in let* ctxt = Node_context.checkout_context node_ctxt block_hash in let*! state = PVM.State.find ctxt in @@ -41,6 +40,7 @@ module Make (PVM : Pvm.S) = struct let proof_of_output node_ctxt output = let open Lwt_result_syntax in let* state = get_state_of_lcc node_ctxt in + let lcc = Reference.get node_ctxt.lcc in match state with | None -> (* @@ -55,7 +55,7 @@ module Make (PVM : Pvm.S) = struct let serialized_proof = Data_encoding.Binary.to_string_exn PVM.output_proof_encoding proof in - return @@ (node_ctxt.lcc.commitment, serialized_proof) + return @@ (lcc.commitment, serialized_proof) | Error err -> failwith "Error producing outbox proof (%a)" diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.ml new file mode 100644 index 0000000000000000000000000000000000000000..2ae31036e3105f7f5d6362c9eabedfd48b18bc7c --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.ml @@ -0,0 +1,70 @@ +(*****************************************************************************) +(* *) +(* 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 + +module Name = struct + (* We only have a single commitment publisher right now *) + type t = unit + + let encoding = Data_encoding.unit + + let base = ["sc_rollup_commitment_publisher"] + + let pp _ _ = () + + let equal () () = true +end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.mli new file mode 100644 index 0000000000000000000000000000000000000000..ab244e31a486323c889645a1a1a44aa815eeb797 --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/publisher_worker_types.mli @@ -0,0 +1,42 @@ +(*****************************************************************************) +(* *) +(* 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 + +module Name : Worker_intf.NAME with type t = unit diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/reference.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/reference.ml new file mode 100644 index 0000000000000000000000000000000000000000..abb57b197bdbc97806cf5d4162170a4966c343d1 --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/reference.ml @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +type ('perm, 'value) t = 'value ref + +type 'a rw = ([`Read | `Write], 'a) t + +type 'a ro = ([`Read], 'a) t + +let get r = !r + +let set r v = r := v + +let new_ v = ref v + +let readonly r = r diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/reference.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/reference.mli new file mode 100644 index 0000000000000000000000000000000000000000..04821bff48341af229c7be4c06ac7960627d1856 --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/reference.mli @@ -0,0 +1,48 @@ +(*****************************************************************************) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** Abstraction module for OCaml references *) + +(** Type [('perm, 'value) t] represents references containing a value + of type ['value] and permissions specified by ['perm]. *) +type ('perm, 'value) t + +(** Read/write reference {!t}. *) +type 'a rw = ([`Read | `Write], 'a) t + +(** Read only reference {!t}. *) +type 'a ro = ([`Read], 'a) t + +(** [get r] returns the value held by reference [r]. *) +val get : (_, 'a) t -> 'a + +(** [set r v] sets reference [r] to the value [v]. *) +val set : 'a rw -> 'a -> unit + +(** [new_ v] creates a fresh reference holding value [v]. *) +val new_ : 'a -> (_, 'a) t + +(** [readonly r] casts reference [r] to be read only. *) +val readonly : (_, 'a) t -> 'a ro diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_node_errors.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_node_errors.ml index 32e4b4c31d19b11237a8becf5e0159ef491f80d5..efbbd9c9cbb4d96c8977e6822780f53033b7f8e7 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_node_errors.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/sc_rollup_node_errors.ml @@ -44,6 +44,7 @@ type error += | Missing_PVM_state of Block_hash.t * Int32.t | Cannot_checkout_context of Block_hash.t * Sc_rollup_context_hash.t option | No_batcher + | No_publisher type error += | Lost_game of @@ -254,4 +255,17 @@ let () = `Permanent Data_encoding.unit (function No_batcher -> Some () | _ -> None) - (fun () -> No_batcher) + (fun () -> No_batcher) ; + + register_error_kind + ~id:"sc_rollup.node.no_publisher" + ~title:"No publisher for this node" + ~description:"This node does not have an operator to publish commitments" + ~pp:(fun ppf () -> + Format.fprintf + ppf + "This rollup node does not have an operator to publish commitments.") + `Permanent + Data_encoding.unit + (function No_publisher -> Some () | _ -> None) + (fun () -> No_publisher) diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment.ml b/src/proto_alpha/lib_sc_rollup_node/commitment.ml index 499207755a3b8c799fb1937392afd8ba8aaf6ccb..f1c09fefe9d21c0a5f589dccaa1fd709cacded25 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment.ml +++ b/src/proto_alpha/lib_sc_rollup_node/commitment.ml @@ -43,6 +43,7 @@ open Protocol open Alpha_context +open Publisher_worker_types module Lwt_result_option_syntax = struct let ( let** ) a f = @@ -83,6 +84,8 @@ let next_commitment_level node_ctxt last_commitment_level = module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct module PVM = PVM + type state = Node_context.ro + let tick_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Lwt_result_syntax in let* block = @@ -252,7 +255,7 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let* _hash = Injector.add_pending_operation ~source publish_operation in return_unit - let publish_commitments (node_ctxt : _ Node_context.t) = + 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 @@ -383,7 +386,7 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct let* _hash = Injector.add_pending_operation ~source cement_operation in return_unit - let cement_commitments node_ctxt = + 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 @@ -396,5 +399,93 @@ module Make (PVM : Pvm.S) : Commitment_sig.S with module PVM = PVM = struct (cement_commitment node_ctxt ~source) cementable_commitments - let start () = Commitment_event.starting () + module Publisher = struct + module Types = struct + type nonrec state = state + + type parameters = {node_ctxt : Node_context.ro} + 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 init 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 + + (* 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 + end end diff --git a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml index c8bedc3424138dead92caefdbdcb9689755a86ac..7f9135d2792a16f0a870196cad9942a9f5fc33e8 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml +++ b/src/proto_alpha/lib_sc_rollup_node/commitment_event.ml @@ -25,6 +25,7 @@ open Protocol open Alpha_context +open Publisher_worker_types module Simple = struct include Internal_event.Simple @@ -120,6 +121,34 @@ module Simple = struct ("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) @@ -158,3 +187,11 @@ let 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 index 7ae1f155a08ae2e525817756ad99ff558982fffd..8f4baf9b0e14b40ddcdbd621c2aa831741bd4f9f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli +++ b/src/proto_alpha/lib_sc_rollup_node/commitment_event.mli @@ -27,6 +27,7 @@ when it is storing and publishing commitments (see {!Commitment}). *) open Protocol.Alpha_context +open Publisher_worker_types val starting : unit -> unit Lwt.t @@ -69,3 +70,19 @@ val compute_commitment : Raw_level.t -> unit Lwt.t being published. *) val publish_commitment : Sc_rollup.Commitment.Hash.t -> Raw_level.t -> 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 index a646980a047bb063b9531ad3f49750ea4b3c8b56..96f2306dd8f084e7f35c0c07c79a5f17c21ddc4b 100644 --- a/src/proto_alpha/lib_sc_rollup_node/commitment_sig.ml +++ b/src/proto_alpha/lib_sc_rollup_node/commitment_sig.ml @@ -54,11 +54,6 @@ module type S = sig Context.rw -> Protocol.Alpha_context.Sc_rollup.Commitment.Hash.t option 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 : _ Node_context.t -> unit 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 @@ -68,13 +63,21 @@ module type S = sig Protocol.Alpha_context.Sc_rollup.Commitment.t -> unit tzresult Lwt.t - (** [cement_commitments node_ctxt] cements the commitments that can be + (** Worker for publishing and cementing commitments. *) + module Publisher : sig + 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 : _ Node_context.t -> unit tzresult Lwt.t + val cement_commitments : unit -> unit tzresult Lwt.t - (** [start ()] only emits the event that the commitment manager - for the rollup node has started. *) - val start : unit -> unit Lwt.t + val shutdown : unit -> unit Lwt.t + end end diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index 9eec68ad2ebd1794c5215775feba360723c21638..2714c43e920f5695f5f911420c6798c04d268099 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -426,8 +426,8 @@ module Make (PVM : Pvm.S) = struct in let*! () = Daemon_event.processing_heads_iteration reorg.new_chain in let* () = List.iter_es (process_head node_ctxt) reorg.new_chain in - let* () = Components.Commitment.publish_commitments node_ctxt in - let* () = Components.Commitment.cement_commitments node_ctxt in + let* () = Components.Commitment.Publisher.publish_commitments () in + let* () = Components.Commitment.Publisher.cement_commitments () in let* () = notify_injector node_ctxt new_head reorg in let*! () = Daemon_event.new_heads_processed reorg.new_chain in let* () = Components.Refutation_game.process head node_ctxt in @@ -490,6 +490,8 @@ module Make (PVM : Pvm.S) = struct let* () = Injector.shutdown () in let* () = message "Shutting down Batcher@." in let* () = Components.Batcher.shutdown () in + let* () = message "Shutting down Commitment Publisher@." in + let* () = Components.Commitment.Publisher.shutdown () in let* (_ : unit tzresult) = Node_context.close node_ctxt in let* () = Event.shutdown_node exit_status in Tezos_base_unix.Internal_event_unix.close () @@ -526,7 +528,6 @@ module Make (PVM : Pvm.S) = struct install_finalizer node_ctxt rpc_server in let*! () = Inbox.start () in - let*! () = Components.Commitment.start () in let signers = Configuration.Operator_purpose_map.bindings node_ctxt.operators |> List.fold_left @@ -547,6 +548,7 @@ module Make (PVM : Pvm.S) = struct in (operator, strategy, purposes)) in + let* () = Components.Commitment.Publisher.init node_ctxt in let* () = Injector.init node_ctxt.cctxt 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 new file mode 100644 index 0000000000000000000000000000000000000000..2ae31036e3105f7f5d6362c9eabedfd48b18bc7c --- /dev/null +++ b/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.ml @@ -0,0 +1,70 @@ +(*****************************************************************************) +(* *) +(* 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 + +module Name = struct + (* We only have a single commitment publisher right now *) + type t = unit + + let encoding = Data_encoding.unit + + let base = ["sc_rollup_commitment_publisher"] + + let pp _ _ = () + + let equal () () = true +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 new file mode 100644 index 0000000000000000000000000000000000000000..ab244e31a486323c889645a1a1a44aa815eeb797 --- /dev/null +++ b/src/proto_alpha/lib_sc_rollup_node/publisher_worker_types.mli @@ -0,0 +1,42 @@ +(*****************************************************************************) +(* *) +(* 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 + +module Name : Worker_intf.NAME with type t = unit diff --git a/src/proto_alpha/lib_sc_rollup_node/sc_rollup_node_errors.ml b/src/proto_alpha/lib_sc_rollup_node/sc_rollup_node_errors.ml index bb38f41cd862abbc5c71c63f61c616275eb91f8d..a5f7c4d1ccfc326735b7cb25a3551e5ce9ae4878 100644 --- a/src/proto_alpha/lib_sc_rollup_node/sc_rollup_node_errors.ml +++ b/src/proto_alpha/lib_sc_rollup_node/sc_rollup_node_errors.ml @@ -44,6 +44,7 @@ type error += | Missing_PVM_state of Block_hash.t * Int32.t | Cannot_checkout_context of Block_hash.t * Sc_rollup_context_hash.t option | No_batcher + | No_publisher type error += | Lost_game of @@ -254,4 +255,17 @@ let () = `Permanent Data_encoding.unit (function No_batcher -> Some () | _ -> None) - (fun () -> No_batcher) + (fun () -> No_batcher) ; + + register_error_kind + ~id:"sc_rollup.node.no_publisher" + ~title:"No publisher for this node" + ~description:"This node does not have an operator to publish commitments" + ~pp:(fun ppf () -> + Format.fprintf + ppf + "This rollup node does not have an operator to publish commitments.") + `Permanent + Data_encoding.unit + (function No_publisher -> Some () | _ -> None) + (fun () -> No_publisher)