diff --git a/CHANGES.rst b/CHANGES.rst index aa89ddfeb8204ecc1a44f63da2720874c0d4509f..a14a01796ec47160e50d0ef07ed8863d8ded2550 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -47,6 +47,10 @@ Client Baker ----- +- **Breaking change** Providing the endpoint of a running DAL node is required + for the baker to be launched, unless opted out with the newly introduced + ``--without-dal`` option. (MR :gl:`!16049`) + Accuser ------- diff --git a/src/proto_alpha/lib_delegate/baking_actions.ml b/src/proto_alpha/lib_delegate/baking_actions.ml index 726dc29335ad2b49d073a7a7a012d580c7b795a1..c452a3b78a41a7a3a5049f47be62f3eb10c05dd5 100644 --- a/src/proto_alpha/lib_delegate/baking_actions.ml +++ b/src/proto_alpha/lib_delegate/baking_actions.ml @@ -462,7 +462,7 @@ let only_if_dal_feature_enabled = incr no_dal_node_warning_counter ; let* () = if !no_dal_node_warning_counter mod 10 = 1 then - Events.(emit no_dal_node ()) + Events.(emit no_dal_node_running ()) else return_unit in return default_value diff --git a/src/proto_alpha/lib_delegate/baking_commands.ml b/src/proto_alpha/lib_delegate/baking_commands.ml index 4b9a271bbc0656ad3d2c8026fac2253453403015..7247560dd706160ad5e4ee736911d02a525b5b4f 100644 --- a/src/proto_alpha/lib_delegate/baking_commands.ml +++ b/src/proto_alpha/lib_delegate/baking_commands.ml @@ -358,6 +358,14 @@ let dal_node_endpoint_arg = ~doc:"endpoint of the DAL node, e.g. 'http://localhost:8933'" (Tezos_clic.parameter (fun _ s -> return @@ Uri.of_string s)) +let without_dal_arg = + Tezos_clic.switch + ~long:"without-dal" + ~doc: + "If without-dal flag is set, the daemon will not try to connect to a DAL \ + node." + () + let block_count_arg = Tezos_clic.default_arg ~long:"count" @@ -690,31 +698,36 @@ let lookup_default_vote_file_path (cctxt : Protocol_client_context.full) = let base_dir_file = Filename.Infix.(cctxt#get_base_dir // default_filename) in when_s file_exists base_dir_file @@ fun () -> return_none -(* Running a DAL node is mandatory on some networks. This function checks that - a DAL node endpoint was given, and that the specified DAL node is "healthy", +(* This function checks that a DAL node endpoint was given, + and that the specified DAL node is "healthy", (the DAL's nodes 'health' RPC is used for that). *) -let check_dal_node cctxt dal_node_rpc_ctxt = +let check_dal_node without_dal dal_node_rpc_ctxt = let open Lwt_result_syntax in - let* node_config = Octez_node_config.Node_services.config cctxt () in - let mandatory (_chain_name : Distributed_db_version.Name.t) = - (* for now there's no network for which the DAL is mandatory *) - false + let result_emit f x = + let*! () = Events.emit f x in + return_unit in - if mandatory node_config.blockchain_network.chain_name then - match dal_node_rpc_ctxt with - | None -> tzfail No_dal_node_endpoint - | Some ctxt -> ( - let* health = Node_rpc.get_dal_health ctxt in - let open Tezos_dal_node_services.Types.Health in - match health.status with - | Up -> return_unit - | _ -> tzfail (Unhealthy_dal_node {health})) - else return_unit + match (dal_node_rpc_ctxt, without_dal) with + | None, true -> + (* The user is aware that no DAL node is running, since they explicitly + used the [--without-dal] option. However, we do not want to reduce the + exposition of bakers to warnings about DAL, so we keep it. *) + result_emit Events.no_dal_node_running () + | None, false -> tzfail No_dal_node_endpoint + | Some _, true -> tzfail Incompatible_dal_options + | Some ctxt, false -> ( + let*! health = Node_rpc.get_dal_health ctxt in + match health with + | Ok health -> ( + match health.status with + | Tezos_dal_node_services.Types.Health.Up -> return_unit + | _ -> result_emit Events.unhealthy_dal_node (ctxt#base, health)) + | Error _ -> result_emit Events.unreachable_dal_node ctxt#base) type baking_mode = Local of {local_data_dir_path : string} | Remote let baker_args = - Tezos_clic.args16 + Tezos_clic.args17 pidfile_arg node_version_check_bypass_arg node_version_allowed_arg @@ -728,6 +741,7 @@ let baker_args = per_block_vote_file_arg operations_arg dal_node_endpoint_arg + without_dal_arg state_recorder_switch_arg pre_emptive_forge_time_arg remote_calls_timeout_arg @@ -746,6 +760,7 @@ let run_baker per_block_vote_file, extra_operations, dal_node_endpoint, + without_dal, state_recorder, pre_emptive_forge_time, remote_calls_timeout ) baking_mode sources cctxt = @@ -773,7 +788,7 @@ let run_baker let dal_node_rpc_ctxt = Option.map create_dal_node_rpc_ctxt dal_node_endpoint in - let* () = check_dal_node cctxt dal_node_rpc_ctxt in + let* () = check_dal_node without_dal dal_node_rpc_ctxt in let* delegates = get_delegates cctxt sources in let context_path = match baking_mode with diff --git a/src/proto_alpha/lib_delegate/baking_errors.ml b/src/proto_alpha/lib_delegate/baking_errors.ml index 73e1b128a2e41c49cac8a93c25e0234913f002f0..1ebc51e5a8f6743474c10e105c95bf60c5ffebea 100644 --- a/src/proto_alpha/lib_delegate/baking_errors.ml +++ b/src/proto_alpha/lib_delegate/baking_errors.ml @@ -403,37 +403,35 @@ let () = (fun (chain, block_hash, length) -> Unexpected_empty_block_list {chain; block_hash; length}) -type error += No_dal_node_endpoint +(* DAL node related errors *) + +type error += No_dal_node_endpoint | Incompatible_dal_options let () = - let description = "The mandatory argument --dal-node is missing." in register_error_kind `Permanent ~id:"Client_commands.no_dal_node_endpoint" ~title:"Missing_dal_node_argument" - ~description - ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + ~description:"Explicit DAL node configuration is required." + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Please connect a running DAL node using '--dal-node '. If \ + you do not want to run a DAL node, you have to opt-out using \ + '--without-dal'.") Data_encoding.unit (function No_dal_node_endpoint -> Some () | _ -> None) - (fun () -> No_dal_node_endpoint) - -type error += - | Unhealthy_dal_node of {health : Tezos_dal_node_services.Types.Health.t} - -let () = - let open Tezos_dal_node_services.Types.Health in + (fun () -> No_dal_node_endpoint) ; register_error_kind `Permanent - ~id:"Client_commands.Unhealthy_dal_node" - ~title:"Unhealthy_DAL_node" - ~description:"The DAL node is not performing well." - ~pp:(fun ppf health -> + ~id:"Client_commands.incompatible_dal_options" + ~title:"Incompatible_dal_options" + ~description:"'--dal-node' and '--without-dal' are incompatible." + ~pp:(fun ppf () -> Format.fprintf ppf - "The DAL node is not performing well.\n\ - Please check your DAL node. Its health is %a" - pp - health) - Data_encoding.(obj1 (req "health" encoding)) - (function Unhealthy_dal_node {health} -> Some health | _ -> None) - (fun health -> Unhealthy_dal_node {health}) + "'--dal-node ' and '--without-dal' are incompatible. Please \ + do not pass '--without-dal' option.") + Data_encoding.unit + (function Incompatible_dal_options -> Some () | _ -> None) + (fun () -> Incompatible_dal_options) diff --git a/src/proto_alpha/lib_delegate/baking_events.ml b/src/proto_alpha/lib_delegate/baking_events.ml index 14c7566113086a697228feaf4bc3bfac6a958b4b..2d18a35865f034390a623f166a0494a16c2f76a6 100644 --- a/src/proto_alpha/lib_delegate/baking_events.ml +++ b/src/proto_alpha/lib_delegate/baking_events.ml @@ -71,6 +71,44 @@ module Commands = struct ( "baker_commit", Data_encoding.option Tezos_version.Octez_node_version.commit_info_encoding ) + + let no_dal_node_running = + declare_0 + ~section + ~name:"no_dal_node_running" + ~level:Warning + ~msg: + "No DAL node endpoint has been provided.\n\ + It will soon be required to launch a DAL node before running the \ + baker. For instructions on running a DAL node, please visit \ + https://docs.tezos.com/tutorials/join-dal-baker." + () + + let unhealthy_dal_node = + declare_2 + ~section + ~name:"unhealthy_dal_node" + ~level:Error + ~msg: + "The DAL node running on {endpoint} is not healthy. DAL attestations \ + cannot be sent.\n\ + Its health is {health}.\n\ + Please check your DAL node and possibly restart it." + ~pp1:Uri.pp + ("endpoint", Tezos_rpc.Encoding.uri_encoding) + ~pp2:Tezos_dal_node_services.Types.Health.pp + ("health", Tezos_dal_node_services.Types.Health.encoding) + + let unreachable_dal_node = + declare_1 + ~section + ~name:"unreachable_dal_node" + ~level:Error + ~msg: + "The DAL node cannot be reached on endpoint: {endpoint}.\n\ + Please check your DAL node and possibly restart it." + ~pp1:Uri.pp + ("endpoint", Tezos_rpc.Encoding.uri_encoding) end module State_transitions = struct @@ -1035,16 +1073,6 @@ module Actions = struct Protocol.Alpha_context.Per_block_votes.adaptive_issuance_vote_encoding ) - let no_dal_node = - declare_0 - ~section - ~name:"no_dal_node" - ~level:Notice - ~msg: - "DAL feature enabled, but no DAL node specified: cannot fetch \ - attestations" - () - let signature_timeout = declare_1 ~section @@ -1074,6 +1102,8 @@ module Actions = struct ("delegates", Data_encoding.list Baking_state.consensus_key_encoding) ~pp2:pp_int32 ("level", Data_encoding.int32) + + let no_dal_node_running = Commands.no_dal_node_running end module VDF = struct diff --git a/tezt/lib_tezos/baker.ml b/tezt/lib_tezos/baker.ml index eac4cd2bce0b7afc0733d458c1e2a77fe74911b2..7caf4664a00e4fd368bfbe2fa98166bbd90b1323 100644 --- a/tezt/lib_tezos/baker.ml +++ b/tezt/lib_tezos/baker.ml @@ -214,6 +214,12 @@ let run ?env ?event_level ?event_sections_levels (baker : t) = Endpoint.as_string baker.persistent_state.dal_node_rpc_endpoint in + let without_dal = + Cli_arg.optional_switch + "without-dal" + (baker.persistent_state.protocol = Protocol.Alpha + && Option.is_none baker.persistent_state.dal_node_rpc_endpoint) + in let dal_node_timeout_percentage = Cli_arg.optional_arg "dal-node-timeout-percentage" @@ -247,7 +253,7 @@ let run ?env ?event_level ?event_sections_levels (baker : t) = let arguments = ["--endpoint"; node_addr; "--base-dir"; base_dir; "run"] @ run_args @ liquidity_baking_toggle_vote @ votefile - @ force_apply_from_round @ operations_pool @ dal_node_endpoint + @ force_apply_from_round @ operations_pool @ dal_node_endpoint @ without_dal @ dal_node_timeout_percentage @ delegates @ minimal_nanotez_per_gas_unit @ state_recorder @ node_version_check_bypass @ node_version_allowed in diff --git a/tezt/lib_tezos/cli_arg.mli b/tezt/lib_tezos/cli_arg.mli index d6c7ddad603e7fa73cd4af125773522089e7f7c6..2779b2d7c65768309ab9498e1c82fc03a8f769af 100644 --- a/tezt/lib_tezos/cli_arg.mli +++ b/tezt/lib_tezos/cli_arg.mli @@ -26,5 +26,5 @@ (** [optional_switch "flag" b] is [["--flag"]] if [b] is true, otherwise [[]] *) val optional_switch : string -> bool -> string list -(** [optional_arg "arg" f opt_v] is [["--arg"; f x]] if [opt_v] is [Some v], otherwise [[]] *) +(** [optional_arg "arg" f opt_v] is [["--arg"; f x]] if [opt_v] is [Some x], otherwise [[]] *) val optional_arg : string -> ('a -> string) -> 'a option -> string list