From 8042ed11ba003150778bbf5013717b09f379e1b5 Mon Sep 17 00:00:00 2001 From: Benjamin Gallois <business@gallois.cc> Date: Mon, 18 Dec 2023 10:13:23 +0100 Subject: [PATCH] Add end2end test for offences (nodes/rust/duniter-v2s!216) * fix rebase errors and formatting * separate offences end2end tests * fix end2end tests offences * add end2end test babe offences * add end2end test grandpa offences * add end2end test im_offline offences --- Cargo.lock | 1 + pallets/authority-members/src/impls.rs | 3 + pallets/authority-members/src/lib.rs | 2 + runtime/gdev/Cargo.toml | 1 + runtime/gdev/tests/offences_tests.rs | 157 +++++++++++++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 runtime/gdev/tests/offences_tests.rs diff --git a/Cargo.lock b/Cargo.lock index 2e3ce8e0e..b66692b9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3234,6 +3234,7 @@ dependencies = [ "sp-offchain", "sp-runtime", "sp-session", + "sp-staking", "sp-std 5.0.0", "sp-transaction-pool", "sp-version", diff --git a/pallets/authority-members/src/impls.rs b/pallets/authority-members/src/impls.rs index 4a2a53304..ade9f7437 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 355eb1ff7..6858083e1 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/Cargo.toml b/runtime/gdev/Cargo.toml index 680b3da34..976999d23 100644 --- a/runtime/gdev/Cargo.toml +++ b/runtime/gdev/Cargo.toml @@ -135,6 +135,7 @@ try-runtime = [ [dev-dependencies] sp-io = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.42', default-features = false } sp-keyring = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.42', default-features = false } +sp-staking = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.42', default-features = false } [dependencies] # local diff --git a/runtime/gdev/tests/offences_tests.rs b/runtime/gdev/tests/offences_tests.rs new file mode 100644 index 000000000..25f8f63ae --- /dev/null +++ b/runtime/gdev/tests/offences_tests.rs @@ -0,0 +1,157 @@ +// Copyright 2021 Axiom-Team +// +// This file is part of Duniter-v2S. +// +// Duniter-v2S is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// Duniter-v2S is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>. + +mod common; + +use common::*; +use frame_support::assert_ok; +use frame_support::traits::ValidatorSet; +use frame_support::traits::ValidatorSetWithIdentification; +use gdev_runtime::*; +use pallet_im_online as im_online; +use pallet_im_online::UnresponsivenessOffence; +use pallet_session::historical::IdentificationTuple; +use sp_runtime::traits::Convert; +use sp_staking::offence::ReportOffence; + +#[test] +fn test_imonline_offence() { + ExtBuilder::new(1, 3, 4).build().execute_with(|| { + run_to_block(1); + let session_index = Session::current_index(); + let current_validators = <Runtime as im_online::Config>::ValidatorSet::validators(); + // Construct an offence where all validators (member: 1) are offenders + let offenders = current_validators + .into_iter() + .enumerate() + .filter_map(|(_, id)| { + <<Runtime as im_online::Config>::ValidatorSet as ValidatorSetWithIdentification< + sp_runtime::AccountId32, + >>::IdentificationOf::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 offence = UnresponsivenessOffence { + session_index, + validator_set_count, + offenders, + }; + assert_ok!( + <Runtime as pallet_im_online::Config>::ReportUnresponsiveness::report_offence( + vec![], + offence + ) + ); + // An offence is deposited + System::assert_has_event(RuntimeEvent::Offences(pallet_offences::Event::Offence { + kind: *b"im-online:offlin", + timeslot: vec![0, 0, 0, 0], + })); + // Offenders are punished + System::assert_has_event(RuntimeEvent::AuthorityMembers( + pallet_authority_members::Event::MemberGoOffline { member: 1 }, + )); + assert_eq!(AuthorityMembers::blacklist().len(), 0); + }) +} +#[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(), + }; + assert_ok!(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 }, + )); + assert_eq!(AuthorityMembers::blacklist().len(), 1); + }) +} +#[test] +fn test_babe_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 offence = pallet_babe::EquivocationOffence { + slot: 0u64.into(), + session_index, + validator_set_count, + offender: offenders.pop().unwrap(), + }; + assert_ok!(Offences::report_offence(vec![], offence)); + // An offence is deposited + System::assert_has_event(RuntimeEvent::Offences(pallet_offences::Event::Offence { + kind: *b"babe:equivocatio", + timeslot: vec![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 }, + )); + assert_eq!(AuthorityMembers::blacklist().len(), 1); + }) +} -- GitLab