polkadot_subsystem_bench/approval/
helpers.rs1use crate::configuration::TestAuthorities;
18use itertools::Itertools;
19use polkadot_node_network_protocol::{
20 grid_topology::{SessionGridTopology, TopologyPeerInfo},
21 View,
22};
23use polkadot_node_primitives::approval::time::{Clock, SystemClock, Tick};
24use polkadot_node_subsystem::messages::{
25 ApprovalDistributionMessage, ApprovalVotingParallelMessage,
26};
27use polkadot_node_subsystem_types::messages::{
28 network_bridge_event::NewGossipTopology, NetworkBridgeEvent,
29};
30use polkadot_overseer::AllMessages;
31use polkadot_primitives::{
32 BlockNumber, CandidateEvent, CandidateReceiptV2, CoreIndex, GroupIndex, Hash, Header,
33 Id as ParaId, MutateDescriptorV2, Slot, ValidatorIndex,
34};
35use polkadot_primitives_test_helpers::dummy_candidate_receipt_v2_bad_sig;
36use rand::{seq::SliceRandom, SeedableRng};
37use rand_chacha::ChaCha20Rng;
38use sc_network_types::PeerId;
39use sp_consensus_babe::{
40 digests::{CompatibleDigestItem, PreDigest, SecondaryVRFPreDigest},
41 AllowedSlots, BabeEpochConfiguration, Epoch as BabeEpoch, VrfSignature, VrfTranscript,
42};
43use sp_core::crypto::VrfSecret;
44use sp_keyring::sr25519::Keyring as Sr25519Keyring;
45use sp_runtime::{Digest, DigestItem};
46use std::sync::{atomic::AtomicU64, Arc};
47
48#[derive(Clone)]
51pub struct PastSystemClock {
52 real_system_clock: SystemClock,
54 delta_ticks: Arc<AtomicU64>,
56}
57
58impl PastSystemClock {
59 pub fn new(real_system_clock: SystemClock, delta_ticks: Arc<AtomicU64>) -> Self {
61 PastSystemClock { real_system_clock, delta_ticks }
62 }
63}
64
65impl Clock for PastSystemClock {
66 fn tick_now(&self) -> Tick {
67 self.real_system_clock.tick_now() -
68 self.delta_ticks.load(std::sync::atomic::Ordering::SeqCst)
69 }
70
71 fn wait(
72 &self,
73 tick: Tick,
74 ) -> std::pin::Pin<Box<dyn futures::prelude::Future<Output = ()> + Send + 'static>> {
75 self.real_system_clock
76 .wait(tick + self.delta_ticks.load(std::sync::atomic::Ordering::SeqCst))
77 }
78}
79
80pub fn generate_babe_epoch(current_slot: Slot, authorities: TestAuthorities) -> BabeEpoch {
83 let authorities = authorities
84 .validator_babe_id
85 .into_iter()
86 .enumerate()
87 .map(|(index, public)| (public, index as u64))
88 .collect_vec();
89 BabeEpoch {
90 epoch_index: 1,
91 start_slot: current_slot.saturating_sub(1u64),
92 duration: 200,
93 authorities,
94 randomness: [0xde; 32],
95 config: BabeEpochConfiguration { c: (1, 4), allowed_slots: AllowedSlots::PrimarySlots },
96 }
97}
98
99pub fn generate_topology(test_authorities: &TestAuthorities) -> SessionGridTopology {
101 let keyrings = test_authorities
102 .validator_authority_id
103 .clone()
104 .into_iter()
105 .zip(test_authorities.peer_ids.clone())
106 .collect_vec();
107
108 let topology = keyrings
109 .clone()
110 .into_iter()
111 .enumerate()
112 .map(|(index, (discovery_id, peer_id))| TopologyPeerInfo {
113 peer_ids: vec![peer_id],
114 validator_index: ValidatorIndex(index as u32),
115 discovery_id,
116 })
117 .collect_vec();
118 let shuffled = (0..keyrings.len()).collect_vec();
119
120 SessionGridTopology::new(shuffled, topology)
121}
122
123pub fn generate_new_session_topology(
125 test_authorities: &TestAuthorities,
126 test_node: ValidatorIndex,
127 approval_voting_parallel_enabled: bool,
128) -> Vec<AllMessages> {
129 let topology = generate_topology(test_authorities);
130
131 let event = NetworkBridgeEvent::NewGossipTopology(NewGossipTopology {
132 session: 1,
133 topology,
134 local_index: Some(test_node),
135 });
136 vec![if approval_voting_parallel_enabled {
137 AllMessages::ApprovalVotingParallel(ApprovalVotingParallelMessage::NetworkBridgeUpdate(
138 event,
139 ))
140 } else {
141 AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NetworkBridgeUpdate(event))
142 }]
143}
144
145pub fn generate_peer_view_change_for(
147 block_hash: Hash,
148 peer_id: PeerId,
149 approval_voting_parallel_enabled: bool,
150) -> AllMessages {
151 let network = NetworkBridgeEvent::PeerViewChange(peer_id, View::new([block_hash], 0));
152 if approval_voting_parallel_enabled {
153 AllMessages::ApprovalVotingParallel(ApprovalVotingParallelMessage::NetworkBridgeUpdate(
154 network,
155 ))
156 } else {
157 AllMessages::ApprovalDistribution(ApprovalDistributionMessage::NetworkBridgeUpdate(network))
158 }
159}
160
161fn garbage_vrf_signature() -> VrfSignature {
163 let transcript = VrfTranscript::new(b"test-garbage", &[]);
164 Sr25519Keyring::Alice.pair().vrf_sign(&transcript.into())
165}
166
167pub fn make_header(parent_hash: Hash, slot: Slot, number: u32) -> Header {
169 let digest =
170 {
171 let mut digest = Digest::default();
172 let vrf_signature = garbage_vrf_signature();
173 digest.push(DigestItem::babe_pre_digest(PreDigest::SecondaryVRF(
174 SecondaryVRFPreDigest { authority_index: 0, slot, vrf_signature },
175 )));
176 digest
177 };
178
179 Header {
180 digest,
181 extrinsics_root: Default::default(),
182 number,
183 state_root: Default::default(),
184 parent_hash,
185 }
186}
187
188fn make_candidate(para_id: ParaId, hash: &Hash) -> CandidateReceiptV2 {
190 let mut r = dummy_candidate_receipt_v2_bad_sig(*hash, Some(Default::default()));
191 r.descriptor.set_para_id(para_id);
192 r
193}
194
195pub fn make_candidates(
197 block_hash: Hash,
198 block_number: BlockNumber,
199 num_cores: u32,
200 num_candidates: u32,
201) -> Vec<CandidateEvent> {
202 let seed = [block_number as u8; 32];
203 let mut rand_chacha = ChaCha20Rng::from_seed(seed);
204 let mut candidates = (0..num_cores)
205 .map(|core| {
206 CandidateEvent::CandidateIncluded(
207 make_candidate(ParaId::from(core), &block_hash),
208 Vec::new().into(),
209 CoreIndex(core),
210 GroupIndex(core),
211 )
212 })
213 .collect_vec();
214 let (candidates, _) = candidates.partial_shuffle(&mut rand_chacha, num_candidates as usize);
215 candidates
216 .iter_mut()
217 .map(|val| val.clone())
218 .sorted_by(|a, b| match (a, b) {
219 (
220 CandidateEvent::CandidateIncluded(_, _, core_a, _),
221 CandidateEvent::CandidateIncluded(_, _, core_b, _),
222 ) => core_a.0.cmp(&core_b.0),
223 (_, _) => todo!("Should not happen"),
224 })
225 .collect_vec()
226}