From d34ca12240413cdc0e20e4bb4be93418058e56ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Wed, 21 Nov 2018 23:49:49 +0100 Subject: [PATCH] Alpha: maintain a set of active delegates with rolls --- .../lib_protocol/src/alpha_context.mli | 2 +- .../lib_protocol/src/delegate_services.ml | 22 ++++--- .../lib_protocol/src/delegate_storage.ml | 32 +++++----- .../lib_protocol/src/delegate_storage.mli | 2 +- .../lib_protocol/src/roll_storage.ml | 58 ++++++++++++++++--- .../lib_protocol/src/roll_storage.mli | 3 + src/proto_alpha/lib_protocol/src/storage.ml | 5 ++ src/proto_alpha/lib_protocol/src/storage.mli | 5 ++ 8 files changed, 97 insertions(+), 32 deletions(-) diff --git a/src/proto_alpha/lib_protocol/src/alpha_context.mli b/src/proto_alpha/lib_protocol/src/alpha_context.mli index 051d717b9..4544148b2 100644 --- a/src/proto_alpha/lib_protocol/src/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/src/alpha_context.mli @@ -719,7 +719,7 @@ module Delegate : sig val deactivated: context -> Signature.Public_key_hash.t -> - bool Lwt.t + bool tzresult Lwt.t val grace_period: context -> Signature.Public_key_hash.t -> diff --git a/src/proto_alpha/lib_protocol/src/delegate_services.ml b/src/proto_alpha/lib_protocol/src/delegate_services.ml index 6f31c9f89..1f01c3cef 100644 --- a/src/proto_alpha/lib_protocol/src/delegate_services.ml +++ b/src/proto_alpha/lib_protocol/src/delegate_services.ml @@ -183,13 +183,19 @@ let register () = if q.active && q.inactive then return delegates else if q.active then - Lwt_list.filter_p - (fun pkh -> Delegate.deactivated ctxt pkh >|= not) - delegates >>= return + filter_map_s + (fun pkh -> + Delegate.deactivated ctxt pkh >>=? function + | true -> return_none + | false -> return_some pkh) + delegates else if q.inactive then - Lwt_list.filter_p - (fun pkh -> Delegate.deactivated ctxt pkh) - delegates >>= return + filter_map_s + (fun pkh -> + Delegate.deactivated ctxt pkh >>=? function + | false -> return_none + | true -> return_some pkh) + delegates else return_nil end ; @@ -200,7 +206,7 @@ let register () = Delegate.staking_balance ctxt pkh >>=? fun staking_balance -> Delegate.delegated_contracts ctxt pkh >>= fun delegated_contracts -> Delegate.delegated_balance ctxt pkh >>=? fun delegated_balance -> - Delegate.deactivated ctxt pkh >>= fun deactivated -> + Delegate.deactivated ctxt pkh >>=? fun deactivated -> Delegate.grace_period ctxt pkh >>=? fun grace_period -> return { balance ; frozen_balance ; frozen_balance_by_cycle ; @@ -227,7 +233,7 @@ let register () = Delegate.delegated_balance ctxt pkh end ; register1 S.deactivated begin fun ctxt pkh () () -> - Delegate.deactivated ctxt pkh >>= return + Delegate.deactivated ctxt pkh end ; register1 S.grace_period begin fun ctxt pkh () () -> Delegate.grace_period ctxt pkh diff --git a/src/proto_alpha/lib_protocol/src/delegate_storage.ml b/src/proto_alpha/lib_protocol/src/delegate_storage.ml index 231746c71..fe2b1fc75 100644 --- a/src/proto_alpha/lib_protocol/src/delegate_storage.ml +++ b/src/proto_alpha/lib_protocol/src/delegate_storage.ml @@ -301,7 +301,7 @@ let set_base c is_delegatable contract delegate = | Some current_delegate when Signature.Public_key_hash.equal delegate current_delegate -> if self_delegation then - Storage.Contract.Inactive_delegate.mem c contract >>= function + Roll_storage.Delegate.is_inactive c delegate >>=? function | true -> return_unit | false -> fail Active_delegate else @@ -336,9 +336,6 @@ let remove ctxt contract = Storage.Contract.Balance.get ctxt contract >>=? fun balance -> unlink ctxt contract balance -let fold = Storage.Delegates.fold -let list = Storage.Delegates.elements - let delegated_contracts ctxt delegate = let contract = Contract_repr.implicit_contract delegate in Storage.Contract.Delegated.elements (ctxt, contract) @@ -470,18 +467,25 @@ let cycle_end ctxt last_cycle unrevealed = match Cycle_repr.sub last_cycle preserved with | None -> return (ctxt, balance_updates, []) | Some unfrozen_cycle -> - fold ctxt - ~init:(Ok (ctxt, balance_updates, [])) + Storage.Delegates.fold ctxt + ~init:(Ok (ctxt, balance_updates)) ~f:(fun delegate acc -> - Lwt.return acc >>=? fun (ctxt, bus, deactivated) -> - unfreeze ctxt delegate unfrozen_cycle >>=? fun (ctxt, balance_updates) -> + Lwt.return acc >>=? fun (ctxt, bus) -> + unfreeze ctxt + delegate unfrozen_cycle >>=? fun (ctxt, balance_updates) -> + return (ctxt, balance_updates @ bus)) >>=? fun (ctxt, balance_updates) -> + Storage.Active_delegates_with_rolls.fold ctxt + ~init:(Ok (ctxt, [])) + ~f:(fun delegate acc -> + Lwt.return acc >>=? fun (ctxt, deactivated) -> 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 >>=? fun ctxt -> - return (ctxt, balance_updates @ bus, delegate::deactivated) + return (ctxt, delegate :: deactivated) else - return (ctxt, balance_updates @ bus, deactivated)) + return (ctxt, deactivated)) >>=? fun (ctxt, deactivated) -> + return (ctxt, balance_updates, deactivated) let punish ctxt delegate cycle = let contract = Contract_repr.implicit_contract delegate in @@ -581,9 +585,7 @@ let full_balance ctxt delegate = Storage.Contract.Balance.get ctxt contract >>=? fun balance -> Lwt.return Tez_repr.(frozen_balance +? balance) -let deactivated ctxt delegate = - let contract = Contract_repr.implicit_contract delegate in - Storage.Contract.Inactive_delegate.mem ctxt contract +let deactivated = Roll_storage.Delegate.is_inactive let grace_period ctxt delegate = let contract = Contract_repr.implicit_contract delegate in @@ -612,3 +614,7 @@ let delegated_balance ctxt delegate = Lwt.return acc >>=? fun acc -> Lwt.return (Tez_repr.(acc +? amount))) >>=? fun self_staking_balance -> Lwt.return Tez_repr.(staking_balance -? self_staking_balance) + +let fold = Storage.Delegates.fold +let list = Storage.Delegates.elements + diff --git a/src/proto_alpha/lib_protocol/src/delegate_storage.mli b/src/proto_alpha/lib_protocol/src/delegate_storage.mli index 365090e89..6f458403b 100644 --- a/src/proto_alpha/lib_protocol/src/delegate_storage.mli +++ b/src/proto_alpha/lib_protocol/src/delegate_storage.mli @@ -180,7 +180,7 @@ val delegated_balance: val deactivated: Raw_context.t -> Signature.Public_key_hash.t -> - bool Lwt.t + bool tzresult Lwt.t val grace_period: Raw_context.t -> Signature.Public_key_hash.t -> diff --git a/src/proto_alpha/lib_protocol/src/roll_storage.ml b/src/proto_alpha/lib_protocol/src/roll_storage.ml index 4e3d788b3..0f1075f16 100644 --- a/src/proto_alpha/lib_protocol/src/roll_storage.ml +++ b/src/proto_alpha/lib_protocol/src/roll_storage.ml @@ -283,6 +283,22 @@ module Delegate = struct | false -> Storage.Roll.Delegate_change.init c delegate Tez_repr.zero + let is_inactive c delegate = + Storage.Contract.Inactive_delegate.mem c + (Contract_repr.implicit_contract delegate) >>= fun inactive -> + if inactive then + return inactive + else + Storage.Contract.Delegate_desactivation.get_option c + (Contract_repr.implicit_contract delegate) >>=? function + | Some last_active_cycle -> + let { Level_repr.cycle = current_cycle } = Raw_context.current_level c in + return Cycle_repr.(last_active_cycle < current_cycle) + | None -> + (* This case is only when called from `set_active`, when creating + a contract. *) + return false + let add_amount c delegate amount = ensure_inited c delegate >>=? fun c -> let tokens_per_roll = Constants_storage.tokens_per_roll c in @@ -297,9 +313,18 @@ module Delegate = struct Lwt.return Tez_repr.(change -? tokens_per_roll) >>=? fun change -> create_roll_in_delegate c delegate delegate_pk >>=? fun c -> loop c change in - Storage.Contract.Inactive_delegate.mem c - (Contract_repr.implicit_contract delegate) >>= fun inactive -> - if inactive then return c else loop c change + is_inactive c delegate >>=? fun inactive -> + if inactive then + return c + else + loop c change >>=? fun c -> + Storage.Roll.Delegate_roll_list.get_option c delegate >>=? fun rolls -> + match rolls with + | None -> + return c + | Some _ -> + Storage.Active_delegates_with_rolls.add c delegate >>= fun c -> + return c let remove_amount c delegate amount = let tokens_per_roll = Constants_storage.tokens_per_roll c in @@ -311,10 +336,19 @@ module Delegate = struct Lwt.return Tez_repr.(change +? tokens_per_roll) >>=? fun change -> loop c change in Storage.Roll.Delegate_change.get c delegate >>=? fun change -> - Storage.Contract.Inactive_delegate.mem c - (Contract_repr.implicit_contract delegate) >>= fun inactive -> + is_inactive c delegate >>=? fun inactive -> begin - if inactive then return (c, change) else loop c change + if inactive then + return (c, change) + else + loop c change >>=? fun (c, change) -> + Storage.Roll.Delegate_roll_list.get_option c delegate >>=? fun rolls -> + match rolls with + | None -> + Storage.Active_delegates_with_rolls.del c delegate >>= fun c -> + return (c, change) + | Some _ -> + return (c, change) end >>=? fun (c, change) -> Lwt.return Tez_repr.(change -? amount) >>=? fun change -> Storage.Roll.Delegate_change.set c delegate change @@ -325,6 +359,7 @@ module Delegate = struct Storage.Roll.Delegate_change.get ctxt delegate >>=? fun change -> Storage.Contract.Inactive_delegate.add ctxt (Contract_repr.implicit_contract delegate) >>= fun ctxt -> + Storage.Active_delegates_with_rolls.del ctxt delegate >>= fun ctxt -> let rec loop ctxt change = Storage.Roll.Delegate_roll_list.get_option ctxt delegate >>=? function | None -> return (ctxt, change) @@ -337,8 +372,7 @@ module Delegate = struct return ctxt let set_active ctxt delegate = - Storage.Contract.Inactive_delegate.mem ctxt - (Contract_repr.implicit_contract delegate) >>= fun inactive -> + is_inactive ctxt 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 @@ -377,7 +411,13 @@ module Delegate = struct create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt -> loop ctxt change in loop ctxt change >>=? fun ctxt -> - return ctxt + Storage.Roll.Delegate_roll_list.get_option ctxt delegate >>=? fun rolls -> + match rolls with + | None -> + return ctxt + | Some _ -> + Storage.Active_delegates_with_rolls.add ctxt delegate >>= fun ctxt -> + return ctxt end end diff --git a/src/proto_alpha/lib_protocol/src/roll_storage.mli b/src/proto_alpha/lib_protocol/src/roll_storage.mli index e652c5e8e..b2c066f77 100644 --- a/src/proto_alpha/lib_protocol/src/roll_storage.mli +++ b/src/proto_alpha/lib_protocol/src/roll_storage.mli @@ -61,6 +61,9 @@ val endorsement_rights_owner : module Delegate : sig + val is_inactive : + Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t + val add_amount : Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/src/storage.ml b/src/proto_alpha/lib_protocol/src/storage.ml index 0eb14cc7c..05439b9f8 100644 --- a/src/proto_alpha/lib_protocol/src/storage.ml +++ b/src/proto_alpha/lib_protocol/src/storage.ml @@ -306,6 +306,11 @@ module Delegates = (Make_subcontext(Raw_context)(struct let name = ["delegates"] end)) (Make_index(Signature.Public_key_hash)) +module Active_delegates_with_rolls = + Make_data_set_storage + (Make_subcontext(Raw_context)(struct let name = ["active_delegates_with_rolls"] end)) + (Make_index(Signature.Public_key_hash)) + (** Rolls *) module Cycle = struct diff --git a/src/proto_alpha/lib_protocol/src/storage.mli b/src/proto_alpha/lib_protocol/src/storage.mli index 74f07d300..622e9e119 100644 --- a/src/proto_alpha/lib_protocol/src/storage.mli +++ b/src/proto_alpha/lib_protocol/src/storage.mli @@ -220,6 +220,11 @@ module Delegates : Data_set_storage with type t := Raw_context.t and type elt = Signature.Public_key_hash.t +(** Set of all active delegates with rolls. *) +module Active_delegates_with_rolls : Data_set_storage + with type t := Raw_context.t + and type elt = Signature.Public_key_hash.t + (** Votes *) module Vote : sig