diff --git a/CHANGES.rst b/CHANGES.rst index 9b6d99e2d7d83bc0463d8470364071e905b276bf..f63fc91be1192e7fa0c6cacfd8e98622ff53c3bc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -178,6 +178,12 @@ Baker baker will wait for ``0.5`` seconds for the DAL attestations' status. (MR :gl:`!14480`) +- **Breaking_change** The baker now accepts a new argument, + ``--force_apply_from_round ``, which replaces ``--force-apply``. + Previously, the baker applied blocks from round 0 if ``--force_apply`` was + used, and from round 1 otherwise. The default is now set to 3 and can be + adjusted using ``--force_apply_from_round ``. (MR :gl:`!14875`) + Accuser ------- diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_actions.ml b/src/proto_021_PsquebeC/lib_delegate/baking_actions.ml index 3157d35a39d17195574ecb0e3098491a37bb8af2..99faaf411d105824367e5352839ef0b30d0b51f0 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_actions.ml +++ b/src/proto_021_PsquebeC/lib_delegate/baking_actions.ml @@ -290,7 +290,9 @@ let prepare_block (global_state : global_state) (block_to_bake : block_to_bake) in let*! () = Events.( - emit forging_block (Int32.succ predecessor.shell.level, round, delegate)) + emit + forging_block + (Int32.succ predecessor.shell.level, round, delegate, force_apply)) in let* injection_level = Plugin.RPC.current_level diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_commands.ml b/src/proto_021_PsquebeC/lib_delegate/baking_commands.ml index 93a46a1b7cfd6a99b15054e7de7819f3937fbc0a..a29dac4e0258c1c0add4186fcd23c6966cb31ae0 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_commands.ml +++ b/src/proto_021_PsquebeC/lib_delegate/baking_commands.ml @@ -195,11 +195,14 @@ let context_path_arg = 'preapply' RPC." string_parameter -let force_apply_switch_arg = - Tezos_clic.switch - ~long:"force-apply" - ~doc:"Force the baker to not only validate but also apply operations." - () +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 attestation_force_switch_arg = Tezos_clic.switch @@ -508,7 +511,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit_arg minimal_nanotez_per_byte_arg minimal_timestamp_switch - force_apply_switch_arg + force_apply_from_round_arg force_switch operations_arg context_path_arg @@ -522,7 +525,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte, minimal_timestamp, - force_apply, + force_apply_from_round, force, extra_operations, context_path, @@ -540,7 +543,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list ~minimal_timestamp ~minimal_nanotez_per_byte ~minimal_fees - ~force_apply + ?force_apply_from_round ~force ~monitor_node_mempool:(not do_not_monitor_node_mempool) ?extra_operations @@ -581,7 +584,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit_arg minimal_nanotez_per_byte_arg minimal_timestamp_switch - force_apply_switch_arg + force_apply_from_round_arg force_switch operations_arg context_path_arg @@ -591,7 +594,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte, minimal_timestamp, - force_apply, + force_apply_from_round, force, extra_operations, context_path, @@ -605,7 +608,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list ~minimal_timestamp ~minimal_nanotez_per_byte ~minimal_fees - ~force_apply + ?force_apply_from_round ~force ?extra_operations ?context_path @@ -683,7 +686,7 @@ let baker_args = minimal_fees_arg minimal_nanotez_per_gas_unit_arg minimal_nanotez_per_byte_arg - force_apply_switch_arg + force_apply_from_round_arg keep_alive_arg liquidity_baking_toggle_vote_arg adaptive_issuance_vote_arg @@ -701,7 +704,7 @@ let run_baker minimal_fees, minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte, - force_apply, + force_apply_from_round, keep_alive, liquidity_baking_vote, adaptive_issuance_vote, @@ -749,7 +752,7 @@ let run_baker ?dal_node_endpoint ?dal_node_timeout_percentage ?pre_emptive_forge_time - ~force_apply + ?force_apply_from_round ~chain:cctxt#chain ?context_path ~keep_alive diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_configuration.ml b/src/proto_021_PsquebeC/lib_delegate/baking_configuration.ml index 1b412886063a213d0967fdbda5f31fcc55cf08a5..d2ef80c8237dddef6718a2092217c56a4e05916b 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_configuration.ml +++ b/src/proto_021_PsquebeC/lib_delegate/baking_configuration.ml @@ -89,7 +89,7 @@ type t = { retries_on_failure : int; user_activated_upgrades : (int32 * Protocol_hash.t) list; per_block_votes : per_block_votes_config; - force_apply : bool; + force_apply_from_round : Round.t; force : bool; state_recorder : state_recorder_config; extra_operations : Operations_source.t option; @@ -127,7 +127,7 @@ let default_votes_config = let default_force = false -let default_force_apply = false +let default_force_apply_from_round = Round.(succ @@ succ @@ succ zero) let default_state_recorder_config = Memory @@ -145,7 +145,7 @@ let default_config = retries_on_failure = default_retries_on_failure_config; user_activated_upgrades = default_user_activated_upgrades; per_block_votes = default_votes_config; - force_apply = default_force_apply; + force_apply_from_round = default_force_apply_from_round; force = default_force; state_recorder = default_state_recorder_config; extra_operations = default_extra_operations; @@ -161,7 +161,7 @@ let make ?(minimal_fees = default_fees_config.minimal_fees) ?(nonce = default_nonce_config) ?context_path ?(retries_on_failure = default_retries_on_failure_config) ?(user_activated_upgrades = default_user_activated_upgrades) - ?(votes = default_votes_config) ?(force_apply = default_force_apply) + ?(votes = default_votes_config) ?force_apply_from_round ?(force = default_force) ?(state_recorder = default_state_recorder_config) ?extra_operations ?dal_node_endpoint ?(dal_node_timeout_percentage = default_dal_node_timeout_percentage) @@ -174,6 +174,14 @@ let make ?(minimal_fees = default_fees_config.minimal_fees) | None -> Node | Some context_path -> Local {context_path} in + let force_apply_from_round = + match force_apply_from_round with + | Some round -> ( + match Round.of_int round with + | Ok round -> round + | Error _ -> default_force_apply_from_round) + | None -> default_force_apply_from_round + in { fees; validation; @@ -181,7 +189,7 @@ let make ?(minimal_fees = default_fees_config.minimal_fees) retries_on_failure; user_activated_upgrades; per_block_votes = votes; - force_apply; + force_apply_from_round; force; state_recorder; extra_operations; @@ -272,7 +280,7 @@ let per_block_votes_config_encoding = let force_config_encoding = Data_encoding.bool -let force_apply_config_encoding = Data_encoding.bool +let force_apply_from_round_config_encoding = Round.encoding let state_recorder_config_encoding = let open Data_encoding in @@ -307,7 +315,7 @@ let encoding : t Data_encoding.t = retries_on_failure; user_activated_upgrades; per_block_votes; - force_apply; + force_apply_from_round; force; state_recorder; extra_operations; @@ -321,7 +329,7 @@ let encoding : t Data_encoding.t = retries_on_failure, user_activated_upgrades, per_block_votes, - force_apply, + force_apply_from_round, force, state_recorder, pre_emptive_forge_time ), @@ -332,7 +340,7 @@ let encoding : t Data_encoding.t = retries_on_failure, user_activated_upgrades, per_block_votes, - force_apply, + force_apply_from_round, force, state_recorder, pre_emptive_forge_time ), @@ -345,7 +353,7 @@ let encoding : t Data_encoding.t = retries_on_failure; user_activated_upgrades; per_block_votes; - force_apply; + force_apply_from_round; force; state_recorder; extra_operations; @@ -363,7 +371,9 @@ let encoding : t Data_encoding.t = "user_activated_upgrades" user_activate_upgrades_config_encoding) (req "votes" per_block_votes_config_encoding) - (req "force_apply" force_apply_config_encoding) + (req + "force_apply_from_round" + force_apply_from_round_config_encoding) (req "force" force_config_encoding) (req "state_recorder" state_recorder_config_encoding) (req "pre_emptive_forge_time" Time.System.Span.encoding)) diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_configuration.mli b/src/proto_021_PsquebeC/lib_delegate/baking_configuration.mli index 1e51ebfb1aa7c0993e3a65168982be1e0764ec74..28269985ff3a6b4182159ad9f9b63fa7817f8761 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_configuration.mli +++ b/src/proto_021_PsquebeC/lib_delegate/baking_configuration.mli @@ -64,7 +64,7 @@ type t = { retries_on_failure : int; user_activated_upgrades : (int32 * Protocol_hash.t) list; per_block_votes : per_block_votes_config; - force_apply : bool; + force_apply_from_round : Protocol.Alpha_context.Round.t; force : bool; state_recorder : state_recorder_config; extra_operations : Operations_source.t option; @@ -85,7 +85,7 @@ val default_user_activated_upgrades : (int32 * Protocol_hash.t) list val default_votes_config : per_block_votes_config -val default_force_apply : bool +val default_force_apply_from_round : Protocol.Alpha_context.Round.t val default_force : bool @@ -106,7 +106,7 @@ val make : ?retries_on_failure:int -> ?user_activated_upgrades:(int32 * Protocol_hash.t) list -> ?votes:per_block_votes_config -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?force:bool -> ?state_recorder:state_recorder_config -> ?extra_operations:Operations_source.t -> diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_events.ml b/src/proto_021_PsquebeC/lib_delegate/baking_events.ml index b34c1a1ca411fde0158872a09cf32d55405bc591..a4aec8a97c7df2ac97c13bbbec69516bba03d8b0 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_events.ml +++ b/src/proto_021_PsquebeC/lib_delegate/baking_events.ml @@ -916,17 +916,20 @@ module Actions = struct ("delegate", Baking_state.consensus_key_and_delegate_encoding) let forging_block = - declare_3 + declare_4 ~section ~name:"forging_block" ~level:Info - ~msg:"forging block at level {level}, round {round} for {delegate}" + ~msg: + "forging block at level {level}, round {round} for {delegate} (force \ + apply: {force_apply})" ~pp1:pp_int32 ~pp2:Round.pp ~pp3:Baking_state.pp_consensus_key_and_delegate ("level", Data_encoding.int32) ("round", Round.encoding) ("delegate", Baking_state.consensus_key_and_delegate_encoding) + ("force_apply", Data_encoding.bool) let delayed_block_injection = declare_4 diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_lib.ml b/src/proto_021_PsquebeC/lib_delegate/baking_lib.ml index 63338a50469165c754e515650a80848c7e124b56..2e982025ec663a74ab75b7479993a02b7e99021d 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_lib.ml +++ b/src/proto_021_PsquebeC/lib_delegate/baking_lib.ml @@ -304,13 +304,16 @@ let propose_at_next_level ~minimal_timestamp state = state.global_state.operation_worker in let kind = Fresh pool in + let force_apply = + Round.(minimal_round >= state.global_state.config.force_apply_from_round) + in let block_to_bake = { predecessor = state.level_state.latest_proposal.block; round = minimal_round; delegate; kind; - force_apply = state.global_state.config.force_apply; + force_apply; } in let* prepared_block = @@ -360,9 +363,9 @@ let attestation_quorum state = - Yes :: repropose block with right payload and preattestations for current round - No :: repropose fresh block for current round *) let propose (cctxt : Protocol_client_context.full) ?minimal_fees - ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force_apply - ?(force = false) ?(minimal_timestamp = false) ?extra_operations - ?context_path ?state_recorder delegates = + ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte + ?force_apply_from_round ?(force = false) ?(minimal_timestamp = false) + ?extra_operations ?context_path ?state_recorder delegates = let open Lwt_result_syntax in let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in let cache = Baking_cache.Block_cache.create 10 in @@ -373,7 +376,7 @@ let propose (cctxt : Protocol_client_context.full) ?minimal_fees ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?context_path - ?force_apply + ?force_apply_from_round ~force ?extra_operations ?state_recorder @@ -691,13 +694,16 @@ let rec baking_minimal_timestamp ~count state signed_attestations.signed_consensus_votes) in let kind = Fresh pool in + let force_apply = + Round.(minimal_round >= state.global_state.config.force_apply_from_round) + in let block_to_bake = { predecessor = latest_proposal.block; round = minimal_round; delegate; kind; - force_apply = state.global_state.config.force_apply; + force_apply; } in let* prepared_block = @@ -757,10 +763,10 @@ let rec baking_minimal_timestamp ~count state baking_minimal_timestamp ~count:(pred count) new_state block_stream let bake (cctxt : Protocol_client_context.full) ?minimal_fees - ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force_apply ?force - ?(minimal_timestamp = false) ?extra_operations - ?(monitor_node_mempool = true) ?context_path ?dal_node_endpoint ?(count = 1) - ?votes ?state_recorder delegates = + ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte + ?force_apply_from_round ?force ?(minimal_timestamp = false) + ?extra_operations ?(monitor_node_mempool = true) ?context_path + ?dal_node_endpoint ?(count = 1) ?votes ?state_recorder delegates = let open Lwt_result_syntax in let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in let config = @@ -769,7 +775,7 @@ let bake (cctxt : Protocol_client_context.full) ?minimal_fees ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?context_path - ?force_apply + ?force_apply_from_round ?force ?extra_operations ?dal_node_endpoint diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_lib.mli b/src/proto_021_PsquebeC/lib_delegate/baking_lib.mli index 6805daf9ae176df7c63a667c3edadedbd10e6d26..cd456f8b048d8bb9d39c7cf38abeaa2470c26b3a 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_lib.mli +++ b/src/proto_021_PsquebeC/lib_delegate/baking_lib.mli @@ -32,7 +32,7 @@ val bake : ?minimal_fees:Tez.t -> ?minimal_nanotez_per_gas_unit:Q.t -> ?minimal_nanotez_per_byte:Q.t -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?force:bool -> ?minimal_timestamp:bool -> ?extra_operations:Baking_configuration.Operations_source.t -> @@ -63,7 +63,7 @@ val propose : ?minimal_fees:Tez.t -> ?minimal_nanotez_per_gas_unit:Q.t -> ?minimal_nanotez_per_byte:Q.t -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?force:bool -> ?minimal_timestamp:bool -> ?extra_operations:Baking_configuration.Operations_source.t -> diff --git a/src/proto_021_PsquebeC/lib_delegate/baking_state.mli b/src/proto_021_PsquebeC/lib_delegate/baking_state.mli index 689b85c0b009b02abd996ed9e02e3b3a9a23aadc..62c4c34c3cb28e7b8cba19f5825ad61c65f7de6f 100644 --- a/src/proto_021_PsquebeC/lib_delegate/baking_state.mli +++ b/src/proto_021_PsquebeC/lib_delegate/baking_state.mli @@ -91,8 +91,8 @@ type block_to_bake = { kind : block_kind; force_apply : bool; (** if true, while baking the block, try and apply the block and its - operations instead of only validating them. this can be permanently - set using the [--force-apply] flag (see [force_apply_switch_arg] in + operations instead of only validating them. This can be set using the + [--force-apply-from-round] flag (see [force_apply_from_round_arg] in [baking_commands.ml]). *) } diff --git a/src/proto_021_PsquebeC/lib_delegate/client_daemon.ml b/src/proto_021_PsquebeC/lib_delegate/client_daemon.ml index a51235b8547b16baa1e9a44b79e72484cef579a2..0acfd412a565327765f3ab6d0bdf4a72cec9b748 100644 --- a/src/proto_021_PsquebeC/lib_delegate/client_daemon.ml +++ b/src/proto_021_PsquebeC/lib_delegate/client_daemon.ml @@ -60,8 +60,8 @@ module Baker = struct let run (cctxt : Protocol_client_context.full) ?minimal_fees ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?votes ?extra_operations ?dal_node_endpoint ?dal_node_timeout_percentage - ?pre_emptive_forge_time ?force_apply ?context_path ?state_recorder ~chain - ~keep_alive delegates = + ?pre_emptive_forge_time ?force_apply_from_round ?context_path + ?state_recorder ~chain ~keep_alive delegates = let open Lwt_result_syntax in let process () = let* user_activated_upgrades = @@ -112,7 +112,7 @@ module Baker = struct ?dal_node_endpoint ?dal_node_timeout_percentage ~pre_emptive_forge_time - ?force_apply + ?force_apply_from_round ?context_path ~user_activated_upgrades ?state_recorder diff --git a/src/proto_021_PsquebeC/lib_delegate/client_daemon.mli b/src/proto_021_PsquebeC/lib_delegate/client_daemon.mli index 5fa115099b6aac801178472bd6175783c1d4cbb6..bc02d9e76cd52b53e7b62ea2c7e9fa350c8a44e4 100644 --- a/src/proto_021_PsquebeC/lib_delegate/client_daemon.mli +++ b/src/proto_021_PsquebeC/lib_delegate/client_daemon.mli @@ -37,7 +37,7 @@ module Baker : sig ?dal_node_endpoint:Uri.t -> ?dal_node_timeout_percentage:int -> ?pre_emptive_forge_time:Q.t -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?context_path:string -> ?state_recorder:Baking_configuration.state_recorder_config -> chain:Shell_services.chain -> diff --git a/src/proto_021_PsquebeC/lib_delegate/state_transitions.ml b/src/proto_021_PsquebeC/lib_delegate/state_transitions.ml index 9cc23c9604ded5cfcf15cc78a62cf2b4cd3f7a15..af2d1c0755424ae1f842beb92ef6d2e92ef8120d 100644 --- a/src/proto_021_PsquebeC/lib_delegate/state_transitions.ml +++ b/src/proto_021_PsquebeC/lib_delegate/state_transitions.ml @@ -531,9 +531,9 @@ let prepare_block_to_bake ~attestations ?last_proposal let kind = Fresh operation_pool in let* () = Events.(emit preparing_fresh_block (delegate, round)) in let force_apply = - state.global_state.config.force_apply || Round.(round <> zero) - (* This is used as a safety net by applying blocks on round > 0, in case - validation-only did not produce a correct round-0 block. *) + (* This is used as a safety net by applying blocks in case validation-only + did not produce correct block. *) + Round.(round >= state.global_state.config.force_apply_from_round) in let block_to_bake : block_to_bake = {predecessor; round; delegate; kind; force_apply} @@ -636,9 +636,9 @@ let propose_block_action state delegate round ~last_proposal = Reproposal {consensus_operations; payload_hash; payload_round; payload} in let force_apply = - true - (* This is used as a safety net by applying blocks on round > 0, in case - validation-only did not produce a correct round-0 block. *) + (* This is used as a safety net by applying blocks in case validation-only + did not produce correct block. *) + Round.(round >= state.global_state.config.force_apply_from_round) in let block_to_bake = {predecessor = proposal.predecessor; round; delegate; kind; force_apply} diff --git a/src/proto_alpha/lib_delegate/baking_actions.ml b/src/proto_alpha/lib_delegate/baking_actions.ml index 0c8565da6e3e04e519abe3f9526dc9023ade5bef..94c2185bebac602dc061266acd4674020744ba8b 100644 --- a/src/proto_alpha/lib_delegate/baking_actions.ml +++ b/src/proto_alpha/lib_delegate/baking_actions.ml @@ -298,7 +298,9 @@ let prepare_block (global_state : global_state) (block_to_bake : block_to_bake) in let*! () = Events.( - emit forging_block (Int32.succ predecessor.shell.level, round, delegate)) + emit + forging_block + (Int32.succ predecessor.shell.level, round, delegate, force_apply)) in let* injection_level = Plugin.RPC.current_level diff --git a/src/proto_alpha/lib_delegate/baking_commands.ml b/src/proto_alpha/lib_delegate/baking_commands.ml index 93a46a1b7cfd6a99b15054e7de7819f3937fbc0a..a29dac4e0258c1c0add4186fcd23c6966cb31ae0 100644 --- a/src/proto_alpha/lib_delegate/baking_commands.ml +++ b/src/proto_alpha/lib_delegate/baking_commands.ml @@ -195,11 +195,14 @@ let context_path_arg = 'preapply' RPC." string_parameter -let force_apply_switch_arg = - Tezos_clic.switch - ~long:"force-apply" - ~doc:"Force the baker to not only validate but also apply operations." - () +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 attestation_force_switch_arg = Tezos_clic.switch @@ -508,7 +511,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit_arg minimal_nanotez_per_byte_arg minimal_timestamp_switch - force_apply_switch_arg + force_apply_from_round_arg force_switch operations_arg context_path_arg @@ -522,7 +525,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte, minimal_timestamp, - force_apply, + force_apply_from_round, force, extra_operations, context_path, @@ -540,7 +543,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list ~minimal_timestamp ~minimal_nanotez_per_byte ~minimal_fees - ~force_apply + ?force_apply_from_round ~force ~monitor_node_mempool:(not do_not_monitor_node_mempool) ?extra_operations @@ -581,7 +584,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit_arg minimal_nanotez_per_byte_arg minimal_timestamp_switch - force_apply_switch_arg + force_apply_from_round_arg force_switch operations_arg context_path_arg @@ -591,7 +594,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte, minimal_timestamp, - force_apply, + force_apply_from_round, force, extra_operations, context_path, @@ -605,7 +608,7 @@ let delegate_commands () : Protocol_client_context.full Tezos_clic.command list ~minimal_timestamp ~minimal_nanotez_per_byte ~minimal_fees - ~force_apply + ?force_apply_from_round ~force ?extra_operations ?context_path @@ -683,7 +686,7 @@ let baker_args = minimal_fees_arg minimal_nanotez_per_gas_unit_arg minimal_nanotez_per_byte_arg - force_apply_switch_arg + force_apply_from_round_arg keep_alive_arg liquidity_baking_toggle_vote_arg adaptive_issuance_vote_arg @@ -701,7 +704,7 @@ let run_baker minimal_fees, minimal_nanotez_per_gas_unit, minimal_nanotez_per_byte, - force_apply, + force_apply_from_round, keep_alive, liquidity_baking_vote, adaptive_issuance_vote, @@ -749,7 +752,7 @@ let run_baker ?dal_node_endpoint ?dal_node_timeout_percentage ?pre_emptive_forge_time - ~force_apply + ?force_apply_from_round ~chain:cctxt#chain ?context_path ~keep_alive diff --git a/src/proto_alpha/lib_delegate/baking_configuration.ml b/src/proto_alpha/lib_delegate/baking_configuration.ml index 1b412886063a213d0967fdbda5f31fcc55cf08a5..d2ef80c8237dddef6718a2092217c56a4e05916b 100644 --- a/src/proto_alpha/lib_delegate/baking_configuration.ml +++ b/src/proto_alpha/lib_delegate/baking_configuration.ml @@ -89,7 +89,7 @@ type t = { retries_on_failure : int; user_activated_upgrades : (int32 * Protocol_hash.t) list; per_block_votes : per_block_votes_config; - force_apply : bool; + force_apply_from_round : Round.t; force : bool; state_recorder : state_recorder_config; extra_operations : Operations_source.t option; @@ -127,7 +127,7 @@ let default_votes_config = let default_force = false -let default_force_apply = false +let default_force_apply_from_round = Round.(succ @@ succ @@ succ zero) let default_state_recorder_config = Memory @@ -145,7 +145,7 @@ let default_config = retries_on_failure = default_retries_on_failure_config; user_activated_upgrades = default_user_activated_upgrades; per_block_votes = default_votes_config; - force_apply = default_force_apply; + force_apply_from_round = default_force_apply_from_round; force = default_force; state_recorder = default_state_recorder_config; extra_operations = default_extra_operations; @@ -161,7 +161,7 @@ let make ?(minimal_fees = default_fees_config.minimal_fees) ?(nonce = default_nonce_config) ?context_path ?(retries_on_failure = default_retries_on_failure_config) ?(user_activated_upgrades = default_user_activated_upgrades) - ?(votes = default_votes_config) ?(force_apply = default_force_apply) + ?(votes = default_votes_config) ?force_apply_from_round ?(force = default_force) ?(state_recorder = default_state_recorder_config) ?extra_operations ?dal_node_endpoint ?(dal_node_timeout_percentage = default_dal_node_timeout_percentage) @@ -174,6 +174,14 @@ let make ?(minimal_fees = default_fees_config.minimal_fees) | None -> Node | Some context_path -> Local {context_path} in + let force_apply_from_round = + match force_apply_from_round with + | Some round -> ( + match Round.of_int round with + | Ok round -> round + | Error _ -> default_force_apply_from_round) + | None -> default_force_apply_from_round + in { fees; validation; @@ -181,7 +189,7 @@ let make ?(minimal_fees = default_fees_config.minimal_fees) retries_on_failure; user_activated_upgrades; per_block_votes = votes; - force_apply; + force_apply_from_round; force; state_recorder; extra_operations; @@ -272,7 +280,7 @@ let per_block_votes_config_encoding = let force_config_encoding = Data_encoding.bool -let force_apply_config_encoding = Data_encoding.bool +let force_apply_from_round_config_encoding = Round.encoding let state_recorder_config_encoding = let open Data_encoding in @@ -307,7 +315,7 @@ let encoding : t Data_encoding.t = retries_on_failure; user_activated_upgrades; per_block_votes; - force_apply; + force_apply_from_round; force; state_recorder; extra_operations; @@ -321,7 +329,7 @@ let encoding : t Data_encoding.t = retries_on_failure, user_activated_upgrades, per_block_votes, - force_apply, + force_apply_from_round, force, state_recorder, pre_emptive_forge_time ), @@ -332,7 +340,7 @@ let encoding : t Data_encoding.t = retries_on_failure, user_activated_upgrades, per_block_votes, - force_apply, + force_apply_from_round, force, state_recorder, pre_emptive_forge_time ), @@ -345,7 +353,7 @@ let encoding : t Data_encoding.t = retries_on_failure; user_activated_upgrades; per_block_votes; - force_apply; + force_apply_from_round; force; state_recorder; extra_operations; @@ -363,7 +371,9 @@ let encoding : t Data_encoding.t = "user_activated_upgrades" user_activate_upgrades_config_encoding) (req "votes" per_block_votes_config_encoding) - (req "force_apply" force_apply_config_encoding) + (req + "force_apply_from_round" + force_apply_from_round_config_encoding) (req "force" force_config_encoding) (req "state_recorder" state_recorder_config_encoding) (req "pre_emptive_forge_time" Time.System.Span.encoding)) diff --git a/src/proto_alpha/lib_delegate/baking_configuration.mli b/src/proto_alpha/lib_delegate/baking_configuration.mli index 1e51ebfb1aa7c0993e3a65168982be1e0764ec74..28269985ff3a6b4182159ad9f9b63fa7817f8761 100644 --- a/src/proto_alpha/lib_delegate/baking_configuration.mli +++ b/src/proto_alpha/lib_delegate/baking_configuration.mli @@ -64,7 +64,7 @@ type t = { retries_on_failure : int; user_activated_upgrades : (int32 * Protocol_hash.t) list; per_block_votes : per_block_votes_config; - force_apply : bool; + force_apply_from_round : Protocol.Alpha_context.Round.t; force : bool; state_recorder : state_recorder_config; extra_operations : Operations_source.t option; @@ -85,7 +85,7 @@ val default_user_activated_upgrades : (int32 * Protocol_hash.t) list val default_votes_config : per_block_votes_config -val default_force_apply : bool +val default_force_apply_from_round : Protocol.Alpha_context.Round.t val default_force : bool @@ -106,7 +106,7 @@ val make : ?retries_on_failure:int -> ?user_activated_upgrades:(int32 * Protocol_hash.t) list -> ?votes:per_block_votes_config -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?force:bool -> ?state_recorder:state_recorder_config -> ?extra_operations:Operations_source.t -> diff --git a/src/proto_alpha/lib_delegate/baking_events.ml b/src/proto_alpha/lib_delegate/baking_events.ml index b34c1a1ca411fde0158872a09cf32d55405bc591..a4aec8a97c7df2ac97c13bbbec69516bba03d8b0 100644 --- a/src/proto_alpha/lib_delegate/baking_events.ml +++ b/src/proto_alpha/lib_delegate/baking_events.ml @@ -916,17 +916,20 @@ module Actions = struct ("delegate", Baking_state.consensus_key_and_delegate_encoding) let forging_block = - declare_3 + declare_4 ~section ~name:"forging_block" ~level:Info - ~msg:"forging block at level {level}, round {round} for {delegate}" + ~msg: + "forging block at level {level}, round {round} for {delegate} (force \ + apply: {force_apply})" ~pp1:pp_int32 ~pp2:Round.pp ~pp3:Baking_state.pp_consensus_key_and_delegate ("level", Data_encoding.int32) ("round", Round.encoding) ("delegate", Baking_state.consensus_key_and_delegate_encoding) + ("force_apply", Data_encoding.bool) let delayed_block_injection = declare_4 diff --git a/src/proto_alpha/lib_delegate/baking_lib.ml b/src/proto_alpha/lib_delegate/baking_lib.ml index 63338a50469165c754e515650a80848c7e124b56..2e982025ec663a74ab75b7479993a02b7e99021d 100644 --- a/src/proto_alpha/lib_delegate/baking_lib.ml +++ b/src/proto_alpha/lib_delegate/baking_lib.ml @@ -304,13 +304,16 @@ let propose_at_next_level ~minimal_timestamp state = state.global_state.operation_worker in let kind = Fresh pool in + let force_apply = + Round.(minimal_round >= state.global_state.config.force_apply_from_round) + in let block_to_bake = { predecessor = state.level_state.latest_proposal.block; round = minimal_round; delegate; kind; - force_apply = state.global_state.config.force_apply; + force_apply; } in let* prepared_block = @@ -360,9 +363,9 @@ let attestation_quorum state = - Yes :: repropose block with right payload and preattestations for current round - No :: repropose fresh block for current round *) let propose (cctxt : Protocol_client_context.full) ?minimal_fees - ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force_apply - ?(force = false) ?(minimal_timestamp = false) ?extra_operations - ?context_path ?state_recorder delegates = + ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte + ?force_apply_from_round ?(force = false) ?(minimal_timestamp = false) + ?extra_operations ?context_path ?state_recorder delegates = let open Lwt_result_syntax in let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in let cache = Baking_cache.Block_cache.create 10 in @@ -373,7 +376,7 @@ let propose (cctxt : Protocol_client_context.full) ?minimal_fees ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?context_path - ?force_apply + ?force_apply_from_round ~force ?extra_operations ?state_recorder @@ -691,13 +694,16 @@ let rec baking_minimal_timestamp ~count state signed_attestations.signed_consensus_votes) in let kind = Fresh pool in + let force_apply = + Round.(minimal_round >= state.global_state.config.force_apply_from_round) + in let block_to_bake = { predecessor = latest_proposal.block; round = minimal_round; delegate; kind; - force_apply = state.global_state.config.force_apply; + force_apply; } in let* prepared_block = @@ -757,10 +763,10 @@ let rec baking_minimal_timestamp ~count state baking_minimal_timestamp ~count:(pred count) new_state block_stream let bake (cctxt : Protocol_client_context.full) ?minimal_fees - ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?force_apply ?force - ?(minimal_timestamp = false) ?extra_operations - ?(monitor_node_mempool = true) ?context_path ?dal_node_endpoint ?(count = 1) - ?votes ?state_recorder delegates = + ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte + ?force_apply_from_round ?force ?(minimal_timestamp = false) + ?extra_operations ?(monitor_node_mempool = true) ?context_path + ?dal_node_endpoint ?(count = 1) ?votes ?state_recorder delegates = let open Lwt_result_syntax in let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in let config = @@ -769,7 +775,7 @@ let bake (cctxt : Protocol_client_context.full) ?minimal_fees ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?context_path - ?force_apply + ?force_apply_from_round ?force ?extra_operations ?dal_node_endpoint diff --git a/src/proto_alpha/lib_delegate/baking_lib.mli b/src/proto_alpha/lib_delegate/baking_lib.mli index 6805daf9ae176df7c63a667c3edadedbd10e6d26..cd456f8b048d8bb9d39c7cf38abeaa2470c26b3a 100644 --- a/src/proto_alpha/lib_delegate/baking_lib.mli +++ b/src/proto_alpha/lib_delegate/baking_lib.mli @@ -32,7 +32,7 @@ val bake : ?minimal_fees:Tez.t -> ?minimal_nanotez_per_gas_unit:Q.t -> ?minimal_nanotez_per_byte:Q.t -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?force:bool -> ?minimal_timestamp:bool -> ?extra_operations:Baking_configuration.Operations_source.t -> @@ -63,7 +63,7 @@ val propose : ?minimal_fees:Tez.t -> ?minimal_nanotez_per_gas_unit:Q.t -> ?minimal_nanotez_per_byte:Q.t -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?force:bool -> ?minimal_timestamp:bool -> ?extra_operations:Baking_configuration.Operations_source.t -> diff --git a/src/proto_alpha/lib_delegate/baking_state.mli b/src/proto_alpha/lib_delegate/baking_state.mli index 6eb41e0402c3b09bb02cdcacb0608f47de7c1afc..a5568a8c28b695f6cf622a49e28c9f408bd1762f 100644 --- a/src/proto_alpha/lib_delegate/baking_state.mli +++ b/src/proto_alpha/lib_delegate/baking_state.mli @@ -350,8 +350,8 @@ type block_to_bake = { kind : block_kind; (** Either a reproposal or a fresh proposal *) force_apply : bool; (** if true, while baking the block, try and apply the block and its - operations instead of only validating them. this can be permanently - set using the [--force-apply] flag (see [force_apply_switch_arg] in + operations instead of only validating them. This can be set using the + [--force-apply-from-round] flag (see [force_apply_from_round_arg] in [baking_commands.ml]). *) } diff --git a/src/proto_alpha/lib_delegate/client_daemon.ml b/src/proto_alpha/lib_delegate/client_daemon.ml index a51235b8547b16baa1e9a44b79e72484cef579a2..0acfd412a565327765f3ab6d0bdf4a72cec9b748 100644 --- a/src/proto_alpha/lib_delegate/client_daemon.ml +++ b/src/proto_alpha/lib_delegate/client_daemon.ml @@ -60,8 +60,8 @@ module Baker = struct let run (cctxt : Protocol_client_context.full) ?minimal_fees ?minimal_nanotez_per_gas_unit ?minimal_nanotez_per_byte ?votes ?extra_operations ?dal_node_endpoint ?dal_node_timeout_percentage - ?pre_emptive_forge_time ?force_apply ?context_path ?state_recorder ~chain - ~keep_alive delegates = + ?pre_emptive_forge_time ?force_apply_from_round ?context_path + ?state_recorder ~chain ~keep_alive delegates = let open Lwt_result_syntax in let process () = let* user_activated_upgrades = @@ -112,7 +112,7 @@ module Baker = struct ?dal_node_endpoint ?dal_node_timeout_percentage ~pre_emptive_forge_time - ?force_apply + ?force_apply_from_round ?context_path ~user_activated_upgrades ?state_recorder diff --git a/src/proto_alpha/lib_delegate/client_daemon.mli b/src/proto_alpha/lib_delegate/client_daemon.mli index 5fa115099b6aac801178472bd6175783c1d4cbb6..bc02d9e76cd52b53e7b62ea2c7e9fa350c8a44e4 100644 --- a/src/proto_alpha/lib_delegate/client_daemon.mli +++ b/src/proto_alpha/lib_delegate/client_daemon.mli @@ -37,7 +37,7 @@ module Baker : sig ?dal_node_endpoint:Uri.t -> ?dal_node_timeout_percentage:int -> ?pre_emptive_forge_time:Q.t -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?context_path:string -> ?state_recorder:Baking_configuration.state_recorder_config -> chain:Shell_services.chain -> diff --git a/src/proto_alpha/lib_delegate/state_transitions.ml b/src/proto_alpha/lib_delegate/state_transitions.ml index 1b08f8c8575237be4a498262de578806d6795ecc..0d9b72534935eefb7873085fba8b27b5711eb787 100644 --- a/src/proto_alpha/lib_delegate/state_transitions.ml +++ b/src/proto_alpha/lib_delegate/state_transitions.ml @@ -532,9 +532,9 @@ let prepare_block_to_bake ~attestations ?last_proposal let kind = Fresh operation_pool in let* () = Events.(emit preparing_fresh_block (delegate, round)) in let force_apply = - state.global_state.config.force_apply || Round.(round <> zero) - (* This is used as a safety net by applying blocks on round > 0, in case - validation-only did not produce a correct round-0 block. *) + (* This is used as a safety net by applying blocks in case validation-only + did not produce correct block. *) + Round.(round >= state.global_state.config.force_apply_from_round) in let block_to_bake : block_to_bake = {predecessor; round; delegate; kind; force_apply} @@ -637,9 +637,9 @@ let propose_block_action state delegate round ~last_proposal = Reproposal {consensus_operations; payload_hash; payload_round; payload} in let force_apply = - true - (* This is used as a safety net by applying blocks on round > 0, in case - validation-only did not produce a correct round-0 block. *) + (* This is used as a safety net by applying blocks in case validation-only + did not produce correct block. *) + Round.(round >= state.global_state.config.force_apply_from_round) in let block_to_bake = {predecessor = proposal.predecessor; round; delegate; kind; force_apply} diff --git a/tezt/lib_tezos/baker.ml b/tezt/lib_tezos/baker.ml index 217ad787f16e13bcc8a55d4080a9c2172f577dbd..86ae3bf92348baae18f07213da727a2773ece14b 100644 --- a/tezt/lib_tezos/baker.ml +++ b/tezt/lib_tezos/baker.ml @@ -49,7 +49,7 @@ module Parameters = struct mutable pending_ready : unit option Lwt.u list; votefile : string option; liquidity_baking_toggle_vote : liquidity_baking_vote option; - force_apply : bool; + force_apply_from_round : int option; remote_mode : bool; operations_pool : string option; minimal_nanotez_per_gas_unit : int option; @@ -100,7 +100,7 @@ let liquidity_baking_votefile ?path vote = let create_from_uris ?runner ~protocol ?(path = Uses.path (Protocol.baker protocol)) ?name ?color ?event_pipe ?(delegates = []) ?votefile ?(liquidity_baking_toggle_vote = Some Pass) - ?(force_apply = false) ?(remote_mode = false) ?operations_pool + ?force_apply_from_round ?(remote_mode = false) ?operations_pool ?dal_node_rpc_endpoint ?dal_node_timeout_percentage ?minimal_nanotez_per_gas_unit ?(state_recorder = false) ?(node_version_check_bypass = false) ?node_version_allowed ~base_dir @@ -123,7 +123,7 @@ let create_from_uris ?runner ~protocol votefile; liquidity_baking_toggle_vote; remote_mode; - force_apply; + force_apply_from_round; operations_pool; dal_node_rpc_endpoint; dal_node_timeout_percentage; @@ -137,8 +137,8 @@ let create_from_uris ?runner ~protocol baker let create ?runner ~protocol ?path ?name ?color ?event_pipe ?(delegates = []) - ?votefile ?(liquidity_baking_toggle_vote = Some Pass) ?(force_apply = false) - ?(remote_mode = false) ?operations_pool ?dal_node + ?votefile ?(liquidity_baking_toggle_vote = Some Pass) + ?force_apply_from_round ?(remote_mode = false) ?operations_pool ?dal_node ?dal_node_timeout_percentage ?minimal_nanotez_per_gas_unit ?(state_recorder = false) ?(node_version_check_bypass = false) ?node_version_allowed node client = @@ -153,7 +153,7 @@ let create ?runner ~protocol ?path ?name ?color ?event_pipe ?(delegates = []) ~delegates ?votefile ~liquidity_baking_toggle_vote - ~force_apply + ?force_apply_from_round ~remote_mode ?operations_pool ?minimal_nanotez_per_gas_unit @@ -185,8 +185,22 @@ let run ?event_level ?event_sections_levels (baker : t) = liquidity_baking_vote_to_string baker.persistent_state.liquidity_baking_toggle_vote in - let force_apply = - Cli_arg.optional_switch "force-apply" baker.persistent_state.force_apply + let force_apply_from_round = + (* From Quebec, the flag --force-apply has been replaced by + --force-apply-from-round, the following maintains back-compatibility with + ParisC tests. *) + if + Protocol.number baker.persistent_state.protocol + > Protocol.number Protocol.ParisC + then + Cli_arg.optional_arg + "force-apply-from-round" + string_of_int + baker.persistent_state.force_apply_from_round + else + Cli_arg.optional_switch + "force-apply" + (Option.is_some baker.persistent_state.force_apply_from_round) in let operations_pool = Cli_arg.optional_arg @@ -232,10 +246,10 @@ let run ?event_level ?event_sections_levels (baker : t) = in let arguments = ["--endpoint"; node_addr; "--base-dir"; base_dir; "run"] - @ run_args @ liquidity_baking_toggle_vote @ votefile @ force_apply - @ operations_pool @ dal_node_endpoint @ dal_node_timeout_percentage - @ delegates @ minimal_nanotez_per_gas_unit @ state_recorder - @ node_version_check_bypass @ node_version_allowed + @ run_args @ liquidity_baking_toggle_vote @ votefile + @ force_apply_from_round @ operations_pool @ dal_node_endpoint + @ dal_node_timeout_percentage @ delegates @ minimal_nanotez_per_gas_unit + @ state_recorder @ node_version_check_bypass @ node_version_allowed in let on_terminate _ = @@ -270,7 +284,7 @@ let wait_for_ready baker = let init ?runner ~protocol ?(path = Uses.path (Protocol.baker protocol)) ?name ?color ?event_level ?event_pipe ?event_sections_levels ?(delegates = []) - ?votefile ?liquidity_baking_toggle_vote ?force_apply ?remote_mode + ?votefile ?liquidity_baking_toggle_vote ?force_apply_from_round ?remote_mode ?operations_pool ?dal_node ?dal_node_timeout_percentage ?minimal_nanotez_per_gas_unit ?state_recorder ?node_version_check_bypass ?node_version_allowed node client = @@ -285,7 +299,7 @@ let init ?runner ~protocol ?(path = Uses.path (Protocol.baker protocol)) ?name ?event_pipe ?votefile ?liquidity_baking_toggle_vote - ?force_apply + ?force_apply_from_round ?remote_mode ?operations_pool ?dal_node diff --git a/tezt/lib_tezos/baker.mli b/tezt/lib_tezos/baker.mli index ce17ca37310c18ecbaeb3dfbb725e3dcc6bff8ab..26c1c5a0c051a1c8991350c07068addca02e7910 100644 --- a/tezt/lib_tezos/baker.mli +++ b/tezt/lib_tezos/baker.mli @@ -126,9 +126,10 @@ val liquidity_baking_votefile : ?path:string -> liquidity_baking_vote -> string is not passed. If it is [Some x] then [--liquidity-baking-toggle-vote x] is passed. The default value is [Some Pass]. - [operations_pool], [force_apply], [state_recorder], + [operations_pool], [force_apply_from_round], [state_recorder], [node_version_check_bypass] and [node_version_allowed] are passed to the - baker daemon through the flag [--operations-pool], [--force_apply], + baker daemon through the flag [--operations-pool], + [--force_apply_from_round], [--record-state], [--node-version-check-bypass] and [--node-version-allowed]. @@ -151,7 +152,7 @@ val create : ?delegates:string list -> ?votefile:string -> ?liquidity_baking_toggle_vote:liquidity_baking_vote option -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?remote_mode:bool -> ?operations_pool:string -> ?dal_node:Dal_node.t -> @@ -192,7 +193,7 @@ val create_from_uris : ?delegates:string list -> ?votefile:string -> ?liquidity_baking_toggle_vote:liquidity_baking_vote option -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?remote_mode:bool -> ?operations_pool:string -> ?dal_node_rpc_endpoint:Endpoint.t -> @@ -237,7 +238,7 @@ val create_from_uris : baker. This defaults to the empty list, which is a shortcut for "every known account". - [votefile], [liquidity_baking_toggle_vote], [force_apply], + [votefile], [liquidity_baking_toggle_vote], [force_apply_from_round], [state_recorder], [node_version_check_bypass], [node_version_allowed] respectively [operations_pool] are passed to the baker daemon through the flags [--votefile], [--liquidity-baking-toggle-vote], [--should-apply], @@ -261,7 +262,7 @@ val init : ?delegates:string list -> ?votefile:string -> ?liquidity_baking_toggle_vote:liquidity_baking_vote option -> - ?force_apply:bool -> + ?force_apply_from_round:int -> ?remote_mode:bool -> ?operations_pool:string -> ?dal_node:Dal_node.t -> diff --git a/tezt/tests/baker_test.ml b/tezt/tests/baker_test.ml index c3f2ee040dd0af706148e928745f9a8ab3fbdb0a..21e55e926261199c1a47c27114f0b5973ffad825 100644 --- a/tezt/tests/baker_test.ml +++ b/tezt/tests/baker_test.ml @@ -34,6 +34,27 @@ let team = Tag.layer1 let hooks = Tezos_regression.hooks +let log_step counter msg = + let color = Log.Color.(bold ++ FG.blue) in + let prefix = "step" ^ string_of_int counter in + Log.info ~color ~prefix msg + +(* [fetch_baking_rights client lvl] calls the baking_rights RPC and returns the + result as an association list. The list associates each round number with the + public key hash of the delegate holding baking rights for that round. *) +let fetch_baking_rights client level = + let* baking_rights_json = + Client.RPC.call client @@ RPC.get_chain_block_helper_baking_rights ~level () + in + return + @@ List.map + JSON.( + fun json -> + let round = json |-> "round" |> as_int in + let delegate_pkh = json |-> "delegate" |> as_string in + (round, delegate_pkh)) + JSON.(as_list baking_rights_json) + let check_node_version_check_bypass_test = Protocol.register_test ~__FILE__ @@ -115,7 +136,7 @@ let baker_reward_test = in unit) -let baker_test ?force_apply protocol ~keys = +let baker_test protocol ~keys = let* parameter_file = Protocol.write_parameter_file ~bootstrap_accounts:(List.map (fun k -> (k, None)) keys) @@ -133,7 +154,7 @@ let baker_test ?force_apply protocol ~keys = in let level_2_promise = Node.wait_for_level node 2 in let level_3_promise = Node.wait_for_level node 3 in - let* baker = Baker.init ?force_apply ~protocol node client in + let* baker = Baker.init ~protocol node client in Log.info "Wait for new head." ; Baker.log_events baker ; let* _ = level_2_promise in @@ -181,7 +202,7 @@ let baker_stresstest_apply = let* node, client = Client.init_with_protocol `Client ~protocol () ~timestamp:Now in - let* _ = Baker.init ~force_apply:true ~protocol node client in + let* _ = Baker.init ~force_apply_from_round:0 ~protocol node client in let* _ = Node.wait_for_level node 3 in (* Use a large tps, to have failing operations too *) let* () = Client.stresstest ~tps:25 ~transfers:100 client in @@ -291,6 +312,100 @@ let baker_check_consensus_branch = unit) ops +(** Test that blocks are applied only if round >= [force_apply_from_round]. *) +let force_apply_from_round = + Protocol.register_test + ~__FILE__ + ~title:"Baker check force apply from round" + ~tags:[team; "baker"; "force_apply_from_round"] + ~supports:Protocol.(From_protocol 021) + ~uses:(fun protocol -> [Protocol.baker protocol]) + @@ fun protocol -> + log_step 1 "initialize a node and a client with protocol" ; + let* node, client = + Client.init_with_protocol `Client ~protocol () ~timestamp:Now + in + + log_step 2 "wait for level 1" ; + let* _ = Node.wait_for_level node 1 in + + log_step 3 "find suitable delegate and rounds" ; + let force_apply_from_round = 3 in + let* baking_rights_at_level_3 = fetch_baking_rights client 2 in + (* pick the delegate that has baking rights at level 3 round 1 *) + let delegate = List.assoc 1 baking_rights_at_level_3 in + (* find the smallest level (>= 4) where [delegate] first baking round is + greater or equal than [force_apply_from_round]. *) + let rec loop level = + let* baking_rights = fetch_baking_rights client level in + match + List.find_opt (fun (_, delegate') -> delegate = delegate') baking_rights + with + | Some (round, _) when round >= force_apply_from_round -> + return (level, round) + | _ -> loop (succ level) + in + let* level, round = loop 4 in + Log.info + "delegate %s has baking rights for level 3 round 1 and level %d round %d" + delegate + level + round ; + + log_step + 5 + "spawn a baker with delegate %s and force_apply_from_round %d" + delegate + force_apply_from_round ; + let* baker = + Baker.init + ~protocol + ~force_apply_from_round + ~delegates:[delegate] + node + client + in + + (* fail if a block is applied at a round < [force_apply_from_round] *) + Baker.on_event baker (fun Baker.{name; value; _} -> + if name = "forging_block.v0" then + let round = JSON.(value |-> "round" |> as_int) in + let level = JSON.(value |-> "level" |> as_int) in + let force_apply = JSON.(value |-> "force_apply" |> as_bool) in + if force_apply && round < force_apply_from_round then + Test.fail + "block at level %d round %d shouldn't have been applied" + level + round) ; + + (* a promise that resolves on event forging_block when + (force_apply = true && round = [round] && level = [level]) *) + let forced_application_promise = + Baker.wait_for baker "forging_block.v0" (fun json -> + let round' = JSON.(json |-> "round" |> as_int) in + let level' = JSON.(json |-> "level" |> as_int) in + let force_apply = JSON.(json |-> "force_apply" |> as_bool) in + if force_apply && level = level' && round = round' then Some () + else None) + in + + let* _ = Node.wait_for_level node level in + log_step + 6 + "level %d round %d has been baked, check that block has been forged with \ + force_apply = true" + level + round ; + + (* promise should be fulfilled *) + if Lwt.state forced_application_promise <> Lwt.Return () then + Tezt.Test.fail + "level %d has been baked at round >= %d and block wasn't forged with \ + force_apply = true" + level + round ; + unit + let register ~protocols = check_node_version_check_bypass_test protocols ; check_node_version_allowed_test protocols ; @@ -301,4 +416,5 @@ let register ~protocols = baker_stresstest_apply protocols ; baker_bls_test protocols ; baker_remote_test protocols ; - baker_check_consensus_branch protocols + baker_check_consensus_branch protocols ; + force_apply_from_round protocols diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index f99be8706d276abf8211010aa7ed0d5ebc5297c7..3c524e3d421c7bf8f83fa86393bd4c091b97f676 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -4587,7 +4587,7 @@ let test_restart_dal_node protocol dal_parameters _cryptobox node client ~delegates:all_pkhs ~liquidity_baking_toggle_vote:(Some On) ~state_recorder:true - ~force_apply:true + ~force_apply_from_round:0 ~dal_node node client @@ -7260,7 +7260,7 @@ let scenario_tutorial_dal_baker = ~delegates:all_delegates ~liquidity_baking_toggle_vote:(Some On) ~state_recorder:true - ~force_apply:true + ~force_apply_from_round:0 node client in