1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! `AttesterSlashing` — pair of conflicting attestations plus the helper
//! that extracts the slashable-validator set.
//!
//! Traces to: [SPEC.md §3.4](../../docs/resources/SPEC.md), catalogue row
//! [DSL-007](../../docs/requirements/domains/evidence/specs/DSL-007.md).
//!
//! # Role
//!
//! Carries two `IndexedAttestation`s that are slashably conflicting under
//! either the double-vote (DSL-014) or surround-vote (DSL-015) predicate.
//! `slashable_indices()` returns the validator indices that signed BOTH —
//! this is the per-validator fan-out consumed by the slash loop in
//! `SlashingManager::submit_evidence` (DSL-022).
//!
//! # Preconditions for the helper
//!
//! Both `attesting_indices` MUST be strictly ascending and deduped —
//! the contract `IndexedAttestation::validate_structure` (DSL-005)
//! enforces. Callers invoke that guard FIRST; if structure is valid,
//! `slashable_indices` is sound. If structure is malformed, the output
//! is still deterministic but may not equal the set-theoretic intersection.
//!
//! # Why a two-pointer sweep
//!
//! `Vec<u32>` is already sorted ascending by precondition, so O(n+m)
//! two-pointer walks beat `HashSet::intersection` (O(n+m) with hashing
//! overhead + non-deterministic iteration order) and `retain` (O(n·m)).
use Ordering;
use ;
use crateIndexedAttestation;
/// A pair of conflicting indexed attestations.
///
/// Per [SPEC §3.4](../../docs/resources/SPEC.md). The two halves are
/// `PartialEq`/`Eq` so higher-level code can detect the degenerate case
/// where both attestations are byte-identical (appeal ground
/// [DSL-041](../../../../docs/requirements/domains/appeal/specs/DSL-041.md)).