Alpha: maintain a set of active delegates with rolls

This commit is contained in:
Grégoire Henry 2018-11-21 23:49:49 +01:00 committed by Pierre Boutillier
parent aebe8319d5
commit d34ca12240
No known key found for this signature in database
GPG Key ID: C2F73508B56A193C
8 changed files with 97 additions and 32 deletions

View File

@ -719,7 +719,7 @@ module Delegate : sig
val deactivated: val deactivated:
context -> Signature.Public_key_hash.t -> context -> Signature.Public_key_hash.t ->
bool Lwt.t bool tzresult Lwt.t
val grace_period: val grace_period:
context -> Signature.Public_key_hash.t -> context -> Signature.Public_key_hash.t ->

View File

@ -183,13 +183,19 @@ let register () =
if q.active && q.inactive then if q.active && q.inactive then
return delegates return delegates
else if q.active then else if q.active then
Lwt_list.filter_p filter_map_s
(fun pkh -> Delegate.deactivated ctxt pkh >|= not) (fun pkh ->
delegates >>= return Delegate.deactivated ctxt pkh >>=? function
| true -> return_none
| false -> return_some pkh)
delegates
else if q.inactive then else if q.inactive then
Lwt_list.filter_p filter_map_s
(fun pkh -> Delegate.deactivated ctxt pkh) (fun pkh ->
delegates >>= return Delegate.deactivated ctxt pkh >>=? function
| false -> return_none
| true -> return_some pkh)
delegates
else else
return_nil return_nil
end ; end ;
@ -200,7 +206,7 @@ let register () =
Delegate.staking_balance ctxt pkh >>=? fun staking_balance -> Delegate.staking_balance ctxt pkh >>=? fun staking_balance ->
Delegate.delegated_contracts ctxt pkh >>= fun delegated_contracts -> Delegate.delegated_contracts ctxt pkh >>= fun delegated_contracts ->
Delegate.delegated_balance ctxt pkh >>=? fun delegated_balance -> 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 -> Delegate.grace_period ctxt pkh >>=? fun grace_period ->
return { return {
balance ; frozen_balance ; frozen_balance_by_cycle ; balance ; frozen_balance ; frozen_balance_by_cycle ;
@ -227,7 +233,7 @@ let register () =
Delegate.delegated_balance ctxt pkh Delegate.delegated_balance ctxt pkh
end ; end ;
register1 S.deactivated begin fun ctxt pkh () () -> register1 S.deactivated begin fun ctxt pkh () () ->
Delegate.deactivated ctxt pkh >>= return Delegate.deactivated ctxt pkh
end ; end ;
register1 S.grace_period begin fun ctxt pkh () () -> register1 S.grace_period begin fun ctxt pkh () () ->
Delegate.grace_period ctxt pkh Delegate.grace_period ctxt pkh

View File

@ -301,7 +301,7 @@ let set_base c is_delegatable contract delegate =
| Some current_delegate | Some current_delegate
when Signature.Public_key_hash.equal delegate current_delegate -> when Signature.Public_key_hash.equal delegate current_delegate ->
if self_delegation then if self_delegation then
Storage.Contract.Inactive_delegate.mem c contract >>= function Roll_storage.Delegate.is_inactive c delegate >>=? function
| true -> return_unit | true -> return_unit
| false -> fail Active_delegate | false -> fail Active_delegate
else else
@ -336,9 +336,6 @@ let remove ctxt contract =
Storage.Contract.Balance.get ctxt contract >>=? fun balance -> Storage.Contract.Balance.get ctxt contract >>=? fun balance ->
unlink ctxt contract balance unlink ctxt contract balance
let fold = Storage.Delegates.fold
let list = Storage.Delegates.elements
let delegated_contracts ctxt delegate = let delegated_contracts ctxt delegate =
let contract = Contract_repr.implicit_contract delegate in let contract = Contract_repr.implicit_contract delegate in
Storage.Contract.Delegated.elements (ctxt, contract) 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 match Cycle_repr.sub last_cycle preserved with
| None -> return (ctxt, balance_updates, []) | None -> return (ctxt, balance_updates, [])
| Some unfrozen_cycle -> | Some unfrozen_cycle ->
fold ctxt Storage.Delegates.fold ctxt
~init:(Ok (ctxt, balance_updates, [])) ~init:(Ok (ctxt, balance_updates))
~f:(fun delegate acc -> ~f:(fun delegate acc ->
Lwt.return acc >>=? fun (ctxt, bus, deactivated) -> Lwt.return acc >>=? fun (ctxt, bus) ->
unfreeze ctxt delegate unfrozen_cycle >>=? fun (ctxt, balance_updates) -> 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 Storage.Contract.Delegate_desactivation.get ctxt
(Contract_repr.implicit_contract delegate) >>=? fun cycle -> (Contract_repr.implicit_contract delegate) >>=? fun cycle ->
if Cycle_repr.(cycle <= last_cycle) then if Cycle_repr.(cycle <= last_cycle) then
Roll_storage.Delegate.set_inactive ctxt delegate >>=? fun ctxt -> Roll_storage.Delegate.set_inactive ctxt delegate >>=? fun ctxt ->
return (ctxt, balance_updates @ bus, delegate::deactivated) return (ctxt, delegate :: deactivated)
else else
return (ctxt, balance_updates @ bus, deactivated)) return (ctxt, deactivated)) >>=? fun (ctxt, deactivated) ->
return (ctxt, balance_updates, deactivated)
let punish ctxt delegate cycle = let punish ctxt delegate cycle =
let contract = Contract_repr.implicit_contract delegate in 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 -> Storage.Contract.Balance.get ctxt contract >>=? fun balance ->
Lwt.return Tez_repr.(frozen_balance +? balance) Lwt.return Tez_repr.(frozen_balance +? balance)
let deactivated ctxt delegate = let deactivated = Roll_storage.Delegate.is_inactive
let contract = Contract_repr.implicit_contract delegate in
Storage.Contract.Inactive_delegate.mem ctxt contract
let grace_period ctxt delegate = let grace_period ctxt delegate =
let contract = Contract_repr.implicit_contract delegate in let contract = Contract_repr.implicit_contract delegate in
@ -612,3 +614,7 @@ let delegated_balance ctxt delegate =
Lwt.return acc >>=? fun acc -> Lwt.return acc >>=? fun acc ->
Lwt.return (Tez_repr.(acc +? amount))) >>=? fun self_staking_balance -> Lwt.return (Tez_repr.(acc +? amount))) >>=? fun self_staking_balance ->
Lwt.return Tez_repr.(staking_balance -? self_staking_balance) Lwt.return Tez_repr.(staking_balance -? self_staking_balance)
let fold = Storage.Delegates.fold
let list = Storage.Delegates.elements

View File

@ -180,7 +180,7 @@ val delegated_balance:
val deactivated: val deactivated:
Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t -> Signature.Public_key_hash.t ->
bool Lwt.t bool tzresult Lwt.t
val grace_period: val grace_period:
Raw_context.t -> Signature.Public_key_hash.t -> Raw_context.t -> Signature.Public_key_hash.t ->

View File

@ -283,6 +283,22 @@ module Delegate = struct
| false -> | false ->
Storage.Roll.Delegate_change.init c delegate Tez_repr.zero 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 = let add_amount c delegate amount =
ensure_inited c delegate >>=? fun c -> ensure_inited c delegate >>=? fun c ->
let tokens_per_roll = Constants_storage.tokens_per_roll c in 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 -> Lwt.return Tez_repr.(change -? tokens_per_roll) >>=? fun change ->
create_roll_in_delegate c delegate delegate_pk >>=? fun c -> create_roll_in_delegate c delegate delegate_pk >>=? fun c ->
loop c change in loop c change in
Storage.Contract.Inactive_delegate.mem c is_inactive c delegate >>=? fun inactive ->
(Contract_repr.implicit_contract delegate) >>= fun inactive -> if inactive then
if inactive then return c else loop c change 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 remove_amount c delegate amount =
let tokens_per_roll = Constants_storage.tokens_per_roll c in 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 -> Lwt.return Tez_repr.(change +? tokens_per_roll) >>=? fun change ->
loop c change in loop c change in
Storage.Roll.Delegate_change.get c delegate >>=? fun change -> Storage.Roll.Delegate_change.get c delegate >>=? fun change ->
Storage.Contract.Inactive_delegate.mem c is_inactive c delegate >>=? fun inactive ->
(Contract_repr.implicit_contract delegate) >>= fun inactive ->
begin 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) -> end >>=? fun (c, change) ->
Lwt.return Tez_repr.(change -? amount) >>=? fun change -> Lwt.return Tez_repr.(change -? amount) >>=? fun change ->
Storage.Roll.Delegate_change.set c delegate 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.Roll.Delegate_change.get ctxt delegate >>=? fun change ->
Storage.Contract.Inactive_delegate.add ctxt Storage.Contract.Inactive_delegate.add ctxt
(Contract_repr.implicit_contract delegate) >>= fun ctxt -> (Contract_repr.implicit_contract delegate) >>= fun ctxt ->
Storage.Active_delegates_with_rolls.del ctxt delegate >>= fun ctxt ->
let rec loop ctxt change = let rec loop ctxt change =
Storage.Roll.Delegate_roll_list.get_option ctxt delegate >>=? function Storage.Roll.Delegate_roll_list.get_option ctxt delegate >>=? function
| None -> return (ctxt, change) | None -> return (ctxt, change)
@ -337,8 +372,7 @@ module Delegate = struct
return ctxt return ctxt
let set_active ctxt delegate = let set_active ctxt delegate =
Storage.Contract.Inactive_delegate.mem ctxt is_inactive ctxt delegate >>=? fun inactive ->
(Contract_repr.implicit_contract delegate) >>= fun inactive ->
let current_cycle = (Raw_context.current_level ctxt).cycle in let current_cycle = (Raw_context.current_level ctxt).cycle in
let preserved_cycles = Constants_storage.preserved_cycles ctxt in let preserved_cycles = Constants_storage.preserved_cycles ctxt in
(* When the delegate is new or inactive, she will become active in (* When the delegate is new or inactive, she will become active in
@ -377,6 +411,12 @@ module Delegate = struct
create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt -> create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt ->
loop ctxt change in loop ctxt change in
loop ctxt change >>=? fun ctxt -> loop ctxt change >>=? fun 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 return ctxt
end end

View File

@ -61,6 +61,9 @@ val endorsement_rights_owner :
module Delegate : sig module Delegate : sig
val is_inactive :
Raw_context.t -> Signature.Public_key_hash.t -> bool tzresult Lwt.t
val add_amount : val add_amount :
Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t Raw_context.t -> Signature.Public_key_hash.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t

View File

@ -306,6 +306,11 @@ module Delegates =
(Make_subcontext(Raw_context)(struct let name = ["delegates"] end)) (Make_subcontext(Raw_context)(struct let name = ["delegates"] end))
(Make_index(Signature.Public_key_hash)) (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 *) (** Rolls *)
module Cycle = struct module Cycle = struct

View File

@ -220,6 +220,11 @@ module Delegates : Data_set_storage
with type t := Raw_context.t with type t := Raw_context.t
and type elt = Signature.Public_key_hash.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 *) (** Votes *)
module Vote : sig module Vote : sig