diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 522186053bb077d4779d8a07c68903348175ac51..6fcfd1635a1c349e0f0b419aeaf9c2c2a33acc35 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2266,6 +2266,11 @@ module Delegate : sig Signature.Public_key_hash.t -> Staking_parameters_repr.t -> context tzresult Lwt.t + + val of_delegate : + context -> + Signature.Public_key_hash.t -> + Staking_parameters_repr.t tzresult Lwt.t end end diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index b94378349bddecf722905be46b433c742967552b..6224b6fd98930cf27c488eb77321b6c796f8e1dd 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -44,6 +44,7 @@ type error += | Invalid_sender of Destination.t | Invalid_self_transaction_destination | Staking_for_nondelegate_while_costaking_disabled + | Staking_to_delegate_that_refuses_costaking | Invalid_nonzero_transaction_amount of Tez.t | Invalid_unstake_request_amount of {requested_amount : Z.t} | Invalid_staking_parameters_sender @@ -239,6 +240,23 @@ let () = (function | Staking_for_nondelegate_while_costaking_disabled -> Some () | _ -> None) (fun () -> Staking_for_nondelegate_while_costaking_disabled) ; + let staking_to_delegate_that_refuses_costaking_description = + "The delegate currently does not accept staking operations from sources \ + other than itself: its `staking_over_baking_limit` parameter is set to 0." + in + register_error_kind + `Permanent + ~id:"operations.staking_to_delegate_that_refuses_costaking" + ~title:"Staking to delegate that does not accept external staking" + ~description:staking_to_delegate_that_refuses_costaking_description + ~pp:(fun ppf () -> + Format.pp_print_string + ppf + staking_to_delegate_that_refuses_costaking_description) + Data_encoding.unit + (function + | Staking_to_delegate_that_refuses_costaking -> Some () | _ -> None) + (fun () -> Staking_to_delegate_that_refuses_costaking) ; register_error_kind `Permanent ~id:"operations.invalid_nonzero_transaction_amount" @@ -353,6 +371,16 @@ let apply_stake ~ctxt ~sender ~amount ~destination ~before_operation = let*? () = error_unless allowed Staking_for_nondelegate_while_costaking_disabled in + let* {staking_over_baking_limit; _} = + Delegate.Staking_parameters.of_delegate ctxt delegate + in + let forbidden = + Signature.Public_key_hash.(delegate <> sender) + && Compare.Int32.(staking_over_baking_limit = 0l) + in + let*? () = + error_when forbidden Staking_to_delegate_that_refuses_costaking + in let* ctxt, balance_updates = Staking.stake ctxt ~sender ~delegate amount in diff --git a/src/proto_alpha/lib_protocol/delegate_staking_parameters.ml b/src/proto_alpha/lib_protocol/delegate_staking_parameters.ml index 7982a66ac465f746bfb18f6095e64859a5c47c18..2a933b5814dd01dcdb80f186e965f0bfeab4b4cf 100644 --- a/src/proto_alpha/lib_protocol/delegate_staking_parameters.ml +++ b/src/proto_alpha/lib_protocol/delegate_staking_parameters.ml @@ -24,7 +24,15 @@ (*****************************************************************************) let of_delegate ctxt delegate = - Storage.Contract.Staking_parameters.get ctxt (Contract_repr.Implicit delegate) + let open Lwt_result_syntax in + let* t = + Storage.Contract.Staking_parameters.find + ctxt + (Contract_repr.Implicit delegate) + in + match t with + | None -> return Staking_parameters_repr.default + | Some t -> return t let raw_pending_updates ctxt delegate = Storage.Contract.Pending_staking_parameters.bindings diff --git a/src/proto_alpha/lib_protocol/staking_parameters_repr.ml b/src/proto_alpha/lib_protocol/staking_parameters_repr.ml index 5393f26bfb9bc3de2ff550e07a230f630ca158ed..e2080c48283f8566dc6d8e647acd28da3bf8820b 100644 --- a/src/proto_alpha/lib_protocol/staking_parameters_repr.ml +++ b/src/proto_alpha/lib_protocol/staking_parameters_repr.ml @@ -32,6 +32,8 @@ let maximum_baking_over_staking_edge = (* max is 1 expressed in portions of 1_000_000_000 *) 1_000_000_000l +let default = {staking_over_baking_limit = 0l; baking_over_staking_edge = 0l} + type error += Invalid_staking_parameters let () = diff --git a/src/proto_alpha/lib_protocol/staking_parameters_repr.mli b/src/proto_alpha/lib_protocol/staking_parameters_repr.mli index 1e371c973c080b10717339cdf661d1da16696d54..1c47f99de79907424e07b8f1a913bd08758500cf 100644 --- a/src/proto_alpha/lib_protocol/staking_parameters_repr.mli +++ b/src/proto_alpha/lib_protocol/staking_parameters_repr.mli @@ -28,6 +28,9 @@ type t = private { baking_over_staking_edge : int32; (* as a portion of 1_000_000_000 *) } +(** Value used when unset *) +val default : t + type error += Invalid_staking_parameters val make :