From 29fce71697d7a2e692cdb5b6d453e2b3b8759468 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Thu, 15 May 2025 17:22:28 +0200 Subject: [PATCH 01/10] Proto: merge double-attestation and double-preattestation denunciations into one operation --- .../lib_client/operation_result.ml | 24 +- .../client_baking_denunciation.ml | 4 +- .../lib_injector/injector_plugin.ml | 3 +- src/proto_alpha/lib_plugin/RPC.ml | 11 +- src/proto_alpha/lib_plugin/mempool.ml | 11 +- .../lib_protocol/alpha_context.mli | 27 +- src/proto_alpha/lib_protocol/apply.ml | 95 +++---- src/proto_alpha/lib_protocol/apply_results.ml | 68 ++--- .../lib_protocol/apply_results.mli | 9 +- .../lib_protocol/operation_repr.ml | 239 ++++++------------ .../lib_protocol/operation_repr.mli | 47 ++-- .../lib_protocol/test/helpers/block.ml | 3 +- .../lib_protocol/test/helpers/op.ml | 4 +- .../test/helpers/operation_generator.ml | 33 ++- .../consensus/test_double_attestation.ml | 3 +- .../validate/generator_descriptors.ml | 3 +- .../test/integration/validate/test_sanity.ml | 7 +- src/proto_alpha/lib_protocol/validate.ml | 182 +++++-------- .../lib_sc_rollup_node/sc_rollup_injector.ml | 3 +- 19 files changed, 268 insertions(+), 508 deletions(-) diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 147708127644..938d4ca32632 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -1077,30 +1077,12 @@ let pp_contents_and_result : (Format.pp_print_list Consensus_key.pp) committee consensus_power - | ( Double_attestation_evidence {op1; op2}, - Double_attestation_evidence_result {forbidden_delegate; balance_updates} - ) -> - Format.fprintf - ppf - "@[Double attestation evidence:@,\ - Exhibit A: %a@,\ - Exhibit B: %a@,\ - %aBalance updates:@,\ - \ %a@]" - Operation_hash.pp - (Operation.hash op1) - Operation_hash.pp - (Operation.hash op2) - pp_forbidden - forbidden_delegate - pp_balance_updates - balance_updates - | ( Double_preattestation_evidence {op1; op2}, - Double_preattestation_evidence_result + | ( Double_consensus_operation_evidence {op1; op2}, + Double_consensus_operation_evidence_result {forbidden_delegate; balance_updates} ) -> Format.fprintf ppf - "@[Double preattestation evidence:@,\ + "@[Double consensus operation evidence:@,\ Exhibit A: %a@,\ Exhibit B: %a@,\ %aBalance updates:@,\ diff --git a/src/proto_alpha/lib_delegate/client_baking_denunciation.ml b/src/proto_alpha/lib_delegate/client_baking_denunciation.ml index de5aa94bffff..4568f44aab0f 100644 --- a/src/proto_alpha/lib_delegate/client_baking_denunciation.ml +++ b/src/proto_alpha/lib_delegate/client_baking_denunciation.ml @@ -166,8 +166,8 @@ let double_consensus_op_evidence (type kind) : op2:kind Alpha_context.operation -> unit -> bytes Environment.Error_monad.shell_tzresult Lwt.t = function - | Attestation -> Plugin.RPC.Forge.double_attestation_evidence - | Preattestation -> Plugin.RPC.Forge.double_preattestation_evidence + | Attestation -> Plugin.RPC.Forge.double_consensus_operation_evidence + | Preattestation -> Plugin.RPC.Forge.double_consensus_operation_evidence let lookup_recorded_consensus (type kind) consensus_key (op_kind : kind denunciable_consensus_operation) map : diff --git a/src/proto_alpha/lib_injector/injector_plugin.ml b/src/proto_alpha/lib_injector/injector_plugin.ml index 1343d761b0de..ac32bd1ae527 100644 --- a/src/proto_alpha/lib_injector/injector_plugin.ml +++ b/src/proto_alpha/lib_injector/injector_plugin.ml @@ -158,8 +158,7 @@ module Proto_client = struct | Preattestations_aggregate_result _ -> Successful | Seed_nonce_revelation_result _ -> Successful | Vdf_revelation_result _ -> Successful - | Double_attestation_evidence_result _ -> Successful - | Double_preattestation_evidence_result _ -> Successful + | Double_consensus_operation_evidence_result _ -> Successful | Double_baking_evidence_result _ -> Successful | Dal_entrapment_evidence_result _ -> Successful | Activate_account_result _ -> Successful diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index cfa7cba8330c..14dfd12bdaca 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -3398,11 +3398,12 @@ module Forge = struct let double_baking_evidence ctxt block ~branch ~bh1 ~bh2 () = operation ctxt block ~branch (Double_baking_evidence {bh1; bh2}) - let double_attestation_evidence ctxt block ~branch ~op1 ~op2 () = - operation ctxt block ~branch (Double_attestation_evidence {op1; op2}) - - let double_preattestation_evidence ctxt block ~branch ~op1 ~op2 () = - operation ctxt block ~branch (Double_preattestation_evidence {op1; op2}) + let double_consensus_operation_evidence ctxt block ~branch ~op1 ~op2 () = + operation + ctxt + block + ~branch + (Double_consensus_operation_evidence {op1; op2}) let dal_entrapment_evidence ctxt block ~branch ~attestation ~consensus_slot ~slot_index ~shard_with_proof = diff --git a/src/proto_alpha/lib_plugin/mempool.ml b/src/proto_alpha/lib_plugin/mempool.ml index 84cf49212ef7..bfb34a76fdaa 100644 --- a/src/proto_alpha/lib_plugin/mempool.ml +++ b/src/proto_alpha/lib_plugin/mempool.ml @@ -555,8 +555,7 @@ let pre_filter info config mempools. *) `Refused [Environment.wrap_tzerror Wrong_operation] | Single (Seed_nonce_revelation _) - | Single (Double_preattestation_evidence _) - | Single (Double_attestation_evidence _) + | Single (Double_consensus_operation_evidence _) | Single (Double_baking_evidence _) | Single (Dal_entrapment_evidence _) | Single (Activate_account _) @@ -695,9 +694,8 @@ let find_manager {shell = _; protocol_data = Operation_data {contents; _}} = ( Preattestation _ | Attestation _ | Preattestations_aggregate _ | Attestations_aggregate _ | Proposals _ | Ballot _ | Seed_nonce_revelation _ | Vdf_revelation _ | Double_baking_evidence _ - | Double_preattestation_evidence _ | Double_attestation_evidence _ - | Dal_entrapment_evidence _ | Activate_account _ | Drain_delegate _ - | Failing_noop _ ) -> + | Double_consensus_operation_evidence _ | Dal_entrapment_evidence _ + | Activate_account _ | Drain_delegate _ | Failing_noop _ ) -> None (* The purpose of this module is to offer a version of @@ -844,8 +842,7 @@ let sources_from_operation ctxt consensus_content (Operation.committee_slots committee) | Single (Seed_nonce_revelation _) - | Single (Double_preattestation_evidence _) - | Single (Double_attestation_evidence _) + | Single (Double_consensus_operation_evidence _) | Single (Double_baking_evidence _) | Single (Dal_entrapment_evidence _) | Single (Activate_account _) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 658a3f5a5d34..f644bd44fc17 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -4602,15 +4602,9 @@ module Kind : sig type vdf_revelation = Vdf_revelation_kind - type 'a double_consensus_operation_evidence = + type double_consensus_operation_evidence = | Double_consensus_operation_evidence - type double_attestation_evidence = - attestation_consensus_kind double_consensus_operation_evidence - - type double_preattestation_evidence = - preattestation_consensus_kind double_consensus_operation_evidence - type double_baking_evidence = Double_baking_evidence_kind type dal_entrapment_evidence = Dal_entrapment_evidence_kind @@ -4770,16 +4764,11 @@ and _ contents = solution : Seed.vdf_solution; } -> Kind.vdf_revelation contents - | Double_preattestation_evidence : { - op1 : Kind.preattestation operation; - op2 : Kind.preattestation operation; + | Double_consensus_operation_evidence : { + op1 : 'a Kind.consensus operation; + op2 : 'b Kind.consensus operation; } - -> Kind.double_preattestation_evidence contents - | Double_attestation_evidence : { - op1 : Kind.attestation operation; - op2 : Kind.attestation operation; - } - -> Kind.double_attestation_evidence contents + -> Kind.double_consensus_operation_evidence contents | Double_baking_evidence : { bh1 : Block_header.t; bh2 : Block_header.t; @@ -5062,10 +5051,8 @@ module Operation : sig val vdf_revelation_case : Kind.vdf_revelation case - val double_preattestation_evidence_case : - Kind.double_preattestation_evidence case - - val double_attestation_evidence_case : Kind.double_attestation_evidence case + val double_consensus_operation_evidence_case : + Kind.double_consensus_operation_evidence case val double_baking_evidence_case : Kind.double_baking_evidence case diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index da4cc1e50659..e28f67ff08cf 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -2247,10 +2247,9 @@ let record_operation (type kind) ctxt hash (operation : kind operation) : | Single (Attestations_aggregate _) -> ctxt | Single ( Failing_noop _ | Proposals _ | Ballot _ | Seed_nonce_revelation _ - | Vdf_revelation _ | Double_attestation_evidence _ - | Double_preattestation_evidence _ | Double_baking_evidence _ - | Dal_entrapment_evidence _ | Activate_account _ | Drain_delegate _ - | Manager_operation _ ) + | Vdf_revelation _ | Double_consensus_operation_evidence _ + | Double_baking_evidence _ | Dal_entrapment_evidence _ + | Activate_account _ | Drain_delegate _ | Manager_operation _ ) | Cons (Manager_operation _, _) -> record_non_consensus_operation_hash ctxt hash @@ -2505,54 +2504,38 @@ let punish_delegate ctxt ~operation_hash delegate level misbehaviour mk_result let content_result = mk_result (Some delegate) [] in return (ctxt, Single_result content_result) -let punish_double_preattestation ctxt ~operation_hash - ~(op1 : Kind.preattestation Operation.t) ~payload_producer = +let punish_double_consensus_operation (type kind) ctxt ~operation_hash + ~payload_producer contents = let open Lwt_result_syntax in - match op1.protocol_data.contents with - | Single (Preattestation consensus_content) -> - let {slot; level; round; _} = consensus_content in - let misbehaviour = - Misbehaviour.{level; round; kind = Double_preattesting} - in - let mk_result forbidden_delegate balance_updates = - Double_preattestation_evidence_result - {forbidden_delegate; balance_updates} - in - let level = Level.from_raw ctxt level in - let* ctxt, {delegate; _} = - Stake_distribution.slot_owner ctxt level slot - in - punish_delegate - ctxt - ~operation_hash - delegate - level - misbehaviour - mk_result - ~payload_producer - -let punish_double_attestation ctxt ~operation_hash - ~(op1 : Kind.attestation Operation.t) ~payload_producer = - let open Lwt_result_syntax in - match op1.protocol_data.contents with - | Single (Attestation {consensus_content; _}) -> - let {slot; level; round; block_payload_hash = _} = consensus_content in - let misbehaviour = Misbehaviour.{level; round; kind = Double_attesting} in - let mk_result forbidden_delegate balance_updates = - Double_attestation_evidence_result {forbidden_delegate; balance_updates} - in - let level = Level.from_raw ctxt level in - let* ctxt, {delegate; _} = - Stake_distribution.slot_owner ctxt level slot - in - punish_delegate - ctxt - ~operation_hash - delegate - level - misbehaviour - mk_result - ~payload_producer + let (Double_consensus_operation_evidence {op1; op2 = _}) = contents in + let*? slot, misbehaviour = + let open Result_syntax in + match op1.protocol_data.contents with + | Single (Attestation {consensus_content; _}) -> + let {slot; level; round; block_payload_hash = _} = consensus_content in + return (slot, Misbehaviour.{level; round; kind = Double_attesting}) + | Single (Preattestation consensus_content) -> + let {slot; level; round; _} = consensus_content in + return (slot, Misbehaviour.{level; round; kind = Double_preattesting}) + | Single (Preattestations_aggregate _ | Attestations_aggregate _) -> + (* TODO : https://gitlab.com/tezos/tezos/-/issues/7598 + handle denunciation for aggregates. *) + tzfail Validate_errors.Anonymous.Aggregate_denunciation_not_implemented + in + let mk_result forbidden_delegate balance_updates = + Double_consensus_operation_evidence_result + {forbidden_delegate; balance_updates} + in + let level = Level.from_raw ctxt misbehaviour.level in + let* ctxt, {delegate; _} = Stake_distribution.slot_owner ctxt level slot in + punish_delegate + ctxt + ~operation_hash + delegate + level + misbehaviour + mk_result + ~payload_producer let punish_double_baking ctxt ~operation_hash (bh1 : Block_header.t) ~payload_producer = @@ -2628,10 +2611,12 @@ let apply_contents_list (type kind) ctxt chain_id (mode : mode) tip in (ctxt, Single_result (Vdf_revelation_result balance_updates)) - | Single (Double_preattestation_evidence {op1; op2 = _}) -> - punish_double_preattestation ctxt ~operation_hash ~op1 ~payload_producer - | Single (Double_attestation_evidence {op1; op2 = _}) -> - punish_double_attestation ctxt ~operation_hash ~op1 ~payload_producer + | Single (Double_consensus_operation_evidence _ as contents) -> + punish_double_consensus_operation + ctxt + ~operation_hash + ~payload_producer + contents | Single (Double_baking_evidence {bh1; bh2 = _}) -> punish_double_baking ctxt ~operation_hash bh1 ~payload_producer | Single diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index ae9d9f45b72a..ebed1fdefd26 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -910,16 +910,11 @@ type 'kind contents_result = | Vdf_revelation_result : Receipt.balance_updates -> Kind.vdf_revelation contents_result - | Double_attestation_evidence_result : { + | Double_consensus_operation_evidence_result : { forbidden_delegate : Signature.public_key_hash option; balance_updates : Receipt.balance_updates; } - -> Kind.double_attestation_evidence contents_result - | Double_preattestation_evidence_result : { - forbidden_delegate : Signature.public_key_hash option; - balance_updates : Receipt.balance_updates; - } - -> Kind.double_preattestation_evidence contents_result + -> Kind.double_consensus_operation_evidence contents_result | Double_baking_evidence_result : { forbidden_delegate : Signature.public_key_hash option; balance_updates : Receipt.balance_updates; @@ -1232,60 +1227,33 @@ module Encoding = struct inj = (fun bus -> Vdf_revelation_result bus); } - let double_attestation_evidence_case = + let double_consensus_operation_evidence_case = Case { - op_case = Operation.Encoding.double_attestation_evidence_case; + op_case = Operation.Encoding.double_consensus_operation_evidence_case; encoding = obj2 (opt "forbidden_delegate" Signature.Public_key_hash.encoding) (dft "balance_updates" Receipt.balance_updates_encoding []); select = (function - | Contents_result (Double_attestation_evidence_result _ as op) -> - Some op - | _ -> None); - mselect = - (function - | Contents_and_result ((Double_attestation_evidence _ as op), res) -> - Some (op, res) - | _ -> None); - proj = - (fun (Double_attestation_evidence_result - {forbidden_delegate; balance_updates}) -> - (forbidden_delegate, balance_updates)); - inj = - (fun (forbidden_delegate, balance_updates) -> - Double_attestation_evidence_result - {forbidden_delegate; balance_updates}); - } - - let double_preattestation_evidence_case = - Case - { - op_case = Operation.Encoding.double_preattestation_evidence_case; - encoding = - obj2 - (opt "forbidden_delegate" Signature.Public_key_hash.encoding) - (dft "balance_updates" Receipt.balance_updates_encoding []); - select = - (function - | Contents_result (Double_preattestation_evidence_result _ as op) -> + | Contents_result (Double_consensus_operation_evidence_result _ as op) + -> Some op | _ -> None); mselect = (function - | Contents_and_result ((Double_preattestation_evidence _ as op), res) - -> + | Contents_and_result + ((Double_consensus_operation_evidence _ as op), res) -> Some (op, res) | _ -> None); proj = - (fun (Double_preattestation_evidence_result + (fun (Double_consensus_operation_evidence_result {forbidden_delegate; balance_updates}) -> (forbidden_delegate, balance_updates)); inj = (fun (forbidden_delegate, balance_updates) -> - Double_preattestation_evidence_result + Double_consensus_operation_evidence_result {forbidden_delegate; balance_updates}); } @@ -1477,8 +1445,8 @@ module Encoding = struct | Contents_result Ballot_result -> None | Contents_result (Seed_nonce_revelation_result _) -> None | Contents_result (Vdf_revelation_result _) -> None - | Contents_result (Double_attestation_evidence_result _) -> None - | Contents_result (Double_preattestation_evidence_result _) -> None + | Contents_result (Double_consensus_operation_evidence_result _) -> + None | Contents_result (Double_baking_evidence_result _) -> None | Contents_result (Dal_entrapment_evidence_result _) -> None | Contents_result (Activate_account_result _) -> None @@ -1786,8 +1754,8 @@ let contents_cases = let open Encoding in attestation_case :: attestation_with_dal_case :: preattestation_case :: attestations_aggregate_case :: preattestations_aggregate_case - :: double_attestation_evidence_case :: double_preattestation_evidence_case - :: dal_entrapment_evidence_case :: common_cases + :: double_consensus_operation_evidence_case :: dal_entrapment_evidence_case + :: common_cases let make_contents_result (Encoding.Case @@ -1955,12 +1923,10 @@ let kind_equal : | Seed_nonce_revelation _, _ -> None | Vdf_revelation _, Vdf_revelation_result _ -> Some Eq | Vdf_revelation _, _ -> None - | Double_preattestation_evidence _, Double_preattestation_evidence_result _ -> - Some Eq - | Double_preattestation_evidence _, _ -> None - | Double_attestation_evidence _, Double_attestation_evidence_result _ -> + | ( Double_consensus_operation_evidence _, + Double_consensus_operation_evidence_result _ ) -> Some Eq - | Double_attestation_evidence _, _ -> None + | Double_consensus_operation_evidence _, _ -> None | Double_baking_evidence _, Double_baking_evidence_result _ -> Some Eq | Double_baking_evidence _, _ -> None | Dal_entrapment_evidence _, Dal_entrapment_evidence_result _ -> Some Eq diff --git a/src/proto_alpha/lib_protocol/apply_results.mli b/src/proto_alpha/lib_protocol/apply_results.mli index 027657a6d52c..52b29c03b4dc 100644 --- a/src/proto_alpha/lib_protocol/apply_results.mli +++ b/src/proto_alpha/lib_protocol/apply_results.mli @@ -91,16 +91,11 @@ and 'kind contents_result = | Vdf_revelation_result : Receipt.balance_updates -> Kind.vdf_revelation contents_result - | Double_attestation_evidence_result : { + | Double_consensus_operation_evidence_result : { forbidden_delegate : Signature.public_key_hash option; balance_updates : Receipt.balance_updates; } - -> Kind.double_attestation_evidence contents_result - | Double_preattestation_evidence_result : { - forbidden_delegate : Signature.public_key_hash option; - balance_updates : Receipt.balance_updates; - } - -> Kind.double_preattestation_evidence contents_result + -> Kind.double_consensus_operation_evidence contents_result | Double_baking_evidence_result : { forbidden_delegate : Signature.public_key_hash option; balance_updates : Receipt.balance_updates; diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 4a91c31f0884..10570c8f3636 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -59,15 +59,9 @@ module Kind = struct type vdf_revelation = Vdf_revelation_kind - type 'a double_consensus_operation_evidence = + type double_consensus_operation_evidence = | Double_consensus_operation_evidence - type double_attestation_evidence = - attestation_consensus_kind double_consensus_operation_evidence - - type double_preattestation_evidence = - preattestation_consensus_kind double_consensus_operation_evidence - type double_baking_evidence = Double_baking_evidence_kind type dal_entrapment_evidence = Dal_entrapment_evidence_kind @@ -308,16 +302,11 @@ and _ contents = solution : Seed_repr.vdf_solution; } -> Kind.vdf_revelation contents - | Double_preattestation_evidence : { - op1 : Kind.preattestation operation; - op2 : Kind.preattestation operation; - } - -> Kind.double_preattestation_evidence contents - | Double_attestation_evidence : { - op1 : Kind.attestation operation; - op2 : Kind.attestation operation; + | Double_consensus_operation_evidence : { + op1 : 'a Kind.consensus operation; + op2 : 'b Kind.consensus operation; } - -> Kind.double_attestation_evidence contents + -> Kind.double_consensus_operation_evidence contents | Double_baking_evidence : { bh1 : Block_header_repr.t; bh2 : Block_header_repr.t; @@ -1128,32 +1117,6 @@ module Encoding = struct inj = (fun preattestation -> Preattestation preattestation); } - let preattestation_encoding = - let make (Case {tag; name; encoding; select = _; proj; inj}) = - case (Tag tag) name encoding (fun o -> Some (proj o)) (fun x -> inj x) - in - let to_list : Kind.preattestation contents_list -> _ = function - | Single o -> o - in - let of_list : Kind.preattestation contents -> _ = function - | o -> Single o - in - def "inlined.preattestation" - @@ conv - (fun ({shell; protocol_data = {contents; signature}} : _ operation) -> - (shell, (contents, signature))) - (fun (shell, (contents, signature)) : _ operation -> - {shell; protocol_data = {contents; signature}}) - (merge_objs - Operation.shell_header_encoding - (obj2 - (req - "operations" - (conv to_list of_list - @@ def "inlined.preattestation.contents" - @@ union [make preattestation_case])) - (varopt "signature" Signature.encoding))) - let dal_content_encoding = conv (fun {attestation} -> attestation) @@ -1211,44 +1174,6 @@ module Encoding = struct inj = attestation_with_dal_encoding_inj; } - let attestation_encoding = - let make kind (Case {tag; name; encoding; select = _; proj; inj}) = - case - (Tag tag) - name - encoding - (function - | o -> ( - match (kind, o) with - | `Without_dal, (Attestation {dal_content = None; _} as op) -> - Some (proj op) - | `With_dal, (Attestation {dal_content = Some _; _} as op) -> - Some (proj op) - | _ -> None)) - (fun x -> inj x) - in - let to_list : Kind.attestation contents_list -> _ = fun (Single o) -> o in - let of_list : Kind.attestation contents -> _ = fun o -> Single o in - def "inlined.attestation" - @@ conv - (fun ({shell; protocol_data = {contents; signature}} : _ operation) -> - (shell, (contents, signature))) - (fun (shell, (contents, signature)) : _ operation -> - {shell; protocol_data = {contents; signature}}) - (merge_objs - Operation.shell_header_encoding - (obj2 - (req - "operations" - (conv to_list of_list - @@ def "inlined.attestation_mempool.contents" - @@ union - [ - make `Without_dal attestation_case; - make `With_dal attestation_with_dal_case; - ])) - (varopt "signature" Signature.encoding))) - let attestations_aggregate_encoding = obj2 (req "consensus_content" consensus_aggregate_content_encoding) @@ -1374,41 +1299,32 @@ module Encoding = struct inj = (fun solution -> Vdf_revelation {solution}); } - let double_preattestation_evidence_case : - Kind.double_preattestation_evidence case = - Case - { - tag = 7; - name = "double_preattestation_evidence"; - encoding = - obj2 - (req "op1" (dynamic_size preattestation_encoding)) - (req "op2" (dynamic_size preattestation_encoding)); - select = - (function - | Contents (Double_preattestation_evidence _ as op) -> Some op - | _ -> None); - proj = (fun (Double_preattestation_evidence {op1; op2}) -> (op1, op2)); - inj = (fun (op1, op2) -> Double_preattestation_evidence {op1; op2}); - } - - let double_attestation_evidence_case : Kind.double_attestation_evidence case = + let double_consensus_operation_evidence_case : + Kind.double_consensus_operation_evidence case = Case { tag = 2; - name = "double_attestation_evidence"; + name = "double_consensus_operation_evidence"; encoding = obj2 - (req "op1" (dynamic_size attestation_encoding)) - (req "op2" (dynamic_size attestation_encoding)); + (req "op1" (dynamic_size inlined_consensus_operation_encoding)) + (req "op2" (dynamic_size inlined_consensus_operation_encoding)); select = (function - | Contents (Double_attestation_evidence _ as op) -> Some op + | Contents (Double_consensus_operation_evidence _ as op) -> Some op | _ -> None); - proj = (fun (Double_attestation_evidence {op1; op2}) -> (op1, op2)); - inj = (fun (op1, op2) -> Double_attestation_evidence {op1; op2}); + proj = + (fun (Double_consensus_operation_evidence {op1; op2}) -> + (Consensus_op op1, Consensus_op op2)); + inj = + (fun (Consensus_op op1, Consensus_op op2) -> + Double_consensus_operation_evidence {op1; op2}); } + (* Note: tag = 7 was used for Double_preattestation_evidence, before + it was merged with Double_attestation_evidence into + Double_consensus_operation_evidence. It is now free. *) + let double_baking_evidence_case = Case { @@ -1688,8 +1604,7 @@ module Encoding = struct [ PCase attestations_aggregate_case; PCase preattestations_aggregate_case; - PCase double_preattestation_evidence_case; - PCase double_attestation_evidence_case; + PCase double_consensus_operation_evidence_case; PCase seed_nonce_revelation_case; PCase vdf_revelation_case; PCase double_baking_evidence_case; @@ -2035,8 +1950,7 @@ let acceptable_pass (op : packed_operation) = | Single (Ballot _) -> Some voting_pass | Single (Seed_nonce_revelation _) -> Some anonymous_pass | Single (Vdf_revelation _) -> Some anonymous_pass - | Single (Double_attestation_evidence _) -> Some anonymous_pass - | Single (Double_preattestation_evidence _) -> Some anonymous_pass + | Single (Double_consensus_operation_evidence _) -> Some anonymous_pass | Single (Double_baking_evidence _) -> Some anonymous_pass | Single (Dal_entrapment_evidence _) -> Some anonymous_pass | Single (Activate_account _) -> Some anonymous_pass @@ -2131,11 +2045,10 @@ let check_signature (type kind) encoding key chain_id (op : kind operation) = | Single (Attestation _) -> to_watermark (Attestation chain_id) | Single ( Failing_noop _ | Proposals _ | Ballot _ | Seed_nonce_revelation _ - | Vdf_revelation _ | Double_attestation_evidence _ - | Double_preattestation_evidence _ | Double_baking_evidence _ - | Dal_entrapment_evidence _ | Activate_account _ | Drain_delegate _ - | Manager_operation _ | Preattestations_aggregate _ - | Attestations_aggregate _ ) -> + | Vdf_revelation _ | Double_consensus_operation_evidence _ + | Double_baking_evidence _ | Dal_entrapment_evidence _ + | Activate_account _ | Drain_delegate _ | Manager_operation _ + | Preattestations_aggregate _ | Attestations_aggregate _ ) -> Generic_operation | Cons (Manager_operation _, _ops) -> Generic_operation in @@ -2223,11 +2136,10 @@ let equal_contents_kind : type a b. a contents -> b contents -> (a, b) eq option | Seed_nonce_revelation _, _ -> None | Vdf_revelation _, Vdf_revelation _ -> Some Eq | Vdf_revelation _, _ -> None - | Double_attestation_evidence _, Double_attestation_evidence _ -> Some Eq - | Double_attestation_evidence _, _ -> None - | Double_preattestation_evidence _, Double_preattestation_evidence _ -> + | Double_consensus_operation_evidence _, Double_consensus_operation_evidence _ + -> Some Eq - | Double_preattestation_evidence _, _ -> None + | Double_consensus_operation_evidence _, _ -> None | Double_baking_evidence _, Double_baking_evidence _ -> Some Eq | Double_baking_evidence _, _ -> None | Dal_entrapment_evidence _, Dal_entrapment_evidence _ -> Some Eq @@ -2343,19 +2255,27 @@ type attestation_infos = { {!block_header} hash. *) type double_baking_infos = {round : round_infos; bh_hash : Block_hash.t} -(** Compute a {!round_infos} from a {consensus_content} of a valid - operation. Hence, the [round] must convert in {!int}. +(** Builds {!type-round_infos} from [level] and [round], handling the + conversions from protocol types to integers. - Precondition: [c] comes from a valid operation. The [round] from a - valid operation should succeed to convert in {!int}. Hence, for the - unreachable path where the convertion failed, we put (-1) as - [round] value. *) -let round_infos_from_consensus_content (c : consensus_content) = - let level = Raw_level_repr.to_int32 c.level in - match Round_repr.to_int c.round with + Precondition: [level] and [round] come from the consensus content + of a valid operation. This means that [round] should successfully + convert to {!int}. Hence, for the unreachable path where the + convertion failed, we put (-1) as [round] value. *) +let round_infos ~level ~round = + let level = Raw_level_repr.to_int32 level in + match Round_repr.to_int round with | Ok round -> {level; round} | Error _ -> {level; round = -1} +(** Builds {!type-round_infos} from a {!consensus_content}. + + Precondition: the {!consensus_content} comes from a valid + operation; see {!val-round_infos}. *) +let round_infos_from_consensus_content + {level; round; block_payload_hash = _; slot = _} = + round_infos ~level ~round + (** Compute a {!attestation_infos} from a {!consensus_content}. It is used to compute the weight of {!Attestation} and {!Preattestation}. @@ -2412,6 +2332,24 @@ let aggregate_infos_from_content (proposal : consensus_aggregate_content) let committee = List.map Slot_repr.to_int committee in {round = round_infos; committee} +(** Computes {!type-round_infos} from the contents of a + [Double_consensus_operation_evidence] operation. Used to compute + the weight of such an operation. + + Precondition: the contents comes from a valid operation; see + {!val-round_infos}. *) +let round_infos_from_double_consensus + (Double_consensus_operation_evidence {op1; _}) = + match op1.protocol_data.contents with + | Single + (Attestation {consensus_content; _} | Preattestation consensus_content) -> + round_infos_from_consensus_content consensus_content + | Single + ( Attestations_aggregate {consensus_content = {level; round; _}; _} + | Preattestations_aggregate {consensus_content = {level; round; _}; _} ) + -> + round_infos ~level ~round + (** Compute a {!double_baking_infos} and a {!Block_header_repr.hash} from a {!Block_header_repr.t}. It is used to compute the weight of a {!Double_baking_evidence}. @@ -2519,8 +2457,9 @@ type _ weight = -> voting_pass_type weight | Weight_seed_nonce_revelation : int32 -> anonymous_pass_type weight | Weight_vdf_revelation : Seed_repr.vdf_solution -> anonymous_pass_type weight - | Weight_double_preattestation : round_infos -> anonymous_pass_type weight - | Weight_double_attestation : round_infos -> anonymous_pass_type weight + | Weight_double_consensus_operation : + round_infos + -> anonymous_pass_type weight | Weight_double_baking : double_baking_infos -> anonymous_pass_type weight | Weight_dal_entrapment_evidence : dal_entrapment_info @@ -2632,20 +2571,11 @@ let weight_of : packed_operation -> operation_weight = W (Anonymous, Weight_seed_nonce_revelation (Raw_level_repr.to_int32 level)) | Single (Vdf_revelation {solution}) -> W (Anonymous, Weight_vdf_revelation solution) - | Single (Double_attestation_evidence {op1; _}) -> ( - match op1.protocol_data.contents with - | Single (Attestation {consensus_content; dal_content = _}) -> - W - ( Anonymous, - Weight_double_attestation - (round_infos_from_consensus_content consensus_content) )) - | Single (Double_preattestation_evidence {op1; _}) -> ( - match op1.protocol_data.contents with - | Single (Preattestation consensus_content) -> - W - ( Anonymous, - Weight_double_preattestation - (round_infos_from_consensus_content consensus_content) )) + | Single (Double_consensus_operation_evidence _ as contents) -> + W + ( Anonymous, + Weight_double_consensus_operation + (round_infos_from_double_consensus contents) ) | Single (Double_baking_evidence {bh1; _}) -> let double_baking_infos = consensus_infos_and_hash_from_block_header bh1 @@ -2826,10 +2756,8 @@ let compare_vote_weight w1 w2 = (** {5 Comparison of valid anonymous operations} *) -(** Comparing two {!Double_attestation_evidence}, or two - {!Double_preattestation_evidence}, or comparing them to each other - is comparing their {!round_infos}, see {!compare_round_infos} for - more details. +(** Comparing two {!Double_consensus_operation_evidence} is comparing + their {!round_infos}, see {!compare_round_infos} for more details. Comparing two {!Double_baking_evidence} is comparing as their {!double_baking_infos}, see {!compare_double_baking_infos} for more @@ -2845,27 +2773,20 @@ let compare_vote_weight w1 w2 = Two {!Activate_account} are compared as their [id]. When comparing different kind of anonymous operations, the order is as - follows: {!Double_preattestation_evidence} > {!Double_attestation_evidence} > + follows: {!Double_consensus_operation_evidence} > {!Double_baking_evidence} > {!Dal_entrapment_evidence} > {!Vdf_revelation} > {!Seed_nonce_revelation} > {!Activate_account}. *) let compare_anonymous_weight w1 w2 = match (w1, w2) with - | Weight_double_preattestation infos1, Weight_double_preattestation infos2 -> - compare_round_infos infos1 infos2 - | Weight_double_preattestation infos1, Weight_double_attestation infos2 -> - let cmp = compare_round_infos infos1 infos2 in - if Compare.Int.(cmp <> 0) then cmp else 1 - | Weight_double_attestation infos1, Weight_double_preattestation infos2 -> - let cmp = compare_round_infos infos1 infos2 in - if Compare.Int.(cmp <> 0) then cmp else -1 - | Weight_double_attestation infos1, Weight_double_attestation infos2 -> + | ( Weight_double_consensus_operation infos1, + Weight_double_consensus_operation infos2 ) -> compare_round_infos infos1 infos2 | ( ( Weight_double_baking _ | Weight_dal_entrapment_evidence _ | Weight_seed_nonce_revelation _ | Weight_vdf_revelation _ | Weight_activate_account _ | Weight_drain_delegate _ ), - (Weight_double_preattestation _ | Weight_double_attestation _) ) -> + Weight_double_consensus_operation _ ) -> -1 - | ( (Weight_double_preattestation _ | Weight_double_attestation _), + | ( Weight_double_consensus_operation _, ( Weight_double_baking _ | Weight_dal_entrapment_evidence _ | Weight_seed_nonce_revelation _ | Weight_vdf_revelation _ | Weight_activate_account _ | Weight_drain_delegate _ ) ) -> diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index 7addb3306a9a..d1d9f6ed75ed 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -95,15 +95,9 @@ module Kind : sig type vdf_revelation = Vdf_revelation_kind - type 'a double_consensus_operation_evidence = + type double_consensus_operation_evidence = | Double_consensus_operation_evidence - type double_attestation_evidence = - attestation_consensus_kind double_consensus_operation_evidence - - type double_preattestation_evidence = - preattestation_consensus_kind double_consensus_operation_evidence - type double_baking_evidence = Double_baking_evidence_kind type dal_entrapment_evidence = Dal_entrapment_evidence_kind @@ -310,27 +304,20 @@ and _ contents = solution : Seed_repr.vdf_solution; } -> Kind.vdf_revelation contents - (* Double_preattestation_evidence: Double-preattestation is a - kind of malicious attack where a byzantine attempts to fork - the chain by preattesting blocks with different - contents (at the same level and same round) - twice. This behavior may be reported and the byzantine will have - its security deposit forfeited. *) - | Double_preattestation_evidence : { - op1 : Kind.preattestation operation; - op2 : Kind.preattestation operation; + (* Double_consensus_operation_evidence: Double-consensus-operation + is a kind of malicious attack where a byzantine attempts to fork + the chain by preattesting or attesting two blocks at the same + level and round with different payloads. This behavior may be + reported and the byzantine will have its security deposit + forfeited. *) + | Double_consensus_operation_evidence : { + op1 : 'a Kind.consensus operation; + op2 : 'b Kind.consensus operation; } - -> Kind.double_preattestation_evidence contents - (* Double_attestation_evidence: Similar to double-preattestation but - for attestations. *) - | Double_attestation_evidence : { - op1 : Kind.attestation operation; - op2 : Kind.attestation operation; - } - -> Kind.double_attestation_evidence contents - (* Double_baking_evidence: Similarly to double-attestation but the - byzantine attempts to fork by signing two different blocks at the - same level. *) + -> Kind.double_consensus_operation_evidence contents + (* Double_baking_evidence: Similarly to + Double_consensus_operation_evidence but the byzantine attempts to + fork by signing two different blocks at the same level. *) | Double_baking_evidence : { bh1 : Block_header_repr.t; bh2 : Block_header_repr.t; @@ -768,10 +755,8 @@ module Encoding : sig val vdf_revelation_case : Kind.vdf_revelation case - val double_preattestation_evidence_case : - Kind.double_preattestation_evidence case - - val double_attestation_evidence_case : Kind.double_attestation_evidence case + val double_consensus_operation_evidence_case : + Kind.double_consensus_operation_evidence case val double_baking_evidence_case : Kind.double_baking_evidence case diff --git a/src/proto_alpha/lib_protocol/test/helpers/block.ml b/src/proto_alpha/lib_protocol/test/helpers/block.ml index 954faaac3d08..2a04bea46b27 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/block.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/block.ml @@ -1172,8 +1172,7 @@ let balance_updates_of_single_content : | Attestations_aggregate_result {balance_updates; _} | Seed_nonce_revelation_result balance_updates | Vdf_revelation_result balance_updates - | Double_attestation_evidence_result {balance_updates; _} - | Double_preattestation_evidence_result {balance_updates; _} + | Double_consensus_operation_evidence_result {balance_updates; _} | Double_baking_evidence_result {balance_updates; _} | Dal_entrapment_evidence_result {balance_updates; _} | Activate_account_result balance_updates diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index 0a1268f8f2c4..faac50e1ee75 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -874,7 +874,7 @@ let activation ctxt (pkh : Signature.Public_key_hash.t) activation_code = } let double_attestation ctxt op1 op2 = - let contents = Single (Double_attestation_evidence {op1; op2}) in + let contents = Single (Double_consensus_operation_evidence {op1; op2}) in let branch = Context.branch ctxt in { shell = {branch}; @@ -882,7 +882,7 @@ let double_attestation ctxt op1 op2 = } let double_preattestation ctxt op1 op2 = - let contents = Single (Double_preattestation_evidence {op1; op2}) in + let contents = Single (Double_consensus_operation_evidence {op1; op2}) in let branch = Context.branch ctxt in { shell = {branch}; diff --git a/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml b/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml index 9983d8ba88eb..26bd7bd9c6c2 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml @@ -55,8 +55,7 @@ let anonymous_kinds = [ `KSeed_nonce_revelation; `KVdf_revelation; - `KDouble_attestation; - `KDouble_preattestation; + `KDouble_consensus_operation; `KDouble_baking; `KActivate_account; ] @@ -101,7 +100,7 @@ let pp_kind fmt k = | `KDal_attestation -> "KDal_attestation" | `KSeed_nonce_revelation -> "KSeed_nonce_revelation" | `KVdf_revelation -> "KVdf_revelation" - | `KDouble_attestation -> "KDouble_attestation" + | `KDouble_consensus_operation -> "KDouble_consensus_operation" | `KDouble_preattestation -> "KDouble_preattestation" | `KDouble_baking -> "KDouble_baking" | `KActivate_account -> "KActivate_account" @@ -397,17 +396,16 @@ let generate_seed_nonce_revelation = let+ nonce = random_nonce in Seed_nonce_revelation {level; nonce} -let generate_double_preattestation = +let generate_double_consensus_operation = let open QCheck2.Gen in - let* op1 = generate_op generate_preattestation in - let+ op2 = generate_op generate_preattestation in - Double_preattestation_evidence {op1; op2} - -let generate_double_attestation = - let open QCheck2.Gen in - let* op1 = generate_op generate_attestation in - let+ op2 = generate_op generate_attestation in - Double_attestation_evidence {op1; op2} + (* TODO: https://gitlab.com/tezos/tezos/-/issues/7971 + Generate any combination of preattestation, attestation, + attestation with DAL, attestations aggregate, preattestations + aggregate *) + let generate_consensus_operation = generate_preattestation in + let* op1 = generate_op generate_consensus_operation in + let+ op2 = generate_op generate_consensus_operation in + Double_consensus_operation_evidence {op1; op2} let generate_double_baking = let open QCheck2.Gen in @@ -636,8 +634,8 @@ let generate_non_manager_operation = | `KAttestation -> generate_operation generate_attestation | `KSeed_nonce_revelation -> generate_operation generate_seed_nonce_revelation | `KVdf_revelation -> generate_operation generate_vdf_revelation - | `KDouble_attestation -> generate_operation generate_double_attestation - | `KDouble_preattestation -> generate_operation generate_double_preattestation + | `KDouble_consensus_operation -> + generate_operation generate_double_consensus_operation | `KDouble_baking -> generate_operation generate_double_baking | `KActivate_account -> generate_operation generate_activate_account | `KProposals -> generate_operation generate_proposals @@ -710,9 +708,8 @@ let generate_operation = | `KSeed_nonce_revelation -> generate_operation generate_seed_nonce_revelation | `KVdf_revelation -> generate_operation generate_vdf_revelation - | `KDouble_attestation -> generate_operation generate_double_attestation - | `KDouble_preattestation -> - generate_operation generate_double_preattestation + | `KDouble_consensus_operation -> + generate_operation generate_double_consensus_operation | `KDouble_baking -> generate_operation generate_double_baking | `KActivate_account -> generate_operation generate_activate_account | `KProposals -> generate_operation generate_proposals diff --git a/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml index 807f2ec9cb33..6efc104a178d 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml @@ -341,7 +341,8 @@ let test_two_double_attestation_evidences_leadsto_no_bake () = { contents = Apply_results.Single_result - (Apply_results.Double_attestation_evidence_result rslt); + (Apply_results.Double_consensus_operation_evidence_result + rslt); } -> rslt.forbidden_delegate = Some delegate | _ -> false) diff --git a/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml b/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml index 68cc1a482129..b4c6e2c00da8 100644 --- a/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml +++ b/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml @@ -884,8 +884,7 @@ let op_kind_of_packed_operation op = | Single (Preattestations_aggregate _) -> KPreattestations_aggregate | Single (Seed_nonce_revelation _) -> KNonce | Single (Vdf_revelation _) -> KVdf - | Single (Double_attestation_evidence _) -> KDbl_consensus - | Single (Double_preattestation_evidence _) -> KDbl_consensus + | Single (Double_consensus_operation_evidence _) -> KDbl_consensus | Single (Double_baking_evidence _) -> KDbl_baking | Single (Dal_entrapment_evidence _) -> KEntrapment | Single (Activate_account _) -> KActivate diff --git a/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml b/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml index ad39211e9e07..049edb3c2672 100644 --- a/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml +++ b/src/proto_alpha/lib_protocol/test/integration/validate/test_sanity.ml @@ -119,12 +119,9 @@ let covalidation_sanity () = | Single (Seed_nonce_revelation _), _ -> assert false | Single (Vdf_revelation _), KVdf -> return_unit | Single (Vdf_revelation _), _ -> assert false - | Single (Double_attestation_evidence _), KDbl_consensus -> + | Single (Double_consensus_operation_evidence _), KDbl_consensus -> return_unit - | Single (Double_attestation_evidence _), _ -> assert false - | Single (Double_preattestation_evidence _), KDbl_consensus -> - return_unit - | Single (Double_preattestation_evidence _), _ -> assert false + | Single (Double_consensus_operation_evidence _), _ -> assert false | Single (Double_baking_evidence _), KDbl_baking -> return_unit | Single (Double_baking_evidence _), _ -> assert false | Single (Dal_entrapment_evidence _), KEntrapment -> return_unit diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index bfc337f2d18a..3590152d78de 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -230,7 +230,7 @@ end type anonymous_state = { activation_pkhs_seen : Operation_hash.t Ed25519.Public_key_hash.Map.t; double_baking_evidences_seen : Operation_hash.t Double_baking_evidence_map.t; - double_attesting_evidences_seen : + double_consensus_operation_evidences_seen : Operation_hash.t Double_operation_evidence_map.t; dal_entrapments_seen : Operation_hash.t Dal_entrapment_map.t; seed_nonce_levels_seen : Operation_hash.t Raw_level.Map.t; @@ -252,27 +252,27 @@ let anonymous_state_encoding = (fun { activation_pkhs_seen; double_baking_evidences_seen; - double_attesting_evidences_seen; + double_consensus_operation_evidences_seen; dal_entrapments_seen; seed_nonce_levels_seen; vdf_solution_seen; } -> ( activation_pkhs_seen, double_baking_evidences_seen, - double_attesting_evidences_seen, + double_consensus_operation_evidences_seen, dal_entrapments_seen, seed_nonce_levels_seen, vdf_solution_seen )) (fun ( activation_pkhs_seen, double_baking_evidences_seen, - double_attesting_evidences_seen, + double_consensus_operation_evidences_seen, dal_entrapments_seen, seed_nonce_levels_seen, vdf_solution_seen ) -> { activation_pkhs_seen; double_baking_evidences_seen; - double_attesting_evidences_seen; + double_consensus_operation_evidences_seen; dal_entrapments_seen; seed_nonce_levels_seen; vdf_solution_seen; @@ -285,7 +285,7 @@ let anonymous_state_encoding = "double_baking_evidences_seen" (Double_baking_evidence_map.encoding Operation_hash.encoding)) (req - "double_attesting_evidences_seen" + "double_consensus_operation_evidences_seen" (Double_operation_evidence_map.encoding Operation_hash.encoding)) (req "dal_entrapments_seen" @@ -299,7 +299,8 @@ let empty_anonymous_state = { activation_pkhs_seen = Ed25519.Public_key_hash.Map.empty; double_baking_evidences_seen = Double_baking_evidence_map.empty; - double_attesting_evidences_seen = Double_operation_evidence_map.empty; + double_consensus_operation_evidences_seen = + Double_operation_evidence_map.empty; dal_entrapments_seen = Dal_entrapment_map.empty; seed_nonce_levels_seen = Raw_level.Map.empty; vdf_solution_seen = None; @@ -2022,10 +2023,19 @@ module Anonymous = struct Consensus.check_attestations_aggregate_signature vi pks weighted_pks op |> Lwt.return - let check_double_attesting_evidence (type kind) vi - (op1 : kind Kind.consensus Operation.t) - (op2 : kind Kind.consensus Operation.t) = + let misbehaviour_kind (type a) (op : a Kind.consensus operation) = + match op.protocol_data.contents with + | Single (Preattestation _ | Preattestations_aggregate _) -> + Misbehaviour.Double_preattesting + | Single (Attestation _ | Attestations_aggregate _) -> + Misbehaviour.Double_attesting + + let check_double_consensus_operation_evidence vi + (operation : Kind.double_consensus_operation_evidence operation) = let open Lwt_result_syntax in + let (Single (Double_consensus_operation_evidence {op1; op2})) = + operation.protocol_data.contents + in let* e1, e2, kind = match (op1.protocol_data.contents, op2.protocol_data.contents) with | Single (Preattestation e1), Single (Preattestation e2) -> @@ -2033,9 +2043,12 @@ module Anonymous = struct | ( Single (Attestation {consensus_content = e1; dal_content = _}), Single (Attestation {consensus_content = e2; dal_content = _}) ) -> return (e1, e2, Misbehaviour.Double_attesting) - | ( Single (Preattestations_aggregate _), - Single (Preattestations_aggregate _) ) - | Single (Attestations_aggregate _), Single (Attestations_aggregate _) -> + | Single (Preattestation _), Single (Attestation _) + | Single (Attestation _), Single (Preattestation _) -> + (* Incompatible kind *) + tzfail (Invalid_denunciation Double_preattesting) + | Single (Preattestations_aggregate _ | Attestations_aggregate _), _ + | _, Single (Preattestations_aggregate _ | Attestations_aggregate _) -> (* TODO : https://gitlab.com/tezos/tezos/-/issues/7598 handle denunciation for aggregates. *) tzfail Aggregate_denunciation_not_implemented @@ -2100,107 +2113,72 @@ module Anonymous = struct let*? () = Operation.check_signature vi.ctxt delegate_pk vi.chain_id op2 in return_unit - let check_double_preattestation_evidence vi - (operation : Kind.double_preattestation_evidence operation) = - let (Single (Double_preattestation_evidence {op1; op2})) = - operation.protocol_data.contents - in - check_double_attesting_evidence vi op1 op2 - - let check_double_attestation_evidence vi - (operation : Kind.double_attestation_evidence operation) = - let (Single (Double_attestation_evidence {op1; op2})) = - operation.protocol_data.contents - in - check_double_attesting_evidence vi op1 op2 - - let check_double_attesting_evidence_conflict vs oph key = + let check_double_consensus_operation_evidence_conflict vs oph key = match Double_operation_evidence_map.find key - vs.anonymous_state.double_attesting_evidences_seen + vs.anonymous_state.double_consensus_operation_evidences_seen with | None -> ok_unit | Some existing -> Error (Operation_conflict {existing; new_operation = oph}) - let conflict_key_of_double_preattestation - (operation : Kind.double_preattestation_evidence operation) = - let (Single (Double_preattestation_evidence {op1; _})) = + let conflict_key_of_double_consensus_operation + (operation : Kind.double_consensus_operation_evidence operation) = + let (Single (Double_consensus_operation_evidence {op1; _})) = operation.protocol_data.contents in match op1.protocol_data.contents with | Single (Preattestation {slot; level; round; _}) -> (level, round, slot, Misbehaviour.Double_preattesting) - - let conflict_key_of_double_attestation - (operation : Kind.double_attestation_evidence operation) = - let (Single (Double_attestation_evidence {op1; _})) = - operation.protocol_data.contents - in - match op1.protocol_data.contents with | Single (Attestation {consensus_content; _}) -> let {slot; level; round; _} = consensus_content in (level, round, slot, Misbehaviour.Double_attesting) + | Single (Preattestations_aggregate _ | Attestations_aggregate _) -> + (* TODO : https://gitlab.com/tezos/tezos/-/issues/7598 + handle denunciation for aggregates. *) + assert false - let check_double_preattestation_evidence_conflict vs oph - (operation : Kind.double_preattestation_evidence operation) = - let key = conflict_key_of_double_preattestation operation in - check_double_attesting_evidence_conflict vs oph key - - let check_double_attestation_evidence_conflict vs oph - (operation : Kind.double_attestation_evidence operation) = - let key = conflict_key_of_double_attestation operation in - check_double_attesting_evidence_conflict vs oph key + let check_double_consensus_operation_evidence_conflict vs oph + (operation : Kind.double_consensus_operation_evidence operation) = + let key = conflict_key_of_double_consensus_operation operation in + check_double_consensus_operation_evidence_conflict vs oph key let wrap_denunciation_conflict kind = function | Ok () -> ok_unit | Error conflict -> result_error (Conflicting_denunciation {kind; conflict}) - let add_double_attesting_evidence vs oph key = - let double_attesting_evidences_seen = + let add_double_consensus_operation_evidence vs oph key = + let double_consensus_operation_evidences_seen = Double_operation_evidence_map.add key oph - vs.anonymous_state.double_attesting_evidences_seen + vs.anonymous_state.double_consensus_operation_evidences_seen in { vs with anonymous_state = - {vs.anonymous_state with double_attesting_evidences_seen}; + {vs.anonymous_state with double_consensus_operation_evidences_seen}; } - let add_double_attestation_evidence vs oph - (operation : Kind.double_attestation_evidence operation) = - let key = conflict_key_of_double_attestation operation in - add_double_attesting_evidence vs oph key + let add_double_consensus_operation_evidence vs oph + (operation : Kind.double_consensus_operation_evidence operation) = + let key = conflict_key_of_double_consensus_operation operation in + add_double_consensus_operation_evidence vs oph key - let add_double_preattestation_evidence vs oph - (operation : Kind.double_preattestation_evidence operation) = - let key = conflict_key_of_double_preattestation operation in - add_double_attesting_evidence vs oph key - - let remove_double_attesting_evidence vs key = - let double_attesting_evidences_seen = + let remove_double_consensus_operation_evidence vs + (operation : Kind.double_consensus_operation_evidence operation) = + let key = conflict_key_of_double_consensus_operation operation in + let double_consensus_operation_evidences_seen = Double_operation_evidence_map.remove key - vs.anonymous_state.double_attesting_evidences_seen + vs.anonymous_state.double_consensus_operation_evidences_seen in let anonymous_state = - {vs.anonymous_state with double_attesting_evidences_seen} + {vs.anonymous_state with double_consensus_operation_evidences_seen} in {vs with anonymous_state} - let remove_double_preattestation_evidence vs - (operation : Kind.double_preattestation_evidence operation) = - let key = conflict_key_of_double_preattestation operation in - remove_double_attesting_evidence vs key - - let remove_double_attestation_evidence vs - (operation : Kind.double_attestation_evidence operation) = - let key = conflict_key_of_double_attestation operation in - remove_double_attesting_evidence vs key - let check_double_baking_evidence vi (operation : Kind.double_baking_evidence operation) = let open Lwt_result_syntax in @@ -3528,11 +3506,8 @@ let check_operation ?(check_signature = true) info (type kind) | Single (Ballot _) -> Voting.check_ballot info ~check_signature operation | Single (Activate_account _) -> Anonymous.check_activate_account info operation |> no_pending_checks - | Single (Double_preattestation_evidence _) -> - Anonymous.check_double_preattestation_evidence info operation - |> no_pending_checks - | Single (Double_attestation_evidence _) -> - Anonymous.check_double_attestation_evidence info operation + | Single (Double_consensus_operation_evidence _) -> + Anonymous.check_double_consensus_operation_evidence info operation |> no_pending_checks | Single (Double_baking_evidence _) -> Anonymous.check_double_baking_evidence info operation |> no_pending_checks @@ -3595,13 +3570,8 @@ let check_operation_conflict (type kind) operation_conflict_state oph operation_conflict_state oph operation - | Single (Double_preattestation_evidence _) -> - Anonymous.check_double_preattestation_evidence_conflict - operation_conflict_state - oph - operation - | Single (Double_attestation_evidence _) -> - Anonymous.check_double_attestation_evidence_conflict + | Single (Double_consensus_operation_evidence _) -> + Anonymous.check_double_consensus_operation_evidence_conflict operation_conflict_state oph operation @@ -3656,13 +3626,8 @@ let add_valid_operation operation_conflict_state oph (type kind) Voting.add_ballot operation_conflict_state oph operation | Single (Activate_account _) -> Anonymous.add_activate_account operation_conflict_state oph operation - | Single (Double_preattestation_evidence _) -> - Anonymous.add_double_preattestation_evidence - operation_conflict_state - oph - operation - | Single (Double_attestation_evidence _) -> - Anonymous.add_double_attestation_evidence + | Single (Double_consensus_operation_evidence _) -> + Anonymous.add_double_consensus_operation_evidence operation_conflict_state oph operation @@ -3707,12 +3672,8 @@ let remove_operation operation_conflict_state (type kind) | Single (Ballot _) -> Voting.remove_ballot operation_conflict_state operation | Single (Activate_account _) -> Anonymous.remove_activate_account operation_conflict_state operation - | Single (Double_preattestation_evidence _) -> - Anonymous.remove_double_preattestation_evidence - operation_conflict_state - operation - | Single (Double_attestation_evidence _) -> - Anonymous.remove_double_attestation_evidence + | Single (Double_consensus_operation_evidence _) -> + Anonymous.remove_double_consensus_operation_evidence operation_conflict_state operation | Single (Double_baking_evidence _) -> @@ -3851,32 +3812,21 @@ let validate_operation ?(check_signature = true) add_activate_account operation_state oph operation in return {info; operation_state; block_state} - | Single (Double_preattestation_evidence _) -> + | Single (Double_consensus_operation_evidence {op1; _}) -> let open Anonymous in - let* () = check_double_preattestation_evidence info operation in + let* () = check_double_consensus_operation_evidence info operation in let*? () = - check_double_preattestation_evidence_conflict + check_double_consensus_operation_evidence_conflict operation_state oph operation - |> wrap_denunciation_conflict Double_preattesting + |> wrap_denunciation_conflict (misbehaviour_kind op1) in let operation_state = - add_double_preattestation_evidence operation_state oph operation - in - return {info; operation_state; block_state} - | Single (Double_attestation_evidence _) -> - let open Anonymous in - let* () = check_double_attestation_evidence info operation in - let*? () = - check_double_attestation_evidence_conflict + add_double_consensus_operation_evidence operation_state oph operation - |> wrap_denunciation_conflict Double_attesting - in - let operation_state = - add_double_attestation_evidence operation_state oph operation in return {info; operation_state; block_state} | Single (Double_baking_evidence _) -> diff --git a/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml b/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml index 02fdc9bf91ca..70514bb17bd9 100644 --- a/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml +++ b/src/proto_alpha/lib_sc_rollup_node/sc_rollup_injector.ml @@ -211,8 +211,7 @@ module Proto_client = struct | Attestations_aggregate_result _ -> Successful | Seed_nonce_revelation_result _ -> Successful | Vdf_revelation_result _ -> Successful - | Double_attestation_evidence_result _ -> Successful - | Double_preattestation_evidence_result _ -> Successful + | Double_consensus_operation_evidence_result _ -> Successful | Double_baking_evidence_result _ -> Successful | Dal_entrapment_evidence_result _ -> Successful | Activate_account_result _ -> Successful -- GitLab From 52cc0b1a4be1371735e28d8bffd4055a3d2d22b9 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Fri, 16 May 2025 15:12:49 +0200 Subject: [PATCH 02/10] kaitai: update encodings for double_consensus_operation_evidence Generated with: dune exec -- client-libs/bin_codec_kaitai/codec.exe dump kaitai specs in client-libs/kaitai-struct-files/files --- .../files/alpha__operation.ksy | 102 ++---------------- .../alpha__operation__bls_mode_unsigned.ksy | 102 ++---------------- .../files/alpha__operation__contents.ksy | 102 ++---------------- .../files/alpha__operation__contents_list.ksy | 102 ++---------------- .../files/alpha__operation__protocol_data.ksy | 102 ++---------------- .../files/alpha__operation__unsigned.ksy | 102 ++---------------- 6 files changed, 54 insertions(+), 558 deletions(-) diff --git a/client-libs/kaitai-struct-files/files/alpha__operation.ksy b/client-libs/kaitai-struct-files/files/alpha__operation.ksy index 656b7ad70349..567cb496a3d6 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation.ksy @@ -68,29 +68,6 @@ types: - id: named type: named_0 if: (alpha__entrypoint_tag == alpha__entrypoint_tag::named) - alpha__inlined__attestation: - seq: - - id: alpha__inlined__attestation - type: operation__shell_header - - id: operations - type: alpha__inlined__attestation_mempool__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__attestation_mempool__contents: - seq: - - id: alpha__inlined__attestation_mempool__contents_tag - type: u1 - enum: alpha__inlined__attestation_mempool__contents_tag - - id: attestation - type: attestation - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation) - - id: attestation_with_dal - type: attestation_with_dal - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation_with_dal) alpha__inlined__consensus_operation: seq: - id: alpha__inlined__consensus_operation @@ -123,26 +100,6 @@ types: - id: attestations_aggregate type: attestations_aggregate if: (alpha__inlined__consensus_operation__contents_tag == alpha__inlined__consensus_operation__contents_tag::attestations_aggregate) - alpha__inlined__preattestation: - seq: - - id: alpha__inlined__preattestation - type: operation__shell_header - - id: operations - type: alpha__inlined__preattestation__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__preattestation__contents: - seq: - - id: alpha__inlined__preattestation__contents_tag - type: u1 - enum: alpha__inlined__preattestation__contents_tag - - id: preattestation - type: preattestation - if: (alpha__inlined__preattestation__contents_tag == alpha__inlined__preattestation__contents_tag::preattestation) alpha__michelson__v1__primitives: seq: - id: alpha__michelson__v1__primitives @@ -183,12 +140,9 @@ types: - id: preattestations_aggregate type: preattestations_aggregate if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::preattestations_aggregate) - - id: double_preattestation_evidence - type: double_preattestation_evidence - if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::double_preattestation_evidence) - - id: double_attestation_evidence - type: double_attestation_evidence - if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::double_attestation_evidence) + - id: double_consensus_operation_evidence + type: double_consensus_operation_evidence + if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::double_consensus_operation_evidence) - id: seed_nonce_revelation type: seed_nonce_revelation if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::seed_nonce_revelation) @@ -574,19 +528,13 @@ types: if: (state_tag == bool::true) - id: tick type: n - double_attestation_evidence: - seq: - - id: op1 - type: op1_2 - - id: op2 - type: op2_2 double_baking_evidence: seq: - id: bh1 type: bh1_0 - id: bh2 type: bh2_0 - double_preattestation_evidence: + double_consensus_operation_evidence: seq: - id: op1 type: op1_0 @@ -779,8 +727,8 @@ types: repeat: eos op1: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op1_0: seq: - id: len_op1 @@ -790,23 +738,10 @@ types: - id: op1 type: op1 size: len_op1 - op1_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op1_2: - seq: - - id: len_op1 - type: u4be - valid: - max: 1073741823 - - id: op1 - type: op1_1 - size: len_op1 op2: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op2_0: seq: - id: len_op2 @@ -816,19 +751,6 @@ types: - id: op2 type: op2 size: len_op2 - op2_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op2_2: - seq: - - id: len_op2 - type: u4be - valid: - max: 1073741823 - - id: op2 - type: op2_1 - size: len_op2 op_0: seq: - id: len_op @@ -1680,17 +1602,12 @@ enums: 8: finalize_unstake 9: set_delegate_parameters 255: named - alpha__inlined__attestation_mempool__contents_tag: - 21: attestation - 23: attestation_with_dal alpha__inlined__consensus_operation__contents_tag: 20: preattestation 21: attestation 23: attestation_with_dal 30: preattestations_aggregate 31: attestations_aggregate - alpha__inlined__preattestation__contents_tag: - 20: preattestation alpha__michelson__v1__primitives: 0: parameter 1: storage @@ -2093,12 +2010,11 @@ enums: doc: IS_IMPLICIT_ACCOUNT alpha__operation__alpha__contents_or_signature_prefix_tag: 1: seed_nonce_revelation - 2: double_attestation_evidence + 2: double_consensus_operation_evidence 3: double_baking_evidence 4: activate_account 5: proposals 6: ballot - 7: double_preattestation_evidence 8: vdf_revelation 9: drain_delegate 17: failing_noop diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy index 08c81623cc03..39004930033b 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy @@ -68,29 +68,6 @@ types: - id: named type: named_0 if: (alpha__entrypoint_tag == alpha__entrypoint_tag::named) - alpha__inlined__attestation: - seq: - - id: alpha__inlined__attestation - type: operation__shell_header - - id: operations - type: alpha__inlined__attestation_mempool__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__attestation_mempool__contents: - seq: - - id: alpha__inlined__attestation_mempool__contents_tag - type: u1 - enum: alpha__inlined__attestation_mempool__contents_tag - - id: attestation - type: attestation - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation) - - id: attestation_with_dal - type: attestation_with_dal - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation_with_dal) alpha__inlined__consensus_operation: seq: - id: alpha__inlined__consensus_operation @@ -123,26 +100,6 @@ types: - id: attestations_aggregate type: attestations_aggregate if: (alpha__inlined__consensus_operation__contents_tag == alpha__inlined__consensus_operation__contents_tag::attestations_aggregate) - alpha__inlined__preattestation: - seq: - - id: alpha__inlined__preattestation - type: operation__shell_header - - id: operations - type: alpha__inlined__preattestation__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__preattestation__contents: - seq: - - id: alpha__inlined__preattestation__contents_tag - type: u1 - enum: alpha__inlined__preattestation__contents_tag - - id: preattestation - type: preattestation - if: (alpha__inlined__preattestation__contents_tag == alpha__inlined__preattestation__contents_tag::preattestation) alpha__michelson__v1__primitives: seq: - id: alpha__michelson__v1__primitives @@ -169,12 +126,9 @@ types: - id: preattestations_aggregate type: preattestations_aggregate if: (alpha__operation__alpha__bls_mode_contents_tag == alpha__operation__alpha__bls_mode_contents_tag::preattestations_aggregate) - - id: double_preattestation_evidence - type: double_preattestation_evidence - if: (alpha__operation__alpha__bls_mode_contents_tag == alpha__operation__alpha__bls_mode_contents_tag::double_preattestation_evidence) - - id: double_attestation_evidence - type: double_attestation_evidence - if: (alpha__operation__alpha__bls_mode_contents_tag == alpha__operation__alpha__bls_mode_contents_tag::double_attestation_evidence) + - id: double_consensus_operation_evidence + type: double_consensus_operation_evidence + if: (alpha__operation__alpha__bls_mode_contents_tag == alpha__operation__alpha__bls_mode_contents_tag::double_consensus_operation_evidence) - id: seed_nonce_revelation type: seed_nonce_revelation if: (alpha__operation__alpha__bls_mode_contents_tag == alpha__operation__alpha__bls_mode_contents_tag::seed_nonce_revelation) @@ -575,19 +529,13 @@ types: if: (state_tag == bool::true) - id: tick type: n - double_attestation_evidence: - seq: - - id: op1 - type: op1_2 - - id: op2 - type: op2_2 double_baking_evidence: seq: - id: bh1 type: bh1_0 - id: bh2 type: bh2_0 - double_preattestation_evidence: + double_consensus_operation_evidence: seq: - id: op1 type: op1_0 @@ -780,8 +728,8 @@ types: repeat: eos op1: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op1_0: seq: - id: len_op1 @@ -791,23 +739,10 @@ types: - id: op1 type: op1 size: len_op1 - op1_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op1_2: - seq: - - id: len_op1 - type: u4be - valid: - max: 1073741823 - - id: op1 - type: op1_1 - size: len_op1 op2: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op2_0: seq: - id: len_op2 @@ -817,19 +752,6 @@ types: - id: op2 type: op2 size: len_op2 - op2_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op2_2: - seq: - - id: len_op2 - type: u4be - valid: - max: 1073741823 - - id: op2 - type: op2_1 - size: len_op2 op_0: seq: - id: len_op @@ -1681,17 +1603,12 @@ enums: 8: finalize_unstake 9: set_delegate_parameters 255: named - alpha__inlined__attestation_mempool__contents_tag: - 21: attestation - 23: attestation_with_dal alpha__inlined__consensus_operation__contents_tag: 20: preattestation 21: attestation 23: attestation_with_dal 30: preattestations_aggregate 31: attestations_aggregate - alpha__inlined__preattestation__contents_tag: - 20: preattestation alpha__michelson__v1__primitives: 0: parameter 1: storage @@ -2094,12 +2011,11 @@ enums: doc: IS_IMPLICIT_ACCOUNT alpha__operation__alpha__bls_mode_contents_tag: 1: seed_nonce_revelation - 2: double_attestation_evidence + 2: double_consensus_operation_evidence 3: double_baking_evidence 4: activate_account 5: proposals 6: ballot - 7: double_preattestation_evidence 8: vdf_revelation 9: drain_delegate 17: failing_noop diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy index e86c7cb8db82..29f792a0b5e8 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy @@ -68,29 +68,6 @@ types: - id: named type: named_0 if: (alpha__entrypoint_tag == alpha__entrypoint_tag::named) - alpha__inlined__attestation: - seq: - - id: alpha__inlined__attestation - type: operation__shell_header - - id: operations - type: alpha__inlined__attestation_mempool__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__attestation_mempool__contents: - seq: - - id: alpha__inlined__attestation_mempool__contents_tag - type: u1 - enum: alpha__inlined__attestation_mempool__contents_tag - - id: attestation - type: attestation - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation) - - id: attestation_with_dal - type: attestation_with_dal - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation_with_dal) alpha__inlined__consensus_operation: seq: - id: alpha__inlined__consensus_operation @@ -123,26 +100,6 @@ types: - id: attestations_aggregate type: attestations_aggregate if: (alpha__inlined__consensus_operation__contents_tag == alpha__inlined__consensus_operation__contents_tag::attestations_aggregate) - alpha__inlined__preattestation: - seq: - - id: alpha__inlined__preattestation - type: operation__shell_header - - id: operations - type: alpha__inlined__preattestation__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__preattestation__contents: - seq: - - id: alpha__inlined__preattestation__contents_tag - type: u1 - enum: alpha__inlined__preattestation__contents_tag - - id: preattestation - type: preattestation - if: (alpha__inlined__preattestation__contents_tag == alpha__inlined__preattestation__contents_tag::preattestation) alpha__michelson__v1__primitives: seq: - id: alpha__michelson__v1__primitives @@ -172,12 +129,9 @@ types: - id: preattestations_aggregate type: preattestations_aggregate if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::preattestations_aggregate) - - id: double_preattestation_evidence - type: double_preattestation_evidence - if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_preattestation_evidence) - - id: double_attestation_evidence - type: double_attestation_evidence - if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_attestation_evidence) + - id: double_consensus_operation_evidence + type: double_consensus_operation_evidence + if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_consensus_operation_evidence) - id: seed_nonce_revelation type: seed_nonce_revelation if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::seed_nonce_revelation) @@ -551,19 +505,13 @@ types: if: (state_tag == bool::true) - id: tick type: n - double_attestation_evidence: - seq: - - id: op1 - type: op1_2 - - id: op2 - type: op2_2 double_baking_evidence: seq: - id: bh1 type: bh1_0 - id: bh2 type: bh2_0 - double_preattestation_evidence: + double_consensus_operation_evidence: seq: - id: op1 type: op1_0 @@ -756,8 +704,8 @@ types: repeat: eos op1: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op1_0: seq: - id: len_op1 @@ -767,23 +715,10 @@ types: - id: op1 type: op1 size: len_op1 - op1_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op1_2: - seq: - - id: len_op1 - type: u4be - valid: - max: 1073741823 - - id: op1 - type: op1_1 - size: len_op1 op2: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op2_0: seq: - id: len_op2 @@ -793,19 +728,6 @@ types: - id: op2 type: op2 size: len_op2 - op2_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op2_2: - seq: - - id: len_op2 - type: u4be - valid: - max: 1073741823 - - id: op2 - type: op2_1 - size: len_op2 op_0: seq: - id: len_op @@ -1657,17 +1579,12 @@ enums: 8: finalize_unstake 9: set_delegate_parameters 255: named - alpha__inlined__attestation_mempool__contents_tag: - 21: attestation - 23: attestation_with_dal alpha__inlined__consensus_operation__contents_tag: 20: preattestation 21: attestation 23: attestation_with_dal 30: preattestations_aggregate 31: attestations_aggregate - alpha__inlined__preattestation__contents_tag: - 20: preattestation alpha__michelson__v1__primitives: 0: parameter 1: storage @@ -2070,12 +1987,11 @@ enums: doc: IS_IMPLICIT_ACCOUNT alpha__operation__alpha__contents_tag: 1: seed_nonce_revelation - 2: double_attestation_evidence + 2: double_consensus_operation_evidence 3: double_baking_evidence 4: activate_account 5: proposals 6: ballot - 7: double_preattestation_evidence 8: vdf_revelation 9: drain_delegate 17: failing_noop diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy index f3c0647035f7..17f694df5999 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy @@ -68,29 +68,6 @@ types: - id: named type: named_0 if: (alpha__entrypoint_tag == alpha__entrypoint_tag::named) - alpha__inlined__attestation: - seq: - - id: alpha__inlined__attestation - type: operation__shell_header - - id: operations - type: alpha__inlined__attestation_mempool__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__attestation_mempool__contents: - seq: - - id: alpha__inlined__attestation_mempool__contents_tag - type: u1 - enum: alpha__inlined__attestation_mempool__contents_tag - - id: attestation - type: attestation - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation) - - id: attestation_with_dal - type: attestation_with_dal - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation_with_dal) alpha__inlined__consensus_operation: seq: - id: alpha__inlined__consensus_operation @@ -123,26 +100,6 @@ types: - id: attestations_aggregate type: attestations_aggregate if: (alpha__inlined__consensus_operation__contents_tag == alpha__inlined__consensus_operation__contents_tag::attestations_aggregate) - alpha__inlined__preattestation: - seq: - - id: alpha__inlined__preattestation - type: operation__shell_header - - id: operations - type: alpha__inlined__preattestation__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__preattestation__contents: - seq: - - id: alpha__inlined__preattestation__contents_tag - type: u1 - enum: alpha__inlined__preattestation__contents_tag - - id: preattestation - type: preattestation - if: (alpha__inlined__preattestation__contents_tag == alpha__inlined__preattestation__contents_tag::preattestation) alpha__michelson__v1__primitives: seq: - id: alpha__michelson__v1__primitives @@ -172,12 +129,9 @@ types: - id: preattestations_aggregate type: preattestations_aggregate if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::preattestations_aggregate) - - id: double_preattestation_evidence - type: double_preattestation_evidence - if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_preattestation_evidence) - - id: double_attestation_evidence - type: double_attestation_evidence - if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_attestation_evidence) + - id: double_consensus_operation_evidence + type: double_consensus_operation_evidence + if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_consensus_operation_evidence) - id: seed_nonce_revelation type: seed_nonce_revelation if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::seed_nonce_revelation) @@ -555,19 +509,13 @@ types: if: (state_tag == bool::true) - id: tick type: n - double_attestation_evidence: - seq: - - id: op1 - type: op1_2 - - id: op2 - type: op2_2 double_baking_evidence: seq: - id: bh1 type: bh1_0 - id: bh2 type: bh2_0 - double_preattestation_evidence: + double_consensus_operation_evidence: seq: - id: op1 type: op1_0 @@ -760,8 +708,8 @@ types: repeat: eos op1: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op1_0: seq: - id: len_op1 @@ -771,23 +719,10 @@ types: - id: op1 type: op1 size: len_op1 - op1_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op1_2: - seq: - - id: len_op1 - type: u4be - valid: - max: 1073741823 - - id: op1 - type: op1_1 - size: len_op1 op2: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op2_0: seq: - id: len_op2 @@ -797,19 +732,6 @@ types: - id: op2 type: op2 size: len_op2 - op2_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op2_2: - seq: - - id: len_op2 - type: u4be - valid: - max: 1073741823 - - id: op2 - type: op2_1 - size: len_op2 op_0: seq: - id: len_op @@ -1661,17 +1583,12 @@ enums: 8: finalize_unstake 9: set_delegate_parameters 255: named - alpha__inlined__attestation_mempool__contents_tag: - 21: attestation - 23: attestation_with_dal alpha__inlined__consensus_operation__contents_tag: 20: preattestation 21: attestation 23: attestation_with_dal 30: preattestations_aggregate 31: attestations_aggregate - alpha__inlined__preattestation__contents_tag: - 20: preattestation alpha__michelson__v1__primitives: 0: parameter 1: storage @@ -2074,12 +1991,11 @@ enums: doc: IS_IMPLICIT_ACCOUNT alpha__operation__alpha__contents_tag: 1: seed_nonce_revelation - 2: double_attestation_evidence + 2: double_consensus_operation_evidence 3: double_baking_evidence 4: activate_account 5: proposals 6: ballot - 7: double_preattestation_evidence 8: vdf_revelation 9: drain_delegate 17: failing_noop diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy index 0d1529b6c4e6..23b05b3beeaf 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy @@ -68,29 +68,6 @@ types: - id: named type: named_0 if: (alpha__entrypoint_tag == alpha__entrypoint_tag::named) - alpha__inlined__attestation: - seq: - - id: alpha__inlined__attestation - type: operation__shell_header - - id: operations - type: alpha__inlined__attestation_mempool__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__attestation_mempool__contents: - seq: - - id: alpha__inlined__attestation_mempool__contents_tag - type: u1 - enum: alpha__inlined__attestation_mempool__contents_tag - - id: attestation - type: attestation - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation) - - id: attestation_with_dal - type: attestation_with_dal - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation_with_dal) alpha__inlined__consensus_operation: seq: - id: alpha__inlined__consensus_operation @@ -123,26 +100,6 @@ types: - id: attestations_aggregate type: attestations_aggregate if: (alpha__inlined__consensus_operation__contents_tag == alpha__inlined__consensus_operation__contents_tag::attestations_aggregate) - alpha__inlined__preattestation: - seq: - - id: alpha__inlined__preattestation - type: operation__shell_header - - id: operations - type: alpha__inlined__preattestation__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__preattestation__contents: - seq: - - id: alpha__inlined__preattestation__contents_tag - type: u1 - enum: alpha__inlined__preattestation__contents_tag - - id: preattestation - type: preattestation - if: (alpha__inlined__preattestation__contents_tag == alpha__inlined__preattestation__contents_tag::preattestation) alpha__michelson__v1__primitives: seq: - id: alpha__michelson__v1__primitives @@ -183,12 +140,9 @@ types: - id: preattestations_aggregate type: preattestations_aggregate if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::preattestations_aggregate) - - id: double_preattestation_evidence - type: double_preattestation_evidence - if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::double_preattestation_evidence) - - id: double_attestation_evidence - type: double_attestation_evidence - if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::double_attestation_evidence) + - id: double_consensus_operation_evidence + type: double_consensus_operation_evidence + if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::double_consensus_operation_evidence) - id: seed_nonce_revelation type: seed_nonce_revelation if: (alpha__operation__alpha__contents_or_signature_prefix_tag == alpha__operation__alpha__contents_or_signature_prefix_tag::seed_nonce_revelation) @@ -574,19 +528,13 @@ types: if: (state_tag == bool::true) - id: tick type: n - double_attestation_evidence: - seq: - - id: op1 - type: op1_2 - - id: op2 - type: op2_2 double_baking_evidence: seq: - id: bh1 type: bh1_0 - id: bh2 type: bh2_0 - double_preattestation_evidence: + double_consensus_operation_evidence: seq: - id: op1 type: op1_0 @@ -779,8 +727,8 @@ types: repeat: eos op1: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op1_0: seq: - id: len_op1 @@ -790,23 +738,10 @@ types: - id: op1 type: op1 size: len_op1 - op1_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op1_2: - seq: - - id: len_op1 - type: u4be - valid: - max: 1073741823 - - id: op1 - type: op1_1 - size: len_op1 op2: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op2_0: seq: - id: len_op2 @@ -816,19 +751,6 @@ types: - id: op2 type: op2 size: len_op2 - op2_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op2_2: - seq: - - id: len_op2 - type: u4be - valid: - max: 1073741823 - - id: op2 - type: op2_1 - size: len_op2 op_0: seq: - id: len_op @@ -1680,17 +1602,12 @@ enums: 8: finalize_unstake 9: set_delegate_parameters 255: named - alpha__inlined__attestation_mempool__contents_tag: - 21: attestation - 23: attestation_with_dal alpha__inlined__consensus_operation__contents_tag: 20: preattestation 21: attestation 23: attestation_with_dal 30: preattestations_aggregate 31: attestations_aggregate - alpha__inlined__preattestation__contents_tag: - 20: preattestation alpha__michelson__v1__primitives: 0: parameter 1: storage @@ -2093,12 +2010,11 @@ enums: doc: IS_IMPLICIT_ACCOUNT alpha__operation__alpha__contents_or_signature_prefix_tag: 1: seed_nonce_revelation - 2: double_attestation_evidence + 2: double_consensus_operation_evidence 3: double_baking_evidence 4: activate_account 5: proposals 6: ballot - 7: double_preattestation_evidence 8: vdf_revelation 9: drain_delegate 17: failing_noop diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy index 2f9a95355340..259c6535976a 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy @@ -68,29 +68,6 @@ types: - id: named type: named_0 if: (alpha__entrypoint_tag == alpha__entrypoint_tag::named) - alpha__inlined__attestation: - seq: - - id: alpha__inlined__attestation - type: operation__shell_header - - id: operations - type: alpha__inlined__attestation_mempool__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__attestation_mempool__contents: - seq: - - id: alpha__inlined__attestation_mempool__contents_tag - type: u1 - enum: alpha__inlined__attestation_mempool__contents_tag - - id: attestation - type: attestation - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation) - - id: attestation_with_dal - type: attestation_with_dal - if: (alpha__inlined__attestation_mempool__contents_tag == alpha__inlined__attestation_mempool__contents_tag::attestation_with_dal) alpha__inlined__consensus_operation: seq: - id: alpha__inlined__consensus_operation @@ -123,26 +100,6 @@ types: - id: attestations_aggregate type: attestations_aggregate if: (alpha__inlined__consensus_operation__contents_tag == alpha__inlined__consensus_operation__contents_tag::attestations_aggregate) - alpha__inlined__preattestation: - seq: - - id: alpha__inlined__preattestation - type: operation__shell_header - - id: operations - type: alpha__inlined__preattestation__contents - - id: signature_tag - type: u1 - enum: bool - - id: signature - size-eos: true - if: (signature_tag == bool::true) - alpha__inlined__preattestation__contents: - seq: - - id: alpha__inlined__preattestation__contents_tag - type: u1 - enum: alpha__inlined__preattestation__contents_tag - - id: preattestation - type: preattestation - if: (alpha__inlined__preattestation__contents_tag == alpha__inlined__preattestation__contents_tag::preattestation) alpha__michelson__v1__primitives: seq: - id: alpha__michelson__v1__primitives @@ -172,12 +129,9 @@ types: - id: preattestations_aggregate type: preattestations_aggregate if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::preattestations_aggregate) - - id: double_preattestation_evidence - type: double_preattestation_evidence - if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_preattestation_evidence) - - id: double_attestation_evidence - type: double_attestation_evidence - if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_attestation_evidence) + - id: double_consensus_operation_evidence + type: double_consensus_operation_evidence + if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::double_consensus_operation_evidence) - id: seed_nonce_revelation type: seed_nonce_revelation if: (alpha__operation__alpha__contents_tag == alpha__operation__alpha__contents_tag::seed_nonce_revelation) @@ -562,19 +516,13 @@ types: if: (state_tag == bool::true) - id: tick type: n - double_attestation_evidence: - seq: - - id: op1 - type: op1_2 - - id: op2 - type: op2_2 double_baking_evidence: seq: - id: bh1 type: bh1_0 - id: bh2 type: bh2_0 - double_preattestation_evidence: + double_consensus_operation_evidence: seq: - id: op1 type: op1_0 @@ -767,8 +715,8 @@ types: repeat: eos op1: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op1_0: seq: - id: len_op1 @@ -778,23 +726,10 @@ types: - id: op1 type: op1 size: len_op1 - op1_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op1_2: - seq: - - id: len_op1 - type: u4be - valid: - max: 1073741823 - - id: op1 - type: op1_1 - size: len_op1 op2: seq: - - id: alpha__inlined__preattestation - type: alpha__inlined__preattestation + - id: alpha__inlined__consensus_operation + type: alpha__inlined__consensus_operation op2_0: seq: - id: len_op2 @@ -804,19 +739,6 @@ types: - id: op2 type: op2 size: len_op2 - op2_1: - seq: - - id: alpha__inlined__attestation - type: alpha__inlined__attestation - op2_2: - seq: - - id: len_op2 - type: u4be - valid: - max: 1073741823 - - id: op2 - type: op2_1 - size: len_op2 op_0: seq: - id: len_op @@ -1668,17 +1590,12 @@ enums: 8: finalize_unstake 9: set_delegate_parameters 255: named - alpha__inlined__attestation_mempool__contents_tag: - 21: attestation - 23: attestation_with_dal alpha__inlined__consensus_operation__contents_tag: 20: preattestation 21: attestation 23: attestation_with_dal 30: preattestations_aggregate 31: attestations_aggregate - alpha__inlined__preattestation__contents_tag: - 20: preattestation alpha__michelson__v1__primitives: 0: parameter 1: storage @@ -2081,12 +1998,11 @@ enums: doc: IS_IMPLICIT_ACCOUNT alpha__operation__alpha__contents_tag: 1: seed_nonce_revelation - 2: double_attestation_evidence + 2: double_consensus_operation_evidence 3: double_baking_evidence 4: activate_account 5: proposals 6: ballot - 7: double_preattestation_evidence 8: vdf_revelation 9: drain_delegate 17: failing_noop -- GitLab From f09e466327f401d4de0b671d3f628241fadaaf23 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Fri, 16 May 2025 11:06:34 +0200 Subject: [PATCH 03/10] Tezt: update denunciation operation name --- tezt/tests/double_consensus.ml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tezt/tests/double_consensus.ml b/tezt/tests/double_consensus.ml index f44562e0c0f6..59625d349f7d 100644 --- a/tezt/tests/double_consensus.ml +++ b/tezt/tests/double_consensus.ml @@ -44,7 +44,12 @@ let double_consensus_already_denounced_waiter accuser oph = Accuser.wait_for accuser "double_consensus_already_denounced.v0" (fun json -> if String.equal (JSON.as_string json) oph then Some () else None) -let get_double_consensus_denounciation_hash consensus_name client = +let get_double_consensus_denounciation_hash protocol consensus_name client = + let double_consensus_kind = + if Protocol.(number protocol > number R022) then + "double_consensus_operation_evidence" + else sf "double_%s_evidence" consensus_name + in let* mempool = Client.RPC.call client @@ RPC.get_chain_mempool_pending_operations ~version:"2" () @@ -56,7 +61,7 @@ let get_double_consensus_denounciation_hash consensus_name client = let kind = JSON.(op |-> "contents" |> as_list |> List.hd |-> "kind" |> as_string) in - if String.equal kind (sf "double_%s_evidence" consensus_name) then + if String.equal kind double_consensus_kind then Some JSON.(op |-> "hash" |> as_string) else None) ops @@ -158,7 +163,9 @@ let double_consensus_wrong_block_payload_hash let op = mk_consensus ~slot:(List.nth slots 0) ~level ~round ~block_payload_hash in - let* oph = get_double_consensus_denounciation_hash consensus_name client in + let* oph = + get_double_consensus_denounciation_hash protocol consensus_name client + in let waiter_already_denounced = double_consensus_already_denounced_waiter accuser oph in @@ -236,7 +243,9 @@ let double_consensus_wrong_branch let op = mk_consensus ~slot:(List.nth slots 0) ~level ~round ~block_payload_hash in - let* oph = get_double_consensus_denounciation_hash consensus_name client in + let* oph = + get_double_consensus_denounciation_hash protocol consensus_name client + in let waiter_already_denounced = double_consensus_already_denounced_waiter accuser oph in -- GitLab From 11100c44f2a30c70ea57231f29680cd49e9aa188 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Fri, 16 May 2025 15:35:07 +0200 Subject: [PATCH 04/10] Proto: add slot field to Double_consensus_operation_evidence --- .../lib_client/operation_result.ml | 5 +++- .../client_baking_denunciation.ml | 2 ++ src/proto_alpha/lib_plugin/RPC.ml | 5 ++-- .../lib_protocol/alpha_context.mli | 1 + src/proto_alpha/lib_protocol/apply.ml | 4 ++- .../lib_protocol/operation_repr.ml | 12 +++++---- .../lib_protocol/operation_repr.mli | 1 + .../lib_protocol/test/helpers/op.ml | 27 ++++++++++++------- .../test/helpers/operation_generator.ml | 3 ++- src/proto_alpha/lib_protocol/validate.ml | 2 +- 10 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 938d4ca32632..0fc82b01eca5 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -1077,16 +1077,19 @@ let pp_contents_and_result : (Format.pp_print_list Consensus_key.pp) committee consensus_power - | ( Double_consensus_operation_evidence {op1; op2}, + | ( Double_consensus_operation_evidence {slot; op1; op2}, Double_consensus_operation_evidence_result {forbidden_delegate; balance_updates} ) -> Format.fprintf ppf "@[Double consensus operation evidence:@,\ + Slot: %a@,\ Exhibit A: %a@,\ Exhibit B: %a@,\ %aBalance updates:@,\ \ %a@]" + Slot.pp + slot Operation_hash.pp (Operation.hash op1) Operation_hash.pp diff --git a/src/proto_alpha/lib_delegate/client_baking_denunciation.ml b/src/proto_alpha/lib_delegate/client_baking_denunciation.ml index 4568f44aab0f..30acea661fb1 100644 --- a/src/proto_alpha/lib_delegate/client_baking_denunciation.ml +++ b/src/proto_alpha/lib_delegate/client_baking_denunciation.ml @@ -162,6 +162,7 @@ let double_consensus_op_evidence (type kind) : #Protocol_client_context.full -> 'a -> branch:Block_hash.t -> + slot:Alpha_context.Slot.t -> op1:kind Alpha_context.operation -> op2:kind Alpha_context.operation -> unit -> @@ -308,6 +309,7 @@ let process_consensus_op (type kind) state cctxt cctxt (`Hash chain_id, block) ~branch:block_hash + ~slot ~op1 ~op2 () diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 14dfd12bdaca..8bba40673591 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -3398,12 +3398,13 @@ module Forge = struct let double_baking_evidence ctxt block ~branch ~bh1 ~bh2 () = operation ctxt block ~branch (Double_baking_evidence {bh1; bh2}) - let double_consensus_operation_evidence ctxt block ~branch ~op1 ~op2 () = + let double_consensus_operation_evidence ctxt block ~branch ~slot ~op1 ~op2 () + = operation ctxt block ~branch - (Double_consensus_operation_evidence {op1; op2}) + (Double_consensus_operation_evidence {slot; op1; op2}) let dal_entrapment_evidence ctxt block ~branch ~attestation ~consensus_slot ~slot_index ~shard_with_proof = diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index f644bd44fc17..2c8428f3ce87 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -4765,6 +4765,7 @@ and _ contents = } -> Kind.vdf_revelation contents | Double_consensus_operation_evidence : { + slot : Slot.t; op1 : 'a Kind.consensus operation; op2 : 'b Kind.consensus operation; } diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index e28f67ff08cf..c85718e62b37 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -2507,7 +2507,9 @@ let punish_delegate ctxt ~operation_hash delegate level misbehaviour mk_result let punish_double_consensus_operation (type kind) ctxt ~operation_hash ~payload_producer contents = let open Lwt_result_syntax in - let (Double_consensus_operation_evidence {op1; op2 = _}) = contents in + let (Double_consensus_operation_evidence {slot = _; op1; op2 = _}) = + contents + in let*? slot, misbehaviour = let open Result_syntax in match op1.protocol_data.contents with diff --git a/src/proto_alpha/lib_protocol/operation_repr.ml b/src/proto_alpha/lib_protocol/operation_repr.ml index 10570c8f3636..a3fce5a3b485 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.ml +++ b/src/proto_alpha/lib_protocol/operation_repr.ml @@ -303,6 +303,7 @@ and _ contents = } -> Kind.vdf_revelation contents | Double_consensus_operation_evidence : { + slot : Slot_repr.t; op1 : 'a Kind.consensus operation; op2 : 'b Kind.consensus operation; } @@ -1306,7 +1307,8 @@ module Encoding = struct tag = 2; name = "double_consensus_operation_evidence"; encoding = - obj2 + obj3 + (req "slot" Slot_repr.encoding) (req "op1" (dynamic_size inlined_consensus_operation_encoding)) (req "op2" (dynamic_size inlined_consensus_operation_encoding)); select = @@ -1314,11 +1316,11 @@ module Encoding = struct | Contents (Double_consensus_operation_evidence _ as op) -> Some op | _ -> None); proj = - (fun (Double_consensus_operation_evidence {op1; op2}) -> - (Consensus_op op1, Consensus_op op2)); + (fun (Double_consensus_operation_evidence {slot; op1; op2}) -> + (slot, Consensus_op op1, Consensus_op op2)); inj = - (fun (Consensus_op op1, Consensus_op op2) -> - Double_consensus_operation_evidence {op1; op2}); + (fun (slot, Consensus_op op1, Consensus_op op2) -> + Double_consensus_operation_evidence {slot; op1; op2}); } (* Note: tag = 7 was used for Double_preattestation_evidence, before diff --git a/src/proto_alpha/lib_protocol/operation_repr.mli b/src/proto_alpha/lib_protocol/operation_repr.mli index d1d9f6ed75ed..8e4933ec74cb 100644 --- a/src/proto_alpha/lib_protocol/operation_repr.mli +++ b/src/proto_alpha/lib_protocol/operation_repr.mli @@ -311,6 +311,7 @@ and _ contents = reported and the byzantine will have its security deposit forfeited. *) | Double_consensus_operation_evidence : { + slot : Slot_repr.t; op1 : 'a Kind.consensus operation; op2 : 'b Kind.consensus operation; } diff --git a/src/proto_alpha/lib_protocol/test/helpers/op.ml b/src/proto_alpha/lib_protocol/test/helpers/op.ml index faac50e1ee75..c7b3d0de6a91 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/op.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/op.ml @@ -873,21 +873,30 @@ let activation ctxt (pkh : Signature.Public_key_hash.t) activation_code = protocol_data = Operation_data {contents; signature = None}; } -let double_attestation ctxt op1 op2 = - let contents = Single (Double_consensus_operation_evidence {op1; op2}) in +let double_consensus_operation (type a) ctxt (op1 : a Kind.consensus operation) + op2 = + let slot = + match op1.protocol_data.contents with + | Single + (Preattestation consensus_content | Attestation {consensus_content; _}) + -> + consensus_content.slot + | Single (Preattestations_aggregate _ | Attestations_aggregate _) -> + invalid_arg + "Op.double_consensus_operation does not support aggregates yet" + in + let contents = + Single (Double_consensus_operation_evidence {slot; op1; op2}) + in let branch = Context.branch ctxt in { shell = {branch}; protocol_data = Operation_data {contents; signature = None}; } -let double_preattestation ctxt op1 op2 = - let contents = Single (Double_consensus_operation_evidence {op1; op2}) in - let branch = Context.branch ctxt in - { - shell = {branch}; - protocol_data = Operation_data {contents; signature = None}; - } +let double_attestation = double_consensus_operation + +let double_preattestation = double_consensus_operation let double_baking ctxt bh1 bh2 = let contents = Single (Double_baking_evidence {bh1; bh2}) in diff --git a/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml b/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml index 26bd7bd9c6c2..d5e328f15e71 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/operation_generator.ml @@ -403,9 +403,10 @@ let generate_double_consensus_operation = attestation with DAL, attestations aggregate, preattestations aggregate *) let generate_consensus_operation = generate_preattestation in + let* slot = gen_slot in let* op1 = generate_op generate_consensus_operation in let+ op2 = generate_op generate_consensus_operation in - Double_consensus_operation_evidence {op1; op2} + Double_consensus_operation_evidence {slot; op1; op2} let generate_double_baking = let open QCheck2.Gen in diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index 3590152d78de..1fd46c5fb933 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -2033,7 +2033,7 @@ module Anonymous = struct let check_double_consensus_operation_evidence vi (operation : Kind.double_consensus_operation_evidence operation) = let open Lwt_result_syntax in - let (Single (Double_consensus_operation_evidence {op1; op2})) = + let (Single (Double_consensus_operation_evidence {slot = _; op1; op2})) = operation.protocol_data.contents in let* e1, e2, kind = -- GitLab From 046247794517640decf15d9caec35bf6f2269c9f Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Fri, 16 May 2025 15:36:11 +0200 Subject: [PATCH 05/10] Kaitai: add slot field to Double_consensus_operation_evidence Generated with: dune exec -- client-libs/bin_codec_kaitai/codec.exe dump kaitai specs in client-libs/kaitai-struct-files/files --- client-libs/kaitai-struct-files/files/alpha__operation.ksy | 2 ++ .../files/alpha__operation__bls_mode_unsigned.ksy | 2 ++ .../kaitai-struct-files/files/alpha__operation__contents.ksy | 2 ++ .../files/alpha__operation__contents_list.ksy | 2 ++ .../files/alpha__operation__protocol_data.ksy | 2 ++ .../kaitai-struct-files/files/alpha__operation__unsigned.ksy | 2 ++ 6 files changed, 12 insertions(+) diff --git a/client-libs/kaitai-struct-files/files/alpha__operation.ksy b/client-libs/kaitai-struct-files/files/alpha__operation.ksy index 567cb496a3d6..4df6f14d8400 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation.ksy @@ -536,6 +536,8 @@ types: type: bh2_0 double_consensus_operation_evidence: seq: + - id: slot + type: u2be - id: op1 type: op1_0 - id: op2 diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy index 39004930033b..8483e674a516 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__bls_mode_unsigned.ksy @@ -537,6 +537,8 @@ types: type: bh2_0 double_consensus_operation_evidence: seq: + - id: slot + type: u2be - id: op1 type: op1_0 - id: op2 diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy index 29f792a0b5e8..bda1b02e0772 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__contents.ksy @@ -513,6 +513,8 @@ types: type: bh2_0 double_consensus_operation_evidence: seq: + - id: slot + type: u2be - id: op1 type: op1_0 - id: op2 diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy index 17f694df5999..397d54de7f4b 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__contents_list.ksy @@ -517,6 +517,8 @@ types: type: bh2_0 double_consensus_operation_evidence: seq: + - id: slot + type: u2be - id: op1 type: op1_0 - id: op2 diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy index 23b05b3beeaf..c381e85797ab 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__protocol_data.ksy @@ -536,6 +536,8 @@ types: type: bh2_0 double_consensus_operation_evidence: seq: + - id: slot + type: u2be - id: op1 type: op1_0 - id: op2 diff --git a/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy b/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy index 259c6535976a..a85dce66dcc9 100644 --- a/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy +++ b/client-libs/kaitai-struct-files/files/alpha__operation__unsigned.ksy @@ -524,6 +524,8 @@ types: type: bh2_0 double_consensus_operation_evidence: seq: + - id: slot + type: u2be - id: op1 type: op1_0 - id: op2 -- GitLab From 452230c019b19682887dc359c7c43673930185df Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Mon, 19 May 2025 14:28:15 +0200 Subject: [PATCH 06/10] Apply: handle denunciation of double operation containing aggregates --- src/proto_alpha/lib_protocol/apply.ml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index c85718e62b37..3442a2af0e35 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -2507,22 +2507,18 @@ let punish_delegate ctxt ~operation_hash delegate level misbehaviour mk_result let punish_double_consensus_operation (type kind) ctxt ~operation_hash ~payload_producer contents = let open Lwt_result_syntax in - let (Double_consensus_operation_evidence {slot = _; op1; op2 = _}) = - contents - in - let*? slot, misbehaviour = - let open Result_syntax in + let (Double_consensus_operation_evidence {slot; op1; op2 = _}) = contents in + let misbehaviour = match op1.protocol_data.contents with - | Single (Attestation {consensus_content; _}) -> - let {slot; level; round; block_payload_hash = _} = consensus_content in - return (slot, Misbehaviour.{level; round; kind = Double_attesting}) - | Single (Preattestation consensus_content) -> - let {slot; level; round; _} = consensus_content in - return (slot, Misbehaviour.{level; round; kind = Double_preattesting}) - | Single (Preattestations_aggregate _ | Attestations_aggregate _) -> - (* TODO : https://gitlab.com/tezos/tezos/-/issues/7598 - handle denunciation for aggregates. *) - tzfail Validate_errors.Anonymous.Aggregate_denunciation_not_implemented + | Single + ( Preattestation {level; round; _} + | Preattestations_aggregate {consensus_content = {level; round; _}; _} + ) -> + Misbehaviour.{level; round; kind = Double_preattesting} + | Single + ( Attestation {consensus_content = {level; round; _}; _} + | Attestations_aggregate {consensus_content = {level; round; _}; _} ) -> + Misbehaviour.{level; round; kind = Double_attesting} in let mk_result forbidden_delegate balance_updates = Double_consensus_operation_evidence_result -- GitLab From f514ffa1a50ba5eeec71b889e2f5f7533801f205 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Mon, 19 May 2025 14:18:05 +0200 Subject: [PATCH 07/10] Validate: handle denunciation of double operation containing aggregates --- .../lib_protocol/alpha_context.mli | 2 + src/proto_alpha/lib_protocol/validate.ml | 157 ++++++++++-------- 2 files changed, 88 insertions(+), 71 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 2c8428f3ce87..12d5a33e59c5 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2267,6 +2267,8 @@ module Misbehaviour : sig val kind_encoding : kind Data_encoding.t val compare_kind : kind -> kind -> int + + val equal_kind : kind -> kind -> bool end (** This module re-exports definitions from {!Delegate_storage}, diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index 1fd46c5fb933..168ba1e910f4 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -2030,87 +2030,108 @@ module Anonymous = struct | Single (Attestation _ | Attestations_aggregate _) -> Misbehaviour.Double_attesting + let consensus_aggregate_content (type a) (op : a Kind.consensus operation) = + match op.protocol_data.contents with + | Single + ( Preattestation {level; round; block_payload_hash; _} + | Attestation + {consensus_content = {level; round; block_payload_hash; _}; _} ) -> + {level; round; block_payload_hash} + | Single + ( Preattestations_aggregate {consensus_content; _} + | Attestations_aggregate {consensus_content; _} ) -> + consensus_content + let check_double_consensus_operation_evidence vi (operation : Kind.double_consensus_operation_evidence operation) = let open Lwt_result_syntax in - let (Single (Double_consensus_operation_evidence {slot = _; op1; op2})) = + let (Single (Double_consensus_operation_evidence {slot; op1; op2})) = operation.protocol_data.contents in - let* e1, e2, kind = - match (op1.protocol_data.contents, op2.protocol_data.contents) with - | Single (Preattestation e1), Single (Preattestation e2) -> - return (e1, e2, Misbehaviour.Double_preattesting) - | ( Single (Attestation {consensus_content = e1; dal_content = _}), - Single (Attestation {consensus_content = e2; dal_content = _}) ) -> - return (e1, e2, Misbehaviour.Double_attesting) - | Single (Preattestation _), Single (Attestation _) - | Single (Attestation _), Single (Preattestation _) -> - (* Incompatible kind *) - tzfail (Invalid_denunciation Double_preattesting) - | Single (Preattestations_aggregate _ | Attestations_aggregate _), _ - | _, Single (Preattestations_aggregate _ | Attestations_aggregate _) -> - (* TODO : https://gitlab.com/tezos/tezos/-/issues/7598 - handle denunciation for aggregates. *) - tzfail Aggregate_denunciation_not_implemented - in - let op1_hash = Operation.hash op1 in - let op2_hash = Operation.hash op2 in - let same_levels = Raw_level.(e1.level = e2.level) in - let same_rounds = Round.(e1.round = e2.round) in - let same_payload = - Block_payload_hash.(e1.block_payload_hash = e2.block_payload_hash) - in - let same_branches = Block_hash.(op1.shell.branch = op2.shell.branch) in - let ordered_hashes = Operation_hash.(op1_hash < op2_hash) in - let is_denunciation_consistent = - same_levels && same_rounds - (* For the double (pre)attestations to be punishable, they must point to - the same block (same level and round), but also have at least a - difference that is the delegate's fault: different payloads or - different branches. Note that different payloads would endanger the - consensus process, while different branches could be used to spam - mempools with a lot of valid operations. On the other hand, if the - operations have identical levels, rounds, payloads, branches, and - slots, then only their signatures are different, which is not - considered the delegate's fault and therefore is not punished. *) - && ((not same_payload) || not same_branches) - && (* we require an order on hashes to avoid the existence of - equivalent evidences *) - ordered_hashes + let kind = misbehaviour_kind op1 in + let ({level; round; block_payload_hash} : consensus_aggregate_content) = + consensus_aggregate_content op1 in - let*? () = - error_unless is_denunciation_consistent (Invalid_denunciation kind) + let ({level = level2; round = round2; block_payload_hash = bph2} + : consensus_aggregate_content) = + consensus_aggregate_content op2 in - (* Disambiguate: levels are equal *) - let level = Level.from_raw vi.ctxt e1.level in let*? () = - check_denunciation_age vi (`Consensus_denounciation kind) level.level - in - let* ctxt, consensus_key1 = - Stake_distribution.slot_owner vi.ctxt level e1.slot + (* Both denounced operations must be of the same kind and point + to the same level and round. *) + error_unless + (Misbehaviour.equal_kind kind (misbehaviour_kind op2) + && Raw_level.(level = level2) + && Round.(round = round2)) + (Invalid_denunciation kind) in - let* ctxt, consensus_key2 = - Stake_distribution.slot_owner ctxt level e2.slot + let*? () = + (* Both denounced operations must involve [slot]. That is, + they must be either a standalone (pre)attestation for [slot], + or an aggregate whose committee includes [slot]. *) + let open Result_syntax in + let check_slot (type a) (op : a Kind.consensus Operation.t) = + match op.protocol_data.contents with + | Single (Preattestation consensus_content) + | Single (Attestation {consensus_content; _}) -> + error_unless + Slot.(consensus_content.slot = slot) + (Invalid_denunciation kind) + | Single (Preattestations_aggregate {committee; _}) -> + error_unless + (List.mem ~equal:Slot.equal slot committee) + (Invalid_denunciation kind) + | Single (Attestations_aggregate {committee; _}) -> + error_unless + (List.mem_assoc ~equal:Slot.equal slot committee) + (Invalid_denunciation kind) + in + let* () = check_slot op1 in + check_slot op2 in - let delegate1, delegate2 = - (consensus_key1.delegate, consensus_key2.delegate) + let*? () = + (* For the double operations to be punishable, they must have at + least one difference that is considered the delegate's fault: + different payloads or different branches. Note that different + payloads would endanger the consensus process, while + different branches could be used to spam mempools with a lot + of valid operations. + + Indeed, we cannot punish a pair of operations just because + they have different hashes: the hash also depends on the + signature, and using signature malleability, anyone could + inject a consensus operation with all the same data as the + delegate's original operation but a different signature. *) + error_unless + (Block_payload_hash.(block_payload_hash <> bph2) + || Block_hash.(op1.shell.branch <> op2.shell.branch)) + (Invalid_denunciation kind) in let*? () = + (* We require an order on hashes so that the denunciation + constructed from two given operations is unique. *) error_unless - (Signature.Public_key_hash.equal delegate1 delegate2) - (Inconsistent_denunciation {kind; delegate1; delegate2}) + Operation_hash.(Operation.hash op1 < Operation.hash op2) + (Invalid_denunciation kind) in - let delegate_pk, delegate = (consensus_key1.consensus_pk, delegate1) in + let level = Level.from_raw vi.ctxt level in + let*? () = + check_denunciation_age vi (`Consensus_denounciation kind) level.level + in + let* ctxt, consensus_key = + Stake_distribution.slot_owner vi.ctxt level slot + in + let delegate = consensus_key.delegate in let* already_slashed = - Delegate.already_denounced ctxt delegate level e1.round kind + Delegate.already_denounced ctxt delegate level round kind in let*? () = error_unless (not already_slashed) (Already_denounced {kind; delegate; level}) in - let*? () = Operation.check_signature vi.ctxt delegate_pk vi.chain_id op1 in - let*? () = Operation.check_signature vi.ctxt delegate_pk vi.chain_id op2 in + let* () = check_consensus_operation_signature vi consensus_key op1 in + let* () = check_consensus_operation_signature vi consensus_key op2 in return_unit let check_double_consensus_operation_evidence_conflict vs oph key = @@ -2125,19 +2146,13 @@ module Anonymous = struct let conflict_key_of_double_consensus_operation (operation : Kind.double_consensus_operation_evidence operation) = - let (Single (Double_consensus_operation_evidence {op1; _})) = + let (Single (Double_consensus_operation_evidence {slot; op1; _})) = operation.protocol_data.contents in - match op1.protocol_data.contents with - | Single (Preattestation {slot; level; round; _}) -> - (level, round, slot, Misbehaviour.Double_preattesting) - | Single (Attestation {consensus_content; _}) -> - let {slot; level; round; _} = consensus_content in - (level, round, slot, Misbehaviour.Double_attesting) - | Single (Preattestations_aggregate _ | Attestations_aggregate _) -> - (* TODO : https://gitlab.com/tezos/tezos/-/issues/7598 - handle denunciation for aggregates. *) - assert false + let ({level; round; _} : consensus_aggregate_content) = + consensus_aggregate_content op1 + in + (level, round, slot, misbehaviour_kind op1) let check_double_consensus_operation_evidence_conflict vs oph (operation : Kind.double_consensus_operation_evidence operation) = -- GitLab From 0279ba055f51f63fe16c51a579447e0d7edfb007 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Tue, 20 May 2025 10:27:24 +0200 Subject: [PATCH 08/10] Proto/test: update error for denouncing different delegates Validation now enforces slot consistency which is a different error than having different slots that belong to different delegates --- .../integration/consensus/test_double_attestation.ml | 8 ++++---- .../integration/consensus/test_double_preattestation.ml | 9 +-------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml index 6efc104a178d..b9c6037fc415 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_attestation.ml @@ -654,8 +654,8 @@ let test_different_delegates () = double_attestation (B blk_b) e_a e_b |> fun operation -> let*! res = Block.bake ~operation blk_b in Assert.proto_error ~loc:__LOC__ res (function - | Validate_errors.Anonymous.Inconsistent_denunciation - {kind = Misbehaviour.Double_attesting; _} -> + | Validate_errors.Anonymous.Invalid_denunciation + Misbehaviour.Double_attesting -> true | _ -> false) @@ -679,8 +679,8 @@ let test_wrong_delegate () = double_attestation (B blk_b) attestation_a attestation_b |> fun operation -> let*! res = Block.bake ~operation blk_b in Assert.proto_error ~loc:__LOC__ res (function - | Validate_errors.Anonymous.Inconsistent_denunciation - {kind = Misbehaviour.Double_attesting; _} -> + | Validate_errors.Anonymous.Invalid_denunciation + Misbehaviour.Double_attesting -> true | _ -> false) diff --git a/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_preattestation.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_preattestation.ml index 22a0a6772f48..718859008607 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_preattestation.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_double_preattestation.ml @@ -107,13 +107,6 @@ end = struct true | _ -> false) - let inconsistent_denunciation loc res = - Assert.proto_error ~loc res (function - | Validate_errors.Anonymous.Inconsistent_denunciation - {kind = Misbehaviour.Double_preattesting; _} -> - true - | _ -> false) - let outdated_denunciation loc res = Assert.proto_error ~loc res (function | Validate_errors.Anonymous.Outdated_denunciation @@ -308,7 +301,7 @@ end = struct ~nb_blocks_before_double:0 ~nb_blocks_before_denunciation:2 ~test_expected_ok:unexpected_success - ~test_expected_ko:inconsistent_denunciation + ~test_expected_ko:invalid_denunciation ~pick_attesters (* pick different attesters *) ~loc:__LOC__ () -- GitLab From 58a80c39d37c228073d7fca778afe3acfb0d2b52 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Fri, 16 May 2025 16:25:08 +0200 Subject: [PATCH 09/10] Tezt: update encoding samples for regression tests Updated tezt/tests/encoding_samples/ files manually then ran: dune exec tezt/tests/main.exe -- -f tezt/tests/encoding.ml alpha -m operation --reset-regressions --- ...ed-double-attestation-evidence.sample.json | 3 +- ...e-consensus-operation-evidence.sample.json | 31 ++++++++ ...double-preattestation-evidence.sample.json | 3 +- ...double-preattestation-evidence.sample.json | 3 +- ...ol encoding regression test- operation.out | 9 ++- ...ng regression test- operation.unsigned.out | 73 +++++++++++++++++-- 6 files changed, 107 insertions(+), 15 deletions(-) create mode 100644 tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-consensus-operation-evidence.sample.json diff --git a/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-attestation-evidence.sample.json b/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-attestation-evidence.sample.json index 884957c25aed..8249f4ad8467 100644 --- a/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-attestation-evidence.sample.json +++ b/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-attestation-evidence.sample.json @@ -2,7 +2,8 @@ "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": [ { - "kind": "double_attestation_evidence", + "kind": "double_consensus_operation_evidence", + "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": { diff --git a/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-consensus-operation-evidence.sample.json b/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-consensus-operation-evidence.sample.json new file mode 100644 index 000000000000..901fc6a09301 --- /dev/null +++ b/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-consensus-operation-evidence.sample.json @@ -0,0 +1,31 @@ +{ + "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "contents": [ + { + "kind": "double_consensus_operation_evidence", + "slot": 0, + "op1": { + "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "operations": { + "kind": "attestation", + "level": 1331, + "block_payload_hash": "vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG", + "round": 0, + "slot": 0 + }, + "signature": "sigbQ5ZNvkjvGssJgoAnUAfY4Wvvg3QZqawBYB1j1VDBNTMBAALnCzRHWzer34bnfmzgHg3EvwdzQKdxgSghB897cono6gbQ" + }, + "op2": { + "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "operations": { + "kind": "preattestation", + "level": 1331, + "block_payload_hash": "vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG", + "round": 0, + "slot": 0 + }, + "signature": "sigbQ5ZNvkjvGssJgoAnUAfY4Wvvg3QZqawBYB1j1VDBNTMBAALnCzRHWzer34bnfmzgHg3EvwdzQKdxgSghB897cono6gbQ" + } + } + ] +} diff --git a/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-preattestation-evidence.sample.json b/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-preattestation-evidence.sample.json index 8aa1305a50e3..39b548c3ae17 100644 --- a/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-preattestation-evidence.sample.json +++ b/tezt/tests/encoding_samples/alpha/operation.unsigned/operation.unsigned-double-preattestation-evidence.sample.json @@ -2,7 +2,8 @@ "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": [ { - "kind": "double_preattestation_evidence", + "kind": "double_consensus_operation_evidence", + "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": { diff --git a/tezt/tests/encoding_samples/alpha/operation/operation-double-preattestation-evidence.sample.json b/tezt/tests/encoding_samples/alpha/operation/operation-double-preattestation-evidence.sample.json index 371a2d8e4e55..0a6492b5ac0e 100644 --- a/tezt/tests/encoding_samples/alpha/operation/operation-double-preattestation-evidence.sample.json +++ b/tezt/tests/encoding_samples/alpha/operation/operation-double-preattestation-evidence.sample.json @@ -2,7 +2,8 @@ "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": [ { - "kind": "double_preattestation_evidence", + "kind": "double_consensus_operation_evidence", + "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": { diff --git a/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.out b/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.out index 2f33acacf984..93444245222c 100644 --- a/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.out +++ b/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.out @@ -314,7 +314,8 @@ "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": [ { - "kind": "double_preattestation_evidence", + "kind": "double_consensus_operation_evidence", + "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": { @@ -341,12 +342,12 @@ ], "signature": "sigbQ5ZNvkjvGssJgoAnUAfY4Wvvg3QZqawBYB1j1VDBNTMBAALnCzRHWzer34bnfmzgHg3EvwdzQKdxgSghB897cono6gbQ" }' -0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8070000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c66804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c +0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c66804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c -./octez-codec decode alpha.operation from 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8070000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c66804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c +./octez-codec decode alpha.operation from 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c66804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": - [ { "kind": "double_preattestation_evidence", + [ { "kind": "double_consensus_operation_evidence", "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": diff --git a/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.unsigned.out b/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.unsigned.out index 69a7b869fb0c..ee395c26cda8 100644 --- a/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.unsigned.out +++ b/tezt/tests/expected/encoding.ml/Alpha- protocol encoding regression test- operation.unsigned.out @@ -181,7 +181,8 @@ "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": [ { - "kind": "double_attestation_evidence", + "kind": "double_consensus_operation_evidence", + "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": { @@ -207,12 +208,12 @@ } ] }' -0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8020000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c +0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c -./octez-codec decode alpha.operation.unsigned from 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8020000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c +./octez-codec decode alpha.operation.unsigned from 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": - [ { "kind": "double_attestation_evidence", + [ { "kind": "double_consensus_operation_evidence", "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": @@ -319,7 +320,63 @@ "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": [ { - "kind": "double_preattestation_evidence", + "kind": "double_consensus_operation_evidence", + "slot": 0, + "op1": { + "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "operations": { + "kind": "attestation", + "level": 1331, + "block_payload_hash": "vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG", + "round": 0, + "slot": 0 + }, + "signature": "sigbQ5ZNvkjvGssJgoAnUAfY4Wvvg3QZqawBYB1j1VDBNTMBAALnCzRHWzer34bnfmzgHg3EvwdzQKdxgSghB897cono6gbQ" + }, + "op2": { + "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "operations": { + "kind": "preattestation", + "level": 1331, + "block_payload_hash": "vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG", + "round": 0, + "slot": 0 + }, + "signature": "sigbQ5ZNvkjvGssJgoAnUAfY4Wvvg3QZqawBYB1j1VDBNTMBAALnCzRHWzer34bnfmzgHg3EvwdzQKdxgSghB897cono6gbQ" + } + } + ] +}' +0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c + +./octez-codec decode alpha.operation.unsigned from 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81500000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c +{ "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "contents": + [ { "kind": "double_consensus_operation_evidence", "slot": 0, + "op1": + { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "operations": + { "kind": "attestation", "slot": 0, "level": 1331, "round": 0, + "block_payload_hash": + "vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG" }, + "signature": + "sigbQ5ZNvkjvGssJgoAnUAfY4Wvvg3QZqawBYB1j1VDBNTMBAALnCzRHWzer34bnfmzgHg3EvwdzQKdxgSghB897cono6gbQ" }, + "op2": + { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "operations": + { "kind": "preattestation", "slot": 0, "level": 1331, + "round": 0, + "block_payload_hash": + "vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG" }, + "signature": + "sigbQ5ZNvkjvGssJgoAnUAfY4Wvvg3QZqawBYB1j1VDBNTMBAALnCzRHWzer34bnfmzgHg3EvwdzQKdxgSghB897cono6gbQ" } } ] } + +./octez-codec encode alpha.operation.unsigned from '{ + "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", + "contents": [ + { + "kind": "double_consensus_operation_evidence", + "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": { @@ -345,12 +402,12 @@ } ] }' -0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8070000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c +0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c -./octez-codec decode alpha.operation.unsigned from 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8070000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c +./octez-codec decode alpha.operation.unsigned from 0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a80200000000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c0000008b0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a81400000000053300000000000000000000000000000000000000000000000000000000000000000000000066804fe735e06e97e26da8236b6341b91c625d5e82b3524ec0a88cc982365e70f8a5b9bc65df2ea6d21ee244cc3a96fb33031c394c78b1179ff1b8a44237740c { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "contents": - [ { "kind": "double_preattestation_evidence", + [ { "kind": "double_consensus_operation_evidence", "slot": 0, "op1": { "branch": "BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb", "operations": -- GitLab From 1bdac0090e2506b065e2ced2254fbf36475d0d22 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Wed, 21 May 2025 11:55:30 +0200 Subject: [PATCH 10/10] Changelog: add entry on Double_consensus_operation_evidence --- docs/protocols/alpha.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index eb2a00a5ecf1..c3b4c0b94af7 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -83,6 +83,17 @@ RPC Changes Operations ---------- +- In order to enable denunciations of aggregated consensus operations, + the ``Double_preattestation_evidence`` and + ``Double_attestation_evidence`` operations have been replaced with a + new ``Double_consensus_operation_evidence`` operation. This new + operation contains a denounced slot and two denounced consensus + operations. For the evidence to be valid, the denounced operations + must both be preattestations (each one may be aggregated or not) or + both be attestations. Moreover, both must involve the denounced + slot, that is, be either a standalone operation for this slot or an + aggregate whose committee includes this slot. (MR :gl:`!18032`) + - The ``Dal_entrapment_evidence`` operation has a new ``consensus_slot`` field, and its ``attestation`` field may now contain any kind of consensus operation. For the evidence to be -- GitLab