diff --git a/contrib/kaitai-struct-files/files/alpha__constants.ksy b/contrib/kaitai-struct-files/files/alpha__constants.ksy index 934d4bb5dc8f9cad65ba60e1285c8fdb0d25698d..df425343fc0e4777eabd965bd207e9ad96ff9002 100644 --- a/contrib/kaitai-struct-files/files/alpha__constants.ksy +++ b/contrib/kaitai-struct-files/files/alpha__constants.ksy @@ -355,6 +355,12 @@ seq: - id: autostaking_enable type: u1 enum: bool +- id: adaptive_issuance_force_activation + type: u1 + enum: bool +- id: ns_enable + type: u1 + enum: bool - id: direct_ticket_spending_enable type: u1 enum: bool diff --git a/contrib/kaitai-struct-files/files/alpha__constants__parametric.ksy b/contrib/kaitai-struct-files/files/alpha__constants__parametric.ksy index 752688d917472a07dfaaf0d9221c5907cb06a29a..bd992556c3fe8183a2b2858ae65ff96937904fe4 100644 --- a/contrib/kaitai-struct-files/files/alpha__constants__parametric.ksy +++ b/contrib/kaitai-struct-files/files/alpha__constants__parametric.ksy @@ -327,6 +327,12 @@ seq: - id: autostaking_enable type: u1 enum: bool +- id: adaptive_issuance_force_activation + type: u1 + enum: bool +- id: ns_enable + type: u1 + enum: bool - id: direct_ticket_spending_enable type: u1 enum: bool diff --git a/contrib/kaitai-struct-files/files/alpha__parameters.ksy b/contrib/kaitai-struct-files/files/alpha__parameters.ksy index 9904127c7c66c26fdd55333b792018eda4aff5e2..acdd2515c22f99e852ecdf0927e94c913cda36e4 100644 --- a/contrib/kaitai-struct-files/files/alpha__parameters.ksy +++ b/contrib/kaitai-struct-files/files/alpha__parameters.ksy @@ -605,6 +605,12 @@ seq: - id: autostaking_enable type: u1 enum: bool +- id: adaptive_issuance_force_activation + type: u1 + enum: bool +- id: ns_enable + type: u1 + enum: bool - id: direct_ticket_spending_enable type: u1 enum: bool diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index 03f75600a51250e8f4806bacecf14ba73b597a66..ad0ec9a000ed4a3902560aa527ecb38a8b1664f2 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -295,6 +295,8 @@ let constants_mainnet = }; activation_vote_enable = false; autostaking_enable = true; + force_activation = false; + ns_enable = false; }; (* TODO: https://gitlab.com/tezos/tezos/-/issues/6668 Enable once at least the following is done: diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index d3dc9f7ef7fb331fc09f2d0cc8bd31dc3da2a04d..7ab3ce62372882e7976e82d30a9debd785705203 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -874,6 +874,8 @@ module Constants : sig adaptive_rewards_params : adaptive_rewards_params; activation_vote_enable : bool; autostaking_enable : bool; + force_activation : bool; + ns_enable : bool; } type issuance_weights = { diff --git a/src/proto_alpha/lib_protocol/constants_parametric_repr.ml b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml index b66fc7a8e6b9e59601f01eb7acb09036d9144fa8..cfc9a65b6653a862ef996b458fa2377d9c3a74c9 100644 --- a/src/proto_alpha/lib_protocol/constants_parametric_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml @@ -163,6 +163,8 @@ type adaptive_issuance = { adaptive_rewards_params : adaptive_rewards_params; activation_vote_enable : bool; autostaking_enable : bool; + force_activation : bool; + ns_enable : bool; } type issuance_weights = { @@ -437,19 +439,25 @@ let adaptive_issuance_encoding = adaptive_rewards_params; activation_vote_enable; autostaking_enable; + force_activation; + ns_enable; } -> ( global_limit_of_staking_over_baking, edge_of_staking_over_delegation, launch_ema_threshold, adaptive_rewards_params, activation_vote_enable, - autostaking_enable )) + autostaking_enable, + force_activation, + ns_enable )) (fun ( global_limit_of_staking_over_baking, edge_of_staking_over_delegation, launch_ema_threshold, adaptive_rewards_params, activation_vote_enable, - autostaking_enable ) -> + autostaking_enable, + force_activation, + ns_enable ) -> { global_limit_of_staking_over_baking; edge_of_staking_over_delegation; @@ -457,14 +465,18 @@ let adaptive_issuance_encoding = adaptive_rewards_params; activation_vote_enable; autostaking_enable; + force_activation; + ns_enable; }) - (obj6 + (obj8 (req "global_limit_of_staking_over_baking" uint8) (req "edge_of_staking_over_delegation" uint8) (req "adaptive_issuance_launch_ema_threshold" int32) (req "adaptive_rewards_params" adaptive_rewards_params_encoding) (req "adaptive_issuance_activation_vote_enable" bool) - (req "autostaking_enable" bool)) + (req "autostaking_enable" bool) + (req "adaptive_issuance_force_activation" bool) + (req "ns_enable" bool)) let issuance_weights_encoding = let open Data_encoding in diff --git a/src/proto_alpha/lib_protocol/constants_parametric_repr.mli b/src/proto_alpha/lib_protocol/constants_parametric_repr.mli index 66a7d0d0272800b0da299262f6d93c5e75fe18fa..ff4b3a1b26c204cd9321c004692685396e09565e 100644 --- a/src/proto_alpha/lib_protocol/constants_parametric_repr.mli +++ b/src/proto_alpha/lib_protocol/constants_parametric_repr.mli @@ -147,6 +147,12 @@ type adaptive_issuance = { (* If set to true, a stake/unstake/finalize operation will be triggered for all delegate at end of cycle. *) bool; + force_activation : + (* For testing purposes. If set to true, the adaptive issuance feature is + enabled without waiting to reach the launch_ema_threshold.*) + bool; + ns_enable : (* If set to true, enables the NS feature *) + bool; } type issuance_weights = { diff --git a/src/proto_alpha/lib_protocol/constants_storage.ml b/src/proto_alpha/lib_protocol/constants_storage.ml index 87755106dee6ad7257f3854c47cebe32bc5c52a5..83da05502109b5754af672047e905e45de24ead0 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.ml +++ b/src/proto_alpha/lib_protocol/constants_storage.ml @@ -262,5 +262,10 @@ let adaptive_issuance_activation_vote_enable c = let adaptive_issuance_autostaking_enable c = (adaptive_issuance c).autostaking_enable +let adaptive_issuance_force_activation c = + (adaptive_issuance c).force_activation + +let adaptive_issuance_ns_enable c = (adaptive_issuance c).ns_enable + let direct_ticket_spending_enable c = (Raw_context.constants c).direct_ticket_spending_enable diff --git a/src/proto_alpha/lib_protocol/constants_storage.mli b/src/proto_alpha/lib_protocol/constants_storage.mli index 77fa0186cf98abcb916af6a7521e61c5b4baa773..78d43459778fdb84da3998d32a8d1af21fcebc21 100644 --- a/src/proto_alpha/lib_protocol/constants_storage.mli +++ b/src/proto_alpha/lib_protocol/constants_storage.mli @@ -159,4 +159,8 @@ val adaptive_issuance_rewards_params : val adaptive_issuance_autostaking_enable : Raw_context.t -> bool +val adaptive_issuance_force_activation : Raw_context.t -> bool + +val adaptive_issuance_ns_enable : Raw_context.t -> bool + val direct_ticket_spending_enable : Raw_context.t -> bool diff --git a/src/proto_alpha/lib_protocol/init_storage.ml b/src/proto_alpha/lib_protocol/init_storage.ml index e5958cf6351346a56da53230eec7f85e813b25cd..8d5ad4dff4f4801b9a9bacf2ef80f29f78e4d8fa 100644 --- a/src/proto_alpha/lib_protocol/init_storage.ml +++ b/src/proto_alpha/lib_protocol/init_storage.ml @@ -209,7 +209,14 @@ let prepare_first_block chain_id ctxt ~typecheck_smart_contract let*! ctxt = Storage.Pending_migration.Balance_updates.add ctxt balance_updates in - return ctxt + if Constants_storage.adaptive_issuance_force_activation ctxt then + let ctxt = Raw_context.set_adaptive_issuance_enable ctxt in + let* ctxt = + let current_cycle = (Level_storage.current ctxt).cycle in + Storage.Adaptive_issuance.Activation.update ctxt (Some current_cycle) + in + return ctxt + else return ctxt let prepare ctxt ~level ~predecessor_timestamp ~timestamp = let open Lwt_result_syntax in diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 424600b31c3cd6745ddace0c242565a70765b91b..6ae22b069247d4bab51bf9f45a0170118364ea78 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -1165,6 +1165,8 @@ let prepare_first_block ~level ~timestamp _chain_id ctxt = activation_vote_enable = c.adaptive_issuance.activation_vote_enable; autostaking_enable = c.adaptive_issuance.autostaking_enable; + force_activation = false; + ns_enable = false; } in let issuance_weights : Constants_parametric_repr.issuance_weights = diff --git a/src/proto_alpha/lib_protocol/test/integration/test_adaptive_issuance_launch.ml b/src/proto_alpha/lib_protocol/test/integration/test_adaptive_issuance_launch.ml index cbb75e645266483ef571f6f0e0533926c2cda56f..9af0c2c7c22fce5bac8cbcd7d076daaa4f2f557c 100644 --- a/src/proto_alpha/lib_protocol/test/integration/test_adaptive_issuance_launch.ml +++ b/src/proto_alpha/lib_protocol/test/integration/test_adaptive_issuance_launch.ml @@ -461,8 +461,96 @@ let test_does_not_launch_without_feature_flag threshold vote_duration () = in return_unit +(* Test that with force_activation feature flag set, the feature activates + without waiting for the activation vote *) +let test_launch_without_vote () = + let open Lwt_result_wrap_syntax in + (* Initialize the state with a single delegate. *) + let constants = + let default_constants = Default_parameters.constants_test in + let issuance_weights = + { + Default_parameters.constants_test.issuance_weights with + base_total_issued_per_minute = Tez.zero; + } + in + let adaptive_issuance = + {default_constants.adaptive_issuance with force_activation = true} + in + let consensus_threshold = 0 in + { + default_constants with + consensus_threshold; + issuance_weights; + adaptive_issuance; + } + in + let* block, delegate = Context.init_with_constants1 constants in + let delegate_pkh = Context.Contract.pkh delegate in + let* block = Block.bake block in + + (* AI should be activated and launch cycle is current cycle (0) *) + let* launch_cycle_opt = + Context.get_adaptive_issuance_launch_cycle (B block) + in + let* launch_cycle = Assert.get_some ~loc:__LOC__ launch_cycle_opt in + let* () = Assert.equal_int32 ~loc:__LOC__ (Cycle.to_int32 launch_cycle) 0l in + + let* () = + assert_total_frozen_stake + ~loc:__LOC__ + block + (Protocol.Alpha_context.Tez.of_mutez_exn 200_000_000_000L) + in + (* feature flag is set, AI should be active, let's use the stake function to check *) + let* operation = + stake + (B block) + delegate + (Protocol.Alpha_context.Tez.of_mutez_exn 180_000_000_000L) + in + let* block = Block.bake ~operation block in + (* Wait until total frozen stake is updated *) + let start_cycle = Block.current_cycle block in + let* block = + Block.bake_while + ~invariant:(fun block -> + assert_total_frozen_stake + ~loc:__LOC__ + block + (Protocol.Alpha_context.Tez.of_mutez_exn 200_000_000_000L)) + (fun block -> + let current_cycle = Block.current_cycle block in + Protocol.Alpha_context.Cycle.( + current_cycle <= add start_cycle constants.preserved_cycles)) + block + in + let* block = Block.bake block in + + let* () = + assert_total_frozen_stake + ~loc:__LOC__ + block + (Protocol.Alpha_context.Tez.of_mutez_exn 380_000_000_000L) + in + let* () = + assert_voting_power + ~loc:__LOC__ + block + delegate_pkh + ~ai_enabled:true + ~expected_staked:380_000_000_000L + ~expected_delegated:0L + ~expected_ext_staked:0L + in + return_unit + let tests = [ + Tztest.tztest + "Launch with force_activation feature flag set activates AI immediately" + `Quick + test_launch_without_vote; Tztest.tztest "the EMA reaches the vote threshold at the expected level and adaptive \ issuance launches (very low threshold, vote enabled)" diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out index 7c82c383618adee01e60b251c5f8c6c5c5286fe1..87840fd9f9e3362ea47128f4319c987ef7497e2c 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out @@ -74,7 +74,8 @@ "center_dz": { "numerator": "1", "denominator": "2" }, "radius_dz": { "numerator": "1", "denominator": "50" } }, "adaptive_issuance_activation_vote_enable": false, - "autostaking_enable": true, "direct_ticket_spending_enable": false } + "autostaking_enable": true, "adaptive_issuance_force_activation": false, + "ns_enable": false, "direct_ticket_spending_enable": false } ./octez-client rpc get /chains/main/blocks/head/helpers/baking_rights [ { "level": 2, "delegate": "[PUBLIC_KEY_HASH]", diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out index 456ddf0b760ba54c8c190e05708c6c791e83fa3e..703252316c0e2c57cfeec15d8a681d076efb8aef 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out @@ -74,7 +74,8 @@ "center_dz": { "numerator": "1", "denominator": "2" }, "radius_dz": { "numerator": "1", "denominator": "50" } }, "adaptive_issuance_activation_vote_enable": false, - "autostaking_enable": true, "direct_ticket_spending_enable": false } + "autostaking_enable": true, "adaptive_issuance_force_activation": false, + "ns_enable": false, "direct_ticket_spending_enable": false } ./octez-client --mode light rpc get /chains/main/blocks/head/helpers/baking_rights [ { "level": 2, "delegate": "[PUBLIC_KEY_HASH]", diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out index 75146fa3223a7ead5b0877d23aaebf2df130e630..0c5903016d5cfe064e5ef389c598d4f4bb9e45d7 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out @@ -74,7 +74,8 @@ "center_dz": { "numerator": "1", "denominator": "2" }, "radius_dz": { "numerator": "1", "denominator": "50" } }, "adaptive_issuance_activation_vote_enable": false, - "autostaking_enable": true, "direct_ticket_spending_enable": false } + "autostaking_enable": true, "adaptive_issuance_force_activation": false, + "ns_enable": false, "direct_ticket_spending_enable": false } ./octez-client --mode proxy rpc get /chains/main/blocks/head/helpers/baking_rights [ { "level": 2, "delegate": "[PUBLIC_KEY_HASH]", diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out index 3ee7bcdc91448df36d03dbdec2286498d08125e0..5ff3277de7e594dc3a7a104004b58510bb23be60 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out @@ -74,7 +74,8 @@ "center_dz": { "numerator": "1", "denominator": "2" }, "radius_dz": { "numerator": "1", "denominator": "50" } }, "adaptive_issuance_activation_vote_enable": false, - "autostaking_enable": true, "direct_ticket_spending_enable": false } + "autostaking_enable": true, "adaptive_issuance_force_activation": false, + "ns_enable": false, "direct_ticket_spending_enable": false } ./octez-client rpc get /chains/main/blocks/head/helpers/baking_rights [ { "level": 3, "delegate": "[PUBLIC_KEY_HASH]", diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out index 3ee7bcdc91448df36d03dbdec2286498d08125e0..5ff3277de7e594dc3a7a104004b58510bb23be60 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out @@ -74,7 +74,8 @@ "center_dz": { "numerator": "1", "denominator": "2" }, "radius_dz": { "numerator": "1", "denominator": "50" } }, "adaptive_issuance_activation_vote_enable": false, - "autostaking_enable": true, "direct_ticket_spending_enable": false } + "autostaking_enable": true, "adaptive_issuance_force_activation": false, + "ns_enable": false, "direct_ticket_spending_enable": false } ./octez-client rpc get /chains/main/blocks/head/helpers/baking_rights [ { "level": 3, "delegate": "[PUBLIC_KEY_HASH]",