From 186ebc5b11991d5ff0e2218a22d63574ee563971 Mon Sep 17 00:00:00 2001 From: Victor Allombert Date: Thu, 31 Oct 2024 15:48:58 +0100 Subject: [PATCH 1/2] Tezt/lib_tezos: introduce Protocol.short_hash --- tezt/lib_tezos/protocol.ml | 4 ++++ tezt/lib_tezos/protocol.mli | 3 +++ 2 files changed, 7 insertions(+) diff --git a/tezt/lib_tezos/protocol.ml b/tezt/lib_tezos/protocol.ml index c90f091b6e15..17ee0453d6c3 100644 --- a/tezt/lib_tezos/protocol.ml +++ b/tezt/lib_tezos/protocol.ml @@ -59,6 +59,10 @@ let hash = function | Quebec -> "PsQuebecnLByd3JwTiGadoG4nGWi3HYiLXUjkibeFV8dCFeVMUg" (* DO NOT REMOVE, AUTOMATICALLY ADD STABILISED PROTOCOL HASH HERE *) +let short_hash protocol_hash = + let long_hash = hash protocol_hash in + String.sub long_hash 0 12 + let genesis_hash = "ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im" let demo_noops_hash = "ProtoDemoNoopsDemoNoopsDemoNoopsDemoNoopsDemo6XBoYp" diff --git a/tezt/lib_tezos/protocol.mli b/tezt/lib_tezos/protocol.mli index d5356d5aca8f..24377f76adda 100644 --- a/tezt/lib_tezos/protocol.mli +++ b/tezt/lib_tezos/protocol.mli @@ -64,6 +64,9 @@ val tag : t -> string (** Get the full hash of a protocol. *) val hash : t -> string +(** Get the short hash of a protocol. *) +val short_hash : t -> string + (** Hash of protocol genesis *) val genesis_hash : string -- GitLab From 429d8f26be9ec159b016b4d24b32ba436cbb0a97 Mon Sep 17 00:00:00 2001 From: Gabriel Moise Date: Mon, 27 Jan 2025 12:45:06 +0000 Subject: [PATCH 2/2] Tezt: add resilence test of agnostic baker protocol migration Co-authored-by: Victor Allombert This is the work of Victor, and I just rebased it onto the new test option for remote signers --- tezt/manual_tests/agnostic_baking.ml | 110 ++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 11 deletions(-) diff --git a/tezt/manual_tests/agnostic_baking.ml b/tezt/manual_tests/agnostic_baking.ml index e0350756fd30..b20182d010dc 100644 --- a/tezt/manual_tests/agnostic_baking.ml +++ b/tezt/manual_tests/agnostic_baking.ml @@ -62,11 +62,21 @@ 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. *) -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 () = + 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 () + = assert (migration_level >= blocks_per_cycle) ; Log.info "Node starting" ; let* client, node = @@ -102,6 +112,14 @@ let perform_protocol_migration ?node_name ?client_name ?parameter_file 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 @@ -111,6 +129,37 @@ let perform_protocol_migration ?node_name ?client_name ?parameter_file 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 ; + Lwt.return_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" ; @@ -134,11 +183,36 @@ let perform_protocol_migration ?node_name ?client_name ?parameter_file ~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 ; + Lwt.return_unit) + else unit + in let* _level = Node.wait_for_level node baked_blocks_after_migration in let* () = Agnostic_baker.terminate baker in Lwt.return_unit -let migrate ~migrate_from ~migrate_to ?(use_remote_signer = false) () = +let raw_migrate ~resilience_test ~migrate_from ~migrate_to + ?(use_remote_signer = false) () = let parameters = JSON.parse_file (Protocol.parameter_file migrate_to) in let blocks_per_cycle = JSON.(get "blocks_per_cycle" parameters |> as_int) in let consensus_rights_delay = @@ -146,17 +220,15 @@ let migrate ~migrate_from ~migrate_to ?(use_remote_signer = false) () = in (* Migration level is set arbitrarily *) let migration_level = blocks_per_cycle in - let remote_signer_text = - if use_remote_signer then " using HTTP remote signer" else "" - in Test.register ~__FILE__ ~title: (Format.sprintf - "Protocol migration (from %s to %s) with agnostic baker%s" + "Protocol migration (from %s to %s) with agnostic baker%s %s" (Protocol.tag migrate_from) (Protocol.tag migrate_to) - remote_signer_text) + (if use_remote_signer then " using HTTP remote signer" else "") + (if resilience_test then " and resilience test" else "")) ~tags:["protocol"; "migration"; "agnostic"; "baker"] ~uses:[Constant.octez_experimental_agnostic_baker] @@ fun () -> @@ -186,7 +258,23 @@ let start_stop = let* () = Agnostic_baker.terminate baker in unit +let migrate ~migrate_from ~migrate_to = + raw_migrate ~resilience_test:false ~migrate_from ~migrate_to + +let migrate_with_resilience_test ~migrate_from ~migrate_to = + raw_migrate ~resilience_test:true ~migrate_from ~migrate_to + let register ~migrate_from ~migrate_to = start_stop ; migrate ~migrate_from ~migrate_to ~use_remote_signer:false () ; - migrate ~migrate_from ~migrate_to ~use_remote_signer:true () + 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 + () -- GitLab