diff --git a/src/proto_alpha/lib_protocol/test/integration/test_adaptive_inflation_launch.ml b/src/proto_alpha/lib_protocol/test/integration/test_adaptive_inflation_launch.ml index c0c333689bf5fe2e8730d52935cb20cb8f529c6e..e83b840e067e118d1afe8765a1a397d3d8142159 100644 --- a/src/proto_alpha/lib_protocol/test/integration/test_adaptive_inflation_launch.ml +++ b/src/proto_alpha/lib_protocol/test/integration/test_adaptive_inflation_launch.ml @@ -53,9 +53,57 @@ let assert_is_not_yet_set_to_launch ~loc blk = cycle) launch_cycle_opt -(* Test that the EMA of the adaptive inflation vote reaches the - threshold after the expected duration. Also test that the launch - cycle is set as soon as the threshold is reached. *) +let assert_cycle_eq ~loc c1 c2 = + Assert.equal + ~loc + Protocol.Alpha_context.Cycle.( = ) + "cycle equality" + Protocol.Alpha_context.Cycle.pp + c1 + c2 + +let assert_current_cycle ~loc (blk : Block.t) expected = + let open Lwt_result_syntax in + let* current_cycle = Block.current_cycle blk in + assert_cycle_eq ~loc current_cycle expected + +let stake ctxt contract amount = + let open Lwt_result_wrap_syntax in + let*?@ entrypoint = + Protocol.Alpha_context.Entrypoint.of_string_strict ~loc:0 "stake" + in + Op.transaction ctxt ~entrypoint contract contract amount + +let set_delegate_parameters ctxt delegate ~staking_over_baking_limit + ~baking_over_staking_edge = + let open Lwt_result_wrap_syntax in + let*?@ entrypoint = + Protocol.Alpha_context.Entrypoint.of_string_strict + ~loc:0 + "set_delegate_parameters" + in + let parameters = + Protocol.Alpha_context.Script.lazy_expr + (Expr.from_string + (Printf.sprintf + "Pair %d (Pair %d Unit)" + staking_over_baking_limit + baking_over_staking_edge)) + in + Op.transaction + ctxt + ~entrypoint + ~parameters + delegate + delegate + Protocol.Alpha_context.Tez.zero + +(* Test that: + - the EMA of the adaptive inflation vote reaches the threshold after the + expected duration, + - the launch cycle is set as soon as the threshold is reached, + - the launch cycle is not reset before it is reached, + - once the launch cycle is reached, costaking is allowed. *) let test_launch threshold expected_vote_duration () = let open Lwt_result_syntax in let assert_ema_above_threshold ~loc @@ -66,7 +114,8 @@ let test_launch threshold expected_vote_duration () = in Assert.lt_int32 ~loc threshold ema in - let* block, _contract = + (* Initialize the state with a single delegate. *) + let* block, delegate = let default_constants = Default_parameters.constants_test in let adaptive_inflation = { @@ -78,7 +127,66 @@ let test_launch threshold expected_vote_duration () = Context.init_with_constants1 {default_constants with consensus_threshold; adaptive_inflation} in + let delegate_pkh = Context.Contract.pkh delegate in + let* () = assert_is_not_yet_set_to_launch ~loc:__LOC__ block in + + (* To test that adaptive inflation is active, we test that + costaking, a feature only available after the activation, is + allowed. But by default, delegates reject costakers, they must + explicitely set a positive staking_over_baking_limit to allow + them. Setting this limit does not immediately take effect but can + be done before the activation. For these reasons, we set it at + the beginning. *) + let* block = + let* operation = + set_delegate_parameters + (B block) + delegate + ~staking_over_baking_limit:1 + ~baking_over_staking_edge:0 + in + Block.bake ~operation ~adaptive_inflation_vote:Toggle_vote_on block + in + + (* Initialization of a delegator account which will attempt to + costake. *) + let wannabe_costaker_account = Account.new_account () in + let wannabe_costaker = + Protocol.Alpha_context.Contract.Implicit + Account.(wannabe_costaker_account.pkh) + in + + (* To set up the wannabe costaker, we need three operations: a + transfer from the delegate to initialize its balance, a + revelation of its public key, and a delegation toward the + delegate. For simplicity we put these operations in different + blocks. *) + let* block = + let* operation = + Op.transaction + (B block) + delegate + wannabe_costaker + (Protocol.Alpha_context.Tez.of_mutez_exn 1_000_000_000L) + in + Block.bake ~operation ~adaptive_inflation_vote:Toggle_vote_on block + in + let* block = + let* operation = Op.revelation (B block) wannabe_costaker_account.pk in + Block.bake ~operation ~adaptive_inflation_vote:Toggle_vote_on block + in + let* block = + let* operation = + Op.delegation (B block) wannabe_costaker (Some delegate_pkh) + in + Block.bake ~operation ~adaptive_inflation_vote:Toggle_vote_on block + in + + (* We are now ready to activate the feature through by baking many + more blocks voting in favor of the activation until the EMA + threshold is reached. *) let* () = assert_is_not_yet_set_to_launch ~loc:__LOC__ block in + let* block = Block.bake_while_with_metadata ~adaptive_inflation_vote:Toggle_vote_on @@ -91,16 +199,58 @@ let test_launch threshold expected_vote_duration () = Compare.Int32.(ema < threshold)) block in + (* At this point we are on the last block before the end of the vote. *) let* () = assert_level ~loc:__LOC__ block (Int32.pred expected_vote_duration) in let* () = assert_is_not_yet_set_to_launch ~loc:__LOC__ block in + (* We bake one more block to end the vote and set the feature to launch. *) let* block, metadata = Block.bake_n_with_metadata ~adaptive_inflation_vote:Toggle_vote_on 1 block in let* () = assert_ema_above_threshold ~loc:__LOC__ metadata in let* () = assert_level ~loc:__LOC__ block expected_vote_duration in - let* _launch_cycle = get_launch_cycle ~loc:__LOC__ block in + (* At this point the feature is not launched yet, it is simply + planned to be launched. *) + (* We check that the feature is not yet active by attempting a + costake operation. *) + let* () = + let* operation = + stake + (B block) + wannabe_costaker + (Protocol.Alpha_context.Tez.of_mutez_exn 10L) + in + let* i = Incremental.begin_construction block in + let*! i = Incremental.add_operation i operation in + Assert.proto_error_with_info + ~loc:__LOC__ + i + "Staking for a non-delegate while co-staking is disabled" + in + + let* launch_cycle = get_launch_cycle ~loc:__LOC__ block in + (* Bake until the activation. *) + let* block = Block.bake_until_cycle launch_cycle block in + let* block, metadata = Block.bake_n_with_metadata 1 block in + let* () = assert_ema_above_threshold ~loc:__LOC__ metadata in + (* Check that keeping the EMA above the threshold did not postpone + the activation. *) + let* launch_cycle_bis = get_launch_cycle ~loc:__LOC__ block in + let* () = assert_cycle_eq ~loc:__LOC__ launch_cycle launch_cycle_bis in + (* Check that the current cycle is the one at which the launch is + planned to happen. *) + let* () = assert_current_cycle ~loc:__LOC__ block launch_cycle in + + (* Test that the wannabe costaker is now allowed to stake a few + mutez. *) + let* operation = + stake + (B block) + wannabe_costaker + (Protocol.Alpha_context.Tez.of_mutez_exn 10L) + in + let* (_block : Block.t) = Block.bake ~operation block in return_unit let tests =