diff --git a/manifest/product_octez.ml b/manifest/product_octez.ml index 830f199187f2325de7101b2e660fe28ebdc39e98..5f3eb0d04b81cfb4d88f5577d8caef03948d07dd 100644 --- a/manifest/product_octez.ml +++ b/manifest/product_octez.ml @@ -8616,6 +8616,7 @@ let _octez_experimental_agnostic_baker = bls12_381_archive; octez_base |> open_ ~m:"TzPervasives" |> open_; octez_base_unix |> open_; + octez_client_base_unix |> open_; octez_experimental_agnostic_baker_lib |> open_; octez_profiler |> open_; ] diff --git a/opam/octez-experimental-agnostic-baker.opam b/opam/octez-experimental-agnostic-baker.opam index eab07475ebd54426345d1c13b2bf634f00b4cdf8..8924250713f5884b44a94d3fccea9b7a96d79c5d 100644 --- a/opam/octez-experimental-agnostic-baker.opam +++ b/opam/octez-experimental-agnostic-baker.opam @@ -13,6 +13,7 @@ depends: [ "octez-libs" { = version } "octez-rust-deps" { = version } "bls12-381" { = version } + "octez-shell-libs" { = version } "octez-experimental-agnostic-baker-lib" { = version } "octez-protocol-021-PsQuebec-libs" { = version } "octez-protocol-022-PsRiotum-libs" { = version } diff --git a/scripts/proto_manager.sh b/scripts/proto_manager.sh index 0d150b3a9a0356986e8cbace79e1b23d87ad89a8..02bc2731e519581b129f1c70d82a3622aaaafcc0 100755 --- a/scripts/proto_manager.sh +++ b/scripts/proto_manager.sh @@ -779,9 +779,8 @@ function copy_source() { ## update agnostic_baker ## add protocol as active before alpha in parameters.ml if ! grep -q "${long_hash}" src/lib_agnostic_baker/parameters.ml; then - ## look for | "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK" -> ("alpha", Active) - ## and add | "${longhash}" ) as full_hash -> (String.sub full_hash 0 8, Active) - sed -i.old -e "/| \"ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK\" ->/a \ | \"${long_hash}\" as full_hash -> (String.sub full_hash 0 8, Active)" src/lib_agnostic_baker/parameters.ml + ## look for "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK" and add "${longhash};" + sed -i.old -e "/ \"ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK\" /a \"${long_hash}\"; " src/lib_agnostic_baker/parameters.ml ocamlformat -i src/lib_agnostic_baker/parameters.ml commit "src: add protocol to agnostic_baker" fi diff --git a/src/bin_agnostic_baker/dune b/src/bin_agnostic_baker/dune index d184c7a2c707fddea5970943a0d616b44d85402d..73b805b34530df8d7c3e82e357046304bd0c0c34 100644 --- a/src/bin_agnostic_baker/dune +++ b/src/bin_agnostic_baker/dune @@ -11,6 +11,7 @@ bls12-381.archive octez-libs.base octez-libs.base.unix + octez-shell-libs.client-base-unix octez-experimental-agnostic-baker-lib octez-libs.octez-profiler octez-protocol-021-PsQuebec-libs.agnostic-baker @@ -30,6 +31,7 @@ -open Tezos_base.TzPervasives -open Tezos_base -open Tezos_base_unix + -open Tezos_client_base_unix -open Octez_experimental_agnostic_baker -open Tezos_profiler)) diff --git a/src/bin_agnostic_baker/main_agnostic_baker.ml b/src/bin_agnostic_baker/main_agnostic_baker.ml index 88c054c752d62e8b6ccac7044fd9eb8896c997df..e9b8324b75e3a0e4fefc05a3c17d826bc22190ca 100644 --- a/src/bin_agnostic_baker/main_agnostic_baker.ml +++ b/src/bin_agnostic_baker/main_agnostic_baker.ml @@ -24,15 +24,9 @@ let[@warning "-32"] may_start_profiler baking_dir = let lwt_run ~args () = let open Lwt_result_syntax in - let base_dir = - Option.value - ~default:Tezos_client_base_unix.Client_config.Cfg_file.default.base_dir - (Run_args.get_base_dir args) - in + let base_dir = Run_args.get_base_dir args in let*! () = - Tezos_base_unix.Internal_event_unix.init - ~config:(Parameters.log_config ~base_dir) - () + Client_main_run.init_logging (module Agnostic_baker_config) ~base_dir () in () [@profiler.overwrite may_start_profiler base_dir] ; let daemon = Daemon.create ~node_endpoint:(Run_args.get_endpoint args) in @@ -41,7 +35,7 @@ let lwt_run ~args () = return_unit let run ~args () = - let open Lwt_result_syntax in + let open Lwt_syntax in let main_promise = Lwt.catch (lwt_run ~args) (function | Failure msg -> failwith "%s" msg @@ -49,8 +43,8 @@ let run ~args () = in Stdlib.exit (Tezos_base_unix.Event_loop.main_run (fun () -> - let*! retcode = - let*! r = Lwt_exit.wrap_and_exit main_promise in + let* retcode = + let* r = Lwt_exit.wrap_and_exit main_promise in match r with | Ok () -> Lwt.return 0 | Error errs -> @@ -59,15 +53,16 @@ let run ~args () = in Format.pp_print_flush Format.err_formatter () ; Format.pp_print_flush Format.std_formatter () ; - let*! () = Tezos_base_unix.Internal_event_unix.close () in - Lwt.return retcode)) + let* () = Tezos_base_unix.Internal_event_unix.close () in + return retcode)) let () = - let open Tezos_client_base_unix in let args = Array.to_list Sys.argv in if Run_args.(is_help_cmd args || is_version_cmd args || is_man_cmd args) then + (* No need to run the baker commands, we just need to get their description, + therefore we do not obtain the protocol plugin. *) Client_main_run.run - (module Daemon_config) + (module Agnostic_baker_config) ~select_commands:(fun _ _ -> Lwt_result_syntax.return @@ Commands.baker_commands ()) else run ~args () diff --git a/src/lib_agnostic_baker/agnostic_baker_config.ml b/src/lib_agnostic_baker/agnostic_baker_config.ml new file mode 100644 index 0000000000000000000000000000000000000000..d2fe3083b4f777864a70bbffc2397ce2c6d4c575 --- /dev/null +++ b/src/lib_agnostic_baker/agnostic_baker_config.ml @@ -0,0 +1,17 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Trilitech *) +(* *) +(*****************************************************************************) + +(* Agnostic Baker Daemon configuration *) + +include Tezos_client_base_unix.Daemon_config + +(* All logging must be centralised in a single place. *) +let default_daily_logs_path = Parameters.default_daily_logs_path + +let clic_commands ~base_dir:_ ~config_commands:_ ~builtin_commands + ~other_commands ~require_auth:_ = + builtin_commands @ other_commands diff --git a/src/lib_agnostic_baker/cli.ml b/src/lib_agnostic_baker/cli.ml new file mode 100644 index 0000000000000000000000000000000000000000..2d1b5f8d2cbeec2d34b4fbec67a122fb6a73c913 --- /dev/null +++ b/src/lib_agnostic_baker/cli.ml @@ -0,0 +1,383 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Trilitech *) +(* *) +(*****************************************************************************) + +(** This is the module where the type of the CLI arguments configuration is + created. An argument of this type will be passed to the main running + function of the agnostic baker. *) + +type error += Block_vote_file_not_found of string + +type error += Bad_minimal_fees of string + +let () = + register_error_kind + `Permanent + ~id:"agnostic_baker.configuration.block_vote_file_not_found" + ~title: + "The provided block vote file path does not point to an existing file." + ~description: + "A block vote file path was provided on the command line but the path \ + does not point to an existing file." + ~pp:(fun ppf file_path -> + Format.fprintf + ppf + "@[The provided block vote file path \"%s\" does not point to an \ + existing file.@]" + file_path) + Data_encoding.(obj1 (req "file_path" string)) + (function + | Block_vote_file_not_found file_path -> Some file_path | _ -> None) + (fun file_path -> Block_vote_file_not_found file_path) ; + register_error_kind + `Permanent + ~id:"agnostic_baker.configuration.badMinimalFeesArg" + ~title:"Bad -minimal-fees arg" + ~description:"invalid fee threshold in -fee-threshold" + ~pp:(fun ppf literal -> + Format.fprintf ppf "invalid minimal fees '%s'" literal) + Data_encoding.(obj1 (req "parameter" string)) + (function Bad_minimal_fees parameter -> Some parameter | _ -> None) + (fun parameter -> Bad_minimal_fees parameter) + +(* Primitive argument parsers *) +let string_parameter = + Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) x -> + Lwt_result.return x) + +let int_parameter = + Tezos_clic.parameter (fun (cctxt : Tezos_client_base.Client_context.full) p -> + try Lwt_result.return (int_of_string p) + with _ -> cctxt#error "Cannot read int") + +let uri_parameter = + Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) x -> + Lwt_result.return (Uri.of_string x)) + +let per_block_vote_parameter = + let open Lwt_result_syntax in + Tezos_clic.parameter + ~autocomplete:(fun _ctxt -> return ["on"; "off"; "pass"]) + (fun (_cctxt : Tezos_client_base.Client_context.full) -> function + | ("on" | "off" | "pass") as s -> return s + | s -> + failwith + "unexpected vote: %s, expected either \"on\", \"off\", or \"pass\"." + s) + +(* Baker arguments *) +let pidfile_arg = + let open Lwt_result_syntax in + Tezos_clic.arg + ~doc:"write process id in file" + ~short:'P' + ~long:"pidfile" + ~placeholder:"filename" + (Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) s -> return s)) + +let may_lock_pidfile pidfile_opt f = + match pidfile_opt with + | None -> f () + | Some pidfile -> + Tezos_stdlib_unix.Lwt_lock_file.with_lock + ~when_locked: + (`Fail (Exn (Failure ("Failed to create the pidfile: " ^ pidfile)))) + ~filename:pidfile + f + +let node_version_check_bypass_arg : + (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg = + Tezos_clic.switch + ~long:"node-version-check-bypass" + ~doc: + "If node-version-check-bypass flag is set, the baker will not check its \ + compatibility with the version of the node to which it is connected." + () + +let node_version_allowed_arg = + Tezos_clic.arg + ~long:"node-version-allowed" + ~placeholder:"-[v].[.0][:]" + ~doc: + "When specified the baker will accept to run with a node of this \ + version. The specified version is composed of the product, for example \ + 'octez'; the major and the minor versions that are positive integers; \ + the info, for example '-rc', '-beta1+dev' or realese if none is \ + provided; optionally the commit that is the hash of the last git commit \ + or a prefix of at least 8 characters long." + string_parameter + +let default_minimal_fees = 100L + +let default_minimal_nanotez_per_gas_unit = Q.of_int 100 + +let default_minimal_nanotez_per_byte = Q.of_int 1000 + +let minimal_fees_arg = + let open Lwt_result_syntax in + Tezos_clic.default_arg + ~long:"minimal-fees" + ~placeholder:"amount" + ~doc:"exclude operations with fees lower than this threshold (in tez)" + ~default:(Int64.to_string default_minimal_fees) + (Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) s -> + match Int64.of_string_opt s with + | Some t -> return t + | None -> tzfail (Bad_minimal_fees s))) + +let minimal_nanotez_per_gas_unit_arg = + let open Lwt_result_syntax in + Tezos_clic.default_arg + ~long:"minimal-nanotez-per-gas-unit" + ~placeholder:"amount" + ~doc: + "exclude operations with fees per gas lower than this threshold (in \ + nanotez)" + ~default:(Q.to_string default_minimal_nanotez_per_gas_unit) + (Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) s -> + try return (Q.of_string s) with _ -> tzfail (Bad_minimal_fees s))) + +let minimal_nanotez_per_byte_arg = + let open Lwt_result_syntax in + Tezos_clic.default_arg + ~long:"minimal-nanotez-per-byte" + ~placeholder:"amount" + ~default:(Q.to_string default_minimal_nanotez_per_byte) + ~doc: + "exclude operations with fees per byte lower than this threshold (in \ + nanotez)" + (Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) s -> + try return (Q.of_string s) with _ -> tzfail (Bad_minimal_fees s))) + +let force_apply_from_round_arg = + Tezos_clic.arg + ~long:"force-apply-from-round" + ~placeholder:"round" + ~doc: + "Force the baker to not only validate but also apply operations starting \ + from the specified round." + int_parameter + +let keep_alive_arg : + (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg = + Tezos_clic.switch + ~doc: + "Keep the daemon process alive: when the connection with the node is \ + lost, the daemon periodically tries to reach it." + ~short:'K' + ~long:"keep-alive" + () + +let liquidity_baking_toggle_vote_arg = + Tezos_clic.arg + ~doc: + "Vote to continue or end the liquidity baking subsidy. The possible \ + values for this option are: \"off\" to request ending the subsidy, \ + \"on\" to request continuing or restarting the subsidy, and \"pass\" to \ + abstain. Note that this \"option\" is mandatory!" + ~long:"liquidity-baking-toggle-vote" + ~placeholder:"vote" + per_block_vote_parameter + +let adaptive_issuance_vote_arg = + Tezos_clic.arg + ~doc: + "Vote to adopt or not the adaptive issuance feature. The possible values \ + for this option are: \"off\" to request not activating it, \"on\" to \ + request activating it, and \"pass\" to abstain. If you do not vote, \ + default value is \"pass\"." + ~long:"adaptive-issuance-vote" + ~placeholder:"vote" + per_block_vote_parameter + +let per_block_vote_file_arg = + Tezos_clic.arg + ~doc:"read per block votes as json file" + ~short:'V' + ~long:"votefile" + ~placeholder:"filename" + (Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) file -> + let open Lwt_result_syntax in + let* file_exists = + protect + ~on_error:(fun _ -> tzfail (Block_vote_file_not_found file)) + (fun () -> + let*! b = Lwt_unix.file_exists file in + return b) + in + if file_exists then return file + else tzfail (Block_vote_file_not_found file))) + +let http_headers_env_variable = + "TEZOS_CLIENT_REMOTE_OPERATIONS_POOL_HTTP_HEADERS" + +let http_headers = + match Sys.getenv_opt http_headers_env_variable with + | None -> None + | Some contents -> + let lines = String.split_on_char '\n' contents in + Some + (List.fold_left + (fun acc line -> + match String.index_opt line ':' with + | None -> + invalid_arg + (Printf.sprintf + "Http headers: invalid %s environment variable, missing \ + colon" + http_headers_env_variable) + | Some pos -> + let header = String.trim (String.sub line 0 pos) in + let header = String.lowercase_ascii header in + if header <> "host" then + invalid_arg + (Printf.sprintf + "Http headers: invalid %s environment variable, only \ + 'host' headers are supported" + http_headers_env_variable) ; + let value = + String.trim + (String.sub line (pos + 1) (String.length line - pos - 1)) + in + (header, value) :: acc) + [] + lines) + +let operations_arg = + Tezos_clic.arg + ~long:"operations-pool" + ~placeholder:"file|uri" + ~doc: + (Printf.sprintf + "When specified, the baker will try to fetch operations from this \ + file (or uri) and to include retrieved operations in the block. The \ + expected format of the contents is a list of operations [ \ + alpha.operation ]. Environment variable '%s' may also be specified \ + to add headers to the requests (only 'host' headers are supported). \ + If the resource cannot be retrieved, e.g., if the file is absent, \ + unreadable, or the web service returns a 404 error, the resource is \ + simply ignored." + http_headers_env_variable) + uri_parameter + +let dal_node_endpoint_arg = + Tezos_clic.arg + ~long:"dal-node" + ~placeholder:"uri" + ~doc:"endpoint of the DAL node, e.g. 'http://localhost:8933'" + uri_parameter + +let without_dal_arg : + (bool, Tezos_client_base.Client_context.full) Tezos_clic.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 state_recorder_switch_arg : + (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg = + Tezos_clic.switch + ~long:"record-state" + ~doc: + "If record-state flag is set, the baker saves all its internal consensus \ + state in the filesystem, otherwise just in memory." + () + +let pre_emptive_forge_time_arg = + let open Lwt_result_syntax in + Tezos_clic.arg + ~long:"pre-emptive-forge-time" + ~placeholder:"seconds" + ~doc: + "Sets the pre-emptive forge time optimization, in seconds. When set, the \ + baker, if it is the next level round 0 proposer, will start forging \ + after quorum has been reached in the current level while idly waiting \ + for it to end. When it is its time to propose, the baker will inject \ + the pre-emptively forged block immediately, allowing more time for the \ + network to reach quorum on it. Operators should note that the higher \ + this value `t`, the lower the operation inclusion window (specifically \ + `block_time - t`) which may lead to lower baking rewards. Defaults to \ + 15/% of block time. Set to 0 to ignore pre-emptive forging." + (Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) s -> + try return (Q.of_string s) + with _ -> failwith "pre-emptive-forge-time expected int or float.")) + +let remote_calls_timeout_arg = + let open Lwt_result_syntax in + Tezos_clic.arg + ~long:"remote-calls-timeout" + ~placeholder:"seconds" + ~doc: + "Sets a timeout for client calls such as signing block header or \ + attestation and for the creation of deterministic nonce. Use only if \ + your remote signer can handle concurrent requests." + (Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) s -> + try return (Q.of_string s) + with _ -> failwith "remote-calls-timeout expected int or float.")) + +let directory_parameter = + let open Lwt_result_syntax in + Tezos_clic.parameter + (fun (_cctxt : Tezos_client_base.Client_context.full) p -> + let*! exists = Tezos_stdlib_unix.Lwt_utils_unix.dir_exists p in + if not exists then failwith "Directory doesn't exist: '%s'" p + else return p) + +let sources_param : + ( Signature.Public_key_hash.t list -> + Tezos_client_base.Client_context.full -> + unit Error_monad.tzresult Lwt.t, + Tezos_client_base.Client_context.full ) + Tezos_clic.params = + Tezos_clic.seq_of_param + (Tezos_client_base.Client_keys.Public_key_hash.source_param + ~name:"baker" + ~desc: + "name of the delegate owning the attestation/baking right or name of \ + the consensus key signing on the delegate's behalf") + +let force_switch : (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg + = + Tezos_clic.switch + ~long:"force" + ~doc:"Overwrites the baker configuration file when it exists." + () + +let baking_config_file_arg = + Tezos_clic.arg + ~long:"config-file" + ~placeholder:"baker.json" + ~doc: + "Location of the configuration file for the agnostic baker. Defaults to \ + `/baker.json`." + string_parameter + +let local_baking_mode_arg = + Tezos_clic.arg + ~long:"local" + ~placeholder:"path" + ~doc: + "Set the baking mode of the baker to be local with the provided node \ + directory path" + directory_parameter + +let remote_baking_mode_arg : + (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg = + Tezos_clic.switch + ~long:"remote" + ~doc:"Set the baking mode of the baker to be remote." + () diff --git a/src/lib_agnostic_baker/commands.ml b/src/lib_agnostic_baker/commands.ml index 71973ebb29a373c5511608f91b5b34a31e9c6106..d3f99ca2a60f9cf1acf536b8409168be6a409dd7 100644 --- a/src/lib_agnostic_baker/commands.ml +++ b/src/lib_agnostic_baker/commands.ml @@ -5,67 +5,136 @@ (* *) (*****************************************************************************) +let group = + { + Tezos_clic.name = "delegate.baker"; + title = "Commands related to the agnostic baker daemon"; + } + +let baker_args = + let open Cli in + Tezos_clic.args17 + pidfile_arg + node_version_check_bypass_arg + node_version_allowed_arg + minimal_fees_arg + minimal_nanotez_per_gas_unit_arg + minimal_nanotez_per_byte_arg + force_apply_from_round_arg + keep_alive_arg + liquidity_baking_toggle_vote_arg + adaptive_issuance_vote_arg + 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 + +let config_init_command = + let open Lwt_result_syntax in + let open Cli in + let open Tezos_clic in + command + ~group + ~desc:"Configure the agnostic baker." + (merge_options + (args4 + force_switch + baking_config_file_arg + local_baking_mode_arg + remote_baking_mode_arg) + baker_args) + (prefixes ["config"; "init"; "for"; "keys"] @@ sources_param) + (fun ( (force, baking_config_file, local_baking_mode, remote_baking_mode), + args ) + sources + cctxt -> + let* baking_mode = + Configuration.resolve_baking_mode ~local_baking_mode ~remote_baking_mode + in + let config = + Configuration.Cli.configuration_from_args args baking_mode sources + in + let baking_config_file = + Configuration.config_filename + ~data_dir:(Run_args.get_base_dir @@ Array.to_list Sys.argv) + baking_config_file + in + let* () = Configuration.save ~force ~baking_config_file config in + let*! () = + cctxt#message + "Agnostic baker configuration written in %s" + baking_config_file + in + return_unit) + let run_with_local_node (module Plugin : Protocol_plugin_sig.S) args local_data_dir_path sources cctxt = - let baking_mode = Some local_data_dir_path in - let configuration = Configuration.create_config args in - Plugin.Baker_commands_helpers.run_baker - ~configuration - ~baking_mode - ~sources - ~cctxt + let baking_mode = Configuration.Local {local_data_dir_path} in + let configuration = + Configuration.Cli.configuration_from_args args baking_mode sources + in + Plugin.Baker_commands_helpers.run_baker ~configuration ~cctxt + +let run_with_local_node_command ?plugin () = + let open Cli in + let open Tezos_clic in + command + ~group + ~desc:"Launch the baker daemon." + baker_args + (prefixes ["run"; "with"; "local"; "node"] + @@ param + ~name:"node_data_path" + ~desc:"Path to the node data directory (e.g. $HOME/.tezos-node)" + directory_parameter + @@ sources_param) + (match plugin with + | Some plugin -> run_with_local_node plugin + | None -> fun _ _ _ _ -> Lwt_result_syntax.return_unit) let run_remotely (module Plugin : Protocol_plugin_sig.S) args sources cctxt = - let baking_mode = None in - let configuration = Configuration.create_config args in - Plugin.Baker_commands_helpers.run_baker - ~configuration - ~baking_mode - ~sources - ~cctxt + let baking_mode = Configuration.Remote in + let configuration = + Configuration.Cli.configuration_from_args args baking_mode sources + in + Plugin.Baker_commands_helpers.run_baker ~configuration ~cctxt + +let run_remotely_command ?plugin () = + let open Cli in + let open Tezos_clic in + command + ~group + ~desc:"Launch the baker daemon using RPCs only." + baker_args + (prefixes ["run"; "remotely"] @@ sources_param) + (match plugin with + | Some plugin -> run_remotely plugin + | None -> fun _ _ _ -> Lwt_result_syntax.return_unit) let run_vdf (module Plugin : Protocol_plugin_sig.S) (pidfile, keep_alive) cctxt = - Configuration.may_lock_pidfile pidfile @@ fun () -> + Cli.may_lock_pidfile pidfile @@ fun () -> Plugin.Baker_commands_helpers.run_vdf_daemon ~cctxt ~keep_alive -let baker_commands ?plugin () = - let open Configuration in +let run_vdf_command ?plugin () = + let open Cli in let open Tezos_clic in - let group = - { - name = "delegate.baker"; - title = "Commands related to the agnostic baker daemon."; - } - in + command + ~group + ~desc:"Launch the VDF daemon" + (args2 pidfile_arg keep_alive_arg) + (prefixes ["run"; "vdf"] @@ stop) + (match plugin with + | Some plugin -> run_vdf plugin + | None -> fun _ _ -> Lwt_result_syntax.return_unit) + +let baker_commands ?plugin () = [ - command - ~group - ~desc:"Launch the baker daemon." - baker_args - (prefixes ["run"; "with"; "local"; "node"] - @@ param - ~name:"node_data_path" - ~desc:"Path to the node data directory (e.g. $HOME/.tezos-node)" - directory_parameter - @@ sources_param) - (match plugin with - | Some plugin -> run_with_local_node plugin - | None -> fun _ _ _ _ -> Lwt_result_syntax.return_unit); - command - ~group - ~desc:"Launch the baker daemon using RPCs only." - baker_args - (prefixes ["run"; "remotely"] @@ sources_param) - (match plugin with - | Some plugin -> run_remotely plugin - | None -> fun _ _ _ -> Lwt_result_syntax.return_unit); - command - ~group - ~desc:"Launch the VDF daemon" - (args2 pidfile_arg keep_alive_arg) - (prefixes ["run"; "vdf"] @@ stop) - (match plugin with - | Some plugin -> run_vdf plugin - | None -> fun _ _ -> Lwt_result_syntax.return_unit); + config_init_command; + run_with_local_node_command ?plugin (); + run_remotely_command ?plugin (); + run_vdf_command ?plugin (); ] diff --git a/src/lib_agnostic_baker/commands.mli b/src/lib_agnostic_baker/commands.mli index c81df40406745ef99039e5d478ef56d9b9608445..ded33916227ff76067d2afbc2922b80313fe8f8c 100644 --- a/src/lib_agnostic_baker/commands.mli +++ b/src/lib_agnostic_baker/commands.mli @@ -5,6 +5,13 @@ (* *) (*****************************************************************************) +(** [baker_commands ?plugin ()] returns a list of CLI commands available for + controlling a baker process in the Tezos client context. + + - If [?plugin] is provided, the returned commands are fully functional and use + the protocol-specific baking implementation defined in the plugin. + - If [?plugin] is omitted, the function returns only the command specifications, + which can be used for documentation without actual execution. *) val baker_commands : ?plugin:(module Protocol_plugin_sig.S) -> unit -> diff --git a/src/lib_agnostic_baker/configuration.ml b/src/lib_agnostic_baker/configuration.ml index b627e9a1c31127cda49e33c1949c4c3adaffeb3e..804076e5dac3878bcf6b83fade8dca01d842fdb7 100644 --- a/src/lib_agnostic_baker/configuration.ml +++ b/src/lib_agnostic_baker/configuration.ml @@ -5,365 +5,49 @@ (* *) (*****************************************************************************) -(** This is the module where the type of the CLI arguments configuration is - created. An argument of this type will be passed to the main running - function of the agnostic baker. *) +type baking_mode = Local of {local_data_dir_path : string} | Remote -type error += Block_vote_file_not_found of string +type error += Too_many_baking_nodes -type error += Bad_minimal_fees of string +type error += Missing_baking_mode let () = register_error_kind - `Permanent - ~id:"agnostic_baker.configuration.block_vote_file_not_found" - ~title: - "The provided block vote file path does not point to an existing file." + ~id:"agnostic_baker.too_many_baking_modes" + ~title:"Cannot decide which baking mode to use" ~description: - "A block vote file path was provided on the command line but the path \ - does not point to an existing file." - ~pp:(fun ppf file_path -> - Format.fprintf + "More than one baking mode has been chosen. Please choose exactly one." + ~pp:(fun ppf () -> + Format.pp_print_string ppf - "@[The provided block vote file path \"%s\" does not point to an \ - existing file.@]" - file_path) - Data_encoding.(obj1 (req "file_path" string)) - (function - | Block_vote_file_not_found file_path -> Some file_path | _ -> None) - (fun file_path -> Block_vote_file_not_found file_path) ; + "More than one baking mode has been chosen. Please choose exactly one.") + `Permanent + Data_encoding.empty + (function Too_many_baking_nodes -> Some () | _ -> None) + (fun () -> Too_many_baking_nodes) ; register_error_kind + ~id:"agnostic_baker.missing_baking_mode" + ~title:"No baking mode has been chosen." + ~description: + "No baking mode has been chosen. Please check documentation to choose \ + one." + ~pp:(fun ppf () -> + Format.pp_print_string + ppf + "No baking mode has been chosen. Please check documentation to choose \ + one.") `Permanent - ~id:"agnostic_baker.configuration.badMinimalFeesArg" - ~title:"Bad -minimal-fees arg" - ~description:"invalid fee threshold in -fee-threshold" - ~pp:(fun ppf literal -> - Format.fprintf ppf "invalid minimal fees '%s'" literal) - Data_encoding.(obj1 (req "parameter" string)) - (function Bad_minimal_fees parameter -> Some parameter | _ -> None) - (fun parameter -> Bad_minimal_fees parameter) - -(* Primitive argument parsers *) -let string_parameter = - Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) x -> - Lwt_result.return x) - -let int_parameter = - Tezos_clic.parameter (fun (cctxt : Tezos_client_base.Client_context.full) p -> - try Lwt_result.return (int_of_string p) - with _ -> cctxt#error "Cannot read int") - -let uri_parameter = - Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) x -> - Lwt_result.return (Uri.of_string x)) - -let per_block_vote_parameter = - let open Lwt_result_syntax in - Tezos_clic.parameter - ~autocomplete:(fun _ctxt -> return ["on"; "off"; "pass"]) - (fun (_cctxt : Tezos_client_base.Client_context.full) -> function - | ("on" | "off" | "pass") as s -> return s - | s -> - failwith - "unexpected vote: %s, expected either \"on\", \"off\", or \"pass\"." - s) - -(* Baker arguments *) -let pidfile_arg = - let open Lwt_result_syntax in - Tezos_clic.arg - ~doc:"write process id in file" - ~short:'P' - ~long:"pidfile" - ~placeholder:"filename" - (Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) s -> return s)) - -let may_lock_pidfile pidfile_opt f = - match pidfile_opt with - | None -> f () - | Some pidfile -> - Tezos_stdlib_unix.Lwt_lock_file.with_lock - ~when_locked: - (`Fail (Exn (Failure ("Failed to create the pidfile: " ^ pidfile)))) - ~filename:pidfile - f - -let node_version_check_bypass_arg : - (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg = - Tezos_clic.switch - ~long:"node-version-check-bypass" - ~doc: - "If node-version-check-bypass flag is set, the baker will not check its \ - compatibility with the version of the node to which it is connected." - () - -let node_version_allowed_arg = - Tezos_clic.arg - ~long:"node-version-allowed" - ~placeholder:"-[v].[.0][:]" - ~doc: - "When specified the baker will accept to run with a node of this \ - version. The specified version is composed of the product, for example \ - 'octez'; the major and the minor versions that are positive integers; \ - the info, for example '-rc', '-beta1+dev' or realese if none is \ - provided; optionally the commit that is the hash of the last git commit \ - or a prefix of at least 8 characters long." - string_parameter - -let default_minimal_fees = 100L - -let default_minimal_nanotez_per_gas_unit = Q.of_int 100 - -let default_minimal_nanotez_per_byte = Q.of_int 1000 - -let minimal_fees_arg = - let open Lwt_result_syntax in - Tezos_clic.default_arg - ~long:"minimal-fees" - ~placeholder:"amount" - ~doc:"exclude operations with fees lower than this threshold (in tez)" - ~default:(Int64.to_string default_minimal_fees) - (Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) s -> - match Int64.of_string_opt s with - | Some t -> return t - | None -> tzfail (Bad_minimal_fees s))) - -let minimal_nanotez_per_gas_unit_arg = - let open Lwt_result_syntax in - Tezos_clic.default_arg - ~long:"minimal-nanotez-per-gas-unit" - ~placeholder:"amount" - ~doc: - "exclude operations with fees per gas lower than this threshold (in \ - nanotez)" - ~default:(Q.to_string default_minimal_nanotez_per_gas_unit) - (Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) s -> - try return (Q.of_string s) with _ -> tzfail (Bad_minimal_fees s))) + Data_encoding.empty + (function Missing_baking_mode -> Some () | _ -> None) + (fun () -> Missing_baking_mode) -let minimal_nanotez_per_byte_arg = +let resolve_baking_mode ~local_baking_mode ~remote_baking_mode = let open Lwt_result_syntax in - Tezos_clic.default_arg - ~long:"minimal-nanotez-per-byte" - ~placeholder:"amount" - ~default:(Q.to_string default_minimal_nanotez_per_byte) - ~doc: - "exclude operations with fees per byte lower than this threshold (in \ - nanotez)" - (Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) s -> - try return (Q.of_string s) with _ -> tzfail (Bad_minimal_fees s))) - -let force_apply_from_round_arg = - Tezos_clic.arg - ~long:"force-apply-from-round" - ~placeholder:"round" - ~doc: - "Force the baker to not only validate but also apply operations starting \ - from the specified round." - int_parameter - -let keep_alive_arg : - (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg = - Tezos_clic.switch - ~doc: - "Keep the daemon process alive: when the connection with the node is \ - lost, the daemon periodically tries to reach it." - ~short:'K' - ~long:"keep-alive" - () - -let liquidity_baking_toggle_vote_arg = - Tezos_clic.arg - ~doc: - "Vote to continue or end the liquidity baking subsidy. The possible \ - values for this option are: \"off\" to request ending the subsidy, \ - \"on\" to request continuing or restarting the subsidy, and \"pass\" to \ - abstain. Note that this \"option\" is mandatory!" - ~long:"liquidity-baking-toggle-vote" - ~placeholder:"vote" - per_block_vote_parameter - -let adaptive_issuance_vote_arg = - Tezos_clic.arg - ~doc: - "Vote to adopt or not the adaptive issuance feature. The possible values \ - for this option are: \"off\" to request not activating it, \"on\" to \ - request activating it, and \"pass\" to abstain. If you do not vote, \ - default value is \"pass\"." - ~long:"adaptive-issuance-vote" - ~placeholder:"vote" - per_block_vote_parameter - -let per_block_vote_file_arg = - Tezos_clic.arg - ~doc:"read per block votes as json file" - ~short:'V' - ~long:"votefile" - ~placeholder:"filename" - (Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) file -> - let open Lwt_result_syntax in - let* file_exists = - protect - ~on_error:(fun _ -> tzfail (Block_vote_file_not_found file)) - (fun () -> - let*! b = Lwt_unix.file_exists file in - return b) - in - if file_exists then return file - else tzfail (Block_vote_file_not_found file))) - -let http_headers_env_variable = - "TEZOS_CLIENT_REMOTE_OPERATIONS_POOL_HTTP_HEADERS" - -let http_headers = - match Sys.getenv_opt http_headers_env_variable with - | None -> None - | Some contents -> - let lines = String.split_on_char '\n' contents in - Some - (List.fold_left - (fun acc line -> - match String.index_opt line ':' with - | None -> - invalid_arg - (Printf.sprintf - "Http headers: invalid %s environment variable, missing \ - colon" - http_headers_env_variable) - | Some pos -> - let header = String.trim (String.sub line 0 pos) in - let header = String.lowercase_ascii header in - if header <> "host" then - invalid_arg - (Printf.sprintf - "Http headers: invalid %s environment variable, only \ - 'host' headers are supported" - http_headers_env_variable) ; - let value = - String.trim - (String.sub line (pos + 1) (String.length line - pos - 1)) - in - (header, value) :: acc) - [] - lines) - -let operations_arg = - Tezos_clic.arg - ~long:"operations-pool" - ~placeholder:"file|uri" - ~doc: - (Printf.sprintf - "When specified, the baker will try to fetch operations from this \ - file (or uri) and to include retrieved operations in the block. The \ - expected format of the contents is a list of operations [ \ - alpha.operation ]. Environment variable '%s' may also be specified \ - to add headers to the requests (only 'host' headers are supported). \ - If the resource cannot be retrieved, e.g., if the file is absent, \ - unreadable, or the web service returns a 404 error, the resource is \ - simply ignored." - http_headers_env_variable) - uri_parameter - -let dal_node_endpoint_arg = - Tezos_clic.arg - ~long:"dal-node" - ~placeholder:"uri" - ~doc:"endpoint of the DAL node, e.g. 'http://localhost:8933'" - uri_parameter - -let without_dal_arg : - (bool, Tezos_client_base.Client_context.full) Tezos_clic.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 state_recorder_switch_arg : - (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg = - Tezos_clic.switch - ~long:"record-state" - ~doc: - "If record-state flag is set, the baker saves all its internal consensus \ - state in the filesystem, otherwise just in memory." - () - -let pre_emptive_forge_time_arg = - let open Lwt_result_syntax in - Tezos_clic.arg - ~long:"pre-emptive-forge-time" - ~placeholder:"seconds" - ~doc: - "Sets the pre-emptive forge time optimization, in seconds. When set, the \ - baker, if it is the next level round 0 proposer, will start forging \ - after quorum has been reached in the current level while idly waiting \ - for it to end. When it is its time to propose, the baker will inject \ - the pre-emptively forged block immediately, allowing more time for the \ - network to reach quorum on it. Operators should note that the higher \ - this value `t`, the lower the operation inclusion window (specifically \ - `block_time - t`) which may lead to lower baking rewards. Defaults to \ - 15/% of block time. Set to 0 to ignore pre-emptive forging." - (Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) s -> - try return (Q.of_string s) - with _ -> failwith "pre-emptive-forge-time expected int or float.")) - -let remote_calls_timeout_arg = - let open Lwt_result_syntax in - Tezos_clic.arg - ~long:"remote-calls-timeout" - ~placeholder:"seconds" - ~doc: - "Sets a timeout for client calls such as signing block header or \ - attestation and for the creation of deterministic nonce. Use only if \ - your remote signer can handle concurrent requests." - (Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) s -> - try return (Q.of_string s) - with _ -> failwith "remote-calls-timeout expected int or float.")) - -let baker_args = - Tezos_clic.args17 - pidfile_arg - node_version_check_bypass_arg - node_version_allowed_arg - minimal_fees_arg - minimal_nanotez_per_gas_unit_arg - minimal_nanotez_per_byte_arg - force_apply_from_round_arg - keep_alive_arg - liquidity_baking_toggle_vote_arg - adaptive_issuance_vote_arg - 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 - -let directory_parameter = - let open Lwt_result_syntax in - Tezos_clic.parameter - (fun (_cctxt : Tezos_client_base.Client_context.full) p -> - let*! exists = Tezos_stdlib_unix.Lwt_utils_unix.dir_exists p in - if not exists then failwith "Directory doesn't exist: '%s'" p - else return p) - -let sources_param = - Tezos_clic.seq_of_param - (Tezos_client_base.Client_keys.Public_key_hash.source_param - ~name:"baker" - ~desc: - "name of the delegate owning the attestation/baking right or name of \ - the consensus key signing on the delegate's behalf") + match (local_baking_mode, remote_baking_mode) with + | Some _, true -> tzfail Too_many_baking_nodes + | Some local_data_dir_path, false -> return @@ Local {local_data_dir_path} + | None, true -> return Remote + | None, false -> tzfail Missing_baking_mode type t = { pidfile : string option; @@ -383,43 +67,198 @@ type t = { state_recorder : bool; pre_emptive_forge_time : Q.t option; remote_calls_timeout : Q.t option; + baking_mode : baking_mode; + sources : Signature.public_key_hash list; } -(** Create the configuration from the given arguments. *) -let create_config - ( pidfile, - node_version_check_bypass, - node_version_allowed, - minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - force_apply_from_round, - keep_alive, - liquidity_baking_vote, - adaptive_issuance_vote, - per_block_vote_file, - extra_operations, - dal_node_endpoint, - without_dal, - state_recorder, - pre_emptive_forge_time, - remote_calls_timeout ) = - { - pidfile; - node_version_check_bypass; - node_version_allowed; - minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - force_apply_from_round; - keep_alive; - liquidity_baking_vote; - adaptive_issuance_vote; - per_block_vote_file; - extra_operations; - dal_node_endpoint; - without_dal; - state_recorder; - pre_emptive_forge_time; - remote_calls_timeout; - } +let q_encoding = conv (fun q -> Q.to_string q) (fun s -> Q.of_string s) string + +let baking_mode_encoding : baking_mode Data_encoding.t = + let open Data_encoding in + let remote_case = + case + ~title:"remote" + ~description:"Baker runs in remote baking mode." + (Tag 0) + (constant "remote") + (function Remote -> Some () | _ -> None) + (fun () -> Remote) + in + let local_case = + case + ~title:"local" + ~description:"Baker runs in local baking mode." + (Tag 1) + (obj1 (req "local" (obj1 (req "node-dir" string)))) + (function + | Local {local_data_dir_path} -> Some local_data_dir_path | _ -> None) + (fun local_data_dir_path -> Local {local_data_dir_path}) + in + union [local_case; remote_case] + +let[@warning "-32"] encoding : t Data_encoding.t = + let open Data_encoding in + conv + (fun { + pidfile; + node_version_check_bypass; + node_version_allowed; + minimal_fees; + minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte; + force_apply_from_round; + keep_alive; + liquidity_baking_vote; + adaptive_issuance_vote; + per_block_vote_file; + extra_operations; + dal_node_endpoint; + without_dal; + state_recorder; + pre_emptive_forge_time; + remote_calls_timeout; + baking_mode; + sources; + } -> + ( ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote ), + ( per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout, + baking_mode, + sources ) )) + (fun ( ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote ), + ( per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout, + baking_mode, + sources ) ) -> + { + pidfile; + node_version_check_bypass; + node_version_allowed; + minimal_fees; + minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte; + force_apply_from_round; + keep_alive; + liquidity_baking_vote; + adaptive_issuance_vote; + per_block_vote_file; + extra_operations; + dal_node_endpoint; + without_dal; + state_recorder; + pre_emptive_forge_time; + remote_calls_timeout; + baking_mode; + sources; + }) + (merge_objs + (obj10 + (opt "pidfile" string) + (req "node_version_check_bypass" bool) + (opt "node_version_allowed" string) + (req "minimal_fees" int64) + (req "minimal_nanotez_per_gas_unit" q_encoding) + (req "minimal_nanotez_per_byte" q_encoding) + (opt "force_apply_from_round" int31) + (req "keep_alive" bool) + (opt "liquidity_baking_vote" string) + (opt "adaptive_issuance_vote" string)) + (obj9 + (opt "per_block_vote_file" string) + (opt "extra_operations" Tezos_rpc.Encoding.uri_encoding) + (opt "dal_node_endpoint" Tezos_rpc.Encoding.uri_encoding) + (req "without_dal" bool) + (req "state_recorder" bool) + (opt "pre_emptive_forge_time" q_encoding) + (opt "remote_calls_timeout" q_encoding) + (req "baking_mode" baking_mode_encoding) + (req "sources" (list Signature.Public_key_hash.encoding)))) + +let config_filename ~data_dir = function + | Some path -> path + | None -> Filename.concat data_dir "baker.json" + +let save ~force ~baking_config_file config = + let open Lwt_result_syntax in + let json = Data_encoding.Json.construct encoding config in + let*! exists = Lwt_unix.file_exists baking_config_file in + if exists && not force then + failwith + "Configuration file %S already exists. Use --force to overwrite." + baking_config_file + else + let*! () = + Tezos_stdlib_unix.Lwt_utils_unix.create_dir + (Filename.dirname baking_config_file) + in + Tezos_stdlib_unix.Lwt_utils_unix.Json.write_file baking_config_file json + +module Cli = struct + let configuration_from_args + ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote, + per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout ) baking_mode sources = + { + pidfile; + node_version_check_bypass; + node_version_allowed; + minimal_fees; + minimal_nanotez_per_gas_unit; + minimal_nanotez_per_byte; + force_apply_from_round; + keep_alive; + liquidity_baking_vote; + adaptive_issuance_vote; + per_block_vote_file; + extra_operations; + dal_node_endpoint; + without_dal; + state_recorder; + pre_emptive_forge_time; + remote_calls_timeout; + baking_mode; + sources; + } +end diff --git a/src/lib_agnostic_baker/configuration.mli b/src/lib_agnostic_baker/configuration.mli index 92edf903dab0e7b560a55cb5611817bd15f8eabc..309e5939150a1af6b7b6ba82956dadcca05dd814 100644 --- a/src/lib_agnostic_baker/configuration.mli +++ b/src/lib_agnostic_baker/configuration.mli @@ -5,51 +5,12 @@ (* *) (*****************************************************************************) -val pidfile_arg : - (string option, Tezos_client_base.Client_context.full) Tezos_clic.arg +type baking_mode = Local of {local_data_dir_path : string} | Remote -val may_lock_pidfile : - string option -> - (unit -> 'a Error_monad.tzresult Lwt.t) -> - 'a Error_monad.tzresult Lwt.t - -val keep_alive_arg : - (bool, Tezos_client_base.Client_context.full) Tezos_clic.arg - -val http_headers_env_variable : string - -val http_headers : (string * string) list option - -val baker_args : - ( string option - * bool - * string option - * int64 - * Q.t - * Q.t - * int option - * bool - * string option - * string option - * string option - * Uri.t option - * Uri.t option - * bool - * bool - * Q.t option - * Q.t option, - Tezos_client_base.Client_context.full ) - Tezos_clic.options - -val directory_parameter : - (string, Tezos_client_base.Client_context.full) Tezos_clic.parameter - -val sources_param : - ( Tezos_crypto.Signature.Public_key_hash.t list -> - Tezos_client_base.Client_context.full -> - unit Error_monad.tzresult Lwt.t, - Tezos_client_base.Client_context.full ) - Tezos_clic.params +val resolve_baking_mode : + local_baking_mode:string option -> + remote_baking_mode:bool -> + baking_mode tzresult Lwt.t type t = { pidfile : string option; @@ -69,24 +30,34 @@ type t = { state_recorder : bool; pre_emptive_forge_time : Q.t option; remote_calls_timeout : Q.t option; + baking_mode : baking_mode; + sources : Signature.public_key_hash trace; } -val create_config : - string option - * bool - * string option - * int64 - * Q.t - * Q.t - * int option - * bool - * string option - * string option - * string option - * Uri.t option - * Uri.t option - * bool - * bool - * Q.t option - * Q.t option -> - t +val config_filename : data_dir:string -> string option -> string + +val save : force:bool -> baking_config_file:string -> t -> unit tzresult Lwt.t + +module Cli : sig + val configuration_from_args : + string option + * bool + * string option + * int64 + * Q.t + * Q.t + * int option + * bool + * string option + * string option + * string option + * Uri.t option + * Uri.t option + * bool + * bool + * Q.t option + * Q.t option -> + baking_mode -> + Signature.public_key_hash trace -> + t +end diff --git a/src/lib_agnostic_baker/daemon.ml b/src/lib_agnostic_baker/daemon.ml index 0647353d0e051569dba6782fde78016ef23f233c..0e0a6232660e1441668a9e483198bcfd18d84c55 100644 --- a/src/lib_agnostic_baker/daemon.ml +++ b/src/lib_agnostic_baker/daemon.ml @@ -6,6 +6,9 @@ (* *) (*****************************************************************************) +open Agnostic_baker_errors +module Events = Agnostic_baker_events + module Profiler = struct include (val Profiler.wrap Agnostic_baker_profiler.agnostic_baker_profiler) @@ -14,29 +17,30 @@ module Profiler = struct Agnostic_baker_profiler.agnostic_baker_profiler end -open Agnostic_baker_errors - -(* Number of extra levels to keep the old baker alive before shutting it down. - This extra time is used to avoid halting the chain in cases such as - reorganization or high round migration blocks. *) -let extra_levels_for_old_baker = 3 - type process = {thread : int Lwt.t; canceller : int Lwt.u} type baker = {protocol_hash : Protocol_hash.t; process : process} -(** [run_thread ~protocol_hash ~baker_commands ~cancel_promise ~logs_path] - returns the main running thread for the baker given its protocol [~procol_hash], - corresponding commands [~baker_commands] and Lwt cancellation promise [~cancel_promise]. +type baker_to_kill = {baker : baker; level_to_kill : int} + +type state = { + node_endpoint : string; + mutable current_baker : baker option; + mutable old_baker : baker_to_kill option; +} - The event logs are stored according to [~logs_path]. *) -let run_thread ~protocol_hash ~baker_commands ~cancel_promise ~logs_path = +type t = state + +(* ---- Baker Process Management ---- *) + +(** [run_thread ~protocol_hash ~baker_commands ~cancel_promise] + returns the main running thread for the baker given its protocol [~protocol_hash], + corresponding commands [~baker_commands] and cancellation [~cancel_promise]. *) +let run_thread ~protocol_hash ~baker_commands ~cancel_promise = let () = Client_commands.register protocol_hash @@ fun _network -> baker_commands in - let select_commands _ _ = Lwt_result_syntax.return baker_commands in - (* This call is not strictly necessary as the parameters are initialized lazily the first time a Sapling operation (validation or forging) is done. This is what the client does. @@ -46,16 +50,11 @@ let run_thread ~protocol_hash ~baker_commands ~cancel_promise ~logs_path = validation will not be more expensive. *) let () = Tezos_sapling.Core.Validator.init_params () in - let module Config = struct - include Daemon_config - - let default_daily_logs_path = logs_path - end in Lwt.pick [ Client_main_run.lwt_run - (module Config) - ~select_commands + (module Agnostic_baker_config) + ~select_commands:(fun _ _ -> Lwt_result_syntax.return baker_commands) (* The underlying logging from the baker must not be initialised, otherwise we double log. *) ~disable_logging:true (); @@ -65,7 +64,7 @@ let run_thread ~protocol_hash ~baker_commands ~cancel_promise ~logs_path = (** [spawn_baker protocol_hash] spawns a new baker process for the given [protocol_hash]. *) let spawn_baker protocol_hash = let open Lwt_result_syntax in - let*! () = Agnostic_baker_events.(emit starting_baker) protocol_hash in + let*! () = Events.(emit starting_baker) protocol_hash in let cancel_promise, canceller = Lwt.wait () in let* thread = let*? plugin = @@ -74,53 +73,11 @@ let spawn_baker protocol_hash = [@profiler.record_f {verbosity = Notice} "proto_plugin_for_protocol"]) in let baker_commands = Commands.baker_commands ~plugin () in - return - @@ run_thread - ~protocol_hash - ~baker_commands - ~cancel_promise - ~logs_path:Parameters.default_daily_logs_path + return @@ run_thread ~protocol_hash ~baker_commands ~cancel_promise in - let*! () = Agnostic_baker_events.(emit baker_running) protocol_hash in + let*! () = Events.(emit baker_running) protocol_hash in return {protocol_hash; process = {thread; canceller}} -type baker_to_kill = {baker : baker; level_to_kill : int} - -type 'a state = { - node_endpoint : string; - mutable current_baker : baker option; - mutable old_baker : baker_to_kill option; -} - -type 'a t = 'a state - -(** [monitor_heads ~node_addr] creates a stream which returns the data - of the heads of the current network; this information is received - from the RPC calls at the endpoint given by [~node_addr]. *) -let monitor_heads ~node_addr = - let open Lwt_result_syntax in - let uri = Format.sprintf "%s/monitor/heads/main" node_addr in - let* _, body = Rpc_services.request_uri ~node_addr ~uri in - let cohttp_stream = Cohttp_lwt.Body.to_stream body in - let buffer = Buffer.create 2048 in - let stream, push = Lwt_stream.create () in - let on_chunk v = push (Some v) and on_close () = push None in - let rec loop () = - let*! v = Lwt_stream.get cohttp_stream in - match v with - | None -> - on_close () ; - Lwt.return_unit - | Some chunk -> - Buffer.add_string buffer chunk ; - let data = Buffer.contents buffer in - Buffer.reset buffer ; - on_chunk data ; - loop () - in - ignore (loop () : unit Lwt.t) ; - return stream - (** [hot_swap_baker ~state ~current_protocol_hash ~next_protocol_hash ~level_to_kill_old_baker] moves the current baker into the old baker slot (to be killed later) and spawns a new baker for [~next_protocol_hash] *) @@ -134,11 +91,10 @@ let hot_swap_baker ~state ~current_protocol_hash ~next_protocol_hash in let next_proto_status = Parameters.protocol_status next_protocol_hash in let*! () = - Agnostic_baker_events.(emit protocol_encountered) - (next_proto_status, next_protocol_hash) + Events.(emit protocol_encountered) (next_proto_status, next_protocol_hash) in let*! () = - Agnostic_baker_events.(emit become_old_baker) + Events.(emit become_old_baker) (current_protocol_hash, level_to_kill_old_baker) in state.old_baker <- @@ -161,9 +117,7 @@ let maybe_kill_old_baker state node_addr = ~node_addr [@profiler.record_s {verbosity = Notice} "get_level"]) in if head_level >= level_to_kill then ( - let*! () = - Agnostic_baker_events.(emit stopping_baker) baker.protocol_hash - in + let*! () = Events.(emit stopping_baker) baker.protocol_hash in Lwt.wakeup baker.process.canceller 0 [@profiler.record_f {verbosity = Notice} "kill old baker"] ; @@ -171,6 +125,35 @@ let maybe_kill_old_baker state node_addr = return_unit) else return_unit +(* ---- Baker and Chain Monitoring ---- *) + +(** [monitor_heads ~node_addr] creates a stream which returns the data + of the heads of the current network; this information is received + from the RPC calls at the endpoint given by [~node_addr]. *) +let monitor_heads ~node_addr = + let open Lwt_result_syntax in + let uri = Format.sprintf "%s/monitor/heads/main" node_addr in + let* _, body = Rpc_services.request_uri ~node_addr ~uri in + let cohttp_stream = Cohttp_lwt.Body.to_stream body in + let buffer = Buffer.create 2048 in + let stream, push = Lwt_stream.create () in + let on_chunk v = push (Some v) and on_close () = push None in + let rec loop () = + let*! v = Lwt_stream.get cohttp_stream in + match v with + | None -> + on_close () ; + Lwt.return_unit + | Some chunk -> + Buffer.add_string buffer chunk ; + let data = Buffer.contents buffer in + Buffer.reset buffer ; + on_chunk data ; + loop () + in + ignore (loop () : unit Lwt.t) ; + return stream + (** [monitor_voting_periods ~state head_stream] continuously monitors [heads_stream] to detect protocol changes. It will: - Shut down an old baker it its time has come; @@ -197,8 +180,7 @@ let monitor_voting_periods ~state head_stream = [@profiler.record_s {verbosity = Notice} "get_current_period"]) in let*! () = - Agnostic_baker_events.(emit period_status) - (block_hash, period_kind, remaining) + Events.(emit period_status) (block_hash, period_kind, remaining) in let* () = (maybe_kill_old_baker @@ -228,7 +210,8 @@ let monitor_voting_periods ~state head_stream = ~state ~current_protocol_hash ~next_protocol_hash - ~level_to_kill_old_baker:(head_level + extra_levels_for_old_baker) + ~level_to_kill_old_baker: + (head_level + Parameters.extra_levels_for_old_baker) [@profiler.record_s {verbosity = Notice} "hot_swap_baker"]) else return_unit in @@ -247,12 +230,14 @@ let baker_thread ~state = in if retcode = 0 then return_unit else tzfail Baker_process_error +(* ---- Agnostic Baker Bootstrap ---- *) + (** [may_start_initial_baker state] recursively waits for an [active] protocol and spawns a baker for it. If the protocol is [frozen] (not [active] anymore), it waits for a head with an [active] protocol. *) let may_start_initial_baker state = let open Lwt_result_syntax in - let*! () = Agnostic_baker_events.(emit experimental_binary) () in + let*! () = Events.(emit experimental_binary) () in let rec may_start ?last_known_proto ~head_stream () = let* protocol_hash = Rpc_services.get_next_protocol_hash ~node_addr:state.node_endpoint @@ -263,8 +248,7 @@ let may_start_initial_baker state = | None -> Lwt.return_unit | Some h -> if not (Protocol_hash.equal h protocol_hash) then - Agnostic_baker_events.(emit protocol_encountered) - (proto_status, protocol_hash) + Events.(emit protocol_encountered) (proto_status, protocol_hash) else Lwt.return_unit in match proto_status with @@ -278,12 +262,9 @@ let may_start_initial_baker state = | Some v -> return v | None -> let*! () = - Agnostic_baker_events.(emit protocol_encountered) - (proto_status, protocol_hash) - in - let*! () = - Agnostic_baker_events.(emit waiting_for_active_protocol) () + Events.(emit protocol_encountered) (proto_status, protocol_hash) in + let*! () = Events.(emit waiting_for_active_protocol) () in monitor_heads ~node_addr:state.node_endpoint in let*! v = Lwt_stream.get head_stream in @@ -303,10 +284,10 @@ let create ~node_endpoint = let run state = let open Lwt_result_syntax in let node_addr = state.node_endpoint in - let*! () = Agnostic_baker_events.(emit starting_daemon) () in + let*! () = Events.(emit starting_daemon) () in let _ccid = Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _ -> - let*! () = Agnostic_baker_events.(emit stopping_daemon) () in + let*! () = Events.(emit stopping_daemon) () in Lwt.return_unit) in let* () = may_start_initial_baker state in diff --git a/src/lib_agnostic_baker/daemon.mli b/src/lib_agnostic_baker/daemon.mli index 618a7547cd7fc15643ae0d913cd61ca05a8da8e1..bbc1bfabd2156b082de52ab1e4a410c9e2727419 100644 --- a/src/lib_agnostic_baker/daemon.mli +++ b/src/lib_agnostic_baker/daemon.mli @@ -9,7 +9,7 @@ (** Daemon handling the baker's life cycle. It is used to [create] and [run] a protocol-agnostic process which uses the existing - baking binaries in an adaptive way, depending on the current protocol obtained + baking processes in an adaptive way, depending on the current protocol obtained from the chain. It relies on a [state] which contains the [endpoint] to contact the running node, @@ -18,14 +18,14 @@ To do so, it also spawns a "monitoring" process which follows the heads of the chain, as reported by the node from the [state], more precisely which monitors the voting period. By doing that, it decides when to swap to a different baking - binary. + process. *) -type 'a t +type t (** [create ~node_endpoint] returns a non initialized daemon. *) -val create : node_endpoint:string -> 'a t +val create : node_endpoint:string -> t -(** [run t] Runs the daemon responsible for the spawn/stop of the +(** [run daemon] Runs the daemon responsible for the spawn/stop of the baker daemons. *) -val run : 'a t -> unit tzresult Lwt.t +val run : t -> unit tzresult Lwt.t diff --git a/src/lib_agnostic_baker/parameters.ml b/src/lib_agnostic_baker/parameters.ml index 7e67520deb12099891ed01bc0b3d712f8f64af1d..3dafdfffd569c2064c7d01e63522a40b911910a8 100644 --- a/src/lib_agnostic_baker/parameters.ml +++ b/src/lib_agnostic_baker/parameters.ml @@ -6,6 +6,8 @@ (* *) (*****************************************************************************) +(* Default parameter values *) + let default_node_endpoint = Format.sprintf "http://localhost:%d" @@ -13,15 +15,9 @@ let default_node_endpoint = let default_daily_logs_path = Some "octez-experimental-agnostic-baker" -let log_config ~base_dir = - let daily_logs_path = - default_daily_logs_path - |> Option.map Filename.Infix.(fun logdir -> base_dir // "logs" // logdir) - in - Tezos_base_unix.Internal_event_unix.make_with_defaults - ?enable_default_daily_logs_at:daily_logs_path - ~log_cfg:Tezos_base_unix.Logs_simple_config.default_cfg - () +let extra_levels_for_old_baker = 3 + +(* Protocol status *) type status = Active | Frozen @@ -42,9 +38,7 @@ let status_encoding = [ case ~title:"active" - ~description: - "Active protocols are currently used on a network, and thus, they \ - have dedicated delegate binaries." + ~description:"Active protocols are currently used on a network." (Tag 0) (constant "active") (function Active -> Some () | _ -> None) @@ -52,48 +46,54 @@ let status_encoding = case ~title:"frozen" ~description: - "Frozen protocols are currently unused on any network, and thus, \ - they do not have dedicated delegate binaries." + "Frozen protocols are not currently used on any network." (Tag 1) (constant "frozen") (function Frozen -> Some () | _ -> None) (fun () -> Frozen); ]) -(* From Manifest/Product_octez/Protocol*) -let protocol_info = function - | ( "ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im" - | "Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P" - | "PtCJ7pwoxe8JasnHY8YonnLYjcVHmhiARPJvqcC6VfHT5s8k8sY" - | "PsYLVpVvgbLhAhoqAkMFUo6gudkJ9weNXhUYCiLDzcUpFpkk8Wt" - | "PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP" - | "Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd" - | "PsBABY5HQTSkA4297zNHfsZNKtxULfL18y95qb3m53QJiXGmrbU" - | "PsBabyM1eUXZseaJdmXFApDSBqj8YBfwELoxZHHW77EMcAbbwAS" - | "PsCARTHAGazKbHtnKfLzQg3kms52kSRpgnDY982a9oYsSXRLQEb" - | "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo" - | "PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq" - | "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA" - | "PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i" - | "PtGRANADsDU8R9daYKAgWnQYAJ64omN1o3KMGVCykShA97vQbvV" - | "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx" - | "Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A" - | "PtJakart2xVj7pYXJBXrqHgd82rdkLey5ZeeGwDgPp9rhQUbSqY" - | "PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg" - | "PtLimaPtLMwfNinJi9rCfDPWea8dFgTZ1MeJ9f1m2SRic6ayiwW" - | "PtMumbai2TmsJHNGRkD8v8YDbtao7BLUC3wjASn1inAKLFCjaH1" - | "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf" - | "ProxfordYmVfjWnRcgjWH36fW6PArwqykTFzotUxRs6gmTcZDuH" - | "PtParisBxoLz5gzMmn3d9WBQNoPSZakgnkMC2VNuQ3KXfUtUQeZ" ) as full_hash -> - (String.sub full_hash 0 8, Frozen) - | ( "PsParisCZo7KAh1Z1smVd9ZMZ1HHn5gkzbM94V3PLCpknFWhUAi" - | "PsQuebecnLByd3JwTiGadoG4nGWi3HYiLXUjkibeFV8dCFeVMUg" ) as full_hash -> - (String.sub full_hash 0 8, Active) - | "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK" -> ("alpha", Active) - | "PsRiotumaAMotcRoDWW1bysEhQy2n1M5fy8JgRp8jjRfHGmfeA7" as full_hash -> - (String.sub full_hash 0 8, Active) - | _ -> (*We assume that unmatched protocols are next ones*) ("next", Active) +(** Lists of known protocol hashes for [Frozen] and [Active] protocols, corresponding + to [Manifest/Product_octez/Protocol] module. *) +let frozen_protocols = + [ + "ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im"; + "Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P"; + "PtCJ7pwoxe8JasnHY8YonnLYjcVHmhiARPJvqcC6VfHT5s8k8sY"; + "PsYLVpVvgbLhAhoqAkMFUo6gudkJ9weNXhUYCiLDzcUpFpkk8Wt"; + "PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP"; + "Pt24m4xiPbLDhVgVfABUjirbmda3yohdN82Sp9FeuAXJ4eV9otd"; + "PsBABY5HQTSkA4297zNHfsZNKtxULfL18y95qb3m53QJiXGmrbU"; + "PsBabyM1eUXZseaJdmXFApDSBqj8YBfwELoxZHHW77EMcAbbwAS"; + "PsCARTHAGazKbHtnKfLzQg3kms52kSRpgnDY982a9oYsSXRLQEb"; + "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo"; + "PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq"; + "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA"; + "PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i"; + "PtGRANADsDU8R9daYKAgWnQYAJ64omN1o3KMGVCykShA97vQbvV"; + "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx"; + "Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A"; + "PtJakart2xVj7pYXJBXrqHgd82rdkLey5ZeeGwDgPp9rhQUbSqY"; + "PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg"; + "PtLimaPtLMwfNinJi9rCfDPWea8dFgTZ1MeJ9f1m2SRic6ayiwW"; + "PtMumbai2TmsJHNGRkD8v8YDbtao7BLUC3wjASn1inAKLFCjaH1"; + "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf"; + "ProxfordYmVfjWnRcgjWH36fW6PArwqykTFzotUxRs6gmTcZDuH"; + "PtParisBxoLz5gzMmn3d9WBQNoPSZakgnkMC2VNuQ3KXfUtUQeZ"; + "PsParisCZo7KAh1Z1smVd9ZMZ1HHn5gkzbM94V3PLCpknFWhUAi"; + ] -let protocol_short_hash h = fst (protocol_info (Protocol_hash.to_b58check h)) +(** If this list format is modified, subsequent modifications must be carried onto + the agnostic baker section from [scripts/proto_manager.sh]. *) +let active_protocols = + [ + "PsQuebecnLByd3JwTiGadoG4nGWi3HYiLXUjkibeFV8dCFeVMUg"; + "PsRiotumaAMotcRoDWW1bysEhQy2n1M5fy8JgRp8jjRfHGmfeA7"; + "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK"; + ] -let protocol_status h = snd (protocol_info (Protocol_hash.to_b58check h)) +let protocol_status proto_hash = + match Protocol_hash.to_b58check proto_hash with + | hash when List.mem ~equal:String.equal hash active_protocols -> Active + | hash when List.mem ~equal:String.equal hash frozen_protocols -> Frozen + | _ -> (* We assume that unmatched protocols are "next" ones *) Active diff --git a/src/lib_agnostic_baker/parameters.mli b/src/lib_agnostic_baker/parameters.mli index 79f7c870b15427fbc491dc6ba16bd0b3c17686ec..6c14efc8c06aa68f5eb9abb6a546364c7c4a0662 100644 --- a/src/lib_agnostic_baker/parameters.mli +++ b/src/lib_agnostic_baker/parameters.mli @@ -13,12 +13,14 @@ val default_node_endpoint : string (** Default logs path for the agnostic baker. *) val default_daily_logs_path : string option -val log_config : base_dir:string -> Tezos_base.Internal_event_config.t +(** Number of extra levels to keep the old baker alive before shutting it down. + This extra time is used to avoid halting the chain in cases such as + reorganization or high round migration blocks. *) +val extra_levels_for_old_baker : int -(** Status of a protocol, based on Manifest/Product_octez/Protocol. A - protocol is considered as [Active] while it is running on a network, - and thus, have dedicated binaries. Otherwise, the protocol is - [Frozen] as not running anymore and no associated binaries. +(** Status of a protocol, based on [Manifest/Product_octez/Protocol]. A + protocol is considered as [Active] while it is running on a network. + Otherwise, the protocol is [Frozen]. Warning, it is needed to update status for each new protocol added. *) @@ -28,6 +30,6 @@ val pp_status : Format.formatter -> status -> unit val status_encoding : status t -val protocol_short_hash : Protocol_hash.t -> string - +(** [protocol_status proto_hash] returns whether the given [proto_hash] is + [Active] or [Frozen]. *) val protocol_status : Protocol_hash.t -> status diff --git a/src/lib_agnostic_baker/protocol_plugin_sig.ml b/src/lib_agnostic_baker/protocol_plugin_sig.ml index a2f73794b821ed9a2de82e73ccfa6a7004bb4c29..f37746d860b52e445bba6d8265e6710ceec035bc 100644 --- a/src/lib_agnostic_baker/protocol_plugin_sig.ml +++ b/src/lib_agnostic_baker/protocol_plugin_sig.ml @@ -9,16 +9,13 @@ module type BAKER_COMMANDS_HELPERS = sig (** [run_baker ~configuration ~baking_mode ~sources ~cctxt] is the main running function signature that all protocol plugins will need to implement. It requires the [~configuration] which contains all the possible CLI arguments - for the agnostic baker, together with a [~baking_mode] argument and delegates - list given by [~sources] in the client context [~cctxt]. + for the agnostic baker in the client context [~cctxt]. Depending on the protocol, the arguments can be transformed in the corresponding plugin, but the structure of the list of arguments will not grow or shrink, to prevent incompatibilities at migrations. *) val run_baker : configuration:Configuration.t -> - baking_mode:string option -> - sources:Tezos_crypto.Signature.public_key_hash list -> cctxt:Tezos_client_base.Client_context.full -> unit Error_monad.tzresult Lwt.t diff --git a/src/lib_agnostic_baker/rpc_services.ml b/src/lib_agnostic_baker/rpc_services.ml index c2415fc5cbc18fd4e3d38a13f3f3d0fb7233b248..e959b25d910613c4e2c9ba9429f40a35100f288c 100644 --- a/src/lib_agnostic_baker/rpc_services.ml +++ b/src/lib_agnostic_baker/rpc_services.ml @@ -2,18 +2,21 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) open Cohttp_lwt_unix open Agnostic_baker_errors +(* RPC helper functions *) + let request_uri ~node_addr ~uri = let open Lwt_result_syntax in Lwt.catch (fun () -> - let*! r = Client.get (Uri.of_string uri) in - return r) + let*! resp = Client.get (Uri.of_string uri) in + return resp) (function | Unix.(Unix_error (ECONNREFUSED, _, _)) -> tzfail (Cannot_connect_to_node node_addr) @@ -43,103 +46,60 @@ let call_and_wrap_rpc ~node_addr ~uri ~f = in raise Not_found -let get_level ~node_addr = +(* Field extraction helpers *) + +(** [get_field ~name json] extracts the field [~name] from the JSON object [json]. + It fails if [json] is not an object or if the field is missing. *) +let get_field ~name = let open Lwt_result_syntax in - let f json = - (* Level field in the RPC result *) - let name = "level" in - let* v = - match json with - | `O fields -> ( - match List.assoc_opt ~equal:( = ) name fields with - | None -> tzfail (Cannot_decode_node_data ("missing field " ^ name)) - | Some node -> return node) - | _ -> tzfail (Cannot_decode_node_data "not an object") - in - let level = Ezjsonm.get_int v in - return level - in + function + | `O fields -> ( + match List.assoc_opt ~equal:( = ) name fields with + | None -> tzfail (Cannot_decode_node_data ("missing field " ^ name)) + | Some v -> return v) + | _ -> tzfail (Cannot_decode_node_data "not an object") + +(** [get_int_field ~name json] extracts an integer field named [~name] from [json]. *) +let get_int_field ~name json = + let open Lwt_result_syntax in + let+ v = get_field ~name json in + Ezjsonm.get_int v + +(** [get_string_field ~name json] extracts a string field named [~name] from [json]. *) +let get_string_field ~name json = + let open Lwt_result_syntax in + let+ v = get_field ~name json in + Ezjsonm.get_string v + +(* RPC specific functions *) + +let get_level ~node_addr = let uri = Format.sprintf "%s/chains/main/blocks/head/header/shell" node_addr in - call_and_wrap_rpc ~node_addr ~uri ~f + call_and_wrap_rpc ~node_addr ~uri ~f:(get_int_field ~name:"level") let get_block_hash ~node_addr = let open Lwt_result_syntax in - let f json = - (* Hash field in the RPC result *) - let name = "hash" in - let* v = - match json with - | `O fields -> ( - match List.assoc_opt ~equal:( = ) name fields with - | None -> tzfail (Cannot_decode_node_data ("missing field " ^ name)) - | Some node -> return node) - | _ -> tzfail (Cannot_decode_node_data "not an object") - in - let block_hash = Block_hash.of_b58check_exn @@ Ezjsonm.get_string v in - return block_hash - in let uri = Format.sprintf "%s/chains/main/blocks/head/header" node_addr in - call_and_wrap_rpc ~node_addr ~uri ~f + call_and_wrap_rpc ~node_addr ~uri ~f:(fun json -> + let+ block_hash = get_string_field ~name:"hash" json in + Block_hash.of_b58check_exn block_hash) let get_next_protocol_hash ~node_addr = let open Lwt_result_syntax in - let f json = - (* Next_protocol hash field in the RPC result *) - let name = "next_protocol" in - let* v = - match json with - | `O fields -> ( - match List.assoc_opt ~equal:( = ) name fields with - | None -> tzfail (Cannot_decode_node_data ("missing field " ^ name)) - | Some node -> return node) - | _ -> tzfail (Cannot_decode_node_data "not an object") - in - let hash = Protocol_hash.of_b58check_exn (Ezjsonm.get_string v) in - return hash - in let uri = Format.sprintf "%s/chains/main/blocks/head/metadata" node_addr in - call_and_wrap_rpc ~node_addr ~uri ~f + call_and_wrap_rpc ~node_addr ~uri ~f:(fun json -> + let+ next_protocol = get_string_field ~name:"next_protocol" json in + Protocol_hash.of_b58check_exn next_protocol) let get_current_period ~node_addr = let open Lwt_result_syntax in - let voting_period_field = "voting_period" in - let kind_field = "kind" in - let remaining_field = "remaining" in - let f json = - let* kind = - match json with - | `O fields -> ( - match List.assoc_opt ~equal:( = ) voting_period_field fields with - | None -> - tzfail - (Cannot_decode_node_data ("missing field " ^ voting_period_field)) - | Some node -> ( - match node with - | `O fields -> ( - match List.assoc_opt ~equal:( = ) kind_field fields with - | None -> - tzfail - (Cannot_decode_node_data - ("missing field " ^ voting_period_field)) - | Some node -> return @@ Ezjsonm.get_string node) - | _ -> tzfail (Cannot_decode_node_data "not an object"))) - | _ -> tzfail (Cannot_decode_node_data "not an object") - in - let* remaining = - match json with - | `O fields -> ( - match List.assoc_opt ~equal:( = ) remaining_field fields with - | None -> - tzfail - (Cannot_decode_node_data ("missing field " ^ remaining_field)) - | Some node -> return @@ Ezjsonm.get_int node) - | _ -> tzfail (Cannot_decode_node_data "not an object") - in - return (kind, remaining) - in let uri = Format.sprintf "%s/chains/main/blocks/head/votes/current_period" node_addr in - call_and_wrap_rpc ~node_addr ~uri ~f + call_and_wrap_rpc ~node_addr ~uri ~f:(fun json -> + let* voting_period = get_field ~name:"voting_period" json in + let* kind = get_string_field ~name:"kind" voting_period in + let+ remaining = get_int_field ~name:"remaining" json in + (kind, remaining)) diff --git a/src/lib_agnostic_baker/rpc_services.mli b/src/lib_agnostic_baker/rpc_services.mli index 904ac48456d98d3bd02bef10fedc3b96ab3eb2bc..b8e1acb6a995cb19b8bb95fa1a43f065a749f9da 100644 --- a/src/lib_agnostic_baker/rpc_services.mli +++ b/src/lib_agnostic_baker/rpc_services.mli @@ -2,30 +2,34 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) -(** [request_uri ~node_addr ~uri] is a raw call that will return the - Cohttp response of an RPC call, given a [~uri], against the - [~node_addr]. *) +(** [request_uri ~node_addr ~uri] issues an HTTP [GET] request to the [~uri] and + returns the response and its body. In case the connection is refused, + it fails with a connection error on [~node_addr]. *) val request_uri : node_addr:string -> uri:string -> (Cohttp_lwt_unix.Response.t * Cohttp_lwt.Body.t) tzresult Lwt.t -(** [get_level ~node_addr] returns the level of the block. *) +(** [get_level ~node_addr] retrieves the current block level from the node at + [~node_addr]. *) val get_level : node_addr:string -> (int, error trace) result Lwt.t -(** [get_level ~node_addr] returns the hash of the block. *) +(** [get_block_hash ~node_addr] retrieves the hash of the current block from the node + at [~node_addr]. *) val get_block_hash : node_addr:string -> (Block_hash.t, error trace) result Lwt.t -(** [get_next_protocol_hash ~node_addr] returns the protocol hash - contained in the [next_protocol] field of the metadata of a - block. *) +(** [get_next_protocol_hash ~node_addr] retrieves the protocol hash from the [next_protocol] + field in the metadata of the current block, as seen by the node at [~node_addr]. *) val get_next_protocol_hash : node_addr:string -> Protocol_hash.t tzresult Lwt.t -(** [get_current_period ~node_addr] returns the current voting - period in addition to the number of remaining blocks until the end - of the period. *) +(** [get_current_period ~node_addr] retrieves the current voting period information + from the node at [~node_addr]. It returns a pair [(kind, remaining)] where: + - [kind] is a string representing the voting period kind, and + - [remaining] is the number of blocks remaining until the end of the voting period. *) + val get_current_period : node_addr:string -> (string * int) tzresult Lwt.t diff --git a/src/lib_agnostic_baker/run_args.ml b/src/lib_agnostic_baker/run_args.ml index c9e53a8298319a257e38b0d2ea979f8c867333a8..5bf2dcc372b9e028b692561f06074e64226bdd54 100644 --- a/src/lib_agnostic_baker/run_args.ml +++ b/src/lib_agnostic_baker/run_args.ml @@ -43,4 +43,6 @@ let get_endpoint args = Option.value ~default:Parameters.default_node_endpoint @@ get_arg_value ~arg:endpoint_arg ~short_arg:endpoint_short_arg args -let get_base_dir = get_arg_value ~arg:base_dir_arg ~short_arg:base_dir_short_arg +let get_base_dir args = + Option.value ~default:Agnostic_baker_config.default_base_dir + @@ get_arg_value ~arg:base_dir_arg ~short_arg:base_dir_short_arg args diff --git a/src/lib_agnostic_baker/run_args.mli b/src/lib_agnostic_baker/run_args.mli index 8483915b1e8592d7a9dd42ddcfbf398026fb6a9b..d613a32ae4151698c1c078581b2725aac4000cdf 100644 --- a/src/lib_agnostic_baker/run_args.mli +++ b/src/lib_agnostic_baker/run_args.mli @@ -19,6 +19,6 @@ val is_man_cmd : string list -> bool amongst [args], and in its absence using the default node RPC port. *) val get_endpoint : string list -> string -(** [get_base_dir] returns the value associated to the [--base-dir] argument - amonsgst [args]. *) -val get_base_dir : string list -> string option +(** [get_base_dir args] returns the value associated to the [--base-dir] argument + amongst [args]. *) +val get_base_dir : string list -> string diff --git a/src/lib_client_base_unix/client_main_run.ml b/src/lib_client_base_unix/client_main_run.ml index d0b5af5c01913763fefb8ec84d7a4540f2d6b8d3..57c1115e5888e08f0e5aeae851c160fb92b9f323 100644 --- a/src/lib_client_base_unix/client_main_run.ml +++ b/src/lib_client_base_unix/client_main_run.ml @@ -419,6 +419,35 @@ let warn_if_argv0_name_not_octez () = expected_name executable_name +let init_logging (module C : M) ?(parsed_args : Client_config.cli_args option) + ?parsed_config_file ~base_dir () = + let open Tezos_base_unix.Internal_event_unix in + let daily_logs_path = + C.default_daily_logs_path + |> Option.map Filename.Infix.(fun logdir -> base_dir // "logs" // logdir) + in + (* Update config with color logging switch and advertise levels *) + let log_cfg = + let colors = + match parsed_args with + | None -> None + | Some parsed_args -> parsed_args.log_coloring + in + Tezos_base_unix.Logs_simple_config.create_cfg + ?advertise_levels:C.advertise_log_levels + ?colors + () + in + let config = + make_with_defaults ?enable_default_daily_logs_at:daily_logs_path ~log_cfg () + in + match parsed_config_file with + | None -> init ~config () + | Some cf -> ( + match cf.Client_config.Cfg_file.internal_events with + | None -> init ~config () + | Some config -> init ~config ()) + (* Main (lwt) entry *) let main (module C : M) ~select_commands ?(disable_logging = false) () = let open Lwt_result_syntax in @@ -481,36 +510,12 @@ let main (module C : M) ~select_commands ?(disable_logging = false) () = let*! () = if disable_logging then Lwt.return_unit else - let open Tezos_base_unix.Internal_event_unix in - let daily_logs_path = - C.default_daily_logs_path - |> Option.map - Filename.Infix.(fun logdir -> base_dir // "logs" // logdir) - in - (* Update config with color logging switch and advertise levels *) - let log_cfg = - let colors = - match parsed_args with - | None -> None - | Some parsed_args -> parsed_args.log_coloring - in - Tezos_base_unix.Logs_simple_config.create_cfg - ?advertise_levels:C.advertise_log_levels - ?colors - () - in - let config = - make_with_defaults - ?enable_default_daily_logs_at:daily_logs_path - ~log_cfg - () - in - match parsed_config_file with - | None -> init ~config () - | Some cf -> ( - match cf.Client_config.Cfg_file.internal_events with - | None -> init ~config () - | Some config -> init ~config ()) + init_logging + (module C) + ?parsed_args + ?parsed_config_file + ~base_dir + () in let rpc_config = let rpc_config : RPC_client_unix.config = diff --git a/src/lib_client_base_unix/client_main_run.mli b/src/lib_client_base_unix/client_main_run.mli index 33ac0a77d4b69a3758d0a9b2de7769a13d36f77d..4848e81b35d4637f41031d15b5cdf491f78ac12d 100644 --- a/src/lib_client_base_unix/client_main_run.mli +++ b/src/lib_client_base_unix/client_main_run.mli @@ -95,6 +95,18 @@ val register_default_signer : Client_context.io_wallet -> unit +(** [init_logging (module M) ?parsed_args ?parsed_config_file ~base_dir ()] + starts the logging process based on optional parsed arguments [?parse_args], + optional configuration file [?parsed_config_file], with output in the + [~base_dir] directory. *) +val init_logging : + (module M) -> + ?parsed_args:Client_config.cli_args -> + ?parsed_config_file:Client_config.Cfg_file.t -> + base_dir:string -> + unit -> + unit Lwt.t + val run : (module M) -> select_commands: diff --git a/src/proto_021_PsQuebec/lib_agnostic_baker/baker_args_parser.ml b/src/proto_021_PsQuebec/lib_agnostic_baker/baker_args_parser.ml index 764f7803957a129ff4aa855a8007458ecc8acef8..a5093e4b691fbef801edd10322cfb383bca182ea 100644 --- a/src/proto_021_PsQuebec/lib_agnostic_baker/baker_args_parser.ml +++ b/src/proto_021_PsQuebec/lib_agnostic_baker/baker_args_parser.ml @@ -5,7 +5,7 @@ (* *) (*****************************************************************************) -open Configuration +open Cli open Protocol.Alpha_context (** [parse_minimal_fees] parses integer valued fees to [Tez] values. *) @@ -36,48 +36,11 @@ let parse_operations = let parse_state_recorder state_recorder = if state_recorder then Baking_configuration.Filesystem else Memory -let parse_configuration - { - pidfile; - node_version_check_bypass; - node_version_allowed; - minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - force_apply_from_round; - keep_alive; - liquidity_baking_vote; - adaptive_issuance_vote; - per_block_vote_file; - extra_operations; - dal_node_endpoint; - without_dal; - state_recorder; - pre_emptive_forge_time; - remote_calls_timeout; - } = - ( pidfile, - node_version_check_bypass, - node_version_allowed, - parse_minimal_fees minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - force_apply_from_round, - keep_alive, - parse_per_block_vote liquidity_baking_vote, - parse_per_block_vote adaptive_issuance_vote, - per_block_vote_file, - parse_operations extra_operations, - dal_node_endpoint, - without_dal, - parse_state_recorder state_recorder, - pre_emptive_forge_time, - remote_calls_timeout ) - let parse_baking_mode baking_mode = match baking_mode with - | Some local_data_dir_path -> Baking_commands.Local {local_data_dir_path} - | None -> Remote + | Configuration.Local {local_data_dir_path} -> + Baking_commands.Local {local_data_dir_path} + | Configuration.Remote -> Baking_commands.Remote let parse_sources = List.map_es (fun source -> diff --git a/src/proto_021_PsQuebec/lib_agnostic_baker/baker_args_parser.mli b/src/proto_021_PsQuebec/lib_agnostic_baker/baker_args_parser.mli deleted file mode 100644 index cd2af5efebd562170e7f458e26eee4aaf5da8f11..0000000000000000000000000000000000000000 --- a/src/proto_021_PsQuebec/lib_agnostic_baker/baker_args_parser.mli +++ /dev/null @@ -1,47 +0,0 @@ -(*****************************************************************************) -(* *) -(* SPDX-License-Identifier: MIT *) -(* Copyright (c) 2025 Trilitech *) -(* *) -(*****************************************************************************) - -(** This module offers transformation tools from protocol-independent types to - protocol specific ones. In this particular instance, the agnostic baker CLI - arguments are defined in a single place, outside the protocol code, and then - they are mapped, depending on the protocol context. -*) - -open Protocol.Alpha_context - -(** [parse_configuration] simply transforms a configuration record type into a - tuple containing the same values. *) -val parse_configuration : - Configuration.t -> - string option - * bool - * string option - * Tez.t - * Q.t - * Q.t - * int option - * bool - * Per_block_votes.per_block_vote option - * Per_block_votes.per_block_vote option - * string option - * Baking_configuration.Operations_source.t option - * Uri.t option - * bool - * Baking_configuration.state_recorder_config - * Q.t option - * Q.t option - -(** [parse_baking_mode baking_mode] maps a optional value to a [Local] or [Remote] - baking mode option. *) -val parse_baking_mode : string option -> Baking_commands.baking_mode - -(** [parse_sources sources] maps all public key hashes to the version expected - by the protocol-specific baking main running function. *) -val parse_sources : - Tezos_base.TzPervasives.Signature.public_key_hash list -> - (Tezos_base.TzPervasives.Signature.V1.public_key_hash list, tztrace) result - Lwt.t diff --git a/src/proto_021_PsQuebec/lib_agnostic_baker/baker_commands_helpers.ml b/src/proto_021_PsQuebec/lib_agnostic_baker/baker_commands_helpers.ml index 89fe030096a9aa605701c77f5ccfdad575825488..6d7380cf98e14c0c19ee9bcd0e193b08c1b6084c 100644 --- a/src/proto_021_PsQuebec/lib_agnostic_baker/baker_commands_helpers.ml +++ b/src/proto_021_PsQuebec/lib_agnostic_baker/baker_commands_helpers.ml @@ -5,13 +5,35 @@ (* *) (*****************************************************************************) -let run_baker ~configuration ~baking_mode ~sources ~cctxt = +let run_baker ~configuration ~cctxt = let open Lwt_result_syntax in - let args = Baker_args_parser.parse_configuration configuration in - let baking_mode = Baker_args_parser.parse_baking_mode baking_mode in - let* sources = Baker_args_parser.parse_sources sources in + let open Baker_args_parser in + let open Configuration in + let* sources = parse_sources configuration.sources in let cctxt = new Protocol_client_context.wrap_full cctxt in - Baking_commands.run_baker args baking_mode sources cctxt + Baking_commands.run_baker + ~pidfile:configuration.pidfile + ~node_version_check_bypass:configuration.node_version_check_bypass + ~node_version_allowed:configuration.node_version_allowed + ~minimal_fees:(parse_minimal_fees configuration.minimal_fees) + ~minimal_nanotez_per_gas_unit:configuration.minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte:configuration.minimal_nanotez_per_byte + ~force_apply_from_round:configuration.force_apply_from_round + ~keep_alive:configuration.keep_alive + ~liquidity_baking_vote: + (parse_per_block_vote configuration.liquidity_baking_vote) + ~adaptive_issuance_vote: + (parse_per_block_vote configuration.adaptive_issuance_vote) + ~per_block_vote_file:configuration.per_block_vote_file + ~extra_operations:(parse_operations configuration.extra_operations) + ~dal_node_endpoint:configuration.dal_node_endpoint + ~without_dal:configuration.without_dal + ~state_recorder:(parse_state_recorder configuration.state_recorder) + ~pre_emptive_forge_time:configuration.pre_emptive_forge_time + ~remote_calls_timeout:configuration.remote_calls_timeout + ~baking_mode:(parse_baking_mode configuration.baking_mode) + ~sources + cctxt let run_vdf_daemon ~cctxt ~keep_alive = let cctxt = new Protocol_client_context.wrap_full cctxt in diff --git a/src/proto_021_PsQuebec/lib_delegate/baking_commands.ml b/src/proto_021_PsQuebec/lib_delegate/baking_commands.ml index c50621ba586f308b135c537122d92ae86dbe447e..8b48a9880d19c6c843d9a4343b1aea8479fcb5dd 100644 --- a/src/proto_021_PsQuebec/lib_delegate/baking_commands.ml +++ b/src/proto_021_PsQuebec/lib_delegate/baking_commands.ml @@ -733,24 +733,12 @@ let baker_args = pre_emptive_forge_time_arg remote_calls_timeout_arg -let run_baker - ( pidfile, - node_version_check_bypass, - node_version_allowed, - minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - force_apply_from_round, - keep_alive, - liquidity_baking_vote, - adaptive_issuance_vote, - per_block_vote_file, - extra_operations, - dal_node_endpoint, - without_dal, - state_recorder, - pre_emptive_forge_time, - remote_calls_timeout ) baking_mode sources cctxt = +let run_baker ~pidfile ~node_version_check_bypass ~node_version_allowed + ~minimal_fees ~minimal_nanotez_per_gas_unit ~minimal_nanotez_per_byte + ~force_apply_from_round ~keep_alive ~liquidity_baking_vote + ~adaptive_issuance_vote ~per_block_vote_file ~extra_operations + ~dal_node_endpoint ~without_dal ~state_recorder ~pre_emptive_forge_time + ~remote_calls_timeout ~baking_mode ~sources cctxt = let open Lwt_result_syntax in may_lock_pidfile pidfile @@ fun () -> let* () = @@ -818,17 +806,92 @@ let baker_commands () : Protocol_client_context.full Tezos_clic.command list = ~desc:"Path to the node data directory (e.g. $HOME/.tezos-node)" directory_parameter @@ sources_param) - (fun args local_data_dir_path sources cctxt -> - let baking_mode = Local {local_data_dir_path} in - run_baker args baking_mode sources cctxt); + (fun ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote, + per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout ) + local_data_dir_path + sources + cctxt -> + run_baker + ~pidfile + ~node_version_check_bypass + ~node_version_allowed + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + ~force_apply_from_round + ~keep_alive + ~liquidity_baking_vote + ~adaptive_issuance_vote + ~per_block_vote_file + ~extra_operations + ~dal_node_endpoint + ~without_dal + ~state_recorder + ~pre_emptive_forge_time + ~remote_calls_timeout + ~baking_mode:(Local {local_data_dir_path}) + ~sources + cctxt); command ~group ~desc:"Launch the baker daemon using RPCs only." baker_args (prefixes ["run"; "remotely"] @@ sources_param) - (fun args sources cctxt -> - let baking_mode = Remote in - run_baker args baking_mode sources cctxt); + (fun ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote, + per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout ) + sources + cctxt -> + run_baker + ~pidfile + ~node_version_check_bypass + ~node_version_allowed + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + ~force_apply_from_round + ~keep_alive + ~liquidity_baking_vote + ~adaptive_issuance_vote + ~per_block_vote_file + ~extra_operations + ~dal_node_endpoint + ~without_dal + ~state_recorder + ~pre_emptive_forge_time + ~remote_calls_timeout + ~baking_mode:Remote + ~sources + cctxt); command ~group ~desc:"Launch the VDF daemon" diff --git a/src/proto_021_PsQuebec/lib_delegate/baking_commands.mli b/src/proto_021_PsQuebec/lib_delegate/baking_commands.mli index c808d30553300e0051930ef11470845e00660c7b..dd3e1d3ee65841e26da84ee942b14791e1aa891c 100644 --- a/src/proto_021_PsQuebec/lib_delegate/baking_commands.mli +++ b/src/proto_021_PsQuebec/lib_delegate/baking_commands.mli @@ -26,25 +26,27 @@ type baking_mode = Local of {local_data_dir_path : string} | Remote val run_baker : - string option - * bool - * string option - * Protocol.Alpha_context.Tez.t - * Q.t - * Q.t - * int option - * bool - * Protocol.Per_block_votes_repr.per_block_vote option - * Protocol.Per_block_votes_repr.per_block_vote option - * string option - * Baking_configuration.Operations_source.t option - * Uri.t option - * bool - * Baking_configuration.state_recorder_config - * Q.t option - * Q.t option -> - baking_mode -> - Environment.Signature.public_key_hash list -> + pidfile:string option -> + node_version_check_bypass:bool -> + node_version_allowed:string option -> + minimal_fees:Tezos_raw_protocol_021_PsQuebec.Alpha_context.Tez.t -> + minimal_nanotez_per_gas_unit:Q.t -> + minimal_nanotez_per_byte:Q.t -> + force_apply_from_round:int option -> + keep_alive:bool -> + liquidity_baking_vote: + Tezos_raw_protocol_021_PsQuebec.Per_block_votes_repr.per_block_vote option -> + adaptive_issuance_vote: + Tezos_raw_protocol_021_PsQuebec.Per_block_votes_repr.per_block_vote option -> + per_block_vote_file:string option -> + extra_operations:Baking_configuration.Operations_source.t option -> + dal_node_endpoint:Uri.t option -> + without_dal:bool -> + state_recorder:Baking_configuration.state_recorder_config -> + pre_emptive_forge_time:Q.t option -> + remote_calls_timeout:Q.t option -> + baking_mode:baking_mode -> + sources:Environment.Signature.public_key_hash list -> Protocol_client_context.full -> unit Error_monad.tzresult Lwt.t diff --git a/src/proto_022_PsRiotum/lib_agnostic_baker/baker_args_parser.ml b/src/proto_022_PsRiotum/lib_agnostic_baker/baker_args_parser.ml index 764f7803957a129ff4aa855a8007458ecc8acef8..a5093e4b691fbef801edd10322cfb383bca182ea 100644 --- a/src/proto_022_PsRiotum/lib_agnostic_baker/baker_args_parser.ml +++ b/src/proto_022_PsRiotum/lib_agnostic_baker/baker_args_parser.ml @@ -5,7 +5,7 @@ (* *) (*****************************************************************************) -open Configuration +open Cli open Protocol.Alpha_context (** [parse_minimal_fees] parses integer valued fees to [Tez] values. *) @@ -36,48 +36,11 @@ let parse_operations = let parse_state_recorder state_recorder = if state_recorder then Baking_configuration.Filesystem else Memory -let parse_configuration - { - pidfile; - node_version_check_bypass; - node_version_allowed; - minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - force_apply_from_round; - keep_alive; - liquidity_baking_vote; - adaptive_issuance_vote; - per_block_vote_file; - extra_operations; - dal_node_endpoint; - without_dal; - state_recorder; - pre_emptive_forge_time; - remote_calls_timeout; - } = - ( pidfile, - node_version_check_bypass, - node_version_allowed, - parse_minimal_fees minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - force_apply_from_round, - keep_alive, - parse_per_block_vote liquidity_baking_vote, - parse_per_block_vote adaptive_issuance_vote, - per_block_vote_file, - parse_operations extra_operations, - dal_node_endpoint, - without_dal, - parse_state_recorder state_recorder, - pre_emptive_forge_time, - remote_calls_timeout ) - let parse_baking_mode baking_mode = match baking_mode with - | Some local_data_dir_path -> Baking_commands.Local {local_data_dir_path} - | None -> Remote + | Configuration.Local {local_data_dir_path} -> + Baking_commands.Local {local_data_dir_path} + | Configuration.Remote -> Baking_commands.Remote let parse_sources = List.map_es (fun source -> diff --git a/src/proto_022_PsRiotum/lib_agnostic_baker/baker_args_parser.mli b/src/proto_022_PsRiotum/lib_agnostic_baker/baker_args_parser.mli deleted file mode 100644 index cd2af5efebd562170e7f458e26eee4aaf5da8f11..0000000000000000000000000000000000000000 --- a/src/proto_022_PsRiotum/lib_agnostic_baker/baker_args_parser.mli +++ /dev/null @@ -1,47 +0,0 @@ -(*****************************************************************************) -(* *) -(* SPDX-License-Identifier: MIT *) -(* Copyright (c) 2025 Trilitech *) -(* *) -(*****************************************************************************) - -(** This module offers transformation tools from protocol-independent types to - protocol specific ones. In this particular instance, the agnostic baker CLI - arguments are defined in a single place, outside the protocol code, and then - they are mapped, depending on the protocol context. -*) - -open Protocol.Alpha_context - -(** [parse_configuration] simply transforms a configuration record type into a - tuple containing the same values. *) -val parse_configuration : - Configuration.t -> - string option - * bool - * string option - * Tez.t - * Q.t - * Q.t - * int option - * bool - * Per_block_votes.per_block_vote option - * Per_block_votes.per_block_vote option - * string option - * Baking_configuration.Operations_source.t option - * Uri.t option - * bool - * Baking_configuration.state_recorder_config - * Q.t option - * Q.t option - -(** [parse_baking_mode baking_mode] maps a optional value to a [Local] or [Remote] - baking mode option. *) -val parse_baking_mode : string option -> Baking_commands.baking_mode - -(** [parse_sources sources] maps all public key hashes to the version expected - by the protocol-specific baking main running function. *) -val parse_sources : - Tezos_base.TzPervasives.Signature.public_key_hash list -> - (Tezos_base.TzPervasives.Signature.V1.public_key_hash list, tztrace) result - Lwt.t diff --git a/src/proto_022_PsRiotum/lib_agnostic_baker/baker_commands_helpers.ml b/src/proto_022_PsRiotum/lib_agnostic_baker/baker_commands_helpers.ml index 89fe030096a9aa605701c77f5ccfdad575825488..6d7380cf98e14c0c19ee9bcd0e193b08c1b6084c 100644 --- a/src/proto_022_PsRiotum/lib_agnostic_baker/baker_commands_helpers.ml +++ b/src/proto_022_PsRiotum/lib_agnostic_baker/baker_commands_helpers.ml @@ -5,13 +5,35 @@ (* *) (*****************************************************************************) -let run_baker ~configuration ~baking_mode ~sources ~cctxt = +let run_baker ~configuration ~cctxt = let open Lwt_result_syntax in - let args = Baker_args_parser.parse_configuration configuration in - let baking_mode = Baker_args_parser.parse_baking_mode baking_mode in - let* sources = Baker_args_parser.parse_sources sources in + let open Baker_args_parser in + let open Configuration in + let* sources = parse_sources configuration.sources in let cctxt = new Protocol_client_context.wrap_full cctxt in - Baking_commands.run_baker args baking_mode sources cctxt + Baking_commands.run_baker + ~pidfile:configuration.pidfile + ~node_version_check_bypass:configuration.node_version_check_bypass + ~node_version_allowed:configuration.node_version_allowed + ~minimal_fees:(parse_minimal_fees configuration.minimal_fees) + ~minimal_nanotez_per_gas_unit:configuration.minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte:configuration.minimal_nanotez_per_byte + ~force_apply_from_round:configuration.force_apply_from_round + ~keep_alive:configuration.keep_alive + ~liquidity_baking_vote: + (parse_per_block_vote configuration.liquidity_baking_vote) + ~adaptive_issuance_vote: + (parse_per_block_vote configuration.adaptive_issuance_vote) + ~per_block_vote_file:configuration.per_block_vote_file + ~extra_operations:(parse_operations configuration.extra_operations) + ~dal_node_endpoint:configuration.dal_node_endpoint + ~without_dal:configuration.without_dal + ~state_recorder:(parse_state_recorder configuration.state_recorder) + ~pre_emptive_forge_time:configuration.pre_emptive_forge_time + ~remote_calls_timeout:configuration.remote_calls_timeout + ~baking_mode:(parse_baking_mode configuration.baking_mode) + ~sources + cctxt let run_vdf_daemon ~cctxt ~keep_alive = let cctxt = new Protocol_client_context.wrap_full cctxt in diff --git a/src/proto_022_PsRiotum/lib_delegate/baking_commands.ml b/src/proto_022_PsRiotum/lib_delegate/baking_commands.ml index 46b48fc5c7e36d0678906b9b6425b6e399ca32a8..168b85e1d686e3d1af0a945de11294f29345bf1f 100644 --- a/src/proto_022_PsRiotum/lib_delegate/baking_commands.ml +++ b/src/proto_022_PsRiotum/lib_delegate/baking_commands.ml @@ -746,24 +746,12 @@ let baker_args = pre_emptive_forge_time_arg remote_calls_timeout_arg -let run_baker - ( pidfile, - node_version_check_bypass, - node_version_allowed, - minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - force_apply_from_round, - keep_alive, - liquidity_baking_vote, - adaptive_issuance_vote, - per_block_vote_file, - extra_operations, - dal_node_endpoint, - without_dal, - state_recorder, - pre_emptive_forge_time, - remote_calls_timeout ) baking_mode sources cctxt = +let run_baker ~pidfile ~node_version_check_bypass ~node_version_allowed + ~minimal_fees ~minimal_nanotez_per_gas_unit ~minimal_nanotez_per_byte + ~force_apply_from_round ~keep_alive ~liquidity_baking_vote + ~adaptive_issuance_vote ~per_block_vote_file ~extra_operations + ~dal_node_endpoint ~without_dal ~state_recorder ~pre_emptive_forge_time + ~remote_calls_timeout ~baking_mode ~sources cctxt = let open Lwt_result_syntax in may_lock_pidfile pidfile @@ fun () -> let* () = @@ -831,17 +819,92 @@ let baker_commands () : Protocol_client_context.full Tezos_clic.command list = ~desc:"Path to the node data directory (e.g. $HOME/.tezos-node)" directory_parameter @@ sources_param) - (fun args local_data_dir_path sources cctxt -> - let baking_mode = Local {local_data_dir_path} in - run_baker args baking_mode sources cctxt); + (fun ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote, + per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout ) + local_data_dir_path + sources + cctxt -> + run_baker + ~pidfile + ~node_version_check_bypass + ~node_version_allowed + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + ~force_apply_from_round + ~keep_alive + ~liquidity_baking_vote + ~adaptive_issuance_vote + ~per_block_vote_file + ~extra_operations + ~dal_node_endpoint + ~without_dal + ~state_recorder + ~pre_emptive_forge_time + ~remote_calls_timeout + ~baking_mode:(Local {local_data_dir_path}) + ~sources + cctxt); command ~group ~desc:"Launch the baker daemon using RPCs only." baker_args (prefixes ["run"; "remotely"] @@ sources_param) - (fun args sources cctxt -> - let baking_mode = Remote in - run_baker args baking_mode sources cctxt); + (fun ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote, + per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout ) + sources + cctxt -> + run_baker + ~pidfile + ~node_version_check_bypass + ~node_version_allowed + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + ~force_apply_from_round + ~keep_alive + ~liquidity_baking_vote + ~adaptive_issuance_vote + ~per_block_vote_file + ~extra_operations + ~dal_node_endpoint + ~without_dal + ~state_recorder + ~pre_emptive_forge_time + ~remote_calls_timeout + ~baking_mode:Remote + ~sources + cctxt); command ~group ~desc:"Launch the VDF daemon" diff --git a/src/proto_022_PsRiotum/lib_delegate/baking_commands.mli b/src/proto_022_PsRiotum/lib_delegate/baking_commands.mli index c808d30553300e0051930ef11470845e00660c7b..1ae49c6b400e8b6a08ebcd827ca73c3ef3939b31 100644 --- a/src/proto_022_PsRiotum/lib_delegate/baking_commands.mli +++ b/src/proto_022_PsRiotum/lib_delegate/baking_commands.mli @@ -26,25 +26,27 @@ type baking_mode = Local of {local_data_dir_path : string} | Remote val run_baker : - string option - * bool - * string option - * Protocol.Alpha_context.Tez.t - * Q.t - * Q.t - * int option - * bool - * Protocol.Per_block_votes_repr.per_block_vote option - * Protocol.Per_block_votes_repr.per_block_vote option - * string option - * Baking_configuration.Operations_source.t option - * Uri.t option - * bool - * Baking_configuration.state_recorder_config - * Q.t option - * Q.t option -> - baking_mode -> - Environment.Signature.public_key_hash list -> + pidfile:string option -> + node_version_check_bypass:bool -> + node_version_allowed:string option -> + minimal_fees:Tezos_raw_protocol_022_PsRiotum.Alpha_context.Tez.t -> + minimal_nanotez_per_gas_unit:Q.t -> + minimal_nanotez_per_byte:Q.t -> + force_apply_from_round:int option -> + keep_alive:bool -> + liquidity_baking_vote: + Tezos_raw_protocol_022_PsRiotum.Per_block_votes_repr.per_block_vote option -> + adaptive_issuance_vote: + Tezos_raw_protocol_022_PsRiotum.Per_block_votes_repr.per_block_vote option -> + per_block_vote_file:string option -> + extra_operations:Baking_configuration.Operations_source.t option -> + dal_node_endpoint:Uri.t option -> + without_dal:bool -> + state_recorder:Baking_configuration.state_recorder_config -> + pre_emptive_forge_time:Q.t option -> + remote_calls_timeout:Q.t option -> + baking_mode:baking_mode -> + sources:Environment.Signature.public_key_hash list -> Protocol_client_context.full -> unit Error_monad.tzresult Lwt.t diff --git a/src/proto_alpha/lib_agnostic_baker/baker_args_parser.ml b/src/proto_alpha/lib_agnostic_baker/baker_args_parser.ml index 3ea1a51283a98eae97561e9f6fd54c19bab467ac..2a0c59b14c3ba7cfd41ae5d9437c162377003ae0 100644 --- a/src/proto_alpha/lib_agnostic_baker/baker_args_parser.ml +++ b/src/proto_alpha/lib_agnostic_baker/baker_args_parser.ml @@ -5,7 +5,7 @@ (* *) (*****************************************************************************) -open Configuration +open Cli open Protocol.Alpha_context (** [parse_minimal_fees] parses integer valued fees to [Tez] values. *) @@ -36,45 +36,8 @@ let parse_operations = let parse_state_recorder state_recorder = if state_recorder then Baking_configuration.Filesystem else Memory -let parse_configuration - { - pidfile; - node_version_check_bypass; - node_version_allowed; - minimal_fees; - minimal_nanotez_per_gas_unit; - minimal_nanotez_per_byte; - force_apply_from_round; - keep_alive; - liquidity_baking_vote; - adaptive_issuance_vote; - per_block_vote_file; - extra_operations; - dal_node_endpoint; - without_dal; - state_recorder; - pre_emptive_forge_time; - remote_calls_timeout; - } = - ( pidfile, - node_version_check_bypass, - node_version_allowed, - parse_minimal_fees minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - force_apply_from_round, - keep_alive, - parse_per_block_vote liquidity_baking_vote, - parse_per_block_vote adaptive_issuance_vote, - per_block_vote_file, - parse_operations extra_operations, - dal_node_endpoint, - without_dal, - parse_state_recorder state_recorder, - pre_emptive_forge_time, - remote_calls_timeout ) - let parse_baking_mode baking_mode = match baking_mode with - | Some local_data_dir_path -> Baking_commands.Local {local_data_dir_path} - | None -> Remote + | Configuration.Local {local_data_dir_path} -> + Baking_commands.Local {local_data_dir_path} + | Configuration.Remote -> Baking_commands.Remote diff --git a/src/proto_alpha/lib_agnostic_baker/baker_args_parser.mli b/src/proto_alpha/lib_agnostic_baker/baker_args_parser.mli deleted file mode 100644 index 9e58b64f5ef33a08e520bfb036b29cd8a69ce121..0000000000000000000000000000000000000000 --- a/src/proto_alpha/lib_agnostic_baker/baker_args_parser.mli +++ /dev/null @@ -1,40 +0,0 @@ -(*****************************************************************************) -(* *) -(* SPDX-License-Identifier: MIT *) -(* Copyright (c) 2025 Trilitech *) -(* *) -(*****************************************************************************) - -(** This module offers transformation tools from protocol-independent types to - protocol specific ones. In this particular instance, the agnostic baker CLI - arguments are defined in a single place, outside the protocol code, and then - they are mapped, depending on the protocol context. -*) - -open Protocol.Alpha_context - -(** [parse_configuration] simply transforms a configuration record type into a - tuple containing the same values. *) -val parse_configuration : - Configuration.t -> - string option - * bool - * string option - * Tez.t - * Q.t - * Q.t - * int option - * bool - * Per_block_votes.per_block_vote option - * Per_block_votes.per_block_vote option - * string option - * Baking_configuration.Operations_source.t option - * Uri.t option - * bool - * Baking_configuration.state_recorder_config - * Q.t option - * Q.t option - -(** [parse_baking_mode baking_mode] maps a optional value to a [Local] or [Remote] - baking mode option. *) -val parse_baking_mode : string option -> Baking_commands.baking_mode diff --git a/src/proto_alpha/lib_agnostic_baker/baker_commands_helpers.ml b/src/proto_alpha/lib_agnostic_baker/baker_commands_helpers.ml index 9996e3999da54d04f06ef5a33b8a98c9a6de157d..4c7622b6871a88a1c31db50534cdf3882bda3338 100644 --- a/src/proto_alpha/lib_agnostic_baker/baker_commands_helpers.ml +++ b/src/proto_alpha/lib_agnostic_baker/baker_commands_helpers.ml @@ -5,11 +5,33 @@ (* *) (*****************************************************************************) -let run_baker ~configuration ~baking_mode ~sources ~cctxt = - let args = Baker_args_parser.parse_configuration configuration in - let baking_mode = Baker_args_parser.parse_baking_mode baking_mode in +let run_baker ~configuration ~cctxt = + let open Baker_args_parser in + let open Configuration in let cctxt = new Protocol_client_context.wrap_full cctxt in - Baking_commands.run_baker args baking_mode sources cctxt + Baking_commands.run_baker + ~pidfile:configuration.pidfile + ~node_version_check_bypass:configuration.node_version_check_bypass + ~node_version_allowed:configuration.node_version_allowed + ~minimal_fees:(parse_minimal_fees configuration.minimal_fees) + ~minimal_nanotez_per_gas_unit:configuration.minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte:configuration.minimal_nanotez_per_byte + ~force_apply_from_round:configuration.force_apply_from_round + ~keep_alive:configuration.keep_alive + ~liquidity_baking_vote: + (parse_per_block_vote configuration.liquidity_baking_vote) + ~adaptive_issuance_vote: + (parse_per_block_vote configuration.adaptive_issuance_vote) + ~per_block_vote_file:configuration.per_block_vote_file + ~extra_operations:(parse_operations configuration.extra_operations) + ~dal_node_endpoint:configuration.dal_node_endpoint + ~without_dal:configuration.without_dal + ~state_recorder:(parse_state_recorder configuration.state_recorder) + ~pre_emptive_forge_time:configuration.pre_emptive_forge_time + ~remote_calls_timeout:configuration.remote_calls_timeout + ~baking_mode:(parse_baking_mode configuration.baking_mode) + ~sources:configuration.sources + cctxt let run_vdf_daemon ~cctxt ~keep_alive = let cctxt = new Protocol_client_context.wrap_full cctxt in diff --git a/src/proto_alpha/lib_delegate/baking_commands.ml b/src/proto_alpha/lib_delegate/baking_commands.ml index 8cb1cbd682297a1c32c143ae49b6dfe0f2d3e542..102b6c9b3d31afc11a0a5d5a553bc12cabe36188 100644 --- a/src/proto_alpha/lib_delegate/baking_commands.ml +++ b/src/proto_alpha/lib_delegate/baking_commands.ml @@ -756,24 +756,12 @@ let baker_args = pre_emptive_forge_time_arg remote_calls_timeout_arg -let run_baker - ( pidfile, - node_version_check_bypass, - node_version_allowed, - minimal_fees, - minimal_nanotez_per_gas_unit, - minimal_nanotez_per_byte, - force_apply_from_round, - keep_alive, - liquidity_baking_vote, - adaptive_issuance_vote, - per_block_vote_file, - extra_operations, - dal_node_endpoint, - without_dal, - state_recorder, - pre_emptive_forge_time, - remote_calls_timeout ) baking_mode sources cctxt = +let run_baker ~pidfile ~node_version_check_bypass ~node_version_allowed + ~minimal_fees ~minimal_nanotez_per_gas_unit ~minimal_nanotez_per_byte + ~force_apply_from_round ~keep_alive ~liquidity_baking_vote + ~adaptive_issuance_vote ~per_block_vote_file ~extra_operations + ~dal_node_endpoint ~without_dal ~state_recorder ~pre_emptive_forge_time + ~remote_calls_timeout ~baking_mode ~sources cctxt = let open Lwt_result_syntax in may_lock_pidfile pidfile @@ fun () -> let* () = @@ -841,17 +829,92 @@ let baker_commands () : Protocol_client_context.full Tezos_clic.command list = ~desc:"Path to the node data directory (e.g. $HOME/.tezos-node)" directory_parameter @@ sources_param) - (fun args local_data_dir_path sources cctxt -> - let baking_mode = Local {local_data_dir_path} in - run_baker args baking_mode sources cctxt); + (fun ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote, + per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout ) + local_data_dir_path + sources + cctxt -> + run_baker + ~pidfile + ~node_version_check_bypass + ~node_version_allowed + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + ~force_apply_from_round + ~keep_alive + ~liquidity_baking_vote + ~adaptive_issuance_vote + ~per_block_vote_file + ~extra_operations + ~dal_node_endpoint + ~without_dal + ~state_recorder + ~pre_emptive_forge_time + ~remote_calls_timeout + ~baking_mode:(Local {local_data_dir_path}) + ~sources + cctxt); command ~group ~desc:"Launch the baker daemon using RPCs only." baker_args (prefixes ["run"; "remotely"] @@ sources_param) - (fun args sources cctxt -> - let baking_mode = Remote in - run_baker args baking_mode sources cctxt); + (fun ( pidfile, + node_version_check_bypass, + node_version_allowed, + minimal_fees, + minimal_nanotez_per_gas_unit, + minimal_nanotez_per_byte, + force_apply_from_round, + keep_alive, + liquidity_baking_vote, + adaptive_issuance_vote, + per_block_vote_file, + extra_operations, + dal_node_endpoint, + without_dal, + state_recorder, + pre_emptive_forge_time, + remote_calls_timeout ) + sources + cctxt -> + run_baker + ~pidfile + ~node_version_check_bypass + ~node_version_allowed + ~minimal_fees + ~minimal_nanotez_per_gas_unit + ~minimal_nanotez_per_byte + ~force_apply_from_round + ~keep_alive + ~liquidity_baking_vote + ~adaptive_issuance_vote + ~per_block_vote_file + ~extra_operations + ~dal_node_endpoint + ~without_dal + ~state_recorder + ~pre_emptive_forge_time + ~remote_calls_timeout + ~baking_mode:Remote + ~sources + cctxt); command ~group ~desc:"Launch the VDF daemon" diff --git a/src/proto_alpha/lib_delegate/baking_commands.mli b/src/proto_alpha/lib_delegate/baking_commands.mli index c808d30553300e0051930ef11470845e00660c7b..d2ae5b9ec1281aa8d945da31210596f6872a2768 100644 --- a/src/proto_alpha/lib_delegate/baking_commands.mli +++ b/src/proto_alpha/lib_delegate/baking_commands.mli @@ -26,25 +26,27 @@ type baking_mode = Local of {local_data_dir_path : string} | Remote val run_baker : - string option - * bool - * string option - * Protocol.Alpha_context.Tez.t - * Q.t - * Q.t - * int option - * bool - * Protocol.Per_block_votes_repr.per_block_vote option - * Protocol.Per_block_votes_repr.per_block_vote option - * string option - * Baking_configuration.Operations_source.t option - * Uri.t option - * bool - * Baking_configuration.state_recorder_config - * Q.t option - * Q.t option -> - baking_mode -> - Environment.Signature.public_key_hash list -> + pidfile:string option -> + node_version_check_bypass:bool -> + node_version_allowed:string option -> + minimal_fees:Tezos_raw_protocol_alpha.Alpha_context.Tez.t -> + minimal_nanotez_per_gas_unit:Q.t -> + minimal_nanotez_per_byte:Q.t -> + force_apply_from_round:int option -> + keep_alive:bool -> + liquidity_baking_vote: + Tezos_raw_protocol_alpha.Per_block_votes_repr.per_block_vote option -> + adaptive_issuance_vote: + Tezos_raw_protocol_alpha.Per_block_votes_repr.per_block_vote option -> + per_block_vote_file:string option -> + extra_operations:Baking_configuration.Operations_source.t option -> + dal_node_endpoint:Uri.t option -> + without_dal:bool -> + state_recorder:Baking_configuration.state_recorder_config -> + pre_emptive_forge_time:Q.t option -> + remote_calls_timeout:Q.t option -> + baking_mode:baking_mode -> + sources:Environment.Signature.public_key_hash list -> Protocol_client_context.full -> unit Error_monad.tzresult Lwt.t