diff --git a/src/proto_alpha/lib_protocol/delegate_storage.ml b/src/proto_alpha/lib_protocol/delegate_storage.ml index b2ee0bfdc66e820dd87d20e0232a5b71ebc5e400..04ee724eba8d941c73970d9882645579780422f4 100644 --- a/src/proto_alpha/lib_protocol/delegate_storage.ml +++ b/src/proto_alpha/lib_protocol/delegate_storage.ml @@ -25,6 +25,25 @@ (* *) (*****************************************************************************) +(* + Some invariants: + + A contract is a delegate <=> + - it is registered (i.e. in the set {!Storage.Delegates.mem}), and + - its full staking balance is initialized. + + If a contract is a delegate then : + - it has no stake in another account, though it may (still) have unstake + requests from another contract. + + If a contract is not a delegate then: + - it has no *own* frozen stake (a.k.a. frozen deposits), + - it has no consensus key. + + Once a contract has become a delegate, it is so forever. There are no ways + to unregister. +*) + type error += | (* `Permanent *) Unregistered_delegate of Signature.Public_key_hash.t @@ -129,7 +148,11 @@ module Contract = struct in let* c = Contract_delegate_storage.set c contract delegate in let* c = - Stake_storage.add_delegated_stake c delegate balance_and_frozen_bonds + (* Initializes the full staking balance of [delegate]. *) + Stake_storage.initialize_delegate + c + delegate + ~delegated:balance_and_frozen_bonds in let*! c = Storage.Delegates.add c delegate in let* c = Delegate_consensus_key.init c delegate pk in diff --git a/src/proto_alpha/lib_protocol/full_staking_balance_repr.ml b/src/proto_alpha/lib_protocol/full_staking_balance_repr.ml index 745ed009b166b5c0be8595a5cfc64c8d8d752a10..1d0e825c5522470edd890c4860db08c6f903ee56 100644 --- a/src/proto_alpha/lib_protocol/full_staking_balance_repr.ml +++ b/src/proto_alpha/lib_protocol/full_staking_balance_repr.ml @@ -14,12 +14,6 @@ type t = { let make ~own_frozen ~staked_frozen ~delegated = {own_frozen; staked_frozen; delegated} -let zero = - make - ~own_frozen:Tez_repr.zero - ~staked_frozen:Tez_repr.zero - ~delegated:Tez_repr.zero - let encoding = let open Data_encoding in conv diff --git a/src/proto_alpha/lib_protocol/full_staking_balance_repr.mli b/src/proto_alpha/lib_protocol/full_staking_balance_repr.mli index 019ab5cf08ad568a40c4f6360455c6f37fe15cd7..0fde0fbfd3ec279e897f724cc6c32a0ff1eef609 100644 --- a/src/proto_alpha/lib_protocol/full_staking_balance_repr.mli +++ b/src/proto_alpha/lib_protocol/full_staking_balance_repr.mli @@ -14,8 +14,6 @@ type t = private { val make : own_frozen:Tez_repr.t -> staked_frozen:Tez_repr.t -> delegated:Tez_repr.t -> t -val zero : t - val encoding : t Data_encoding.t (** The weight of a delegate used for voting rights. *) diff --git a/src/proto_alpha/lib_protocol/stake_storage.ml b/src/proto_alpha/lib_protocol/stake_storage.ml index 1cbe43ee1bc47020a9353548d694f27c74a76e26..bd3255e5c265f3d0b6ad131cc17714042da608ea 100644 --- a/src/proto_alpha/lib_protocol/stake_storage.ml +++ b/src/proto_alpha/lib_protocol/stake_storage.ml @@ -73,20 +73,7 @@ module Selected_distribution_for_cycle = struct Storage.Stake.Selected_distribution_for_cycle.remove_existing ctxt cycle end -let get_full_staking_balance ctxt delegate = - let open Lwt_result_syntax in - let+ staking_balance_opt = Storage.Stake.Staking_balance.find ctxt delegate in - Option.value staking_balance_opt ~default:Full_staking_balance_repr.zero - -let get_initialized_stake ctxt delegate = - let open Lwt_result_syntax in - let* balance_opt = Storage.Stake.Staking_balance.find ctxt delegate in - match balance_opt with - | Some staking_balance -> return (staking_balance, ctxt) - | None -> - let balance = Full_staking_balance_repr.zero in - let* ctxt = Storage.Stake.Staking_balance.init ctxt delegate balance in - return (balance, ctxt) +let get_full_staking_balance = Storage.Stake.Staking_balance.get let has_minimal_stake ctxt {Full_staking_balance_repr.own_frozen; staked_frozen; delegated} = @@ -108,9 +95,25 @@ let has_minimal_stake_and_frozen_stake ctxt Tez_repr.(own_frozen >= minimal_frozen_stake) && has_minimal_stake ctxt full_staking_balance +let initialize_delegate ctxt delegate ~delegated = + let open Lwt_result_syntax in + let balance = + Full_staking_balance_repr.make + ~own_frozen:Tez_repr.zero + ~staked_frozen:Tez_repr.zero + ~delegated + in + let* ctxt = Storage.Stake.Staking_balance.init ctxt delegate balance in + if has_minimal_stake ctxt balance then + let*! ctxt = + Storage.Stake.Active_delegates_with_minimal_stake.add ctxt delegate () + in + return ctxt + else return ctxt + let update_stake ~f ctxt delegate = let open Lwt_result_syntax in - let* staking_balance_before, ctxt = get_initialized_stake ctxt delegate in + let* staking_balance_before = get_full_staking_balance ctxt delegate in let*? staking_balance = f staking_balance_before in let* ctxt = Storage.Stake.Staking_balance.update ctxt delegate staking_balance @@ -209,7 +212,7 @@ let set_active ctxt delegate = let* ctxt, inactive = Delegate_activation_storage.set_active ctxt delegate in if not inactive then return ctxt else - let* staking_balance, ctxt = get_initialized_stake ctxt delegate in + let* staking_balance = get_full_staking_balance ctxt delegate in if has_minimal_stake ctxt staking_balance then let*! ctxt = Storage.Stake.Active_delegates_with_minimal_stake.add ctxt delegate () diff --git a/src/proto_alpha/lib_protocol/stake_storage.mli b/src/proto_alpha/lib_protocol/stake_storage.mli index 413ebf3582f2f9dd8d26a37e1b353b87c1d4a451..440aa77b7761be6533bd4fde831a56182f24971d 100644 --- a/src/proto_alpha/lib_protocol/stake_storage.mli +++ b/src/proto_alpha/lib_protocol/stake_storage.mli @@ -34,6 +34,12 @@ - {!Storage.Stake.Total_active_stake} *) +val initialize_delegate : + Raw_context.t -> + Signature.public_key_hash -> + delegated:Tez_repr.t -> + Raw_context.t tzresult Lwt.t + val get_full_staking_balance : Raw_context.t -> Signature.public_key_hash ->