diff --git a/src/proto_alpha/lib_protocol/src/contract_storage.ml b/src/proto_alpha/lib_protocol/src/contract_storage.ml index 63f39fc76..333b240fa 100644 --- a/src/proto_alpha/lib_protocol/src/contract_storage.ml +++ b/src/proto_alpha/lib_protocol/src/contract_storage.ml @@ -353,7 +353,20 @@ let credit c contract amount = | Some balance -> Lwt.return Tez_repr.(amount +? balance) >>=? fun balance -> Storage.Contract.Balance.set c contract balance >>=? fun c -> - Roll_storage.Contract.add_amount c contract amount + Roll_storage.Contract.add_amount c contract amount >>=? fun c -> + begin + match contract with + | Implicit delegate -> + Delegate_storage.registered c delegate >>= fun registered -> + if registered then + Roll_storage.Delegate.set_active c delegate >>=? fun c -> + return c + else + return c + | Originated _ -> + return c + end >>=? fun c -> + return c let spend c contract amount = is_spendable c contract >>=? fun spendable -> diff --git a/src/proto_alpha/lib_protocol/src/delegate_storage.ml b/src/proto_alpha/lib_protocol/src/delegate_storage.ml index 8014e85da..4d8ae62b1 100644 --- a/src/proto_alpha/lib_protocol/src/delegate_storage.ml +++ b/src/proto_alpha/lib_protocol/src/delegate_storage.ml @@ -150,10 +150,12 @@ let set c contract delegate = link c contract delegate balance >>=? fun c -> begin if self_delegation then - Storage.Delegates.add c delegate + Storage.Delegates.add c delegate >>= fun c -> + Roll_storage.Delegate.set_active c ~init:true delegate >>=? fun c -> + return c else - Lwt.return c - end >>= fun c -> + return c + end >>=? fun c -> return c let remove ctxt contract = @@ -178,6 +180,7 @@ let credit_frozen_bond ctxt contract cycle amount = let freeze_bond ctxt delegate amount = let { Level_repr.cycle ; _ } = Level_storage.current ctxt in + Roll_storage.Delegate.set_active ctxt delegate >>=? fun ctxt -> let contract = Contract_repr.implicit_contract delegate in Storage.Contract.Balance.get ctxt contract >>=? fun balance -> Lwt.return Tez_repr.(balance -? amount) >>=? fun new_balance -> @@ -285,8 +288,13 @@ let cycle_end ctxt last_cycle unrevealed = ~init:(Ok ctxt) ~f:(fun delegate ctxt -> Lwt.return ctxt >>=? fun ctxt -> - unfreeze ctxt delegate unfrozen_cycle) - + unfreeze ctxt delegate unfrozen_cycle >>=? fun ctxt -> + Storage.Contract.Delegate_desactivation.get ctxt + (Contract_repr.implicit_contract delegate) >>=? fun cycle -> + if Cycle_repr.(cycle <= last_cycle) then + Roll_storage.Delegate.set_inactive ctxt delegate + else + return ctxt) let punish ctxt delegate cycle = let contract = Contract_repr.implicit_contract delegate in diff --git a/src/proto_alpha/lib_protocol/src/delegate_storage.mli b/src/proto_alpha/lib_protocol/src/delegate_storage.mli index 65971796f..8cb46955c 100644 --- a/src/proto_alpha/lib_protocol/src/delegate_storage.mli +++ b/src/proto_alpha/lib_protocol/src/delegate_storage.mli @@ -25,6 +25,8 @@ val get: Raw_context.t -> Contract_repr.t -> Ed25519.Public_key_hash.t option tzresult Lwt.t +val registered: Raw_context.t -> Ed25519.Public_key_hash.t -> bool Lwt.t + (** Updating the delegate of a contract. When calling this function on an "implicit contract" this function diff --git a/src/proto_alpha/lib_protocol/src/roll_storage.ml b/src/proto_alpha/lib_protocol/src/roll_storage.ml index 9fbb416c1..f74863e47 100644 --- a/src/proto_alpha/lib_protocol/src/roll_storage.ml +++ b/src/proto_alpha/lib_protocol/src/roll_storage.ml @@ -272,9 +272,21 @@ module Delegate = struct Storage.Roll.Delegate_change.set ctxt delegate change >>=? fun ctxt -> return ctxt - let set_active ctxt delegate = + let set_active ctxt ?(init = false) delegate = Storage.Contract.Inactive_delegate.mem ctxt (Contract_repr.implicit_contract delegate) >>= fun inactive -> + let current_cycle = (Raw_context.current_level ctxt).cycle in + let preserved_cycles = Constants_storage.preserved_cycles ctxt in + (* When the delegate is new or inactive, she will become active in + `1+preserved_cycles`, and we allows `preserved_cycles` for the + delegate to start baking. When the delegate is active, we only + give me at least `preserved_cycles` after the current cycle + before to be deactivated. *) + let delay = + if init || inactive then (1+2*preserved_cycles) else 1+preserved_cycles in + Storage.Contract.Delegate_desactivation.init_set ctxt + (Contract_repr.implicit_contract delegate) + Cycle_repr.(add current_cycle delay) >>= fun ctxt -> if not inactive then return ctxt else begin diff --git a/src/proto_alpha/lib_protocol/src/roll_storage.mli b/src/proto_alpha/lib_protocol/src/roll_storage.mli index 8c3d680c7..ee622bea5 100644 --- a/src/proto_alpha/lib_protocol/src/roll_storage.mli +++ b/src/proto_alpha/lib_protocol/src/roll_storage.mli @@ -52,7 +52,7 @@ module Delegate : sig val set_inactive : Raw_context.t -> Ed25519.Public_key_hash.t -> Raw_context.t tzresult Lwt.t - val set_active : Raw_context.t -> Ed25519.Public_key_hash.t -> Raw_context.t tzresult Lwt.t + val set_active : Raw_context.t -> ?init:bool -> Ed25519.Public_key_hash.t -> Raw_context.t tzresult Lwt.t end diff --git a/src/proto_alpha/lib_protocol/src/storage.ml b/src/proto_alpha/lib_protocol/src/storage.ml index 835856570..32fe33272 100644 --- a/src/proto_alpha/lib_protocol/src/storage.ml +++ b/src/proto_alpha/lib_protocol/src/storage.ml @@ -109,6 +109,11 @@ module Contract = struct Indexed_context.Make_set (struct let name = ["inactive_delegate"] end) + module Delegate_desactivation = + Indexed_context.Make_map + (struct let name = ["delegate_desactivation"] end) + (Make_value(Cycle_repr)) + module Delegated = Make_data_set_storage (Make_subcontext diff --git a/src/proto_alpha/lib_protocol/src/storage.mli b/src/proto_alpha/lib_protocol/src/storage.mli index 2f9222c15..4a826cdd0 100644 --- a/src/proto_alpha/lib_protocol/src/storage.mli +++ b/src/proto_alpha/lib_protocol/src/storage.mli @@ -137,6 +137,12 @@ module Contract : sig with type elt = Contract_repr.t and type t = Raw_context.t + (** The cycle where the delegate should be desactivated. *) + module Delegate_desactivation : Indexed_data_storage + with type key = Contract_repr.t + and type value = Cycle_repr.t + and type t := Raw_context.t + module Spendable : Data_set_storage with type elt = Contract_repr.t and type t := Raw_context.t