authority_selection_inherents/
select_authorities.rs1use crate::authority_selection_inputs::AuthoritySelectionInputs;
4use crate::filter_invalid_candidates::{
5 Candidate, filter_invalid_permissioned_candidates, filter_trustless_candidates_registrations,
6};
7use log::{info, warn};
8use plutus::*;
9use sidechain_domain::{EpochNonce, ScEpochNumber, UtxoId};
10use sp_core::{U256, ecdsa, ed25519, sr25519};
11
12pub fn select_authorities<
15 TAccountId: Clone + Ord + TryFrom<sidechain_domain::SidechainPublicKey> + From<ecdsa::Public>,
16 TAccountKeys: Clone + Ord + From<(sr25519::Public, ed25519::Public)>,
17>(
18 genesis_utxo: UtxoId,
19 input: AuthoritySelectionInputs,
20 sidechain_epoch: ScEpochNumber,
21) -> Option<Vec<Candidate<TAccountId, TAccountKeys>>> {
22 let valid_registered_candidates = filter_trustless_candidates_registrations::<
23 TAccountId,
24 TAccountKeys,
25 >(input.registered_candidates, genesis_utxo);
26 let valid_permissioned_candidates =
27 filter_invalid_permissioned_candidates(input.permissioned_candidates);
28 let valid_permissioned_count = valid_permissioned_candidates.len();
29 let valid_registered_count = valid_registered_candidates.len();
30
31 let random_seed = seed_from_nonce_and_sc_epoch(&input.epoch_nonce, &sidechain_epoch);
32
33 if let Some(validators) = selection::ariadne_v2::select_authorities(
34 input.d_parameter.num_registered_candidates,
35 input.d_parameter.num_permissioned_candidates,
36 valid_registered_candidates,
37 valid_permissioned_candidates,
38 random_seed,
39 ) {
40 info!(
41 "💼 Selected committee of {} seats for epoch {} from {valid_permissioned_count} permissioned and {valid_registered_count} registered candidates",
42 validators.len(),
43 sidechain_epoch
44 );
45 Some(validators)
46 } else {
47 warn!("🚫 Failed to select validators for epoch {}", sidechain_epoch);
48 None
49 }
50}
51
52pub fn seed_from_nonce_and_sc_epoch(
54 epoch_nonce: &EpochNonce,
55 partner_chain_epoch_number: &ScEpochNumber,
56) -> [u8; 32] {
57 U256::from_big_endian(&epoch_nonce.as_array())
58 .overflowing_add(U256::from(partner_chain_epoch_number.0))
59 .0
60 .to_big_endian()
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use sidechain_domain::{EpochNonce, ScEpochNumber};
67 use sp_core::U256;
68
69 #[test]
70 fn should_create_correct_seed() {
71 let nonce_vec = Vec::from(U256::from(10).to_big_endian());
72 assert_eq!(
73 seed_from_nonce_and_sc_epoch(&EpochNonce(nonce_vec), &ScEpochNumber(2)),
74 U256::from(12).to_big_endian()
75 );
76 }
77}