Raw File
delegate_activation_storage.ml
(*****************************************************************************)
(*                                                                           *)
(* Open Source License                                                       *)
(* Copyright (c) 2021 Nomadic Labs, <contact@nomadic-labs.com>               *)
(*                                                                           *)
(* Permission is hereby granted, free of charge, to any person obtaining a   *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense,  *)
(* and/or sell copies of the Software, and to permit persons to whom the     *)
(* Software is furnished to do so, subject to the following conditions:      *)
(*                                                                           *)
(* The above copyright notice and this permission notice shall be included   *)
(* in all copies or substantial portions of the Software.                    *)
(*                                                                           *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL   *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER       *)
(* DEALINGS IN THE SOFTWARE.                                                 *)
(*                                                                           *)
(*****************************************************************************)

let is_inactive ctxt delegate =
  Storage.Contract.Inactive_delegate.mem ctxt (Contract_repr.Implicit delegate)
  >>= fun inactive ->
  if inactive then return inactive
  else
    Storage.Contract.Delegate_last_cycle_before_deactivation.find
      ctxt
      (Contract_repr.Implicit delegate)
    >|=? function
    | Some last_active_cycle ->
        let ({Level_repr.cycle = current_cycle; _} : Level_repr.t) =
          Raw_context.current_level ctxt
        in
        Cycle_repr.(last_active_cycle < current_cycle)
    | None ->
        (* This case is only when called from `set_active`, when creating
             a contract. *)
        false

let last_cycle_before_deactivation ctxt delegate =
  let contract = Contract_repr.Implicit delegate in
  Storage.Contract.Delegate_last_cycle_before_deactivation.get ctxt contract

let set_inactive ctxt delegate =
  Storage.Contract.Inactive_delegate.add ctxt (Contract_repr.Implicit delegate)

let set_active ctxt delegate =
  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
  (* We allow a number of cycles before a delegate is deactivated as follows:
     - if the delegate is active, we give it at least `1 + preserved_cycles`
     after the current cycle before to be deactivated.
     - if the delegate is new or inactive, we give it additionally
     `preserved_cycles` because the delegate needs this number of cycles to
     receive rights, so `1 + 2 * preserved_cycles` in total. *)
  let delegate_contract = Contract_repr.Implicit delegate in
  Storage.Contract.Delegate_last_cycle_before_deactivation.find
    ctxt
    delegate_contract
  >>=? fun current_last_active_cycle ->
  let last_active_cycle =
    match current_last_active_cycle with
    | None -> Cycle_repr.add current_cycle (1 + (2 * preserved_cycles))
    | Some current_last_active_cycle ->
        let delay =
          if inactive then 1 + (2 * preserved_cycles) else 1 + preserved_cycles
        in
        let updated = Cycle_repr.add current_cycle delay in
        Cycle_repr.max current_last_active_cycle updated
  in
  Storage.Contract.Delegate_last_cycle_before_deactivation.add
    ctxt
    delegate_contract
    last_active_cycle
  >>= fun ctxt ->
  if not inactive then return (ctxt, inactive)
  else
    Storage.Contract.Inactive_delegate.remove ctxt delegate_contract
    >>= fun ctxt -> return (ctxt, inactive)
back to top