diff --git a/.gitlab/ci/pipelines/before_merging.yml b/.gitlab/ci/pipelines/before_merging.yml index 3429cc7aee3e9648cd788cd6d3a00ace5018d32a..21d042fa2b9c3ae452a18f7b6f1ba8a1e4324ad2 100644 --- a/.gitlab/ci/pipelines/before_merging.yml +++ b/.gitlab/ci/pipelines/before_merging.yml @@ -1888,6 +1888,7 @@ opam:all_2: - octez-smart-rollup-node-lib - octez-smart-rollup-node-alpha - octez-smart-rollup-node-PtParisB + - octez-smart-rollup-node-PtNairob - octez-protocol-alpha-libs - octez-protocol-022-PsRiotum-libs - octez-protocol-021-PsQuebec-libs @@ -1968,81 +1969,11 @@ opam:all_1: parallel: matrix: - package: - - octez-smart-rollup-node-PtNairob - octez-smart-rollup-node-PsRiotum - octez-smart-rollup-node-PsQuebec - octez-smart-rollup-node-PsParisC - octez-smart-rollup-node-Proxford -opam:exec_2: - image: ${ci_image_name}/prebuild:${ci_image_tag} - stage: packaging - tags: - - gcp - rules: - - if: $CI_MERGE_REQUEST_LABELS =~ /(?:^|,)ci--opam(?:$|,)/ - when: delayed - start_in: 2 minutes - - changes: - - '**/*.dune.inc' - - '**/*.opam' - - '**/dune' - - '**/dune-project' - - '**/dune-workspace' - - '**/dune.inc' - - .gitlab/ci/jobs/packaging/opam:prepare.yml - - .gitlab/ci/jobs/packaging/opam_package.yml - - manifest/**/*.ml* - - scripts/opam-prepare-repo.sh - - scripts/version.sh - when: delayed - start_in: 2 minutes - needs: - - oc.docker:ci:amd64 - - opam:prepare - dependencies: - - oc.docker:ci:amd64 - - opam:prepare - timeout: 60 minutes - cache: - - key: opam-sccache - paths: - - $CI_PROJECT_DIR/_build/_sccache - policy: pull-push - - key: cargo-$CI_JOB_NAME_SLUG - paths: - - $CI_PROJECT_DIR/.cargo/registry/cache - policy: pull-push - before_script: - - eval $(opam env) - - mkdir -p $CI_PROJECT_DIR/opam_logs - - . ./scripts/ci/sccache-start.sh - script: - - opam remote add dev-repo ./_opam-repo-for-release - - opam install --yes ${package}.dev - - opam reinstall --yes --with-test ${package}.dev - after_script: - - eval $(opam env) - - OPAM_LOGS=opam_logs ./scripts/ci/opam_handle_output.sh - - ./scripts/ci/sccache-stop.sh - variables: - RUNTEZTALIAS: "true" - SCCACHE_DIR: $CI_PROJECT_DIR/_build/_sccache - SCCACHE_CACHE_SIZE: 5G - SCCACHE_ERROR_LOG: $CI_PROJECT_DIR/opam_logs/sccache.log - SCCACHE_IDLE_TIMEOUT: "0" - CARGO_NET_OFFLINE: "false" - artifacts: - expire_in: 1 week - paths: - - opam_logs/ - when: always - retry: 2 - parallel: - matrix: - - package: - - octez-experimental-agnostic-baker - opam:all_3: image: ${ci_image_name}/prebuild:${ci_image_tag} stage: packaging @@ -2351,6 +2282,7 @@ opam:exec_1: - octez-smart-rollup-wasm-debugger - octez-smart-rollup-node - octez-node + - octez-experimental-agnostic-baker - octez-dal-node - octez-codec - octez-client diff --git a/.gitlab/ci/pipelines/merge_train.yml b/.gitlab/ci/pipelines/merge_train.yml index c18c33af87b8aad008ed83ede79800c480e5e18f..a4b877454bd546a3c301593a3a7290e280dd1c5e 100644 --- a/.gitlab/ci/pipelines/merge_train.yml +++ b/.gitlab/ci/pipelines/merge_train.yml @@ -1887,6 +1887,7 @@ opam:all_2: - octez-smart-rollup-node-lib - octez-smart-rollup-node-alpha - octez-smart-rollup-node-PtParisB + - octez-smart-rollup-node-PtNairob - octez-protocol-alpha-libs - octez-protocol-022-PsRiotum-libs - octez-protocol-021-PsQuebec-libs @@ -1967,81 +1968,11 @@ opam:all_1: parallel: matrix: - package: - - octez-smart-rollup-node-PtNairob - octez-smart-rollup-node-PsRiotum - octez-smart-rollup-node-PsQuebec - octez-smart-rollup-node-PsParisC - octez-smart-rollup-node-Proxford -opam:exec_2: - image: ${ci_image_name}/prebuild:${ci_image_tag} - stage: packaging - tags: - - gcp - rules: - - if: $CI_MERGE_REQUEST_LABELS =~ /(?:^|,)ci--opam(?:$|,)/ - when: delayed - start_in: 2 minutes - - changes: - - '**/*.dune.inc' - - '**/*.opam' - - '**/dune' - - '**/dune-project' - - '**/dune-workspace' - - '**/dune.inc' - - .gitlab/ci/jobs/packaging/opam:prepare.yml - - .gitlab/ci/jobs/packaging/opam_package.yml - - manifest/**/*.ml* - - scripts/opam-prepare-repo.sh - - scripts/version.sh - when: delayed - start_in: 2 minutes - needs: - - oc.docker:ci:amd64 - - opam:prepare - dependencies: - - oc.docker:ci:amd64 - - opam:prepare - timeout: 60 minutes - cache: - - key: opam-sccache - paths: - - $CI_PROJECT_DIR/_build/_sccache - policy: pull-push - - key: cargo-$CI_JOB_NAME_SLUG - paths: - - $CI_PROJECT_DIR/.cargo/registry/cache - policy: pull-push - before_script: - - eval $(opam env) - - mkdir -p $CI_PROJECT_DIR/opam_logs - - . ./scripts/ci/sccache-start.sh - script: - - opam remote add dev-repo ./_opam-repo-for-release - - opam install --yes ${package}.dev - - opam reinstall --yes --with-test ${package}.dev - after_script: - - eval $(opam env) - - OPAM_LOGS=opam_logs ./scripts/ci/opam_handle_output.sh - - ./scripts/ci/sccache-stop.sh - variables: - RUNTEZTALIAS: "true" - SCCACHE_DIR: $CI_PROJECT_DIR/_build/_sccache - SCCACHE_CACHE_SIZE: 5G - SCCACHE_ERROR_LOG: $CI_PROJECT_DIR/opam_logs/sccache.log - SCCACHE_IDLE_TIMEOUT: "0" - CARGO_NET_OFFLINE: "false" - artifacts: - expire_in: 1 week - paths: - - opam_logs/ - when: always - retry: 2 - parallel: - matrix: - - package: - - octez-experimental-agnostic-baker - opam:all_3: image: ${ci_image_name}/prebuild:${ci_image_tag} stage: packaging @@ -2350,6 +2281,7 @@ opam:exec_1: - octez-smart-rollup-wasm-debugger - octez-smart-rollup-node - octez-node + - octez-experimental-agnostic-baker - octez-dal-node - octez-codec - octez-client diff --git a/.gitlab/ci/pipelines/schedule_extended_test.yml b/.gitlab/ci/pipelines/schedule_extended_test.yml index f640de40b44fc577f198669ce3196e0d9fd22942..d8347658628cee5b46b35aeaf2a9e436e3ba5461 100644 --- a/.gitlab/ci/pipelines/schedule_extended_test.yml +++ b/.gitlab/ci/pipelines/schedule_extended_test.yml @@ -1296,6 +1296,7 @@ opam:all_2: - octez-smart-rollup-node-lib - octez-smart-rollup-node-alpha - octez-smart-rollup-node-PtParisB + - octez-smart-rollup-node-PtNairob - octez-protocol-alpha-libs - octez-protocol-022-PsRiotum-libs - octez-protocol-021-PsQuebec-libs @@ -1360,67 +1361,11 @@ opam:all_1: parallel: matrix: - package: - - octez-smart-rollup-node-PtNairob - octez-smart-rollup-node-PsRiotum - octez-smart-rollup-node-PsQuebec - octez-smart-rollup-node-PsParisC - octez-smart-rollup-node-Proxford -opam:exec_2: - image: ${ci_image_name}/prebuild:${ci_image_tag} - stage: packaging - tags: - - gcp - rules: - - when: delayed - start_in: 2 minutes - needs: - - oc.docker:ci:amd64 - - opam:prepare - dependencies: - - oc.docker:ci:amd64 - - opam:prepare - timeout: 60 minutes - cache: - - key: opam-sccache - paths: - - $CI_PROJECT_DIR/_build/_sccache - policy: pull-push - - key: cargo-$CI_JOB_NAME_SLUG - paths: - - $CI_PROJECT_DIR/.cargo/registry/cache - policy: pull-push - interruptible: false - before_script: - - eval $(opam env) - - mkdir -p $CI_PROJECT_DIR/opam_logs - - . ./scripts/ci/sccache-start.sh - script: - - opam remote add dev-repo ./_opam-repo-for-release - - opam install --yes ${package}.dev - - opam reinstall --yes --with-test ${package}.dev - after_script: - - eval $(opam env) - - OPAM_LOGS=opam_logs ./scripts/ci/opam_handle_output.sh - - ./scripts/ci/sccache-stop.sh - variables: - RUNTEZTALIAS: "true" - SCCACHE_DIR: $CI_PROJECT_DIR/_build/_sccache - SCCACHE_CACHE_SIZE: 5G - SCCACHE_ERROR_LOG: $CI_PROJECT_DIR/opam_logs/sccache.log - SCCACHE_IDLE_TIMEOUT: "0" - CARGO_NET_OFFLINE: "false" - artifacts: - expire_in: 1 week - paths: - - opam_logs/ - when: always - retry: 2 - parallel: - matrix: - - package: - - octez-experimental-agnostic-baker - opam:all_3: image: ${ci_image_name}/prebuild:${ci_image_tag} stage: packaging @@ -1669,6 +1614,7 @@ opam:exec_1: - octez-smart-rollup-wasm-debugger - octez-smart-rollup-node - octez-node + - octez-experimental-agnostic-baker - octez-dal-node - octez-codec - octez-client diff --git a/CHANGES.rst b/CHANGES.rst index a16ebcdaff6fa0ce3439f7edd466c5e3478161de..97e0afbb62c39a4c9a6b6de39857a58252527953 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -55,6 +55,29 @@ Baker Agnostic Baker -------------- +- The agnostic baker no longer requires the protocol specific baking binaries, instead + it directly spawns baking processes using a protocol plugin to retrieve the necessary + functionalities. (MR :gl:`!16583`) + +- Release agnostic baker binary as experimental. (MR :gl:`!16318`) + +- Use of a generic watchdog. (MR :gl:`!15508`) + +- Change the binary name to ``octez-experimental-agnostic-baker``. (MR :gl:`!16434`) + +- Added a mechanism for the agnostic baker to switch on new protocol. (MR :gl:`!15305`) + +- Introduced a dummy agnostic baker. (MR :gl:`!15029`) + +Overview: The Agnostic Baker is a protocol-independent binary that dynamically determines +and executes the appropriate baking binary based on the active protocol. It continuously +monitors the blockchain state and automatically transitions to the correct binary whenever +a new protocol is detected, such as during migrations or at startup. + +Please note that this feature is in an EXPERIMENTAL phase, as clearly suggested by its name. +Therefore, it should NOT be used on ``mainnet``. For further clarifications, you can consult +the README from ``src/bin_agnostic_baker``. + Accuser ------- diff --git a/manifest/product_octez.ml b/manifest/product_octez.ml index 238513cf02e9860f7da44113a7365f4f6379d03c..1423a8c7ac5b54d72426fe801ce10f052626003c 100644 --- a/manifest/product_octez.ml +++ b/manifest/product_octez.ml @@ -5347,6 +5347,8 @@ module Protocol : sig val dal : t -> target option + val agnostic_baker : t -> target option + val parameters_exn : t -> target val benchmarks_proto_exn : t -> target @@ -5459,6 +5461,7 @@ end = struct plugin : target option; plugin_registerer : target option; dal : target option; + agnostic_baker : target option; test_helpers : target option; parameters : target option; benchmarks_proto : target option; @@ -5470,9 +5473,9 @@ end = struct let make ?client ?client_commands ?client_commands_registration ?baking_commands_registration ?plugin ?plugin_registerer ?dal - ?test_helpers ?parameters ?benchmarks_proto ?octez_sc_rollup - ?octez_sc_rollup_node ?octez_injector ?baking ~status ~name ~main - ~embedded () = + ?agnostic_baker ?test_helpers ?parameters ?benchmarks_proto + ?octez_sc_rollup ?octez_sc_rollup_node ?octez_injector ?baking ~status + ~name ~main ~embedded () = { status; name; @@ -5485,6 +5488,7 @@ end = struct plugin; plugin_registerer; dal; + agnostic_baker; test_helpers; parameters; benchmarks_proto; @@ -5544,6 +5548,8 @@ end = struct let dal p = p.dal + let agnostic_baker p = p.agnostic_baker + let parameters_exn p = mandatory "parameters" p p.parameters let benchmarks_proto_exn p = mandatory "benchmarks_proto" p p.benchmarks_proto @@ -7110,6 +7116,26 @@ let hash = Protocol.hash alcotezt; ] in + let agnostic_baker = + only_if (active && N.(number >= 021)) @@ fun () -> + octez_protocol_lib + "agnostic-baker" + ~internal_name:(sf "tezos_agnostic_baker_%s" name_dash) + ~path:(path // "lib_agnostic_baker") + ~synopsis:"Protocol specific library for the Agnostic Baker" + ~deps: + [ + octez_base |> open_ ~m:"TzPervasives"; + client |> if_some |> open_; + embedded |> open_; + main |> open_; + octez_validation |> open_; + baking_commands |> if_some |> open_; + octez_client_commands |> open_; + octez_client_base_unix |> open_; + ] + ~linkall:true + in let octez_injector = only_if N.(active && number >= 017) @@ fun () -> private_lib @@ -7435,6 +7461,7 @@ let hash = Protocol.hash ?plugin ?plugin_registerer ?dal + ?agnostic_baker ?test_helpers ?parameters ?benchmarks_proto @@ -8169,6 +8196,18 @@ let _octez_node = ] let _octez_experimental_agnostic_baker = + let protocol_deps = + let deps_for_protocol protocol = + let is_optional = + match (Protocol.status protocol, Protocol.number protocol) with + | Active, V _ -> false + | (Frozen | Overridden | Not_mainnet), _ | Active, (Dev | Other) -> true + in + let targets = List.filter_map Fun.id [Protocol.agnostic_baker protocol] in + if is_optional then List.map optional targets else targets + in + List.map deps_for_protocol Protocol.all |> List.flatten + in public_exe "octez-experimental-agnostic-baker" ~path:"src/bin_agnostic_baker" @@ -8177,27 +8216,17 @@ let _octez_experimental_agnostic_baker = ~release_status:Released ~with_macos_security_framework:true ~deps: - [ - octez_rustzcash_deps; - bls12_381_archive; - data_encoding |> open_; - octez_base |> open_ ~m:"TzPervasives" |> open_; - octez_base_unix |> open_; - octez_validation |> open_; - octez_client_base_unix |> open_; - octez_client_base |> open_; - octez_rpc |> open_; - octez_rpc_http_client |> open_; - octez_rpc_http_client_unix |> open_; - octez_rpc_http |> open_; - cohttp_lwt_unix; - octez_node_config; - octez_clic; - octez_stdlib_unix |> open_; - octez_event_logging |> open_; - octez_signer_services; - octez_version_value; - ] + ([ + octez_rustzcash_deps; + bls12_381_archive; + data_encoding |> open_; + octez_base |> open_ ~m:"TzPervasives" |> open_; + octez_base_unix |> open_; + octez_validation |> open_; + octez_client_base_unix |> open_; + octez_node_config; + ] + @ protocol_deps) ~linkall:true let _octez_client = diff --git a/opam/octez-experimental-agnostic-baker.opam b/opam/octez-experimental-agnostic-baker.opam index a45ed011a42f0991d969de7cf9c604e51a4ed8a4..5772210e784997eb7ac47addb07bc77251f27afc 100644 --- a/opam/octez-experimental-agnostic-baker.opam +++ b/opam/octez-experimental-agnostic-baker.opam @@ -15,7 +15,14 @@ depends: [ "octez-libs" { = version } "octez-shell-libs" { = version } "octez-node-config" { = version } - "octez-version" { = version } + "octez-protocol-021-PsQuebec-libs" { = version } + "octez-protocol-022-PsRiotum-libs" { = version } +] +depopts: [ + "octez-protocol-alpha-libs" +] +conflicts: [ + "octez-protocol-alpha-libs" { != version } ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/script-inputs/ci-opam-package-tests b/script-inputs/ci-opam-package-tests index 5d501664af82686636ff3102dc9dc7c74987db46..a2c8f759c7592730b745025cf8a55a6262071b0c 100644 --- a/script-inputs/ci-opam-package-tests +++ b/script-inputs/ci-opam-package-tests @@ -12,7 +12,7 @@ octez-crawler all 4 octez-dal-node exec 1 octez-distributed-internal all 7 octez-distributed-lwt-internal all 7 -octez-experimental-agnostic-baker exec 2 +octez-experimental-agnostic-baker exec 1 octez-injector all 2 octez-internal-libs all 7 octez-l2-libs all 6 @@ -59,7 +59,7 @@ octez-smart-rollup-node-Proxford all 1 octez-smart-rollup-node-PsParisC all 1 octez-smart-rollup-node-PsQuebec all 1 octez-smart-rollup-node-PsRiotum all 1 -octez-smart-rollup-node-PtNairob all 1 +octez-smart-rollup-node-PtNairob all 2 octez-smart-rollup-node-PtParisB all 2 octez-smart-rollup-node-alpha all 2 octez-smart-rollup-node-lib all 2 diff --git a/src/bin_agnostic_baker/README.md b/src/bin_agnostic_baker/README.md index bec810985ea7dfe3a0bc9f9503ac3f8b49f216d3..3dff0205eaa21e5509b0da54dd58f7f357901b36 100644 --- a/src/bin_agnostic_baker/README.md +++ b/src/bin_agnostic_baker/README.md @@ -3,12 +3,13 @@ ## Overview Agnostic Baker is a protocol-independent binary that dynamically selects the -appropriate baking binary based on the active protocol. It monitors the state of -the blockchain and automatically switches to the correct binary when a new +appropriate baking process based on the active protocol. It monitors the state of +the blockchain and automatically switches to the correct process when a new protocol is encountered (for example, during migrations, or at startup). It is designed to simplify the baking process for users, such that they will no -longer need to run two baker binaries at migration time. +longer need to run two baker binaries at migration time. This makes the need for +protocol specific baking binaries obsolete. ## Experimental purpose @@ -29,10 +30,6 @@ for the protocol-dependent baking binaries: The `[OCTEZ-EXPERIMENTAL-AGNOSTIC-BAKER-COMMANDS]` list consists of arguments specific to the agnostic baker binary and they include: -- `--binaries-directory` : where to find the baker binaries to use -- `--endpoint` : endpoint to communicate with the connected node -- `--base-dir` : directory dedicated to the agnostic baker (that can contain logs -and configuration files) -- `--help` : displays help information The `[OCTEZ-BAKER-COMMANDS]` list consists of all the arguments that can be used @@ -44,7 +41,7 @@ the agnostic baker to replace a baking command which would be ``` they can do this by using the same `[OCTEZ-BAKER-COMMANDS]` and let the agnostic -baker run the binary for ``, information obtained from the node. +baker run the baker process for ``, information obtained from the node. Notice that the two types of arguments are separated by a clear `--`. @@ -52,8 +49,8 @@ Notice that the two types of arguments are separated by a clear `--`. 1. **Initialization**: The daemon starts and connects to the specified Tezos node. 2. **Protocol Detection**: It fetches the currently active protocol. This is done via an RPC request on the `head` metadata against the Tezos node. -3. **Baker Selection**: Based on the active protocol, it selects the corresponding `octez-baker-` binary. -4. **Baker Execution**: The chosen binary is executed with the specified arguments +3. **Baker Selection**: Based on the active protocol, it selects the corresponding baking process. +4. **Baker Execution**: The chosen baker process is executed with the specified arguments (`[OCTEZ-BAKER-COMMANDS]`). 5. **Chain Monitoring**: The daemon continuously monitors the chain for new blocks and protocol changes (based on the voting period). -6. **Protocol Updates**: If a new protocol is encountered, the daemon stops the current baker and starts a new one matching the new protocol. +6. **Protocol Updates**: If a new protocol is encountered, the daemon stops the current baker process and starts a new one matching the new protocol. This is currently done via an Lwt cancelling mechanism. diff --git a/src/bin_agnostic_baker/agnostic_baker_errors.ml b/src/bin_agnostic_baker/agnostic_baker_errors.ml index 0ebe3b98d84aa6ae1620c918cf968a3a9afb6222..ab4ebb55d04b2a92defeaf73cdcf2b503994d84f 100644 --- a/src/bin_agnostic_baker/agnostic_baker_errors.ml +++ b/src/bin_agnostic_baker/agnostic_baker_errors.ml @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) @@ -10,6 +11,8 @@ type error += | Cannot_connect_to_node of string | Cannot_decode_node_data of string | Missing_current_baker + | Missing_agnostic_baker_plugin of string + | Baker_process_error let () = Error_monad.register_error_kind @@ -47,8 +50,32 @@ let () = `Permanent ~id:"agnostic_baker.missing_current_baker" ~title:"Missing current baker" - ~description:"The current baker binary is missing." + ~description:"The current baker process is missing." ~pp:(fun ppf () -> Format.fprintf ppf "Missing current baker") Data_encoding.(unit) (function Missing_current_baker -> Some () | _ -> None) - (fun () -> Missing_current_baker) + (fun () -> Missing_current_baker) ; + Error_monad.register_error_kind + `Permanent + ~id:"agnostic_baker.missing_agnostic_baker_plugin" + ~title:"Missing agnostic baker plugin" + ~description:"Missing agnostic baker plugin." + ~pp:(fun ppf proto_hash -> + Format.fprintf + ppf + "Cannot find agnostic baker plugin for protocol %s" + proto_hash) + Data_encoding.(obj1 (req "proto_hash" string)) + (function + | Missing_agnostic_baker_plugin proto_hash -> Some proto_hash | _ -> None) + (fun proto_hash -> Missing_agnostic_baker_plugin proto_hash) ; + Error_monad.register_error_kind + `Permanent + ~id:"agnostic_baker.baker_process_error" + ~title:"Underlying baker process error" + ~description:"There is an error in the underlying baker process." + ~pp:(fun ppf () -> + Format.fprintf ppf "Error in the underlying baker process") + Data_encoding.(unit) + (function Baker_process_error -> Some () | _ -> None) + (fun () -> Baker_process_error) diff --git a/src/bin_agnostic_baker/daemon.ml b/src/bin_agnostic_baker/daemon.ml index e9f013d5bef7ceda2d2422e760a768f09494653c..d731b934192fdec1f4e8f536e7e696b1eeff2658 100644 --- a/src/bin_agnostic_baker/daemon.ml +++ b/src/bin_agnostic_baker/daemon.ml @@ -2,106 +2,64 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) open Agnostic_baker_errors -type baker = { - protocol_hash : Protocol_hash.t; - binary_path : string; - process : unit Lwt_process_watchdog.t; - ccid : Lwt_exit.clean_up_callback_id; -} - -module type BAKER = sig - module Event : sig - val emit : 'a Agnostic_baker_events.t -> 'a -> unit Lwt.t - - val shutting_down_process : unit Agnostic_baker_events.t - - val process_started : int Agnostic_baker_events.t - - val process_exited_abnormally : - (int * Unix.process_status) Agnostic_baker_events.t - - val cannot_start_process : string Agnostic_baker_events.t - - val waiting_for_process_restart : float Agnostic_baker_events.t - end - - val baker_path : ?user_path:string -> Protocol_hash.t -> string - - val shutdown : baker -> unit Lwt.t +type process = {thread : int Lwt.t; canceller : int Lwt.u} - val spawn_baker : - Protocol_hash.t -> - binaries_directory:string option -> - baker_args:string trace -> - (baker, tztrace) result Lwt.t -end +type baker = {protocol_hash : Protocol_hash.t; process : process} -module MakeBaker (Name : Lwt_process_watchdog.NAME) : BAKER = struct - module Event = Lwt_process_watchdog.MakeEvent (Name) - module Watchdog = Lwt_process_watchdog.Daemon (Event) - - let baker_path ?(user_path = "./") proto_hash = - let short_name = Parameters.protocol_short_hash proto_hash in - Format.sprintf "%soctez-baker-%s" user_path short_name - - let shutdown baker = - let open Lwt_syntax in - let* () = Agnostic_baker_events.(emit stopping_baker) baker.protocol_hash in - Watchdog.stop baker.process - - (** [spawn_baker protocol_hash ~binaries_directory ~baker_args] spawns a baker - for the given [protocol_hash] using the [~binaries_directory] as path for - the baker binary and with [~baker_args] as command line arguments. *) - let spawn_baker protocol_hash ~binaries_directory ~baker_args = - let open Lwt_result_syntax in - let args_as_string = - Format.asprintf - "%a" - (Format.pp_print_list - ~pp_sep:Format.pp_print_space - Format.pp_print_string) - baker_args - in - let*! () = - Agnostic_baker_events.(emit starting_baker) (protocol_hash, args_as_string) - in - let binary_path = baker_path ?user_path:binaries_directory protocol_hash in - let baker_args = binary_path :: baker_args in - let baker_args = Array.of_list baker_args in - let w = - Lwt_process_watchdog.create - ~parameters:() - ~parameters_encoding:Data_encoding.unit - in - let run_process = - Watchdog.run_process w ~binary_path ~arguments:baker_args - in - let* new_baker = run_process () in - let _ = Watchdog.watch_dog ~start_new_server:run_process new_baker in - let*! () = Agnostic_baker_events.(emit baker_running) protocol_hash in - let ccid = - Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _ -> - let*! () = - Agnostic_baker_events.(emit stopping_baker) protocol_hash - in - let*! () = Watchdog.stop new_baker in - Lwt.return_unit) - in - return {protocol_hash; binary_path; process = new_baker; ccid} -end +let shutdown baker = + let open Lwt_syntax in + let* () = Agnostic_baker_events.(emit stopping_baker) baker.protocol_hash in + Lwt.wakeup baker.process.canceller 0 ; + return_unit -type baker_instance = Baker : (module BAKER) -> baker_instance +(** [spawn_baker protocol_hash ~baker_args] spawns a baker for the given [protocol_hash] + with [~baker_args] as command line arguments. *) +let spawn_baker protocol_hash ~baker_args = + let open Lwt_result_syntax in + let args_as_string = + Format.asprintf + "%a" + (Format.pp_print_list + ~pp_sep:Format.pp_print_space + Format.pp_print_string) + baker_args + in + let*! () = + Agnostic_baker_events.(emit starting_baker) (protocol_hash, args_as_string) + in + (* The mocked binary argument is necessary for command line parsing done in the running + baker function below. It will be discarded, so its value is not important. *) + let baker_args = "./mock-binary" :: baker_args in + let cancel_promise, canceller = Lwt.wait () in + let* thread = + match Protocol_plugin.find_agnostic_baker_plugin protocol_hash with + | Some (module Agnostic_baker_plugin) -> + (* The internal event logging needs to be closed, because another one will be + initialised in the [run_baker_binary]. *) + let*! () = Tezos_base_unix.Internal_event_unix.close () in + return + @@ Agnostic_baker_plugin.run_baker_binary + ~baker_args + ~cancel_promise + ~logs_path:Parameters.default_daily_logs_path + | None -> + tzfail + (Missing_agnostic_baker_plugin + (Protocol_hash.to_short_b58check protocol_hash)) + in + let*! () = Agnostic_baker_events.(emit baker_running) protocol_hash in + return {protocol_hash; process = {thread; canceller}} type 'a state = { - binaries_directory : string option; node_endpoint : string; baker_args : string list; - mutable current_baker : (baker_instance * baker) option; + mutable current_baker : baker option; } type 'a t = 'a state @@ -135,14 +93,13 @@ let monitor_heads ~node_addr = (** [hot_swap_baker ~state ~next_protocol_hash] performs a swap in the current [~state] of the agnostic baker, exchanging the current baker with the one - corresponding to [~next_protocol_hash]. This is done by shutting down the - current baking binary and generating the new binary instead. *) + corresponding to [~next_protocol_hash]. This is done by stopping the + current baking process and spawning a new process instead. *) let hot_swap_baker ~state ~next_protocol_hash = let open Lwt_result_syntax in - let* (module CurrentBaker : BAKER), current_baker = + let* current_baker = match state.current_baker with - | Some (Baker (module Baker), baker) -> - return ((module Baker : BAKER), baker) + | Some baker -> return baker | None -> tzfail Missing_current_baker in let next_proto_status = Parameters.protocol_status next_protocol_hash in @@ -151,29 +108,10 @@ let hot_swap_baker ~state ~next_protocol_hash = (next_proto_status, next_protocol_hash) in (* Shutdown previous baker *) - let*! () = - let*! () = CurrentBaker.shutdown current_baker in - let () = Lwt_exit.unregister_clean_up_callback current_baker.ccid in - state.current_baker <- None ; - Lwt.return_unit - in + let*! () = shutdown current_baker in + state.current_baker <- None ; let* new_baker = - let module Name = struct - let base = ["agnostic"; "baker"] - - let component = - [ - "baker"; Format.asprintf "%a" Protocol_hash.pp_short next_protocol_hash; - ] - end in - let module NewBaker = MakeBaker (Name) in - let* new_baker = - NewBaker.spawn_baker - next_protocol_hash - ~binaries_directory:state.binaries_directory - ~baker_args:state.baker_args - in - return (Baker (module NewBaker), new_baker) + spawn_baker next_protocol_hash ~baker_args:state.baker_args in state.current_baker <- Some new_baker ; return_unit @@ -201,7 +139,7 @@ let monitor_voting_periods ~state head_stream = let* current_protocol_hash = match state.current_baker with | None -> tzfail Missing_current_baker - | Some (_, v) -> return v.protocol_hash + | Some v -> return v.protocol_hash in let* () = if not (Protocol_hash.equal current_protocol_hash next_protocol_hash) @@ -209,11 +147,22 @@ let monitor_voting_periods ~state head_stream = else return_unit in loop () - | None -> return_unit + | None -> tzfail Lost_node_connection in let* () = loop () in return_unit +(** [baker_thread ~state] monitors the current baker thread for any potential error, and + it propagates any error that can appear. *) +let baker_thread ~state = + let open Lwt_result_syntax in + let*! retcode = + match state.current_baker with + | Some baker -> baker.process.thread + | None -> Lwt.return 0 + in + if retcode = 0 then return_unit else tzfail Baker_process_error + (** [may_start_initial_baker state] aims to start the baker associated to the current protocol. If the protocol is considered as [frozen] (not [active] anymore), and there is thus no actual baker binary anymore, the @@ -239,23 +188,7 @@ let may_start_initial_baker state = match proto_status with | Active -> let* current_baker = - let module Name = struct - let base = ["agnostic"; "baker"] - - let component = - [ - "baker"; - Format.asprintf "%a" Protocol_hash.pp_short protocol_hash; - ] - end in - let module NewBaker = MakeBaker (Name) in - let* new_baker = - NewBaker.spawn_baker - protocol_hash - ~binaries_directory:state.binaries_directory - ~baker_args:state.baker_args - in - return (Baker (module NewBaker), new_baker) + spawn_baker protocol_hash ~baker_args:state.baker_args in state.current_baker <- Some current_baker ; return_unit @@ -284,8 +217,8 @@ let may_start_initial_baker state = in may_start ~head_stream:None () -let create ~binaries_directory ~node_endpoint ~baker_args = - {binaries_directory; node_endpoint; baker_args; current_baker = None} +let create ~node_endpoint ~baker_args = + {node_endpoint; baker_args; current_baker = None} let run state = let open Lwt_result_syntax in @@ -301,5 +234,7 @@ let run state = let* head_stream = monitor_heads ~node_addr in (* Monitoring voting periods through heads monitoring to avoid missing UAUs. *) - let* () = monitor_voting_periods ~state head_stream in + let* () = + Lwt.pick [monitor_voting_periods ~state head_stream; baker_thread ~state] + in return_unit diff --git a/src/bin_agnostic_baker/daemon.mli b/src/bin_agnostic_baker/daemon.mli index 0577ab5eef4ae61c4101e6c12de7e436e77aacdc..38d8b90c5f336fbea181488d346d35772dbd1a44 100644 --- a/src/bin_agnostic_baker/daemon.mli +++ b/src/bin_agnostic_baker/daemon.mli @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) @@ -22,13 +23,8 @@ type 'a t -(** [create ~binaries_directory ~node_endpoint ~baker_args] returns a non - initialized daemon. *) -val create : - binaries_directory:string option -> - node_endpoint:string -> - baker_args:string trace -> - 'a t +(** [create ~node_endpoint ~baker_args] returns a non initialized daemon. *) +val create : node_endpoint:string -> baker_args:string list -> 'a t (** [run t] Runs the daemon responsible for the spawn/stop of the baker daemons. *) diff --git a/src/bin_agnostic_baker/dune b/src/bin_agnostic_baker/dune index 642fd938ec2e4307cb105cc9a1cdcf22c44b7aa2..35dcc526cb82069745e180d87719e0781e7d878a 100644 --- a/src/bin_agnostic_baker/dune +++ b/src/bin_agnostic_baker/dune @@ -14,18 +14,12 @@ octez-libs.base.unix octez-shell-libs.validation octez-shell-libs.client-base-unix - octez-shell-libs.client-base - octez-libs.rpc - octez-libs.rpc-http-client - octez-libs.rpc-http-client-unix - octez-libs.rpc-http - octez-libs.cohttp-lwt-unix octez-node-config - octez-libs.clic - octez-libs.stdlib-unix - octez-libs.event-logging - octez-shell-libs.signer-services - octez-version.value) + octez-protocol-021-PsQuebec-libs.agnostic-baker + octez-protocol-022-PsRiotum-libs.agnostic-baker + (select void_for_linking-octez-protocol-alpha-libs-agnostic-baker from + (octez-protocol-alpha-libs.agnostic-baker -> void_for_linking-octez-protocol-alpha-libs-agnostic-baker.empty) + (-> void_for_linking-octez-protocol-alpha-libs-agnostic-baker.empty))) (link_flags (:standard) (:include %{workspace_root}/static-link-flags.sexp) @@ -38,11 +32,9 @@ -open Tezos_base -open Tezos_base_unix -open Tezos_validation - -open Tezos_client_base_unix - -open Tezos_client_base - -open Tezos_rpc - -open Tezos_rpc_http_client - -open Tezos_rpc_http_client_unix - -open Tezos_rpc_http - -open Tezos_stdlib_unix - -open Tezos_event_logging)) + -open Tezos_client_base_unix)) + +(rule + (action + (progn + (write-file void_for_linking-octez-protocol-alpha-libs-agnostic-baker.empty "")))) diff --git a/src/bin_agnostic_baker/main_agnostic_baker.ml b/src/bin_agnostic_baker/main_agnostic_baker.ml index 493a23ff60d632b6e7bc63d44b963eefacdabb5f..61e471eca75d97185c571f8a4e1e95c6ceb6a01e 100644 --- a/src/bin_agnostic_baker/main_agnostic_baker.ml +++ b/src/bin_agnostic_baker/main_agnostic_baker.ml @@ -2,12 +2,13 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) let run () = let open Lwt_result_syntax in - let Run_args.{node_endpoint; base_dir; binaries_directory; baker_args} = + let Run_args.{node_endpoint; base_dir; baker_args} = Run_args.parse_args Sys.argv in let*! () = @@ -15,7 +16,7 @@ let run () = ~config:(Parameters.log_config ~base_dir) () in - let daemon = Daemon.create ~binaries_directory ~node_endpoint ~baker_args in + let daemon = Daemon.create ~node_endpoint ~baker_args in let* (_ : unit) = Daemon.run daemon in let*! () = Lwt_utils.never_ending () in return_unit diff --git a/src/bin_agnostic_baker/parameters.ml b/src/bin_agnostic_baker/parameters.ml index 723aedec3a17088392de1d65d9ebbe336b0734ff..e273beaa109b79c761b6e53d4827ea757b76c0ef 100644 --- a/src/bin_agnostic_baker/parameters.ml +++ b/src/bin_agnostic_baker/parameters.ml @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) diff --git a/src/bin_agnostic_baker/parameters.mli b/src/bin_agnostic_baker/parameters.mli index fe22e5bf98cd6238013b72a7c17ccc9e0dec874b..df009a953ce5c48539be61c21b50d56a1d5244c0 100644 --- a/src/bin_agnostic_baker/parameters.mli +++ b/src/bin_agnostic_baker/parameters.mli @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) @@ -9,6 +10,9 @@ [Octez_node_config.Config_file.default_rpc_port]. *) 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 option -> Tezos_base.Internal_event_config.t (** Status of a protocol, based on Manifest/Product_octez/Protocol. A diff --git a/src/bin_agnostic_baker/run_args.ml b/src/bin_agnostic_baker/run_args.ml index 7b7654d93d299e2876170dd16311686ee6d542bb..1ce213c7cedaddaf583faacf7c647b65cc00ee19 100644 --- a/src/bin_agnostic_baker/run_args.ml +++ b/src/bin_agnostic_baker/run_args.ml @@ -2,11 +2,10 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) -let binaries_directory_arg = "--binaries-directory" - let endpoint_arg = "--endpoint" let endpoint_short_arg = "-E" @@ -24,11 +23,8 @@ let print_help () = [OCTEZ-EXPERIMENTAL-AGNOSTIC-BAKER-COMMANDS] -- \ [OCTEZ-BAKER-COMMANDS]@.@." ; Format.printf - "OCTEZ-EXPERIMENTAL-AGNOSTIC-BAKER-COMMANDS:\n\ - \ %s: display help\n\ - \ %s: path to the octez-baker binaries@.@." - help_arg - binaries_directory_arg ; + "OCTEZ-EXPERIMENTAL-AGNOSTIC-BAKER-COMMANDS:\n %s: display help@.@." + help_arg ; Format.printf "OCTEZ-BAKER-COMMANDS:\n Run ./octez-baker- --help@." @@ -62,8 +58,6 @@ let get_arg_value ~arg ?(short_arg = "") = let get_endpoint = get_arg_value ~arg:endpoint_arg ~short_arg:endpoint_short_arg -let get_binaries_directory = get_arg_value ~arg:binaries_directory_arg - let fail_on_empty_baker_args baker_args = if List.is_empty baker_args then ( Format.eprintf @@ -77,7 +71,6 @@ let get_base_dir = get_arg_value ~arg:base_dir_arg ~short_arg:base_dir_short_arg type args = { node_endpoint : string; base_dir : string option; - binaries_directory : string option; baker_args : string list; } @@ -96,6 +89,5 @@ let parse_args all_args = ~default:Parameters.default_node_endpoint (get_endpoint baker_args) in - let binaries_directory = get_binaries_directory agnostic_baker_args in let base_dir = get_base_dir baker_args in - {node_endpoint; base_dir; binaries_directory; baker_args} + {node_endpoint; base_dir; baker_args} diff --git a/src/bin_agnostic_baker/run_args.mli b/src/bin_agnostic_baker/run_args.mli index cfe66e06de6da01c29db4de0b3061d57deaca748..83a39f03a5f5ef16d292472cb939a0ea9efbd2d7 100644 --- a/src/bin_agnostic_baker/run_args.mli +++ b/src/bin_agnostic_baker/run_args.mli @@ -2,6 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2024 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (*****************************************************************************) @@ -9,11 +10,10 @@ type args = { node_endpoint : string; base_dir : string option; - binaries_directory : string option; baker_args : string list; } (** [parse_args args] is a raw utility that aims to parse the given arguments from the command line and to return, respectively, the - [endpoint], [base_dir], [binaries_directory] and [baker_args]. *) + [endpoint], [base_dir] and [baker_args]. *) val parse_args : string array -> args diff --git a/src/lib_client_base_unix/client_main_run.ml b/src/lib_client_base_unix/client_main_run.ml index 02d2f5bc8200ccf99036ade78f136cb7f7e4de65..9fbdfd8826ca748ef09731da2ded2ad476dc5350 100644 --- a/src/lib_client_base_unix/client_main_run.ml +++ b/src/lib_client_base_unix/client_main_run.ml @@ -3,6 +3,7 @@ (* Open Source License *) (* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) (* Copyright (c) 2018 Nomadic Labs, *) +(* Copyright (c) 2025 Trilitech *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -405,7 +406,7 @@ let warn_if_argv0_name_not_octez () = executable_name (* Main (lwt) entry *) -let main (module C : M) ~select_commands = +let main (module C : M) ~select_commands ?cmd_args () = let open Lwt_result_syntax in let global_options = C.global_options () in let executable_name = Filename.basename Sys.executable_name in @@ -418,7 +419,7 @@ let main (module C : M) ~select_commands = | x :: rest -> move_autocomplete_token_upfront (x :: acc) rest | [] -> (List.rev acc, None) in - match Array.to_list Sys.argv with + match Option.value ~default:(Array.to_list Sys.argv) cmd_args with | _ :: args -> move_autocomplete_token_upfront [] args | [] -> ([], None) in @@ -632,4 +633,13 @@ let run (module M : M) Lwt.Exception_filter.(set handle_all_except_runtime) ; Stdlib.exit @@ Tezos_base_unix.Event_loop.main_run @@ Lwt_exit.wrap_and_forward - @@ main (module M) ~select_commands + @@ main (module M) ~select_commands () + +let lwt_run (module M : M) + ~(select_commands : + RPC_client_unix.http_ctxt -> + Client_config.cli_args -> + Client_context.full Tezos_clic.command list tzresult Lwt.t) ?cmd_args () + = + Lwt.Exception_filter.(set handle_all_except_runtime) ; + Lwt_exit.wrap_and_forward @@ main (module M) ~select_commands ?cmd_args () diff --git a/src/lib_client_base_unix/client_main_run.mli b/src/lib_client_base_unix/client_main_run.mli index 6eb6d1763bfc7f0c96d67daecc372854e786682f..0796d1ae7a9095c51d09f2d3ec3f0e16b7438e7d 100644 --- a/src/lib_client_base_unix/client_main_run.mli +++ b/src/lib_client_base_unix/client_main_run.mli @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. *) +(* Copyright (c) 2025 Trilitech *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -97,3 +98,18 @@ val run : Client_config.cli_args -> Client_context.full Tezos_clic.command list tzresult Lwt.t) -> unit + +(** [lwt_run (module M) ~select_commands ?cmd_args ()] sets up the main + application computation as an Lwt promise. Unlike [run], this function + does not run the event loop, it merely returns the wrapped promise to be + integrated into an existing Lwt-based application. It can optionally use + [?cmd_args] as already parsed arguments to the [main] function. *) +val lwt_run : + (module M) -> + select_commands: + (RPC_client_unix.http_ctxt -> + Client_config.cli_args -> + Client_context.full Tezos_clic.command list tzresult Lwt.t) -> + ?cmd_args:string list -> + unit -> + int Lwt.t diff --git a/src/lib_validation/protocol_plugin.ml b/src/lib_validation/protocol_plugin.ml index b1c6bc8aba5776978bcb6c2d1c50f834a948b980..71bbcd6c394347d44c90a9014218689e7d84640f 100644 --- a/src/lib_validation/protocol_plugin.ml +++ b/src/lib_validation/protocol_plugin.ml @@ -3,7 +3,7 @@ (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2018 Nomadic Development. *) (* Copyright (c) 2018-2022 Nomadic Labs, *) -(* Copyright (c) 2024 TriliTech *) +(* Copyright (c) 2024-2025 TriliTech *) (* *) (*****************************************************************************) @@ -165,6 +165,16 @@ module type SHELL_HELPERS = sig Tezos_protocol_environment.Context.t -> int32 option Lwt.t end +module type AGNOSTIC_BAKER_PLUGIN = sig + val hash : Protocol_hash.t + + val run_baker_binary : + baker_args:string list -> + cancel_promise:int Lwt.t -> + logs_path:string option -> + int Lwt.t +end + let rpc_table : (module RPC) Protocol_hash.Table.t = Protocol_hash.Table.create 5 @@ -178,6 +188,10 @@ let http_cache_headers_table : (module HTTP_CACHE_HEADERS) Protocol_hash.Table.t let shell_helpers_table : (module SHELL_HELPERS) Protocol_hash.Table.t = Protocol_hash.Table.create 5 +let agnostic_baker_plugin_table : + (module AGNOSTIC_BAKER_PLUGIN) Protocol_hash.Table.t = + Protocol_hash.Table.create 5 + let register_rpc (module Rpc : RPC) = assert (not (Protocol_hash.Table.mem rpc_table Rpc.Proto.hash)) ; Protocol_hash.Table.add rpc_table Rpc.Proto.hash (module Rpc) @@ -202,6 +216,18 @@ let register_shell_helpers (module Shell_helpers : SHELL_HELPERS) = Shell_helpers.hash (module Shell_helpers) +let register_agnostic_baker_plugin + (module Agnostic_baker_plugin : AGNOSTIC_BAKER_PLUGIN) = + assert ( + not + (Protocol_hash.Table.mem + agnostic_baker_plugin_table + Agnostic_baker_plugin.hash)) ; + Protocol_hash.Table.add + agnostic_baker_plugin_table + Agnostic_baker_plugin.hash + (module Agnostic_baker_plugin) + let find_rpc = Protocol_hash.Table.find rpc_table let find_metrics = Protocol_hash.Table.find metrics_table @@ -210,6 +236,9 @@ let find_http_cache_headers = Protocol_hash.Table.find http_cache_headers_table let find_shell_helpers = Protocol_hash.Table.find shell_helpers_table +let find_agnostic_baker_plugin = + Protocol_hash.Table.find agnostic_baker_plugin_table + let safe_find_metrics hash = match find_metrics hash with | Some proto_metrics -> Lwt.return proto_metrics diff --git a/src/lib_validation/protocol_plugin.mli b/src/lib_validation/protocol_plugin.mli index f3c5ad98978a18666cd8b8806c7c4e92d069ac3b..213ef58277b570141d6909e5b9ad2d7bc1f5487f 100644 --- a/src/lib_validation/protocol_plugin.mli +++ b/src/lib_validation/protocol_plugin.mli @@ -3,7 +3,7 @@ (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2018 Nomadic Development. *) (* Copyright (c) 2018-2022 Nomadic Labs, *) -(* Copyright (c) 2024 TriliTech *) +(* Copyright (c) 2024-2025 TriliTech *) (* *) (*****************************************************************************) @@ -212,6 +212,18 @@ module type SHELL_HELPERS = sig Tezos_protocol_environment.Context.t -> int32 option Lwt.t end +(** Protocol specific plugin to expose functions helpful in the scope + of the agnostic baker binary. *) +module type AGNOSTIC_BAKER_PLUGIN = sig + val hash : Protocol_hash.t + + val run_baker_binary : + baker_args:string list -> + cancel_promise:int Lwt.t -> + logs_path:string option -> + int Lwt.t +end + (** Register a validation plugin for a specific protocol (according to its [Proto.hash]). *) val register_validation_plugin : (module T) -> unit @@ -228,6 +240,9 @@ val register_http_cache_headers_plugin : (module HTTP_CACHE_HEADERS) -> unit (** Register a Shell_helpers plugin module *) val register_shell_helpers : (module SHELL_HELPERS) -> unit +(** Register an Agnostic_baker_plugin module *) +val register_agnostic_baker_plugin : (module AGNOSTIC_BAKER_PLUGIN) -> unit + (** Retrieves the registered protocol with the provided hash and wraps it together with its validation plugin. @@ -258,3 +273,7 @@ val find_http_cache_headers : (** Looks for a shell helpers plugin module for a specific protocol *) val find_shell_helpers : Protocol_hash.t -> (module SHELL_HELPERS) option + +(** Looks for an agnostic baker plugin module for a specific protocol *) +val find_agnostic_baker_plugin : + Protocol_hash.t -> (module AGNOSTIC_BAKER_PLUGIN) option diff --git a/src/proto_021_PsQuebec/lib_agnostic_baker/agnostic_baker_plugin_registration.ml b/src/proto_021_PsQuebec/lib_agnostic_baker/agnostic_baker_plugin_registration.ml new file mode 100644 index 0000000000000000000000000000000000000000..2cda851a511ff4b6c65e0a5af14f608d727740c5 --- /dev/null +++ b/src/proto_021_PsQuebec/lib_agnostic_baker/agnostic_baker_plugin_registration.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Trilitech *) +(* *) +(*****************************************************************************) + +module Agnostic_baker_plugin = struct + let hash = Registerer.Registered.hash + + let register_commands () = + Client_commands.register Protocol.hash @@ fun _network -> + List.map (Tezos_clic.map_command (new Protocol_client_context.wrap_full)) + @@ Baking_commands.baker_commands () + + let select_commands _ _ = + let open Lwt_result_syntax in + return + (List.map + (Tezos_clic.map_command (new Protocol_client_context.wrap_full)) + (Baking_commands.baker_commands ())) + + (* 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. + For a long running binary however it is important to make sure that the + parameters files are there at the start and avoid failing much later while + validating an operation. Plus paying this cost upfront means that the first + validation will not be more expensive. *) + let init_sapling_params () = Tezos_sapling.Core.Validator.init_params () + + let run_baker_binary ~baker_args ~cancel_promise ~logs_path = + let module Config = struct + include Daemon_config + + let default_daily_logs_path = logs_path + end in + register_commands () ; + init_sapling_params () ; + Lwt.pick + [ + Client_main_run.lwt_run + (module Config) + ~select_commands + ~cmd_args:baker_args + (); + cancel_promise; + ] +end + +let () = + Protocol_plugin.register_agnostic_baker_plugin (module Agnostic_baker_plugin) diff --git a/src/proto_021_PsQuebec/lib_agnostic_baker/dune b/src/proto_021_PsQuebec/lib_agnostic_baker/dune new file mode 100644 index 0000000000000000000000000000000000000000..09ef392b712c906553c9cd6a860fc314e8a53f42 --- /dev/null +++ b/src/proto_021_PsQuebec/lib_agnostic_baker/dune @@ -0,0 +1,27 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name tezos_agnostic_baker_021_PsQuebec) + (public_name octez-protocol-021-PsQuebec-libs.agnostic-baker) + (instrumentation (backend bisect_ppx)) + (libraries + octez-libs.base + octez-protocol-021-PsQuebec-libs.client + tezos-protocol-021-PsQuebec.embedded-protocol + tezos-protocol-021-PsQuebec.protocol + octez-shell-libs.validation + octez-protocol-021-PsQuebec-libs.baking-commands + octez-shell-libs.client-commands + octez-shell-libs.client-base-unix) + (library_flags (:standard -linkall)) + (flags + (:standard) + -open Tezos_base.TzPervasives + -open Tezos_client_021_PsQuebec + -open Tezos_embedded_protocol_021_PsQuebec + -open Tezos_protocol_021_PsQuebec + -open Tezos_validation + -open Tezos_baking_021_PsQuebec_commands + -open Tezos_client_commands + -open Tezos_client_base_unix)) diff --git a/src/proto_021_PsQuebec/lib_plugin/index.mld b/src/proto_021_PsQuebec/lib_plugin/index.mld index fceabc94bbb8036b183c14bd15664acbb8eb0702..85f6a5a73ef3994f37c8ef51ab3784e240595017 100644 --- a/src/proto_021_PsQuebec/lib_plugin/index.mld +++ b/src/proto_021_PsQuebec/lib_plugin/index.mld @@ -5,6 +5,7 @@ This is a package containing some libraries related to the Tezos 021-PsQuebec pr It contains the following libraries: - {{!module-Tezos_021_PsQuebec_test_helpers}Tezos_021_PsQuebec_test_helpers}: Protocol testing framework +- {{!module-Tezos_agnostic_baker_021_PsQuebec}Tezos_agnostic_baker_021_PsQuebec}: Protocol specific library for the Agnostic Baker - {{!module-Tezos_baking_021_PsQuebec}Tezos_baking_021_PsQuebec}: Base library for `tezos-baker/accuser` - {{!module-Tezos_baking_021_PsQuebec_commands}Tezos_baking_021_PsQuebec_commands}: Protocol-specific commands for baking - {{!module-Tezos_client_021_PsQuebec}Tezos_client_021_PsQuebec}: Protocol specific library for `octez-client` diff --git a/src/proto_022_PsRiotum/lib_agnostic_baker/agnostic_baker_plugin_registration.ml b/src/proto_022_PsRiotum/lib_agnostic_baker/agnostic_baker_plugin_registration.ml new file mode 100644 index 0000000000000000000000000000000000000000..2cda851a511ff4b6c65e0a5af14f608d727740c5 --- /dev/null +++ b/src/proto_022_PsRiotum/lib_agnostic_baker/agnostic_baker_plugin_registration.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Trilitech *) +(* *) +(*****************************************************************************) + +module Agnostic_baker_plugin = struct + let hash = Registerer.Registered.hash + + let register_commands () = + Client_commands.register Protocol.hash @@ fun _network -> + List.map (Tezos_clic.map_command (new Protocol_client_context.wrap_full)) + @@ Baking_commands.baker_commands () + + let select_commands _ _ = + let open Lwt_result_syntax in + return + (List.map + (Tezos_clic.map_command (new Protocol_client_context.wrap_full)) + (Baking_commands.baker_commands ())) + + (* 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. + For a long running binary however it is important to make sure that the + parameters files are there at the start and avoid failing much later while + validating an operation. Plus paying this cost upfront means that the first + validation will not be more expensive. *) + let init_sapling_params () = Tezos_sapling.Core.Validator.init_params () + + let run_baker_binary ~baker_args ~cancel_promise ~logs_path = + let module Config = struct + include Daemon_config + + let default_daily_logs_path = logs_path + end in + register_commands () ; + init_sapling_params () ; + Lwt.pick + [ + Client_main_run.lwt_run + (module Config) + ~select_commands + ~cmd_args:baker_args + (); + cancel_promise; + ] +end + +let () = + Protocol_plugin.register_agnostic_baker_plugin (module Agnostic_baker_plugin) diff --git a/src/proto_022_PsRiotum/lib_agnostic_baker/dune b/src/proto_022_PsRiotum/lib_agnostic_baker/dune new file mode 100644 index 0000000000000000000000000000000000000000..593e525dd92406b7b9bd275bb09ece1781a8b4b3 --- /dev/null +++ b/src/proto_022_PsRiotum/lib_agnostic_baker/dune @@ -0,0 +1,27 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name tezos_agnostic_baker_022_PsRiotum) + (public_name octez-protocol-022-PsRiotum-libs.agnostic-baker) + (instrumentation (backend bisect_ppx)) + (libraries + octez-libs.base + octez-protocol-022-PsRiotum-libs.client + tezos-protocol-022-PsRiotum.embedded-protocol + tezos-protocol-022-PsRiotum.protocol + octez-shell-libs.validation + octez-protocol-022-PsRiotum-libs.baking-commands + octez-shell-libs.client-commands + octez-shell-libs.client-base-unix) + (library_flags (:standard -linkall)) + (flags + (:standard) + -open Tezos_base.TzPervasives + -open Tezos_client_022_PsRiotum + -open Tezos_embedded_protocol_022_PsRiotum + -open Tezos_protocol_022_PsRiotum + -open Tezos_validation + -open Tezos_baking_022_PsRiotum_commands + -open Tezos_client_commands + -open Tezos_client_base_unix)) diff --git a/src/proto_022_PsRiotum/lib_plugin/index.mld b/src/proto_022_PsRiotum/lib_plugin/index.mld index d93ce8738ccec7a75e5faf34ffba808af7ce0a4b..fb9418b42a379231dd1059940e0d74131afffe60 100644 --- a/src/proto_022_PsRiotum/lib_plugin/index.mld +++ b/src/proto_022_PsRiotum/lib_plugin/index.mld @@ -5,6 +5,7 @@ This is a package containing some libraries related to the Tezos 022-PsRiotum pr It contains the following libraries: - {{!module-Tezos_022_PsRiotum_test_helpers}Tezos_022_PsRiotum_test_helpers}: Protocol testing framework +- {{!module-Tezos_agnostic_baker_022_PsRiotum}Tezos_agnostic_baker_022_PsRiotum}: Protocol specific library for the Agnostic Baker - {{!module-Tezos_baking_022_PsRiotum}Tezos_baking_022_PsRiotum}: Base library for `tezos-baker/accuser` - {{!module-Tezos_baking_022_PsRiotum_commands}Tezos_baking_022_PsRiotum_commands}: Protocol-specific commands for baking - {{!module-Tezos_client_022_PsRiotum}Tezos_client_022_PsRiotum}: Protocol specific library for `octez-client` diff --git a/src/proto_alpha/lib_agnostic_baker/agnostic_baker_plugin_registration.ml b/src/proto_alpha/lib_agnostic_baker/agnostic_baker_plugin_registration.ml new file mode 100644 index 0000000000000000000000000000000000000000..2cda851a511ff4b6c65e0a5af14f608d727740c5 --- /dev/null +++ b/src/proto_alpha/lib_agnostic_baker/agnostic_baker_plugin_registration.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Trilitech *) +(* *) +(*****************************************************************************) + +module Agnostic_baker_plugin = struct + let hash = Registerer.Registered.hash + + let register_commands () = + Client_commands.register Protocol.hash @@ fun _network -> + List.map (Tezos_clic.map_command (new Protocol_client_context.wrap_full)) + @@ Baking_commands.baker_commands () + + let select_commands _ _ = + let open Lwt_result_syntax in + return + (List.map + (Tezos_clic.map_command (new Protocol_client_context.wrap_full)) + (Baking_commands.baker_commands ())) + + (* 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. + For a long running binary however it is important to make sure that the + parameters files are there at the start and avoid failing much later while + validating an operation. Plus paying this cost upfront means that the first + validation will not be more expensive. *) + let init_sapling_params () = Tezos_sapling.Core.Validator.init_params () + + let run_baker_binary ~baker_args ~cancel_promise ~logs_path = + let module Config = struct + include Daemon_config + + let default_daily_logs_path = logs_path + end in + register_commands () ; + init_sapling_params () ; + Lwt.pick + [ + Client_main_run.lwt_run + (module Config) + ~select_commands + ~cmd_args:baker_args + (); + cancel_promise; + ] +end + +let () = + Protocol_plugin.register_agnostic_baker_plugin (module Agnostic_baker_plugin) diff --git a/src/proto_alpha/lib_agnostic_baker/dune b/src/proto_alpha/lib_agnostic_baker/dune new file mode 100644 index 0000000000000000000000000000000000000000..f1483edf2d59b588f27ccc28047608795254d1e6 --- /dev/null +++ b/src/proto_alpha/lib_agnostic_baker/dune @@ -0,0 +1,27 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name tezos_agnostic_baker_alpha) + (public_name octez-protocol-alpha-libs.agnostic-baker) + (instrumentation (backend bisect_ppx)) + (libraries + octez-libs.base + octez-protocol-alpha-libs.client + tezos-protocol-alpha.embedded-protocol + tezos-protocol-alpha.protocol + octez-shell-libs.validation + octez-protocol-alpha-libs.baking-commands + octez-shell-libs.client-commands + octez-shell-libs.client-base-unix) + (library_flags (:standard -linkall)) + (flags + (:standard) + -open Tezos_base.TzPervasives + -open Tezos_client_alpha + -open Tezos_embedded_protocol_alpha + -open Tezos_protocol_alpha + -open Tezos_validation + -open Tezos_baking_alpha_commands + -open Tezos_client_commands + -open Tezos_client_base_unix)) diff --git a/src/proto_alpha/lib_plugin/index.mld b/src/proto_alpha/lib_plugin/index.mld index ff090a2a0ab16803f3eb25c450d87a6708ca5a50..3d4d386ddbe3ffe9e1c352e54ad8296e53a388ce 100644 --- a/src/proto_alpha/lib_plugin/index.mld +++ b/src/proto_alpha/lib_plugin/index.mld @@ -4,6 +4,7 @@ This is a package containing some libraries related to the Tezos alpha protocol. It contains the following libraries: +- {{!module-Tezos_agnostic_baker_alpha}Tezos_agnostic_baker_alpha}: Protocol specific library for the Agnostic Baker - {{!module-Tezos_alpha_test_helpers}Tezos_alpha_test_helpers}: Protocol testing framework - {{!module-Tezos_baking_alpha}Tezos_baking_alpha}: Base library for `tezos-baker/accuser` - {{!module-Tezos_baking_alpha_commands}Tezos_baking_alpha_commands}: Protocol-specific commands for baking diff --git a/tezt/lib_tezos/agnostic_baker.ml b/tezt/lib_tezos/agnostic_baker.ml index ab8693674a11d0f56e94ee6e6408bb705066e131..151838945af3afbb544a3d5e6f23becf6368431c 100644 --- a/tezt/lib_tezos/agnostic_baker.ml +++ b/tezt/lib_tezos/agnostic_baker.ml @@ -12,6 +12,12 @@ let liquidity_baking_vote_to_string = function | On -> "on" | Pass -> "pass" +let liquidity_baking_vote_of_string_opt = function + | "off" -> Some Off + | "on" -> Some On + | "pass" -> Some Pass + | _ -> None + type protocol_status = Active | Frozen | Ignore let protocol_status = function Protocol.Alpha -> Ignore | _ -> Active @@ -25,6 +31,7 @@ module Parameters = struct node_rpc_endpoint : Endpoint.t; dal_node_rpc_endpoint : Endpoint.t option; mutable pending_ready : unit option Lwt.u list; + votefile : string option; liquidity_baking_toggle_vote : liquidity_baking_vote option; force_apply_from_round : int option; remote_mode : bool; @@ -55,13 +62,28 @@ let set_ready agnostic_baker = | Running status -> status.session_state.ready <- true) ; trigger_ready agnostic_baker (Some ()) +let liquidity_baking_votefile ?path vote = + let votefile = + Option.value + path + ~default:(Temp.file "liquidity_baking_toggle_votefile.json") + in + JSON.encode_to_file_u + votefile + (`O + [ + ( "liquidity_baking_toggle_vote", + `String (liquidity_baking_vote_to_string vote) ); + ]) ; + votefile + let create_from_uris ?runner ?(path = Uses.path Constant.octez_experimental_agnostic_baker) ?name ?color - ?event_pipe ?(delegates = []) ?(liquidity_baking_toggle_vote = Some Pass) - ?force_apply_from_round ?(remote_mode = false) ?operations_pool - ?dal_node_rpc_endpoint ?(state_recorder = false) - ?(node_version_check_bypass = false) ?node_version_allowed ~base_dir - ~node_data_dir ~node_rpc_endpoint () = + ?event_pipe ?(delegates = []) ?votefile + ?(liquidity_baking_toggle_vote = Some Pass) ?force_apply_from_round + ?(remote_mode = false) ?operations_pool ?dal_node_rpc_endpoint + ?(state_recorder = false) ?(node_version_check_bypass = false) + ?node_version_allowed ~base_dir ~node_data_dir ~node_rpc_endpoint () = let agnostic_baker = create ~path @@ -76,6 +98,7 @@ let create_from_uris ?runner node_data_dir; node_rpc_endpoint; pending_ready = []; + votefile; liquidity_baking_toggle_vote; force_apply_from_round; remote_mode; @@ -91,7 +114,7 @@ let create_from_uris ?runner let handle_event node ({name; _} : event) = match name with "starting_daemon.v0" -> set_ready node | _ -> () -let create ?runner ?path ?name ?color ?event_pipe ?(delegates = []) +let create ?runner ?path ?name ?color ?event_pipe ?(delegates = []) ?votefile ?(liquidity_baking_toggle_vote = Some Pass) ?force_apply_from_round ?(remote_mode = false) ?operations_pool ?dal_node ?(state_recorder = false) ?(node_version_check_bypass = false) ?node_version_allowed node client = @@ -104,6 +127,7 @@ let create ?runner ?path ?name ?color ?event_pipe ?(delegates = []) ?color ?event_pipe ~delegates + ?votefile ~liquidity_baking_toggle_vote ?force_apply_from_round ~remote_mode @@ -132,6 +156,12 @@ let run ?event_level ?event_sections_levels (agnostic_baker : t) = let node_addr = Endpoint.as_string agnostic_baker.persistent_state.node_rpc_endpoint in + let votefile = + Cli_arg.optional_arg + "votefile" + Fun.id + agnostic_baker.persistent_state.votefile + in let liquidity_baking_toggle_vote = Cli_arg.optional_arg "liquidity-baking-toggle-vote" @@ -186,7 +216,7 @@ let run ?event_level ?event_sections_levels (agnostic_baker : t) = in let arguments = ["--"; "--endpoint"; node_addr; "--base-dir"; base_dir; "run"] - @ run_args @ delegates @ liquidity_baking_toggle_vote + @ run_args @ delegates @ liquidity_baking_toggle_vote @ votefile @ force_apply_from_round @ operations_pool @ dal_node_endpoint @ without_dal @ state_recorder @ node_version_check_bypass @ node_version_allowed in @@ -225,9 +255,10 @@ let wait_for_ready agnostic_baker = let init ?runner ?(path = Uses.path Constant.octez_experimental_agnostic_baker) ?name ?color ?event_level ?event_pipe ?event_sections_levels - ?(delegates = []) ?liquidity_baking_toggle_vote ?force_apply_from_round - ?remote_mode ?operations_pool ?dal_node ?state_recorder - ?node_version_check_bypass ?node_version_allowed node client = + ?(delegates = []) ?votefile ?liquidity_baking_toggle_vote + ?force_apply_from_round ?remote_mode ?operations_pool ?dal_node + ?state_recorder ?node_version_check_bypass ?node_version_allowed node client + = let* () = Node.wait_for_ready node in let agnostic_baker = create @@ -236,6 +267,7 @@ let init ?runner ?(path = Uses.path Constant.octez_experimental_agnostic_baker) ?name ?color ?event_pipe + ?votefile ?liquidity_baking_toggle_vote ?force_apply_from_round ?remote_mode diff --git a/tezt/lib_tezos/agnostic_baker.mli b/tezt/lib_tezos/agnostic_baker.mli index 1ee9d43483a24b5127d087bb6c479e86d8314d4d..bb2b992958a7d919e8f9753ceddfeba12aae9ba5 100644 --- a/tezt/lib_tezos/agnostic_baker.mli +++ b/tezt/lib_tezos/agnostic_baker.mli @@ -60,6 +60,19 @@ type liquidity_baking_vote = Off | On | Pass (** Returns the string representation of a [liquidity_baking_vote]. *) val liquidity_baking_vote_to_string : liquidity_baking_vote -> string +(** Returns the [liquidity_baking_vote] corresponding to a string, or None if the + string is not a valid liquidity baking vote. *) +val liquidity_baking_vote_of_string_opt : string -> liquidity_baking_vote option + +(** Writes a liquidity baking votefile, as read by the bakers [--votefile] + argument. + + If [path] is set, the vote file is written there. Otherwise, it is written + to a temporary file. + + Returns the path to the file that was written. *) +val liquidity_baking_votefile : ?path:string -> liquidity_baking_vote -> string + (** Protocol status values. *) type protocol_status = Active | Frozen | Ignore @@ -94,9 +107,9 @@ val protocol_status : Protocol.t -> protocol_status agnostic baker. This defaults to the empty list, which is a shortcut for "every known account". - [force_apply_from_round], [operations_pool], [state_recorder], [node_version_check_bypass], - [node_version_allowed] and [liquidity_baking_toggle_vote] are passed to the - baker daemon through the flags [--force-apply-from-round], + [votefile], [force_apply_from_round], [operations_pool], [state_recorder], + [node_version_check_bypass], [node_version_allowed] and [liquidity_baking_toggle_vote] are + passed to the baker daemon through the flags [--votefile], [--force-apply-from-round], [--operations-pool], [--record-state], [--node-version-check-bypass], [--node-version-allowed] and [--liquidity-baking-toggle-vote]. If [--liquidity-baking-toggle-vote] is [None], then [--liquidity-baking-toggle-vote] is not passed. If it is [Some x] then @@ -115,6 +128,7 @@ val create : ?color:Log.Color.t -> ?event_pipe:string -> ?delegates:string list -> + ?votefile:string -> ?liquidity_baking_toggle_vote:liquidity_baking_vote option -> ?force_apply_from_round:int -> ?remote_mode:bool -> @@ -152,6 +166,7 @@ val create_from_uris : ?color:Log.Color.t -> ?event_pipe:string -> ?delegates:string list -> + ?votefile:string -> ?liquidity_baking_toggle_vote:liquidity_baking_vote option -> ?force_apply_from_round:int -> ?remote_mode:bool -> @@ -211,6 +226,7 @@ val init : ?event_pipe:string -> ?event_sections_levels:(string * Daemon.Level.level) list -> ?delegates:string list -> + ?votefile:string -> ?liquidity_baking_toggle_vote:liquidity_baking_vote option -> ?force_apply_from_round:int -> ?remote_mode:bool -> diff --git a/tezt/tests/agnostic_baker_test.ml b/tezt/tests/agnostic_baker_test.ml index 838c20814516a4115a31e98f3b4cb74ad7514447..60fb3d5f97398f70e8984f590bb785c0fc885bff 100644 --- a/tezt/tests/agnostic_baker_test.ml +++ b/tezt/tests/agnostic_baker_test.ml @@ -29,21 +29,10 @@ let wait_for_active_protocol_waiting agnostic_baker = "waiting_for_active_protocol.v0" (fun _json -> Some ()) -let wait_for_baker_process agnostic_baker protocol_short_hash = - Agnostic_baker.wait_for - agnostic_baker - (Format.sprintf "baker_%s_started.v0" protocol_short_hash) - (fun json -> JSON.(json |> as_int_opt)) - -(* Performs a protocol migration thanks to a UAU and the agnostic - baker. - The [resilience_test] flag aims to test the resilience of the - agnostic baker thanks to a kill of the baker daemon during the - test, making sure it is restarted as expected. *) -let perform_protocol_migration ?(resilience_test = false) ?node_name - ?client_name ?parameter_file ?(use_remote_signer = false) ~blocks_per_cycle - ~migration_level ~migrate_from ~migrate_to ~baked_blocks_after_migration () - = +(* Performs a protocol migration thanks to a UAU and the agnostic baker. *) +let perform_protocol_migration ?node_name ?client_name ?parameter_file + ?(use_remote_signer = false) ~blocks_per_cycle ~migration_level + ~migrate_from ~migrate_to ~baked_blocks_after_migration () = assert (migration_level >= blocks_per_cycle) ; Log.info "Node starting" ; let* client, node = @@ -79,14 +68,6 @@ let perform_protocol_migration ?(resilience_test = false) ?node_name let* () = Agnostic_baker.run baker in let* () = wait_for_active_protocol_waiting in let* () = Agnostic_baker.wait_for_ready baker in - let wait_pre_migration_baker_pid = - if resilience_test then - let wait = - wait_for_baker_process baker (Protocol.short_hash migrate_from) - in - wait - else Lwt.return (-1) - in let* () = Client.activate_protocol ~protocol:migrate_from @@ -96,37 +77,6 @@ let perform_protocol_migration ?(resilience_test = false) ?node_name in Log.info "Protocol %s activated" (Protocol.hash migrate_from) ; Log.info "Baking at least %d blocks to trigger migration" migration_level ; - let* () = - if resilience_test then ( - (* If resilience test is activated, we kill the pre migration - baker process in the middle of the migration period. The - baker is expected to be restarted automatically so that the - test is expected to continue smoothly. *) - let* pid = wait_pre_migration_baker_pid in - let* _level = Node.wait_for_level node (migration_level / 2) in - let wait_new_baker_pid = - wait_for_baker_process baker (Protocol.short_hash migrate_from) - in - Log.info "Kill the pre-migration baker (pid %d) with SIGTERM signal" pid ; - Unix.kill pid Sys.sigterm ; - let* new_pid = wait_new_baker_pid in - Log.info - "New pre-migration baker process is taking over (pid: %d)" - new_pid ; - unit) - else unit - in - (* Wait one block before the new protocol activation to register the - post migration baker's pid waiter. *) - let* _level = Node.wait_for_level node (migration_level - 1) in - let wait_post_migration_baker_pid = - if resilience_test then - let wait = - wait_for_baker_process baker (Protocol.short_hash migrate_to) - in - wait - else Lwt.return (-1) - in let* _level = Node.wait_for_level node migration_level in (* Ensure that the block before migration is consistent *) Log.info "Checking migration block consistency" ; @@ -150,35 +100,11 @@ let perform_protocol_migration ?(resilience_test = false) ?node_name ~level:(migration_level + 1) in (* Test that we can still bake after migration *) - let* () = - if resilience_test then ( - (* If resilience test is activated, we kill the post migration - baker process close to the end of the post migration - period. The baker is expected to be restarted automatically - so that the test is expected to continue smoothly. *) - let* pid = wait_post_migration_baker_pid in - let* _level = - Node.wait_for_level - node - (baked_blocks_after_migration - blocks_per_cycle) - in - let wait_new_baker_pid = - wait_for_baker_process baker (Protocol.short_hash migrate_to) - in - Log.info "Kill the post-migration baker (pid %d) with SIGTERM signal" pid ; - Unix.kill pid Sys.sigterm ; - let* new_pid = wait_new_baker_pid in - Log.info - "New post-migration baker process is taking over (pid: %d)" - new_pid ; - unit) - else unit - in let* _level = Node.wait_for_level node baked_blocks_after_migration in let* () = Agnostic_baker.terminate baker in unit -let raw_migrate ~migrate_from ~migrate_to ~resilience_test ~use_remote_signer = +let migrate ~migrate_from ~migrate_to ~use_remote_signer = let remote_signer_text, remote_signer = if use_remote_signer then (" using HTTP remote signer", [Constant.octez_signer]) @@ -190,11 +116,10 @@ let raw_migrate ~migrate_from ~migrate_to ~resilience_test ~use_remote_signer = ~title: (Format.asprintf "Protocol migration from protocol %s to protocol %s with agnostic \ - baker%s %s" + baker%s" (Protocol.tag migrate_from) (Protocol.tag migrate_to) - remote_signer_text - (if resilience_test then "and resilience test" else "")) + remote_signer_text) ~tags: [ "protocol"; @@ -225,23 +150,11 @@ let raw_migrate ~migrate_from ~migrate_to ~resilience_test ~use_remote_signer = in unit -let migrate = raw_migrate ~resilience_test:false - -let migrate_with_resilience_test = raw_migrate ~resilience_test:true - let register ~migrate_from ~migrate_to = (* We want to migrate only from Active protocols *) if Agnostic_baker.protocol_status migrate_from = Active then ( migrate ~migrate_from ~migrate_to ~use_remote_signer:false ; - migrate ~migrate_from ~migrate_to ~use_remote_signer:true ; - migrate_with_resilience_test - ~migrate_from - ~migrate_to - ~use_remote_signer:false ; - migrate_with_resilience_test - ~migrate_from - ~migrate_to - ~use_remote_signer:true) + migrate ~migrate_from ~migrate_to ~use_remote_signer:true) else () let register_protocol_independent () = diff --git a/tezt/tests/liquidity_baking_per_block_votes.ml b/tezt/tests/liquidity_baking_per_block_votes.ml index 1eebdb96258c56d0be705fb41f386e28f7876523..b4b8e08edad5d4156779addf1613d669efb666e4 100644 --- a/tezt/tests/liquidity_baking_per_block_votes.ml +++ b/tezt/tests/liquidity_baking_per_block_votes.ml @@ -41,12 +41,13 @@ let ensure_removal path p = unit let baker_wait_for_vote baker = - Baker.wait_for baker "vote_for_liquidity_baking_toggle.v0" @@ fun json -> - JSON.as_string json |> Baker.liquidity_baking_vote_of_string_opt + Agnostic_baker.wait_for baker "vote_for_liquidity_baking_toggle.v0" + @@ fun json -> + JSON.as_string json |> Agnostic_baker.liquidity_baking_vote_of_string_opt let baker_wait_for_per_block_vote_file_error ?expected_id ?expected_file_path baker = - Baker.wait_for baker "per_block_vote_file_error.v0" @@ fun json -> + Agnostic_baker.wait_for baker "per_block_vote_file_error.v0" @@ fun json -> let json = JSON.(json |=> 0) in let id = JSON.(json |-> "id" |> as_string) in let file_path = JSON.(json |-> "file_path" |> as_string) in @@ -56,7 +57,8 @@ let baker_wait_for_per_block_vote_file_error ?expected_id ?expected_file_path then Some (id, file_path) else None -let vote_typ = Check.(convert Baker.liquidity_baking_vote_to_string string) +let vote_typ = + Check.(convert Agnostic_baker.liquidity_baking_vote_to_string string) let check_vote ?__LOC__ expected_vote obtained_vote = Check.(obtained_vote = expected_vote) @@ -110,7 +112,7 @@ let test_all_per_block_votes = ~tags:[team; "liquidity"; "baking"; "votes"] ~supports: (Protocol.Between_protocols (Protocol.number Alpha, Protocol.number Alpha)) - ~uses:(fun protocol -> [Protocol.baker protocol]) + ~uses:(fun _protocol -> [Constant.octez_experimental_agnostic_baker]) @@ fun protocol -> let ( >|= ) = Lwt.( >|= ) in let error_prefix = "baker." ^ Protocol.encoding_prefix protocol ^ "." in @@ -145,17 +147,16 @@ let test_all_per_block_votes = not set [--liquidity-baking-toggle-vote pass] as the normal baker does. *) let run_vote_file ?votefile ?liquidity_baking_toggle_vote baker = - let* () = Baker.terminate baker in + let* () = Agnostic_baker.terminate baker in let delegates = Array.map (fun Account.{alias; _} -> alias) Account.Bootstrap.keys |> Array.to_list in let baker = - Baker.create + Agnostic_baker.create ~liquidity_baking_toggle_vote ?votefile - ~protocol ~delegates node client @@ -168,30 +169,30 @@ let test_all_per_block_votes = let* error = baker_wait_for_per_block_vote_file_error baker in return (baker, Error error) in - let* () = Baker.run baker in - let* () = Baker.wait_for_ready baker in + let* () = Agnostic_baker.run baker in + let* () = Agnostic_baker.wait_for_ready baker in Lwt.pick [p_vote; p_error] in - let* baker = Baker.init ~protocol node client in + let* baker = Agnostic_baker.init node client in Log.info "Test [off] vote file" ; let* baker = - let votefile = Baker.liquidity_baking_votefile Off in + let votefile = Agnostic_baker.liquidity_baking_votefile Off in run_vote_file ~votefile ~liquidity_baking_toggle_vote:On baker >|= check_vote_success ~__LOC__ Off in Log.info "Test [on] vote file" ; let* baker = - let votefile = Baker.liquidity_baking_votefile On in + let votefile = Agnostic_baker.liquidity_baking_votefile On in run_vote_file ~votefile ~liquidity_baking_toggle_vote:Off baker >|= check_vote_success ~__LOC__ On in Log.info "Test [pass] vote file" ; let* baker = - let votefile = Baker.liquidity_baking_votefile Pass in + let votefile = Agnostic_baker.liquidity_baking_votefile Pass in run_vote_file ~votefile ~liquidity_baking_toggle_vote:On baker >|= check_vote_success ~__LOC__ Pass in @@ -230,14 +231,18 @@ let test_all_per_block_votes = Log.info "Test vote file at default file location " ; let* baker = ensure_removal default_votefile @@ fun () -> - let _ = Baker.liquidity_baking_votefile ~path:default_votefile On in + let _ = + Agnostic_baker.liquidity_baking_votefile ~path:default_votefile On + in run_vote_file baker >|= check_vote_success ~__LOC__ On in Log.info "Test caching of the votefile setting" ; let* _baker = ensure_removal default_votefile @@ fun () -> - let _ = Baker.liquidity_baking_votefile ~path:default_votefile On in + let _ = + Agnostic_baker.liquidity_baking_votefile ~path:default_votefile On + in let* baker = run_vote_file baker >|= check_vote_success ~__LOC__ On in (* Explicitly remove the votefile to check that the baker has retained its value *) let p_error = @@ -259,8 +264,10 @@ let test_all_per_block_votes = Log.info "Test [--votefile] overrides default file location " ; let* baker = ensure_removal default_votefile @@ fun () -> - let _ = Baker.liquidity_baking_votefile ~path:default_votefile On in - let votefile = Baker.liquidity_baking_votefile Off in + let _ = + Agnostic_baker.liquidity_baking_votefile ~path:default_votefile On + in + let votefile = Agnostic_baker.liquidity_baking_votefile Off in run_vote_file ~votefile baker >|= check_vote_success ~__LOC__ Off in