diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index d918565a9af63321e031f1755d86e61289506b1c..f08ef4e7123a0ef760c9fdb5be14470e2c3d98c0 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -424,6 +424,7 @@ let pp_balance_updates ppf balance_updates = | Dal_attesting_rewards -> "DAL attesting rewards" | Storage_fees -> "storage fees" | Double_signing_punishments -> "double signing punishments" + | Dal_entrapment_punishment -> "DAL entrapment punishment" | Lost_attesting_rewards (pkh, p, r) -> let reason = match (p, r) with diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index eb860a93b097d348b3ef49ac5ec2fb55e0bce4d8..40d459363c48db0c40306e2bd2c195baacd66bdf 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2158,6 +2158,7 @@ module Receipt : sig | Dal_attesting_rewards : Tez.t balance | Storage_fees : Tez.t balance | Double_signing_punishments : Tez.t balance + | Dal_entrapment_punishment : Tez.t balance | Lost_attesting_rewards : public_key_hash * bool * bool -> Tez.t balance | Lost_dal_attesting_rewards : public_key_hash -> Tez.t balance | Liquidity_baking_subsidies : Tez.t balance @@ -2296,6 +2297,15 @@ module Delegate : sig rewarded:public_key_hash -> context tzresult Lwt.t + (** See {!Delegate_slashed_deposits_storage.punish_dal_entrapment}. *) + val punish_dal_entrapment : + context -> + operation_hash:Operation_hash.t -> + public_key_hash -> + Level.t -> + rewarded:public_key_hash -> + (context * Receipt.balance_updates) tzresult Lwt.t + type level_participation = Participated | Didn't_participate val record_baking_activity_and_pay_rewards_and_fees : @@ -5375,6 +5385,7 @@ module Token : sig type receiver = [ `Storage_fees | `Double_signing_punishments + | `Dal_entrapment_punishment | `Lost_attesting_rewards of public_key_hash * bool * bool | `Lost_dal_attesting_rewards of public_key_hash | `Burned diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index 094b8b2ece5a23ccc0e71820259f77e35895bc1d..7db611e6bb834e0247238e4a8522293d53482143 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -2428,6 +2428,26 @@ let punish_double_baking ctxt ~operation_hash (bh1 : Block_header.t) (fun forbidden_delegate balance_updates -> Double_baking_evidence_result {forbidden_delegate; balance_updates}) +let punish_dal_entrapment ctxt ~operation_hash + ~(attestation : Kind.attestation Operation.t) ~payload_producer = + let open Lwt_result_syntax in + let {slot; level = raw_level; _} = + match attestation.protocol_data.contents with + | Single (Attestation {consensus_content; _}) -> consensus_content + in + let level = Level.from_raw ctxt raw_level in + let* ctxt, consensus_pk = Stake_distribution.slot_owner ctxt level slot in + let rewarded = payload_producer.Consensus_key.delegate in + let+ ctxt, balance_updates = + Delegate.punish_dal_entrapment + ctxt + ~operation_hash + consensus_pk.delegate + level + ~rewarded + in + (ctxt, Single_result (Dal_entrapment_evidence_result {balance_updates})) + let apply_contents_list (type kind) ctxt chain_id (mode : mode) ~payload_producer ~operation ~operation_hash (contents_list : kind contents_list) : @@ -2482,12 +2502,9 @@ let apply_contents_list (type kind) ctxt chain_id (mode : mode) ~payload_producer | Single (Double_baking_evidence {bh1; bh2 = _}) -> punish_double_baking ctxt ~operation_hash bh1 ~payload_producer - | Single (Dal_entrapment_evidence _) -> + | Single (Dal_entrapment_evidence {attestation; _}) -> (* This should be unreachable, because this operation is not yet valid. *) - return - ( ctxt, - Single_result (Dal_entrapment_evidence_result {balance_updates = []}) - ) + punish_dal_entrapment ctxt ~operation_hash ~attestation ~payload_producer | Single (Activate_account {id = pkh; activation_code}) -> let blinded_pkh = Blinded_public_key_hash.of_ed25519_pkh activation_code pkh diff --git a/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.ml b/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.ml index 069a1a4f5da01a91c0b8259f4bbd4b53bc7af13e..e63521d1038fd5cf07dbe06a2abd8fa03b6e4e3f 100644 --- a/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.ml +++ b/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.ml @@ -479,6 +479,33 @@ let apply_and_clear_denunciations ctxt = in return (ctxt, balance_updates) +let punish_dal_entrapment ctxt ~operation_hash delegate (_level : Level_repr.t) + ~rewarded = + let open Lwt_result_syntax in + let global_limit_of_staking_over_baking = + Constants_storage.adaptive_issuance_global_limit_of_staking_over_baking ctxt + in + let*? punishing_amount = Tez_repr.(one *? 100L) in + let* to_burn, to_reward = + init_to_burn_and_reward + ctxt + global_limit_of_staking_over_baking + delegate + punishing_amount + in + let origin = Receipt_repr.Delayed_operation {operation_hash} in + let* ctxt, punish_balance_updates = + Token.transfer_n ctxt ~origin to_burn `Double_signing_punishments + in + let+ ctxt, reward_balance_updates = + Token.transfer_n + ctxt + ~origin + to_reward + (`Contract (Contract_repr.Implicit rewarded)) + in + (ctxt, punish_balance_updates @ reward_balance_updates) + module For_RPC = struct let get_pending_misbehaviour_map ctxt = Storage.Pending_denunciations.fold diff --git a/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.mli b/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.mli index 02e0705ade682174e5f0f76670837474b4cdc191..cde69715f6fc40470a6d17b2b715ea050bd59410 100644 --- a/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.mli +++ b/src/proto_alpha/lib_protocol/delegate_slashed_deposits_storage.mli @@ -68,6 +68,15 @@ val punish_double_signing : rewarded:Signature.public_key_hash -> Raw_context.t tzresult Lwt.t +(* TODO *) +val punish_dal_entrapment : + Raw_context.t -> + operation_hash:Operation_hash.t -> + Signature.public_key_hash -> + Level_repr.t -> + rewarded:Signature.public_key_hash -> + (Raw_context.t * Receipt_repr.balance_updates) tzresult Lwt.t + (** Applies pending denunciations in {!Storage.Pending_denunciations} at the end of a cycle. The applicable denunciations are those that point to a misbehavior whose max slashable period is ending. diff --git a/src/proto_alpha/lib_protocol/receipt_repr.ml b/src/proto_alpha/lib_protocol/receipt_repr.ml index 93fa0f50cb40e601a4f805436377db87db9be87f..9c185bd8a5b25042842cf239de8975810b7621a7 100644 --- a/src/proto_alpha/lib_protocol/receipt_repr.ml +++ b/src/proto_alpha/lib_protocol/receipt_repr.ml @@ -83,6 +83,7 @@ type 'token balance = | Dal_attesting_rewards : Tez_repr.t balance | Storage_fees : Tez_repr.t balance | Double_signing_punishments : Tez_repr.t balance + | Dal_entrapment_punishment : Tez_repr.t balance | Lost_attesting_rewards : Signature.Public_key_hash.t * bool * bool -> Tez_repr.t balance @@ -120,6 +121,7 @@ let token_of_balance : type token. token balance -> token Token.t = function | Dal_attesting_rewards -> Token.Tez | Storage_fees -> Token.Tez | Double_signing_punishments -> Token.Tez + | Dal_entrapment_punishment -> Token.Tez | Lost_attesting_rewards _ -> Token.Tez | Lost_dal_attesting_rewards _ -> Token.Tez | Liquidity_baking_subsidies -> Token.Tez @@ -193,6 +195,7 @@ let compare_balance : | Staking_delegate_denominator _ -> 22 | Dal_attesting_rewards -> 23 | Lost_dal_attesting_rewards _ -> 24 + | Dal_entrapment_punishment -> 25 (* don't forget to add parameterized cases in the first part of the function *) in Compare.Int.compare (index ba) (index bb) diff --git a/src/proto_alpha/lib_protocol/receipt_repr.mli b/src/proto_alpha/lib_protocol/receipt_repr.mli index 34bb154e0ab3e4ef211152c6b5e6bd17f1377a95..41668a3ad5327f6f172ee1ea481e156c67d37a3b 100644 --- a/src/proto_alpha/lib_protocol/receipt_repr.mli +++ b/src/proto_alpha/lib_protocol/receipt_repr.mli @@ -56,6 +56,7 @@ type 'token balance = | Dal_attesting_rewards : Tez_repr.t balance | Storage_fees : Tez_repr.t balance | Double_signing_punishments : Tez_repr.t balance + | Dal_entrapment_punishment : Tez_repr.t balance | Lost_attesting_rewards : Signature.Public_key_hash.t * bool * bool -> Tez_repr.t balance diff --git a/src/proto_alpha/lib_protocol/token.ml b/src/proto_alpha/lib_protocol/token.ml index 2c31121bed8abf6890d402b7d8c04145329d52b6..b246d43fe1419907c560b075dc68955f1ec2b36f 100644 --- a/src/proto_alpha/lib_protocol/token.ml +++ b/src/proto_alpha/lib_protocol/token.ml @@ -49,6 +49,7 @@ type giver = [infinite_source | container] type infinite_sink = [ `Storage_fees | `Double_signing_punishments + | `Dal_entrapment_punishment | `Lost_attesting_rewards of Signature.Public_key_hash.t * bool * bool | `Lost_dal_attesting_rewards of Signature.Public_key_hash.t | `Sc_rollup_refutation_punishments @@ -74,6 +75,7 @@ let credit ctxt receiver amount origin = match infinite_sink with | `Storage_fees -> Storage_fees | `Double_signing_punishments -> Double_signing_punishments + | `Dal_entrapment_punishment -> Dal_entrapment_punishment | `Lost_attesting_rewards (d, p, r) -> Lost_attesting_rewards (d, p, r) | `Lost_dal_attesting_rewards d -> Lost_dal_attesting_rewards d | `Sc_rollup_refutation_punishments -> diff --git a/src/proto_alpha/lib_protocol/token.mli b/src/proto_alpha/lib_protocol/token.mli index a4b4a653257f5d55067ae4abdb2f4539b6342770..671715f6cc64e3b0933bb52d4b63906583f42471 100644 --- a/src/proto_alpha/lib_protocol/token.mli +++ b/src/proto_alpha/lib_protocol/token.mli @@ -96,6 +96,7 @@ type giver = [infinite_source | container] type infinite_sink = [ `Storage_fees (** Fees burnt to compensate storage usage *) | `Double_signing_punishments (** Consensus slashing *) + | `Dal_entrapment_punishment (** DAL slashing *) | `Lost_attesting_rewards of Signature.Public_key_hash.t * bool * bool (** Consensus rewards not distributed because the participation of the delegate was too low. *) | `Lost_dal_attesting_rewards of Signature.Public_key_hash.t