diff --git a/src/proto_alpha/lib_protocol/src/roll_storage.ml b/src/proto_alpha/lib_protocol/src/roll_storage.ml index 56311ca82..9fbb416c1 100644 --- a/src/proto_alpha/lib_protocol/src/roll_storage.ml +++ b/src/proto_alpha/lib_protocol/src/roll_storage.ml @@ -229,7 +229,9 @@ module Delegate = struct Lwt.return Tez_repr.(change -? roll_value) >>=? fun change -> create_roll_in_delegate c delegate delegate_pk >>=? fun c -> loop c change in - loop c change + Storage.Contract.Inactive_delegate.mem c + (Contract_repr.implicit_contract delegate) >>= fun inactive -> + if inactive then return c else loop c change let remove_amount c delegate amount = let roll_value = Raw_context.roll_value c in @@ -241,14 +243,58 @@ module Delegate = struct Lwt.return Tez_repr.(change +? roll_value) >>=? fun change -> loop c change in Storage.Roll.Delegate_change.get c delegate >>=? fun change -> - loop c change >>=? fun (c, change) -> + Storage.Contract.Inactive_delegate.mem c + (Contract_repr.implicit_contract delegate) >>= fun inactive -> + begin + if inactive then return (c, change) else loop c change + end >>=? fun (c, change) -> Lwt.return Tez_repr.(change -? amount) >>=? fun change -> Storage.Roll.Delegate_roll_list.mem c delegate >>= fun rolls -> - if Tez_repr.(change = zero) && not rolls then + if not inactive && Tez_repr.(change = zero) && not rolls then Storage.Roll.Delegate_change.delete c delegate else Storage.Roll.Delegate_change.set c delegate change + let set_inactive ctxt delegate = + ensure_inited ctxt delegate >>=? fun ctxt -> + let roll_value = Raw_context.roll_value ctxt in + Storage.Roll.Delegate_change.get ctxt delegate >>=? fun change -> + Storage.Contract.Inactive_delegate.add ctxt + (Contract_repr.implicit_contract delegate) >>= fun ctxt -> + let rec loop ctxt change = + Storage.Roll.Delegate_roll_list.get_option ctxt delegate >>=? function + | None -> return (ctxt, change) + | Some _roll -> + pop_roll_from_delegate ctxt delegate >>=? fun (_, ctxt) -> + Lwt.return Tez_repr.(change +? roll_value) >>=? fun change -> + loop ctxt change in + loop ctxt change >>=? fun (ctxt, change) -> + Storage.Roll.Delegate_change.set ctxt delegate change >>=? fun ctxt -> + return ctxt + + let set_active ctxt delegate = + Storage.Contract.Inactive_delegate.mem ctxt + (Contract_repr.implicit_contract delegate) >>= fun inactive -> + if not inactive then + return ctxt + else begin + ensure_inited ctxt delegate >>=? fun ctxt -> + let roll_value = Raw_context.roll_value ctxt in + Storage.Roll.Delegate_change.get ctxt delegate >>=? fun change -> + Storage.Contract.Inactive_delegate.del ctxt + (Contract_repr.implicit_contract delegate) >>= fun ctxt -> + delegate_pubkey ctxt delegate >>=? fun delegate_pk -> + let rec loop ctxt change = + if Tez_repr.(change < roll_value) then + return ctxt + else + Lwt.return Tez_repr.(change -? roll_value) >>=? fun change -> + create_roll_in_delegate ctxt delegate delegate_pk >>=? fun ctxt -> + loop ctxt change in + loop ctxt change >>=? fun ctxt -> + return ctxt + end + end module Contract = struct diff --git a/src/proto_alpha/lib_protocol/src/roll_storage.mli b/src/proto_alpha/lib_protocol/src/roll_storage.mli index 97cbc4e6d..8c3d680c7 100644 --- a/src/proto_alpha/lib_protocol/src/roll_storage.mli +++ b/src/proto_alpha/lib_protocol/src/roll_storage.mli @@ -50,6 +50,10 @@ module Delegate : sig val remove_amount : Raw_context.t -> Ed25519.Public_key_hash.t -> Tez_repr.t -> Raw_context.t tzresult Lwt.t + 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 + end module Contract : sig diff --git a/src/proto_alpha/lib_protocol/src/storage.ml b/src/proto_alpha/lib_protocol/src/storage.ml index 1214c232f..835856570 100644 --- a/src/proto_alpha/lib_protocol/src/storage.ml +++ b/src/proto_alpha/lib_protocol/src/storage.ml @@ -105,6 +105,10 @@ module Contract = struct (struct let name = ["delegate"] end) (Make_value(Ed25519.Public_key_hash)) + module Inactive_delegate = + Indexed_context.Make_set + (struct let name = ["inactive_delegate"] end) + 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 192ba93ba..2f9222c15 100644 --- a/src/proto_alpha/lib_protocol/src/storage.mli +++ b/src/proto_alpha/lib_protocol/src/storage.mli @@ -133,6 +133,10 @@ module Contract : sig with type elt = Contract_hash.t and type t = Raw_context.t * Contract_repr.t + module Inactive_delegate : Data_set_storage + with type elt = Contract_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