1919#![ deny( unused_crate_dependencies) ]
2020
2121use std:: collections:: { HashMap , HashSet } ;
22- use std:: convert:: TryFrom ;
2322use std:: pin:: Pin ;
2423use std:: sync:: Arc ;
2524
@@ -28,13 +27,12 @@ use futures::{channel::{mpsc, oneshot}, Future, FutureExt, SinkExt, StreamExt};
2827
2928use sp_keystore:: SyncCryptoStorePtr ;
3029use polkadot_primitives:: v1:: {
31- CommittedCandidateReceipt , BackedCandidate , Id as ParaId , ValidatorId ,
32- ValidatorIndex , SigningContext , PoV , CandidateHash ,
33- CandidateDescriptor , AvailableData , ValidatorSignature , Hash , CandidateReceipt ,
34- CoreState , CoreIndex , CollatorId , ValidityAttestation , CandidateCommitments ,
30+ AvailableData , BackedCandidate , CandidateCommitments , CandidateDescriptor , CandidateHash ,
31+ CandidateReceipt , CollatorId , CommittedCandidateReceipt , CoreIndex , CoreState , Hash , Id as ParaId ,
32+ PoV , SigningContext , ValidatorId , ValidatorIndex , ValidatorSignature , ValidityAttestation ,
3533} ;
3634use polkadot_node_primitives:: {
37- FromTableMisbehavior , Statement , SignedFullStatement , MisbehaviorReport , ValidationResult ,
35+ Statement , SignedFullStatement , ValidationResult ,
3836} ;
3937use polkadot_subsystem:: {
4038 JaegerSpan , PerLeafSpan ,
@@ -60,8 +58,9 @@ use statement_table::{
6058 Context as TableContextTrait ,
6159 Table ,
6260 v1:: {
61+ SignedStatement as TableSignedStatement ,
6362 Statement as TableStatement ,
64- SignedStatement as TableSignedStatement , Summary as TableSummary ,
63+ Summary as TableSummary ,
6564 } ,
6665} ;
6766use thiserror:: Error ;
@@ -145,8 +144,6 @@ struct CandidateBackingJob {
145144 /// The candidates that are includable, by hash. Each entry here indicates
146145 /// that we've sent the provisioner the backed candidate.
147146 backed : HashSet < CandidateHash > ,
148- /// We have already reported misbehaviors for these validators.
149- reported_misbehavior_for : HashSet < ValidatorIndex > ,
150147 keystore : SyncCryptoStorePtr ,
151148 table : Table < TableContext > ,
152149 table_context : TableContext ,
@@ -644,36 +641,17 @@ impl CandidateBackingJob {
644641 }
645642
646643 /// Check if there have happened any new misbehaviors and issue necessary messages.
647- ///
648- /// TODO: Report multiple misbehaviors (https://github.com/paritytech/polkadot/issues/1387)
649644 #[ tracing:: instrument( level = "trace" , skip( self ) , fields( subsystem = LOG_TARGET ) ) ]
650645 async fn issue_new_misbehaviors ( & mut self ) -> Result < ( ) , Error > {
651- let mut reports = Vec :: new ( ) ;
652-
653- for ( k, v) in self . table . get_misbehavior ( ) . iter ( ) {
654- if !self . reported_misbehavior_for . contains ( k) {
655- self . reported_misbehavior_for . insert ( * k) ;
656-
657- let f = FromTableMisbehavior {
658- id : * k,
659- report : v. clone ( ) ,
660- signing_context : self . table_context . signing_context . clone ( ) ,
661- key : self . table_context . validators [ * k as usize ] . clone ( ) ,
662- } ;
663-
664- if let Ok ( report) = MisbehaviorReport :: try_from ( f) {
665- let message = ProvisionerMessage :: ProvisionableData (
666- self . parent ,
667- ProvisionableData :: MisbehaviorReport ( self . parent , report) ,
668- ) ;
669-
670- reports. push ( message) ;
671- }
672- }
673- }
674-
675- for report in reports. drain ( ..) {
676- self . send_to_provisioner ( report) . await ?
646+ // collect the misbehaviors to avoid double mutable self borrow issues
647+ let misbehaviors: Vec < _ > = self . table . drain_misbehaviors ( ) . collect ( ) ;
648+ for ( validator_id, report) in misbehaviors {
649+ self . send_to_provisioner (
650+ ProvisionerMessage :: ProvisionableData (
651+ self . parent ,
652+ ProvisionableData :: MisbehaviorReport ( self . parent , validator_id, report)
653+ )
654+ ) . await ?
677655 }
678656
679657 Ok ( ( ) )
@@ -1086,7 +1064,6 @@ impl util::JobTrait for CandidateBackingJob {
10861064 seconded : None ,
10871065 unbacked_candidates : HashMap :: new ( ) ,
10881066 backed : HashSet :: new ( ) ,
1089- reported_misbehavior_for : HashSet :: new ( ) ,
10901067 keystore,
10911068 table : Table :: default ( ) ,
10921069 table_context,
@@ -1199,9 +1176,7 @@ mod tests {
11991176 use super :: * ;
12001177 use assert_matches:: assert_matches;
12011178 use futures:: { future, Future } ;
1202- use polkadot_primitives:: v1:: {
1203- ScheduledCore , BlockData , PersistedValidationData , HeadData , GroupRotationInfo ,
1204- } ;
1179+ use polkadot_primitives:: v1:: { BlockData , GroupRotationInfo , HeadData , PersistedValidationData , ScheduledCore } ;
12051180 use polkadot_subsystem:: {
12061181 messages:: { RuntimeApiRequest , RuntimeApiMessage } ,
12071182 ActiveLeavesUpdate , FromOverseer , OverseerSignal ,
@@ -1210,12 +1185,23 @@ mod tests {
12101185 use sp_keyring:: Sr25519Keyring ;
12111186 use sp_application_crypto:: AppKey ;
12121187 use sp_keystore:: { CryptoStore , SyncCryptoStore } ;
1188+ use statement_table:: v1:: Misbehavior ;
12131189 use std:: collections:: HashMap ;
12141190
12151191 fn validator_pubkeys ( val_ids : & [ Sr25519Keyring ] ) -> Vec < ValidatorId > {
12161192 val_ids. iter ( ) . map ( |v| v. public ( ) . into ( ) ) . collect ( )
12171193 }
12181194
1195+ fn table_statement_to_primitive (
1196+ statement : TableStatement ,
1197+ ) -> Statement {
1198+ match statement {
1199+ TableStatement :: Candidate ( committed_candidate_receipt) => Statement :: Seconded ( committed_candidate_receipt) ,
1200+ TableStatement :: Valid ( candidate_hash) => Statement :: Valid ( candidate_hash) ,
1201+ TableStatement :: Invalid ( candidate_hash) => Statement :: Invalid ( candidate_hash) ,
1202+ }
1203+ }
1204+
12191205 struct TestState {
12201206 chain_ids : Vec < ParaId > ,
12211207 keystore : SyncCryptoStorePtr ,
@@ -1950,19 +1936,30 @@ mod tests {
19501936 _,
19511937 ProvisionableData :: MisbehaviorReport (
19521938 relay_parent,
1953- MisbehaviorReport :: SelfContradiction ( _, s1, s2) ,
1939+ validator_index,
1940+ Misbehavior :: ValidityDoubleVote ( vdv) ,
19541941 )
19551942 )
19561943 ) if relay_parent == test_state. relay_parent => {
1957- s1. check_signature(
1944+ let ( ( t1, s1) , ( t2, s2) ) = vdv. deconstruct:: <TableContext >( ) ;
1945+ let t1 = table_statement_to_primitive( t1) ;
1946+ let t2 = table_statement_to_primitive( t2) ;
1947+
1948+ SignedFullStatement :: new(
1949+ t1,
1950+ validator_index,
1951+ s1,
19581952 & test_state. signing_context,
1959- & test_state. validator_public[ s1 . validator_index( ) as usize ] ,
1960- ) . unwrap ( ) ;
1953+ & test_state. validator_public[ validator_index as usize ] ,
1954+ ) . expect ( "signature must be valid" ) ;
19611955
1962- s2. check_signature(
1956+ SignedFullStatement :: new(
1957+ t2,
1958+ validator_index,
1959+ s2,
19631960 & test_state. signing_context,
1964- & test_state. validator_public[ s2 . validator_index( ) as usize ] ,
1965- ) . unwrap ( ) ;
1961+ & test_state. validator_public[ validator_index as usize ] ,
1962+ ) . expect ( "signature must be valid" ) ;
19661963 }
19671964 ) ;
19681965
@@ -1979,19 +1976,30 @@ mod tests {
19791976 _,
19801977 ProvisionableData :: MisbehaviorReport (
19811978 relay_parent,
1982- MisbehaviorReport :: SelfContradiction ( _, s1, s2) ,
1979+ validator_index,
1980+ Misbehavior :: ValidityDoubleVote ( vdv) ,
19831981 )
19841982 )
19851983 ) if relay_parent == test_state. relay_parent => {
1986- s1. check_signature(
1984+ let ( ( t1, s1) , ( t2, s2) ) = vdv. deconstruct:: <TableContext >( ) ;
1985+ let t1 = table_statement_to_primitive( t1) ;
1986+ let t2 = table_statement_to_primitive( t2) ;
1987+
1988+ SignedFullStatement :: new(
1989+ t1,
1990+ validator_index,
1991+ s1,
19871992 & test_state. signing_context,
1988- & test_state. validator_public[ s1 . validator_index( ) as usize ] ,
1989- ) . unwrap ( ) ;
1993+ & test_state. validator_public[ validator_index as usize ] ,
1994+ ) . expect ( "signature must be valid" ) ;
19901995
1991- s2. check_signature(
1996+ SignedFullStatement :: new(
1997+ t2,
1998+ validator_index,
1999+ s2,
19922000 & test_state. signing_context,
1993- & test_state. validator_public[ s2 . validator_index( ) as usize ] ,
1994- ) . unwrap ( ) ;
2001+ & test_state. validator_public[ validator_index as usize ] ,
2002+ ) . expect ( "signature must be valid" ) ;
19952003 }
19962004 ) ;
19972005 } ) ;
@@ -2464,6 +2472,7 @@ mod tests {
24642472 #[ test]
24652473 fn candidate_backing_reorders_votes ( ) {
24662474 use sp_core:: Encode ;
2475+ use std:: convert:: TryFrom ;
24672476
24682477 let relay_parent = [ 1 ; 32 ] . into ( ) ;
24692478 let para_id = ParaId :: from ( 10 ) ;
0 commit comments