@@ -20,7 +20,7 @@ use crate::LOG_TARGET;
20
20
21
21
use beefy_primitives:: {
22
22
crypto:: { AuthorityId , Public , Signature } ,
23
- Commitment , SignedCommitment , ValidatorSet , ValidatorSetId , VoteMessage ,
23
+ Commitment , EquivocationProof , SignedCommitment , ValidatorSet , ValidatorSetId , VoteMessage ,
24
24
} ;
25
25
use codec:: { Decode , Encode } ;
26
26
use log:: debug;
@@ -61,7 +61,7 @@ pub fn threshold(authorities: usize) -> usize {
61
61
pub enum VoteImportResult < B : Block > {
62
62
Ok ,
63
63
RoundConcluded ( SignedCommitment < NumberFor < B > , Signature > ) ,
64
- Equivocation , /* TODO: (EquivocationProof<NumberFor<B>, Public, Signature>) */
64
+ Equivocation ( EquivocationProof < NumberFor < B > , Public , Signature > ) ,
65
65
Invalid ,
66
66
Stale ,
67
67
}
@@ -149,8 +149,10 @@ where
149
149
target: LOG_TARGET ,
150
150
"🥩 detected equivocated vote: 1st: {:?}, 2nd: {:?}" , previous_vote, vote
151
151
) ;
152
- // TODO: build `EquivocationProof` and return it here.
153
- return VoteImportResult :: Equivocation
152
+ return VoteImportResult :: Equivocation ( EquivocationProof {
153
+ first : previous_vote. clone ( ) ,
154
+ second : vote,
155
+ } )
154
156
}
155
157
} else {
156
158
// this is the first vote sent by `id` for `num`, all good
@@ -197,8 +199,8 @@ mod tests {
197
199
use sc_network_test:: Block ;
198
200
199
201
use beefy_primitives:: {
200
- crypto:: Public , keyring :: Keyring , known_payloads:: MMR_ROOT_ID , Commitment , Payload ,
201
- SignedCommitment , ValidatorSet , VoteMessage ,
202
+ crypto:: Public , known_payloads:: MMR_ROOT_ID , Commitment , EquivocationProof , Keyring ,
203
+ Payload , SignedCommitment , ValidatorSet , VoteMessage ,
202
204
} ;
203
205
204
206
use super :: { threshold, Block as BlockT , RoundTracker , Rounds } ;
@@ -452,4 +454,42 @@ mod tests {
452
454
rounds. conclude ( 3 ) ;
453
455
assert ! ( rounds. previous_votes. is_empty( ) ) ;
454
456
}
457
+
458
+ #[ test]
459
+ fn should_provide_equivocation_proof ( ) {
460
+ sp_tracing:: try_init_simple ( ) ;
461
+
462
+ let validators = ValidatorSet :: < Public > :: new (
463
+ vec ! [ Keyring :: Alice . public( ) , Keyring :: Bob . public( ) ] ,
464
+ Default :: default ( ) ,
465
+ )
466
+ . unwrap ( ) ;
467
+ let validator_set_id = validators. id ( ) ;
468
+ let session_start = 1u64 . into ( ) ;
469
+ let mut rounds = Rounds :: < Block > :: new ( session_start, validators) ;
470
+
471
+ let payload1 = Payload :: from_single_entry ( MMR_ROOT_ID , vec ! [ 1 , 1 , 1 , 1 ] ) ;
472
+ let payload2 = Payload :: from_single_entry ( MMR_ROOT_ID , vec ! [ 2 , 2 , 2 , 2 ] ) ;
473
+ let commitment1 = Commitment { block_number : 1 , payload : payload1, validator_set_id } ;
474
+ let commitment2 = Commitment { block_number : 1 , payload : payload2, validator_set_id } ;
475
+
476
+ let alice_vote1 = VoteMessage {
477
+ id : Keyring :: Alice . public ( ) ,
478
+ commitment : commitment1,
479
+ signature : Keyring :: Alice . sign ( b"I am committed" ) ,
480
+ } ;
481
+ let mut alice_vote2 = alice_vote1. clone ( ) ;
482
+ alice_vote2. commitment = commitment2;
483
+
484
+ let expected_result = VoteImportResult :: Equivocation ( EquivocationProof {
485
+ first : alice_vote1. clone ( ) ,
486
+ second : alice_vote2. clone ( ) ,
487
+ } ) ;
488
+
489
+ // vote on one payload - ok
490
+ assert_eq ! ( rounds. add_vote( alice_vote1) , VoteImportResult :: Ok ) ;
491
+
492
+ // vote on _another_ commitment/payload -> expected equivocation proof
493
+ assert_eq ! ( rounds. add_vote( alice_vote2) , expected_result) ;
494
+ }
455
495
}
0 commit comments