From ebc851b0c5a14dcd565b2ef5d45107ffb0eb4d4d Mon Sep 17 00:00:00 2001 From: Adam Allombert-Goget Date: Thu, 5 Dec 2024 10:54:50 +0100 Subject: [PATCH 1/2] Proto: attestation with different slots are no longer slashed under feature flag --- src/proto_alpha/lib_protocol/validate.ml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index 1380ec715b56..4a9dc28ba37f 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -1370,6 +1370,16 @@ module Anonymous = struct let same_branches = Block_hash.(op1.shell.branch = op2.shell.branch) in let same_slots = Slot.(e1.slot = e2.slot) in let ordered_hashes = Operation_hash.(op1_hash < op2_hash) in + (* attestations with different slots are not slashed when + aggregate_attestation feature flag is enabled. *) + let aggregate_attestation_feature_flag = + Constants.aggregate_attestation vi.ctxt + in + let is_slot_denunciable = + match kind with + | Misbehaviour.Double_attesting -> not aggregate_attestation_feature_flag + | _ -> true + in let is_denunciation_consistent = same_levels && same_rounds (* For the double (pre)attestations to be punishable, they @@ -1385,7 +1395,8 @@ module Anonymous = struct 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) || not same_slots) + && ((not same_payload) || (not same_branches) + || ((not same_slots) && is_slot_denunciable)) && (* we require an order on hashes to avoid the existence of equivalent evidences *) ordered_hashes -- GitLab From 0423bf397eaf1160a1488c104698bb1a6b0986cd Mon Sep 17 00:00:00 2001 From: Adam Allombert-Goget Date: Thu, 5 Dec 2024 11:57:32 +0100 Subject: [PATCH 2/2] proto-unit-tests: add a test double_attestation with different slots under feature flag --- .../consensus/test_double_attestation.ml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) 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 310c5d16cf73..6eb8ec9856af 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 @@ -907,6 +907,42 @@ let test_two_double_attestation_evidences_leads_to_duplicate_denunciation () = true | _ -> false) +(** Check that a double attestation evidence fails under aggregate_attestation + feature flag when operations have distinct slots and are otherwise + identical. *) +let different_slots_under_feature_flag () = + let open Lwt_result_syntax in + let* genesis, _ = + Context.init2 ~consensus_threshold_size:0 ~aggregate_attestation:true () + in + let* block = Block.bake genesis in + let* attesters = Context.get_attesters (B block) in + let delegate, slot1, slot2 = + (* Find an attester with more than 1 slot. *) + WithExceptions.Option.get + ~loc:__LOC__ + (List.find_map + (fun (attester : RPC.Validators.t) -> + match attester.slots with + | slot1 :: slot2 :: _ -> Some (attester.delegate, slot1, slot2) + | _ -> None) + attesters) + in + let* attestation1 = Op.raw_attestation ~delegate ~slot:slot1 block in + let* attestation2 = Op.raw_attestation ~delegate ~slot:slot2 block in + let double_attestation_evidence = + double_attestation (B block) attestation1 attestation2 + in + let*! res = Block.bake ~operation:double_attestation_evidence block in + let* () = + Assert.proto_error ~loc:__LOC__ res (function + | Validate_errors.Anonymous.Invalid_denunciation + Misbehaviour.Double_attesting -> + true + | _ -> false) + in + return_unit + let tests = [ Tztest.tztest @@ -957,6 +993,10 @@ let tests = test_too_late_double_attestation_evidence; Tztest.tztest "different delegates" `Quick test_different_delegates; Tztest.tztest "wrong delegate" `Quick test_wrong_delegate; + Tztest.tztest + "different slots under feature flag" + `Quick + different_slots_under_feature_flag; (* This test has been deactivated following the changes of the forbidding mechanism that now forbids delegates right after the first denunciation, it should be fixed and reactivated -- GitLab