diff --git a/pallets/authority-members/src/impls.rs b/pallets/authority-members/src/impls.rs index 4a2a53304ae75c44157c346aabec14e90e74a82c..ade9f7437bcf80a0e396625d44530c901841dd35 100644 --- a/pallets/authority-members/src/impls.rs +++ b/pallets/authority-members/src/impls.rs @@ -59,6 +59,9 @@ where { if !blacklist.contains(&member_id) { blacklist.push(member_id); + Self::deposit_event(Event::MemberAddedToBlacklist { + member: member_id, + }); add_db_reads_writes(0, 1); } Self::insert_out(member_id); diff --git a/pallets/authority-members/src/lib.rs b/pallets/authority-members/src/lib.rs index 355eb1ff7f517e0567ef64aae7926b26d49336fe..6858083e14ce180092307546059eb318b0fd36d3 100644 --- a/pallets/authority-members/src/lib.rs +++ b/pallets/authority-members/src/lib.rs @@ -179,6 +179,8 @@ pub mod pallet { MemberRemoved { member: T::MemberId }, /// A member has been removed from the blacklist. MemberRemovedFromBlacklist { member: T::MemberId }, + /// A member has been blacklisted. + MemberAddedToBlacklist { member: T::MemberId }, } // ERRORS // diff --git a/runtime/gdev/tests/integration_tests.rs b/runtime/gdev/tests/integration_tests.rs index 7b77c3548d9810054a620d97cac5a3b2c869e5e2..655382508e5cd5c79eb2027d1f5e6252555a0e8e 100644 --- a/runtime/gdev/tests/integration_tests.rs +++ b/runtime/gdev/tests/integration_tests.rs @@ -1348,3 +1348,47 @@ fn test_imonline_offence() { )); }) } +#[test] +fn test_grandpa_offence() { + ExtBuilder::new(1, 3, 4).build().execute_with(|| { + run_to_block(1); + let session_index = Session::current_index(); + let current_validators = <Runtime as pallet_im_online::Config>::ValidatorSet::validators(); + // Construct an offence where all validators (member: 1) are offenders + let mut offenders = current_validators + .into_iter() + .enumerate() + .filter_map(|(_, id)| { + <Runtime as pallet_session::historical::Config>::FullIdentificationOf::convert( + id.clone(), + ) + .map(|full_id| (id, full_id)) + }) + .collect::<Vec<IdentificationTuple<Runtime>>>(); + let keys = ImOnline::keys(); + let validator_set_count = keys.len() as u32; + let time_slot = pallet_grandpa::TimeSlot { + set_id: 0, + round: 0, + }; + let offence = pallet_grandpa::EquivocationOffence { + time_slot, + session_index, + validator_set_count, + offender: offenders.pop().unwrap().into(), + }; + let _ = Offences::report_offence(vec![], offence); + // An offence is deposited + System::assert_has_event(RuntimeEvent::Offences(pallet_offences::Event::Offence { + kind: *b"grandpa:equivoca", + timeslot: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + })); + // Offenders are punished + System::assert_has_event(RuntimeEvent::AuthorityMembers( + pallet_authority_members::Event::MemberGoOffline { member: 1 }, + )); + System::assert_has_event(RuntimeEvent::AuthorityMembers( + pallet_authority_members::Event::MemberAddedToBlacklist { member: 1 }, + )); + }) +}