From 31f2f07d3aa41fff967ecb4555bb82f6814cf663 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Mon, 27 May 2024 16:45:09 +0200 Subject: [PATCH 1/4] Proto/AI/tests: update test --- .../lib_protocol/test/helpers/scenario_op.ml | 1 + .../test/integration/test_scenario_stake.ml | 69 ++++++++++++++++--- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/helpers/scenario_op.ml b/src/proto_alpha/lib_protocol/test/helpers/scenario_op.ml index 9f3701c77faa..d12946b258bc 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/scenario_op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/scenario_op.ml @@ -170,6 +170,7 @@ let set_delegate src_name delegate_name_opt : (t, t) scenarios = let state = (* if self delegating *) if Option.equal String.equal delegate_name_opt (Some src_name) then + let src = State.find_account src_name state in State.update_map ~f:(fun acc_map -> String.Map.add diff --git a/src/proto_alpha/lib_protocol/test/integration/test_scenario_stake.ml b/src/proto_alpha/lib_protocol/test/integration/test_scenario_stake.ml index 2890eb9a4393..f774be782ae7 100644 --- a/src/proto_alpha/lib_protocol/test/integration/test_scenario_stake.ml +++ b/src/proto_alpha/lib_protocol/test/integration/test_scenario_stake.ml @@ -301,6 +301,51 @@ let odd_behavior = in loop 20 one_cycle +(* Test changing delegate to self delegation while having staked funds. *) +let change_delegate_to_self = + let init_params = + {limit_of_staking_over_baking = Q.one; edge_of_baking_over_staking = Q.one} + in + init_constants () + --> set S.Adaptive_issuance.autostaking_enable false + --> activate_ai `Force --> begin_test ["delegate"] + --> set_delegate_params "delegate" init_params + --> add_account_with_funds + "staker" + ~funder:"delegate" + (Amount (Tez.of_mutez 2_000_000_000_000L)) + --> set_delegate "staker" (Some "delegate") + --> wait_delegate_parameters_activation --> stake "staker" Half --> next_cycle + --> set_delegate "staker" (Some "staker") + (* Can't stake: "A contract tries to stake to its delegate while + having unstake requests to a previous delegate that cannot be + finalized yet. Try again in a later cycle (no more than + consensus_rights_delay + max_slashing_period)." *) + --> assert_failure (stake "staker" Half) + --> unstake "staker" Max_tez + --> wait_n_cycles_f (unstake_wait -- 1) (* Still can't stake. *) + --> check_balance_field "staker" `Unstaked_finalizable Tez.zero + --> assert_failure (stake "staker" Half) + --> next_cycle + (* The unstake request from changing delegates is now finalizable. *) + --> assert_failure + (check_balance_field "staker" `Unstaked_finalizable Tez.zero) + --> assert_success + (* Can directly stake again, which automatically finalizes, + even though the finalizable unstaked request is about a + previous delegate. *) + (stake "staker" Half + --> check_balance_field "staker" `Unstaked_finalizable Tez.zero) + --> (Tag "finalize" + --> (* Explicitly finalize, so that we can check that the balances + are identical to the beginning. This proves that changing + delegates has indeed unstaked all staked funds. *) + finalize "staker" + --> check_snapshot_balances "init" + --> check_balance_field "staker" `Unstaked_finalizable Tez.zero + |+ Tag "don't finalize" --> Empty) + --> stake "staker" Half --> unstake "staker" Half --> stake "staker" Half + (* Test changing delegates while having staked funds. *) let change_delegate = let init_params = @@ -327,6 +372,7 @@ let change_delegate = finalized yet. Try again in a later cycle (no more than consensus_rights_delay + max_slashing_period)." *) --> assert_failure (stake "staker" Half) + --> unstake "staker" Max_tez --> wait_n_cycles_f (unstake_wait -- 1) (* Still can't stake. *) --> check_balance_field "staker" `Unstaked_finalizable Tez.zero --> assert_failure (stake "staker" Half) @@ -340,14 +386,20 @@ let change_delegate = previous delegate. *) (stake "staker" Half --> check_balance_field "staker" `Unstaked_finalizable Tez.zero) - --> (* Explicitly finalize, so that we can check that the balances - are identical to the beginning. This proves that changing - delegates has indeed unstaked all staked funds. *) - finalize "staker" - --> check_snapshot_balances "init" - --> check_balance_field "staker" `Unstaked_finalizable Tez.zero - --> (* Staking again is also possible. *) stake "staker" Half - --> check_snapshot_balances "after_stake" + --> (Tag "finalize" + --> (* Explicitly finalize, so that we can check that the balances + are identical to the beginning. This proves that changing + delegates has indeed unstaked all staked funds. *) + finalize "staker" + --> check_snapshot_balances "init" + --> check_balance_field "staker" `Unstaked_finalizable Tez.zero + --> (* Staking again is also possible. *) stake "staker" Half + --> check_snapshot_balances "after_stake" + |+ Tag "don't finalize" --> stake "staker" Half) + --> (Tag "finally, unstake" --> unstake "staker" Half + |+ Tag "finally, change delegate one last time" + --> set_delegate "staker" (Some "delegate1") + |+ Tag "finally, unset delegate" --> set_delegate "staker" None) let unset_delegate = let init_params = @@ -534,6 +586,7 @@ let tests = ("Test full balance in finalizable", full_balance_in_finalizable); ("Test stake unstake every cycle", odd_behavior); ("Test change delegate", change_delegate); + ("Test change delegate to self", change_delegate_to_self); ("Test unset delegate", unset_delegate); ("Test forbid costake", forbid_costaking); ("Test stake from unstake", shorter_roundtrip_for_baker); -- GitLab From 4837097dc5f69ad0fb89ba87a25e28d5d8b81913 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Mon, 27 May 2024 16:45:34 +0200 Subject: [PATCH 2/4] Proto/AI: fix UX --- src/proto_alpha/lib_protocol/staking.ml | 7 ++-- .../lib_protocol/unstake_requests_storage.ml | 41 ++++++++++++++++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/proto_alpha/lib_protocol/staking.ml b/src/proto_alpha/lib_protocol/staking.ml index 6b7fce09b3e4..53b30cb6b8fb 100644 --- a/src/proto_alpha/lib_protocol/staking.ml +++ b/src/proto_alpha/lib_protocol/staking.ml @@ -195,9 +195,10 @@ let stake_from_unstake_for_delegate ctxt ~for_next_cycle_use_only_after_slashing match unfinalizable_requests_opt with | None -> return (ctxt, [], amount) | Some Unstake_requests_storage.{delegate = delegate_requests; requests} -> - if Signature.Public_key_hash.(delegate <> delegate_requests) then - (* Possible. If reached, stake should not do anything, - so we also set the amount to stake from the liquid part to zero. *) + if + Signature.Public_key_hash.(delegate <> delegate_requests) + && not (List.is_empty requests) + then (* Should not be possible *) return (ctxt, [], Tez_repr.zero) else let* allowed = diff --git a/src/proto_alpha/lib_protocol/unstake_requests_storage.ml b/src/proto_alpha/lib_protocol/unstake_requests_storage.ml index d6ca6d6deb5b..046954b03d02 100644 --- a/src/proto_alpha/lib_protocol/unstake_requests_storage.ml +++ b/src/proto_alpha/lib_protocol/unstake_requests_storage.ml @@ -23,6 +23,27 @@ (* *) (*****************************************************************************) +type error += + | Cannot_unstake_with_unfinalizable_unstake_requests_to_another_delegate + +let () = + register_error_kind + `Permanent + ~id: + "operation.cannot_unstake_with_unfinalizable_unstake_requests_to_another_delegate" + ~title: + "Cannot unstake with unfinalizable unstake requests to another delegate" + ~description: + "Cannot unstake with unfinalizable unstake requests to another delegate" + Data_encoding.unit + (function + | Cannot_unstake_with_unfinalizable_unstake_requests_to_another_delegate + -> + Some () + | _ -> None) + (fun () -> + Cannot_unstake_with_unfinalizable_unstake_requests_to_another_delegate) + type finalizable = (Signature.Public_key_hash.t * Cycle_repr.t * Tez_repr.t) list @@ -165,12 +186,22 @@ let update = Storage.Contract.Unstake_requests.update let add ctxt ~contract ~delegate cycle amount = let open Lwt_result_syntax in let* requests_opt = Storage.Contract.Unstake_requests.find ctxt contract in - let requests = + let*? requests = match requests_opt with - | None -> [] - | Some {delegate = request_delegate; requests} -> - assert (Signature.Public_key_hash.(delegate = request_delegate)) ; - requests + | None -> Ok [] + | Some {delegate = request_delegate; requests} -> ( + match requests with + | [] -> Ok [] + | _ -> + if Signature.Public_key_hash.(delegate <> request_delegate) then + (* This would happen if the staker was allowed to stake towards + a new delegate while having unfinalizable unstake requests, + which is not allowed: it will fail earlier. Also, unstaking + for 0 tez is a noop and does not change the state of the storage, + so it does not allow to reach this error either. *) + Result_syntax.tzfail + Cannot_unstake_with_unfinalizable_unstake_requests_to_another_delegate + else Ok requests) in let*? requests = Storage.Unstake_request.add cycle amount requests in let unstake_request = Storage.Unstake_request.{delegate; requests} in -- GitLab From efcfd46b99a39e699315fffccde3429adc4f7efb Mon Sep 17 00:00:00 2001 From: Killian Delarue Date: Tue, 28 May 2024 11:17:39 +0200 Subject: [PATCH 3/4] Tezt: Add memory-3k to some tests --- tezt/tests/dal.ml | 2 +- tezt/tests/sc_rollup.ml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 48d76711efbd..e35378fef577 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -333,7 +333,7 @@ let with_dal_node ?peers ?attester_profiles ?producer_profiles (* Wrapper scenario functions that should be re-used as much as possible when writing tests. *) -let scenario_with_layer1_node ?regression ?(tags = [team]) +let scenario_with_layer1_node ?regression ?(tags = [team; Tag.memory_3k]) ?additional_bootstrap_accounts ?attestation_lag ?number_of_shards ?number_of_slots ?custom_constants ?commitment_period ?challenge_window ?(dal_enable = true) ?event_sections_levels ?node_arguments diff --git a/tezt/tests/sc_rollup.ml b/tezt/tests/sc_rollup.ml index db67df09aca4..53def98c5c20 100644 --- a/tezt/tests/sc_rollup.ml +++ b/tezt/tests/sc_rollup.ml @@ -1514,7 +1514,7 @@ let test_commitment_scenario ?supports ?commitment_period ?challenge_window ?commitment_period ?challenge_window { - tags = ["commitment"] @ extra_tags; + tags = ["commitment"; Tag.memory_3k] @ extra_tags; variant = Some variant; description = "rollup node - correct handling of commitments"; } -- GitLab From 2f372a39256dbfe4f22fc8447f1afac1d0665f69 Mon Sep 17 00:00:00 2001 From: Killian Delarue Date: Tue, 28 May 2024 13:11:09 +0200 Subject: [PATCH 4/4] Ci: More parallel tezt-memory-3k jobs --- .gitlab/ci/pipelines/before_merging.yml | 2 +- .gitlab/ci/pipelines/schedule_extended_test.yml | 2 +- ci/bin/code_verification.ml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab/ci/pipelines/before_merging.yml b/.gitlab/ci/pipelines/before_merging.yml index 4abd183d61d7..b53f86825953 100644 --- a/.gitlab/ci/pipelines/before_merging.yml +++ b/.gitlab/ci/pipelines/before_merging.yml @@ -7798,7 +7798,7 @@ tezt-memory-3k: junit: $JUNIT when: always retry: 2 - parallel: 4 + parallel: 6 tezt-memory-4k: image: ${build_deps_image_name}:runtime-e2etest-dependencies--${build_deps_image_version} diff --git a/.gitlab/ci/pipelines/schedule_extended_test.yml b/.gitlab/ci/pipelines/schedule_extended_test.yml index fbe4072c9851..3fafff3bbee9 100644 --- a/.gitlab/ci/pipelines/schedule_extended_test.yml +++ b/.gitlab/ci/pipelines/schedule_extended_test.yml @@ -7454,7 +7454,7 @@ tezt-memory-3k: junit: $JUNIT when: always retry: 2 - parallel: 4 + parallel: 6 tezt-memory-4k: image: ${build_deps_image_name}:runtime-e2etest-dependencies--${build_deps_image_version} diff --git a/ci/bin/code_verification.ml b/ci/bin/code_verification.ml index 6d018af40e28..27e308d95d59 100644 --- a/ci/bin/code_verification.ml +++ b/ci/bin/code_verification.ml @@ -1338,7 +1338,7 @@ let jobs pipeline_type = ~name:"tezt-memory-3k" ~tezt_tests:(tezt_tests ~memory_3k:true []) ~tezt_variant:"-memory_3k" - ~parallel:(Vector 4) + ~parallel:(Vector 6) ~dependencies ~rules () -- GitLab