Skip to content

Commit 3e8c12b

Browse files
authored
add e2e tests for permissionless election (#702)
1 parent 00b30e4 commit 3e8c12b

File tree

4 files changed

+132
-6
lines changed

4 files changed

+132
-6
lines changed

.github/workflows/e2e-tests-main-devnet.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,21 @@ jobs:
518518
follow-up-finalization-check: true
519519
timeout-minutes: 15
520520

521+
run-e2e-permissionless-ban:
522+
needs: [ build-test-docker, build-test-client ]
523+
name: Run permissionless ban test
524+
runs-on: ubuntu-20.04
525+
steps:
526+
- name: Checkout source code
527+
uses: actions/checkout@v2
528+
529+
- name: Run e2e test
530+
uses: ./.github/actions/run-e2e-test
531+
with:
532+
test-case: permissionless_ban
533+
follow-up-finalization-check: true
534+
timeout-minutes: 15
535+
521536
run-e2e-version-upgrade:
522537
needs: [build-test-docker, build-test-client]
523538
name: Run basic (positive) version-upgrade test
@@ -642,6 +657,7 @@ jobs:
642657
run-e2e-ban-counter-clearing,
643658
run-e2e-ban-threshold,
644659
run-e2e-version-upgrade,
660+
run-e2e-permissionless-ban,
645661
# run-e2e-failing-version-upgrade,
646662
# run-e2e-version-upgrade-catchup,
647663
]

aleph-client/src/pallets/elections.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use crate::{
66
pallet_elections::pallet::Call::set_ban_config,
77
primitives::{BanReason, CommitteeSeats, EraValidators},
88
},
9-
pallet_elections::pallet::Call::{ban_from_committee, change_validators},
10-
primitives::{BanConfig, BanInfo},
9+
pallet_elections::pallet::Call::{
10+
ban_from_committee, change_validators, set_elections_openness,
11+
},
12+
primitives::{BanConfig, BanInfo, ElectionOpenness},
1113
AccountId, BlockHash,
1214
Call::Elections,
1315
Connection, RootConnection, SudoCall, TxStatus,
@@ -68,6 +70,11 @@ pub trait ElectionsSudoApi {
6870
ban_reason: Vec<u8>,
6971
status: TxStatus,
7072
) -> anyhow::Result<BlockHash>;
73+
async fn set_election_openness(
74+
&self,
75+
mode: ElectionOpenness,
76+
status: TxStatus,
77+
) -> anyhow::Result<BlockHash>;
7178
}
7279

7380
#[async_trait::async_trait]
@@ -212,4 +219,14 @@ impl ElectionsSudoApi for RootConnection {
212219
});
213220
self.sudo_unchecked(call, status).await
214221
}
222+
223+
async fn set_election_openness(
224+
&self,
225+
mode: ElectionOpenness,
226+
status: TxStatus,
227+
) -> anyhow::Result<BlockHash> {
228+
let call = Elections(set_elections_openness { openness: mode });
229+
230+
self.sudo_unchecked(call, status).await
231+
}
215232
}

e2e-tests/src/test/ban.rs

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use std::collections::HashSet;
2+
13
use aleph_client::{
24
pallets::{
35
elections::{ElectionsApi, ElectionsSudoApi},
46
session::SessionApi,
5-
staking::StakingApi,
7+
staking::{StakingApi, StakingUserApi},
68
},
7-
primitives::{BanInfo, BanReason},
9+
primitives::{BanInfo, BanReason, CommitteeSeats, ElectionOpenness},
810
sp_core::bounded::bounded_vec::BoundedVec,
911
waiting::{BlockStatus, WaitingExt},
1012
SignedConnection, TxStatus,
@@ -16,14 +18,15 @@ use primitives::{
1618
};
1719

1820
use crate::{
19-
accounts::{get_validator_seed, NodeKeys},
21+
accounts::{account_ids_from_keys, get_validator_seed, NodeKeys},
2022
ban::{
2123
check_ban_config, check_ban_event, check_ban_info_for_validator,
2224
check_underperformed_count_for_sessions, check_underperformed_validator_reason,
2325
check_underperformed_validator_session_count, check_validators, setup_test,
2426
},
2527
config,
2628
rewards::set_invalid_keys_for_validator,
29+
validators::get_test_validators,
2730
};
2831

2932
const SESSIONS_TO_CHECK: SessionCount = 5;
@@ -50,6 +53,17 @@ async fn disable_validator(validator_address: &str, validator_seed: u32) -> anyh
5053
set_invalid_keys_for_validator(&connection_to_disable).await
5154
}
5255

56+
async fn signed_connection_for_disabled_controller() -> SignedConnection {
57+
let validator_seed = get_validator_seed(VALIDATOR_TO_DISABLE_OVERALL_INDEX);
58+
let stash_controller = NodeKeys::from(validator_seed);
59+
let controller_key_to_disable = stash_controller.controller;
60+
SignedConnection::new(
61+
NODE_TO_DISABLE_ADDRESS.to_string(),
62+
controller_key_to_disable,
63+
)
64+
.await
65+
}
66+
5367
/// Runs a chain, sets up a committee and validators. Sets an incorrect key for one of the
5468
/// validators. Waits for the offending validator to hit the ban threshold of sessions without
5569
/// producing blocks. Verifies that the offending validator has in fact been banned out for the
@@ -272,6 +286,83 @@ pub async fn clearing_session_count() -> anyhow::Result<()> {
272286
Ok(())
273287
}
274288

289+
/// Setup reserved validators, non_reserved are set to empty vec. Set ban config ban_period to 2.
290+
/// Set Openness to Permissionless.
291+
/// Ban manually one validator. Check if the banned validator is out of the non_reserved and is back
292+
/// after ban period.
293+
#[tokio::test]
294+
pub async fn permissionless_ban() -> anyhow::Result<()> {
295+
let config = config::setup_test();
296+
let root_connection = config.create_root_connection().await;
297+
298+
let validator_keys = get_test_validators(config);
299+
let reserved_validators = account_ids_from_keys(&validator_keys.reserved);
300+
let non_reserved_validators = account_ids_from_keys(&validator_keys.non_reserved);
301+
302+
let seats = CommitteeSeats {
303+
reserved_seats: 2,
304+
non_reserved_seats: 2,
305+
};
306+
307+
let validator_to_ban =
308+
&non_reserved_validators[VALIDATOR_TO_DISABLE_NON_RESERVED_INDEX as usize];
309+
let mut non_reserved_without_banned = non_reserved_validators.to_vec();
310+
non_reserved_without_banned.remove(VALIDATOR_TO_DISABLE_NON_RESERVED_INDEX as usize);
311+
312+
let ban_period = 2;
313+
root_connection
314+
.change_validators(
315+
Some(reserved_validators),
316+
Some(non_reserved_validators.clone()),
317+
Some(seats),
318+
TxStatus::InBlock,
319+
)
320+
.await?;
321+
root_connection
322+
.set_election_openness(ElectionOpenness::Permissionless, TxStatus::InBlock)
323+
.await?;
324+
root_connection
325+
.set_ban_config(None, None, None, Some(ban_period), TxStatus::InBlock)
326+
.await?;
327+
root_connection
328+
.ban_from_committee(validator_to_ban.clone(), vec![], TxStatus::InBlock)
329+
.await?;
330+
root_connection
331+
.connection
332+
.wait_for_n_eras(2, BlockStatus::Finalized)
333+
.await;
334+
335+
let without_banned = HashSet::<_>::from_iter(non_reserved_without_banned);
336+
let non_reserved = HashSet::<_>::from_iter(
337+
root_connection
338+
.connection
339+
.get_current_era_validators(None)
340+
.await
341+
.non_reserved,
342+
);
343+
assert_eq!(without_banned, non_reserved);
344+
345+
let signed_connection = signed_connection_for_disabled_controller().await;
346+
// validate again
347+
signed_connection.validate(0, TxStatus::InBlock).await?;
348+
root_connection
349+
.connection
350+
.wait_for_n_eras(2, BlockStatus::Finalized)
351+
.await;
352+
let expected_non_reserved = HashSet::<_>::from_iter(non_reserved_validators);
353+
let non_reserved = HashSet::<_>::from_iter(
354+
root_connection
355+
.connection
356+
.get_current_era_validators(None)
357+
.await
358+
.non_reserved,
359+
);
360+
361+
assert_eq!(expected_non_reserved, non_reserved);
362+
363+
Ok(())
364+
}
365+
275366
/// Runs a chain, sets up a committee and validators. Changes the ban config to require 100%
276367
/// performance. Checks that each validator has all the sessions in which they were chosen for the
277368
/// committee marked as ones in which they underperformed.

e2e-tests/src/test/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
pub use ban::{ban_automatic, ban_manual, ban_threshold, clearing_session_count};
1+
pub use ban::{
2+
ban_automatic, ban_manual, ban_threshold, clearing_session_count, permissionless_ban,
3+
};
24
pub use electing_validators::authorities_are_staking;
35
pub use era_payout::era_payouts_calculated_correctly;
46
pub use era_validators::era_validators;

0 commit comments

Comments
 (0)