1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
16

            
17
#![allow(dead_code)]
18

            
19
use {
20
    crate::{
21
        Authorship, BlockProductionCost, CollatorAssignmentCost, ExternalValidatorSlashes,
22
        MessageQueue, RuntimeCall,
23
    },
24
    babe_primitives::{
25
        digests::{PreDigest, SecondaryPlainPreDigest},
26
        BABE_ENGINE_ID,
27
    },
28
    beefy_primitives::{ecdsa_crypto::AuthorityId as BeefyId, ConsensusLog, BEEFY_ENGINE_ID},
29
    bitvec::prelude::BitVec,
30
    cumulus_primitives_core::{
31
        relay_chain::{
32
            node_features::FeatureIndex, AvailabilityBitfield, BackedCandidate,
33
            CandidateCommitments, CandidateDescriptor, CollatorPair, CommittedCandidateReceipt,
34
            CompactStatement, CoreIndex, GroupIndex, HeadData,
35
            InherentData as ParachainsInherentData, PersistedValidationData, SigningContext,
36
            UncheckedSigned, ValidationCode, ValidatorIndex, ValidityAttestation,
37
        },
38
        ParaId,
39
    },
40
    frame_support::{
41
        assert_ok,
42
        traits::{OnFinalize, OnInitialize},
43
    },
44
    frame_system::pallet_prelude::{BlockNumberFor, HeaderFor},
45
    nimbus_primitives::NimbusId,
46
    pallet_registrar_runtime_api::ContainerChainGenesisData,
47
    pallet_services_payment::{ProvideBlockProductionCost, ProvideCollatorAssignmentCost},
48
    parity_scale_codec::{Decode, Encode, MaxEncodedLen},
49
    runtime_parachains::{
50
        paras::{ParaGenesisArgs, ParaKind},
51
        paras_inherent as parachains_paras_inherent,
52
    },
53
    snowbridge_beacon_primitives::{types::deneb, ExecutionProof, VersionedExecutionPayloadHeader},
54
    snowbridge_core::inbound::Proof,
55
    sp_core::Pair,
56
    sp_keystore::{KeystoreExt, KeystorePtr},
57
    sp_runtime::{
58
        traits::{Dispatchable, Header, One, SaturatedConversion, Zero},
59
        BuildStorage, Digest, DigestItem,
60
    },
61
    sp_std::collections::btree_map::BTreeMap,
62
    sp_storage::well_known_keys,
63
    test_relay_sproof_builder::ParaHeaderSproofBuilder,
64
};
65

            
66
mod xcm;
67

            
68
pub use crate::{
69
    genesis_config_presets::get_authority_keys_from_seed, AccountId, AuthorNoting, Babe, Balance,
70
    Balances, Beefy, BeefyMmrLeaf, ContainerRegistrar, DataPreservers, Grandpa, InflationRewards,
71
    Initializer, Mmr, Runtime, RuntimeOrigin, Session, System, TanssiAuthorityAssignment,
72
    TanssiCollatorAssignment, TransactionPayment,
73
};
74

            
75
pub const UNIT: Balance = 1_000_000_000_000_000_000;
76

            
77
3
pub fn read_last_entropy() -> [u8; 32] {
78
3
    let mut last = [0u8; 32];
79
3
    sp_io::storage::read(well_known_keys::INTRABLOCK_ENTROPY, &mut last[..], 0);
80
3
    last
81
3
}
82

            
83
176
pub fn session_to_block(n: u32) -> u32 {
84
176
    // let block_number = flashbox_runtime::Period::get() * n;
85
176
    let block_number = Babe::current_epoch().duration.saturated_into::<u32>() * n;
86
176

            
87
176
    // Add 1 because the block that emits the NewSession event cannot contain any extrinsics,
88
176
    // so this is the first block of the new session that can actually be used
89
176
    block_number + 1
90
176
}
91

            
92
17
pub fn babe_authorities() -> Vec<babe_primitives::AuthorityId> {
93
17
    Babe::authorities()
94
17
        .iter()
95
34
        .map(|(key, _)| key.clone())
96
17
        .collect()
97
17
}
98

            
99
8
pub fn grandpa_authorities() -> Vec<pallet_grandpa::AuthorityId> {
100
8
    Grandpa::grandpa_authorities()
101
8
        .iter()
102
16
        .map(|(key, _)| key.clone())
103
8
        .collect()
104
8
}
105

            
106
13
pub fn authorities_for_container(para_id: ParaId) -> Option<Vec<NimbusId>> {
107
13
    let session_index = Session::current_index();
108
13

            
109
13
    TanssiAuthorityAssignment::collator_container_chain(session_index)
110
13
        .expect("authorities should be set")
111
13
        .container_chains
112
13
        .get(&para_id)
113
13
        .cloned()
114
13
}
115

            
116
pub fn accounts_for_container(para_id: ParaId) -> Option<Vec<AccountId>> {
117
    TanssiCollatorAssignment::collator_container_chain()
118
        .container_chains
119
        .get(&para_id)
120
        .cloned()
121
}
122

            
123
3
pub fn get_beefy_digest(log: ConsensusLog<BeefyId>) -> DigestItem {
124
3
    DigestItem::Consensus(BEEFY_ENGINE_ID, log.encode())
125
3
}
126

            
127
/// FIXME: run_to_session(n) only runs to the last block of session n-1, so Session::index() will
128
/// return n-1. To actually run to session n, create an additional block afterwards using `run_block()`.
129
170
pub fn run_to_session(n: u32) {
130
170
    run_to_block(session_to_block(n));
131
170
}
132

            
133
/// Utility function that advances the chain to the desired block number.
134
///
135
/// After this function returns, the current block number will be `n`, and the block will be "open",
136
/// meaning that on_initialize has been executed, but on_finalize has not. To execute on_finalize as
137
/// well, for example to test a runtime api, manually call `end_block` after this, run the test, and
138
/// call `start_block` to ensure that this function keeps working as expected.
139
/// Extrinsics should always be executed before on_finalize.
140
255
pub fn run_to_block(n: u32) -> BTreeMap<u32, RunSummary> {
141
255
    let current_block_number = System::block_number();
142
255
    assert!(
143
255
        current_block_number < n,
144
        "run_to_block called with block {} when current block is {}",
145
        n,
146
        current_block_number
147
    );
148

            
149
255
    let mut summaries = BTreeMap::new();
150

            
151
3649
    while System::block_number() < n {
152
3394
        let summary = run_block();
153
3394
        let block_number = System::block_number();
154
3394
        summaries.insert(block_number, summary);
155
3394
    }
156

            
157
255
    summaries
158
255
}
159

            
160
40
pub fn get_genesis_data_with_validation_code() -> (ContainerChainGenesisData, Vec<u8>) {
161
40
    let validation_code = mock_validation_code().0;
162
40
    let genesis_data = ContainerChainGenesisData {
163
40
        storage: vec![(b":code".to_vec(), validation_code.clone()).into()],
164
40
        name: Default::default(),
165
40
        id: Default::default(),
166
40
        fork_id: Default::default(),
167
40
        extensions: vec![],
168
40
        properties: Default::default(),
169
40
    };
170
40
    (genesis_data, validation_code)
171
40
}
172

            
173
3582
pub fn insert_authorities_and_slot_digests(slot: u64) {
174
3582
    let pre_digest = Digest {
175
3582
        logs: vec![DigestItem::PreRuntime(
176
3582
            BABE_ENGINE_ID,
177
3582
            PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
178
3582
                slot: slot.into(),
179
3582
                authority_index: 0,
180
3582
            })
181
3582
            .encode(),
182
3582
        )],
183
3582
    };
184
3582

            
185
3582
    System::reset_events();
186
3582
    System::initialize(
187
3582
        &(System::block_number() + 1),
188
3582
        &System::parent_hash(),
189
3582
        &pre_digest,
190
3582
    );
191
3582
}
192

            
193
#[derive(Debug, Clone, Eq, PartialEq)]
194
pub struct RunSummary {
195
    pub inflation: Balance,
196
}
197

            
198
#[derive(Clone, Encode, Decode, PartialEq, Debug, scale_info::TypeInfo, MaxEncodedLen)]
199
enum RunBlockState {
200
3429
    Start(u32),
201
3428
    End(u32),
202
}
203

            
204
impl RunBlockState {
205
7011
    fn assert_can_advance(&self, new_state: &RunBlockState) {
206
7011
        match self {
207
3429
            RunBlockState::Start(n) => {
208
3429
                assert_eq!(
209
3429
                    new_state,
210
3429
                    &RunBlockState::End(*n),
211
                    "expected a call to end_block({}), but user called {:?}",
212
                    *n,
213
                    new_state
214
                );
215
            }
216
3582
            RunBlockState::End(n) => {
217
3582
                assert_eq!(
218
3582
                    new_state,
219
3582
                    &RunBlockState::Start(*n + 1),
220
                    "expected a call to start_block({}), but user called {:?}",
221
                    *n + 1,
222
                    new_state
223
                )
224
            }
225
        }
226
7011
    }
227
}
228

            
229
7011
fn advance_block_state_machine(new_state: RunBlockState) {
230
7011
    if frame_support::storage::unhashed::exists(b"__mock_is_xcm_test") {
231
        // Disable this check in XCM tests, because the XCM emulator runs on_initialize and
232
        // on_finalize automatically
233
        return;
234
7011
    }
235
7011
    let old_state: RunBlockState =
236
7011
        frame_support::storage::unhashed::get(b"__mock_debug_block_state").unwrap_or(
237
7011
            // Initial state is expecting a call to start() with block number 1, so old state should be
238
7011
            // end of block 0
239
7011
            RunBlockState::End(0),
240
7011
        );
241
7011
    old_state.assert_can_advance(&new_state);
242
7011
    frame_support::storage::unhashed::put(b"__mock_debug_block_state", &new_state);
243
7011
}
244

            
245
3582
pub fn start_block() -> RunSummary {
246
3582
    let block_number = System::block_number();
247
3582
    advance_block_state_machine(RunBlockState::Start(block_number + 1));
248
3582

            
249
3582
    insert_authorities_and_slot_digests(current_slot() + 1);
250
3582

            
251
3582
    // Initialize the new block
252
3582
    Babe::on_initialize(System::block_number());
253
3582
    Authorship::on_initialize(System::block_number());
254
3582
    ContainerRegistrar::on_initialize(System::block_number());
255
3582
    ExternalValidatorSlashes::on_initialize(System::block_number());
256
3582
    Session::on_initialize(System::block_number());
257
3582

            
258
3582
    Initializer::on_initialize(System::block_number());
259
3582
    TanssiCollatorAssignment::on_initialize(System::block_number());
260
3582
    MessageQueue::on_initialize(System::block_number());
261
3582

            
262
3582
    let current_issuance = Balances::total_issuance();
263
3582
    InflationRewards::on_initialize(System::block_number());
264
3582
    let new_issuance = Balances::total_issuance();
265
3582

            
266
3582
    let maybe_mock_inherent = take_new_inherent_data();
267
3582
    if let Some(mock_inherent_data) = maybe_mock_inherent {
268
9
        set_paras_inherent(mock_inherent_data);
269
3573
    }
270

            
271
3582
    Beefy::on_initialize(System::block_number());
272
3582
    Mmr::on_initialize(System::block_number());
273
3582
    BeefyMmrLeaf::on_initialize(System::block_number());
274
3582
    RunSummary {
275
3582
        inflation: new_issuance - current_issuance,
276
3582
    }
277
3582
}
278

            
279
3429
pub fn end_block() {
280
3429
    let block_number = System::block_number();
281
3429
    advance_block_state_machine(RunBlockState::End(block_number));
282
3429
    // Finalize the block
283
3429
    Babe::on_finalize(System::block_number());
284
3429
    Authorship::on_finalize(System::block_number());
285
3429
    Session::on_finalize(System::block_number());
286
3429
    Grandpa::on_finalize(System::block_number());
287
3429
    TransactionPayment::on_finalize(System::block_number());
288
3429
    Initializer::on_finalize(System::block_number());
289
3429
    ContainerRegistrar::on_finalize(System::block_number());
290
3429
    TanssiCollatorAssignment::on_finalize(System::block_number());
291
3429
    Beefy::on_finalize(System::block_number());
292
3429
    Mmr::on_finalize(System::block_number());
293
3429
    BeefyMmrLeaf::on_finalize(System::block_number());
294
3429
}
295

            
296
3425
pub fn run_block() -> RunSummary {
297
3425
    end_block();
298
3425

            
299
3425
    start_block()
300
3425
}
301

            
302
#[derive(Default, Clone)]
303
pub struct ParaRegistrationParams {
304
    pub para_id: u32,
305
    pub genesis_data: ContainerChainGenesisData,
306
    pub block_production_credits: u32,
307
    pub collator_assignment_credits: u32,
308
    pub parathread_params: Option<tp_traits::ParathreadParams>,
309
}
310

            
311
impl From<(u32, ContainerChainGenesisData, u32, u32)> for ParaRegistrationParams {
312
10
    fn from(value: (u32, ContainerChainGenesisData, u32, u32)) -> Self {
313
10
        Self {
314
10
            para_id: value.0,
315
10
            genesis_data: value.1,
316
10
            block_production_credits: value.2,
317
10
            collator_assignment_credits: value.3,
318
10
            parathread_params: None,
319
10
        }
320
10
    }
321
}
322

            
323
160
pub fn default_config() -> pallet_configuration::HostConfiguration {
324
160
    pallet_configuration::HostConfiguration {
325
160
        max_collators: 100,
326
160
        min_orchestrator_collators: 2,
327
160
        max_orchestrator_collators: 2,
328
160
        collators_per_container: 2,
329
160
        full_rotation_period: 0,
330
160
        ..Default::default()
331
160
    }
332
160
}
333

            
334
#[derive(Clone)]
335
pub struct ExtBuilder {
336
    // endowed accounts with balances
337
    balances: Vec<(AccountId, Balance)>,
338
    // [validator, amount]
339
    validators: Vec<(AccountId, Balance)>,
340
    // [validator, amount]
341
    external_validators: Vec<(AccountId, Balance)>,
342
    // [collator, amount]
343
    collators: Vec<(AccountId, Balance)>,
344
    // sudo key
345
    sudo: Option<AccountId>,
346
    // list of registered para ids: para_id, genesis_data, boot_nodes, block_credits, session_credits
347
    para_ids: Vec<ParaRegistrationParams>,
348
    // configuration to apply
349
    config: pallet_configuration::HostConfiguration,
350
    relay_config: runtime_parachains::configuration::HostConfiguration<BlockNumberFor<Runtime>>,
351
    own_para_id: Option<ParaId>,
352
    next_free_para_id: ParaId,
353
    keystore: Option<KeystorePtr>,
354
    safe_xcm_version: Option<u32>,
355
}
356

            
357
impl Default for ExtBuilder {
358
160
    fn default() -> Self {
359
160
        Self {
360
160
            balances: vec![
361
160
                // Alice gets 10k extra tokens for her mapping deposit
362
160
                (AccountId::from(ALICE), 210_000 * UNIT),
363
160
                (AccountId::from(BOB), 100_000 * UNIT),
364
160
            ],
365
160
            validators: vec![
366
160
                (AccountId::from(ALICE), 210 * UNIT),
367
160
                (AccountId::from(BOB), 100 * UNIT),
368
160
            ],
369
160
            external_validators: vec![],
370
160
            collators: Default::default(),
371
160
            sudo: Default::default(),
372
160
            para_ids: Default::default(),
373
160
            config: default_config(),
374
160
            relay_config: runtime_parachains::configuration::HostConfiguration {
375
160
                scheduler_params: SchedulerParams {
376
160
                    num_cores: 6,
377
160
                    ..Default::default()
378
160
                },
379
160
                max_head_data_size: 20500,
380
160
                ..Default::default()
381
160
            },
382
160
            own_para_id: Default::default(),
383
160
            next_free_para_id: Default::default(),
384
160
            keystore: None,
385
160
            safe_xcm_version: Default::default(),
386
160
        }
387
160
    }
388
}
389

            
390
impl ExtBuilder {
391
134
    pub fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
392
134
        self.balances = balances;
393
134
        self
394
134
    }
395

            
396
1
    pub fn with_sudo(mut self, sudo: AccountId) -> Self {
397
1
        self.sudo = Some(sudo);
398
1
        self
399
1
    }
400

            
401
13
    pub fn with_validators(mut self, validators: Vec<(AccountId, Balance)>) -> Self {
402
13
        self.validators = validators;
403
13
        self
404
13
    }
405

            
406
6
    pub fn with_external_validators(mut self, validators: Vec<(AccountId, Balance)>) -> Self {
407
6
        self.external_validators = validators;
408
6
        self
409
6
    }
410

            
411
73
    pub fn with_collators(mut self, collators: Vec<(AccountId, Balance)>) -> Self {
412
73
        self.collators = collators;
413
73
        self
414
73
    }
415

            
416
13
    pub fn with_para_ids(mut self, para_ids: Vec<ParaRegistrationParams>) -> Self {
417
13
        self.para_ids = para_ids;
418
13
        self
419
13
    }
420

            
421
    /// Helper function like `with_para_ids` but registering parachains with an empty genesis data,
422
    /// and max amount of credits.
423
45
    pub fn with_empty_parachains(mut self, para_ids: Vec<u32>) -> Self {
424
45
        self.para_ids = para_ids
425
45
            .into_iter()
426
100
            .map(|para_id| ParaRegistrationParams {
427
100
                para_id,
428
100
                genesis_data: empty_genesis_data(),
429
100
                block_production_credits: u32::MAX,
430
100
                collator_assignment_credits: u32::MAX,
431
100
                parathread_params: None,
432
100
            })
433
45
            .collect();
434
45
        self
435
45
    }
436

            
437
5
    pub fn with_additional_empty_parathreads(mut self, para_ids: Vec<u32>) -> Self {
438
5
        self.para_ids = self
439
5
            .para_ids
440
5
            .iter()
441
5
            .cloned()
442
14
            .chain(para_ids.into_iter().map(|para_id| ParaRegistrationParams {
443
14
                para_id,
444
14
                genesis_data: empty_genesis_data(),
445
14
                block_production_credits: u32::MAX,
446
14
                collator_assignment_credits: u32::MAX,
447
14
                parathread_params: Some(ParathreadParams {
448
14
                    slot_frequency: Default::default(),
449
14
                }),
450
14
            }))
451
5
            .collect();
452
5
        self
453
5
    }
454

            
455
    // Maybe change to with_collators_config?
456
19
    pub fn with_config(mut self, config: pallet_configuration::HostConfiguration) -> Self {
457
19
        self.config = config;
458
19
        self
459
19
    }
460

            
461
6
    pub fn with_safe_xcm_version(mut self, safe_xcm_version: u32) -> Self {
462
6
        self.safe_xcm_version = Some(safe_xcm_version);
463
6
        self
464
6
    }
465

            
466
    // Maybe change to with_collators_config?
467
19
    pub fn with_relay_config(
468
19
        mut self,
469
19
        relay_config: runtime_parachains::configuration::HostConfiguration<BlockNumberFor<Runtime>>,
470
19
    ) -> Self {
471
19
        self.relay_config = relay_config;
472
19
        self
473
19
    }
474

            
475
    // Maybe change to with_collators_config?
476
1
    pub fn with_next_free_para_id(mut self, para_id: ParaId) -> Self {
477
1
        self.next_free_para_id = para_id;
478
1
        self
479
1
    }
480

            
481
    // Maybe change to with_collators_config?
482
8
    pub fn with_keystore(mut self, keystore: KeystorePtr) -> Self {
483
8
        self.keystore = Some(keystore);
484
8
        self
485
8
    }
486

            
487
160
    pub fn build_storage(self) -> sp_core::storage::Storage {
488
160
        let mut t = frame_system::GenesisConfig::<Runtime>::default()
489
160
            .build_storage()
490
160
            .unwrap();
491
160

            
492
160
        pallet_babe::GenesisConfig::<Runtime> {
493
160
            ..Default::default()
494
160
        }
495
160
        .assimilate_storage(&mut t)
496
160
        .unwrap();
497
160

            
498
160
        pallet_balances::GenesisConfig::<Runtime> {
499
160
            balances: self.balances,
500
160
        }
501
160
        .assimilate_storage(&mut t)
502
160
        .unwrap();
503
160

            
504
160
        // We need to initialize these pallets first. When initializing pallet-session,
505
160
        // these values will be taken into account for collator-assignment.
506
160

            
507
160
        pallet_registrar::GenesisConfig::<Runtime> {
508
160
            para_ids: self
509
160
                .para_ids
510
160
                .iter()
511
160
                .cloned()
512
160
                .map(|registered_para| {
513
133
                    (
514
133
                        registered_para.para_id.into(),
515
133
                        registered_para.genesis_data,
516
133
                        registered_para.parathread_params,
517
133
                    )
518
160
                })
519
160
                .collect(),
520
160
            ..Default::default()
521
160
        }
522
160
        .assimilate_storage(&mut t)
523
160
        .unwrap();
524
160

            
525
160
        // We register mock wasm
526
160
        runtime_parachains::paras::GenesisConfig::<Runtime> {
527
160
            paras: self
528
160
                .para_ids
529
160
                .iter()
530
160
                .cloned()
531
160
                .map(|registered_para| {
532
133
                    let para_kind = if registered_para.parathread_params.is_some() {
533
18
                        ParaKind::Parathread
534
                    } else {
535
115
                        ParaKind::Parachain
536
                    };
537
133
                    (
538
133
                        registered_para.para_id.into(),
539
133
                        ParaGenesisArgs {
540
133
                            validation_code: mock_validation_code(),
541
133
                            para_kind,
542
133
                            genesis_head: HeadData::from(vec![0u8]),
543
133
                        },
544
133
                    )
545
160
                })
546
160
                .collect(),
547
160
            ..Default::default()
548
160
        }
549
160
        .assimilate_storage(&mut t)
550
160
        .unwrap();
551
160

            
552
160
        pallet_services_payment::GenesisConfig::<Runtime> {
553
160
            para_id_credits: self
554
160
                .para_ids
555
160
                .clone()
556
160
                .into_iter()
557
160
                .map(|registered_para| {
558
133
                    (
559
133
                        registered_para.para_id.into(),
560
133
                        registered_para.block_production_credits,
561
133
                        registered_para.collator_assignment_credits,
562
133
                    )
563
133
                        .into()
564
160
                })
565
160
                .collect(),
566
160
        }
567
160
        .assimilate_storage(&mut t)
568
160
        .unwrap();
569
160

            
570
160
        runtime_common::paras_registrar::GenesisConfig::<Runtime> {
571
160
            next_free_para_id: self.next_free_para_id,
572
160
            ..Default::default()
573
160
        }
574
160
        .assimilate_storage(&mut t)
575
160
        .unwrap();
576
160

            
577
160
        // TODO: add here pallet_services_payment::GenesisConfig
578
160

            
579
160
        pallet_configuration::GenesisConfig::<Runtime> {
580
160
            config: self.config,
581
160
            ..Default::default()
582
160
        }
583
160
        .assimilate_storage(&mut t)
584
160
        .unwrap();
585
160

            
586
160
        pallet_xcm::GenesisConfig::<Runtime> {
587
160
            safe_xcm_version: self.safe_xcm_version,
588
160
            ..Default::default()
589
160
        }
590
160
        .assimilate_storage(&mut t)
591
160
        .unwrap();
592
160

            
593
160
        runtime_parachains::configuration::GenesisConfig::<Runtime> {
594
160
            config: self.relay_config,
595
160
        }
596
160
        .assimilate_storage(&mut t)
597
160
        .unwrap();
598
160

            
599
160
        let mut keys: Vec<_> = Vec::new();
600
160
        let mut non_authority_keys: Vec<_> = Vec::new();
601
160
        if !self.validators.is_empty() {
602
154
            let validator_keys: Vec<_> = self
603
154
                .validators
604
154
                .clone()
605
154
                .into_iter()
606
323
                .map(|(account, _balance)| {
607
323
                    let authority_keys =
608
323
                        get_authority_keys_from_seed(&account.to_string(), self.keystore.as_ref());
609
323
                    (
610
323
                        account.clone(),
611
323
                        account,
612
323
                        crate::SessionKeys {
613
323
                            babe: authority_keys.babe.clone(),
614
323
                            grandpa: authority_keys.grandpa.clone(),
615
323
                            para_validator: authority_keys.para_validator.clone(),
616
323
                            para_assignment: authority_keys.para_assignment.clone(),
617
323
                            authority_discovery: authority_keys.authority_discovery.clone(),
618
323
                            beefy: authority_keys.beefy.clone(),
619
323
                            nimbus: authority_keys.nimbus.clone(),
620
323
                        },
621
323
                    )
622
323
                })
623
154
                .collect();
624
154
            keys.extend(validator_keys)
625
6
        }
626

            
627
160
        if !self.external_validators.is_empty() {
628
6
            let validator_keys: Vec<_> = self
629
6
                .external_validators
630
6
                .clone()
631
6
                .into_iter()
632
12
                .map(|(account, _balance)| {
633
12
                    let authority_keys =
634
12
                        get_authority_keys_from_seed(&account.to_string(), self.keystore.as_ref());
635
12
                    (
636
12
                        account.clone(),
637
12
                        account,
638
12
                        crate::SessionKeys {
639
12
                            babe: authority_keys.babe.clone(),
640
12
                            grandpa: authority_keys.grandpa.clone(),
641
12
                            para_validator: authority_keys.para_validator.clone(),
642
12
                            para_assignment: authority_keys.para_assignment.clone(),
643
12
                            authority_discovery: authority_keys.authority_discovery.clone(),
644
12
                            beefy: authority_keys.beefy.clone(),
645
12
                            nimbus: authority_keys.nimbus.clone(),
646
12
                        },
647
12
                    )
648
12
                })
649
6
                .collect();
650
6
            keys.extend(validator_keys)
651
154
        }
652

            
653
160
        if !self.collators.is_empty() {
654
            // We set invulnerables in pallet_invulnerables
655
73
            let invulnerables: Vec<AccountId> = self
656
73
                .collators
657
73
                .clone()
658
73
                .into_iter()
659
233
                .map(|(account, _balance)| account)
660
73
                .collect();
661
73

            
662
73
            pallet_invulnerables::GenesisConfig::<Runtime> {
663
73
                invulnerables: invulnerables.clone(),
664
73
            }
665
73
            .assimilate_storage(&mut t)
666
73
            .unwrap();
667
73

            
668
73
            // But we also initialize their keys in the session pallet
669
73
            // We discard those that had the key initialized already
670
73
            // from the validator list
671
73
            // in other words, for testing purposes we allow to inject a validator account
672
73
            // in the collator list
673
73
            let validator_unique_accounts: Vec<_> = self
674
73
                .validators
675
73
                .iter()
676
146
                .map(|(account, _)| account.clone())
677
73
                .collect();
678
73
            let collator_keys: Vec<_> = self
679
73
                .collators
680
73
                .into_iter()
681
233
                .filter_map(|(account, _balance)| {
682
233
                    if validator_unique_accounts.contains(&account) {
683
146
                        None
684
                    } else {
685
87
                        let authority_keys =
686
87
                            get_authority_keys_from_seed(&account.to_string(), None);
687
87
                        Some((
688
87
                            account.clone(),
689
87
                            account,
690
87
                            crate::SessionKeys {
691
87
                                babe: authority_keys.babe.clone(),
692
87
                                grandpa: authority_keys.grandpa.clone(),
693
87
                                para_validator: authority_keys.para_validator.clone(),
694
87
                                para_assignment: authority_keys.para_assignment.clone(),
695
87
                                authority_discovery: authority_keys.authority_discovery.clone(),
696
87
                                beefy: authority_keys.beefy.clone(),
697
87
                                nimbus: authority_keys.nimbus.clone(),
698
87
                            },
699
87
                        ))
700
                    }
701
233
                })
702
73
                .collect();
703
73
            non_authority_keys.extend(collator_keys)
704
87
        }
705

            
706
160
        pallet_external_validators::GenesisConfig::<Runtime> {
707
160
            skip_external_validators: false,
708
160
            whitelisted_validators: self
709
160
                .validators
710
160
                .iter()
711
323
                .map(|(account, _)| account.clone())
712
160
                .collect(),
713
160
            external_validators: self
714
160
                .external_validators
715
160
                .iter()
716
160
                .map(|(account, _)| account.clone())
717
160
                .collect(),
718
160
        }
719
160
        .assimilate_storage(&mut t)
720
160
        .unwrap();
721
160

            
722
160
        pallet_session::GenesisConfig::<Runtime> {
723
160
            keys,
724
160
            non_authority_keys,
725
160
        }
726
160
        .assimilate_storage(&mut t)
727
160
        .unwrap();
728
160

            
729
160
        pallet_sudo::GenesisConfig::<Runtime> { key: self.sudo }
730
160
            .assimilate_storage(&mut t)
731
160
            .unwrap();
732
160

            
733
160
        snowbridge_pallet_system::GenesisConfig::<Runtime> {
734
160
            // This is irrelevant, we can put any number here
735
160
            // as long as it is a non-used para id
736
160
            para_id: 1000u32.into(),
737
160
            asset_hub_para_id: 1001u32.into(),
738
160
            ..Default::default()
739
160
        }
740
160
        .assimilate_storage(&mut t)
741
160
        .unwrap();
742
160

            
743
160
        if self.safe_xcm_version.is_some() {
744
6
            // Disable run_block checks in XCM tests, because the XCM emulator runs on_initialize and
745
6
            // on_finalize automatically
746
6
            t.top.insert(b"__mock_is_xcm_test".to_vec(), b"1".to_vec());
747
154
        }
748

            
749
160
        t
750
160
    }
751

            
752
154
    pub fn build(self) -> sp_io::TestExternalities {
753
154
        let keystore = self.keystore.clone();
754
154
        let t = self.build_storage();
755
154
        let mut ext = sp_io::TestExternalities::new(t);
756
154
        if let Some(keystore) = keystore {
757
8
            ext.register_extension(KeystoreExt(keystore));
758
146
        }
759
154
        ext.execute_with(|| {
760
154
            // Start block 1
761
154
            start_block();
762
154
        });
763
154
        ext
764
154
    }
765
}
766

            
767
151
pub fn root_origin() -> <Runtime as frame_system::Config>::RuntimeOrigin {
768
151
    <Runtime as frame_system::Config>::RuntimeOrigin::root()
769
151
}
770

            
771
325
pub fn origin_of(account_id: AccountId) -> <Runtime as frame_system::Config>::RuntimeOrigin {
772
325
    <Runtime as frame_system::Config>::RuntimeOrigin::signed(account_id)
773
325
}
774

            
775
17
pub fn inherent_origin() -> <Runtime as frame_system::Config>::RuntimeOrigin {
776
17
    <Runtime as frame_system::Config>::RuntimeOrigin::none()
777
17
}
778

            
779
/// This function is different in solochains: instead of creating a storage proof and calling the
780
/// `set_latest_author_data` inherent with that proof as argument, this writes to storage directly.
781
8
pub fn set_author_noting_inherent_data(builder: ParaHeaderSproofBuilder) {
782
8
    for (k, v) in builder.key_values() {
783
8
        frame_support::storage::unhashed::put_raw(&k, &v);
784
8
    }
785

            
786
8
    assert_ok!(RuntimeCall::AuthorNoting(
787
8
        pallet_author_noting::Call::<Runtime>::set_latest_author_data { data: () }
788
8
    )
789
8
    .dispatch(inherent_origin()));
790
8
}
791

            
792
133
pub fn empty_genesis_data() -> ContainerChainGenesisData {
793
133
    ContainerChainGenesisData {
794
133
        storage: Default::default(),
795
133
        name: Default::default(),
796
133
        id: Default::default(),
797
133
        fork_id: Default::default(),
798
133
        extensions: Default::default(),
799
133
        properties: Default::default(),
800
133
    }
801
133
}
802

            
803
3582
pub fn current_slot() -> u64 {
804
3582
    Babe::current_slot().into()
805
3582
}
806

            
807
21
pub fn block_credits_to_required_balance(number_of_blocks: u32, para_id: ParaId) -> Balance {
808
21
    let block_cost = BlockProductionCost::block_cost(&para_id).0;
809
21
    u128::from(number_of_blocks).saturating_mul(block_cost)
810
21
}
811

            
812
4
pub fn collator_assignment_credits_to_required_balance(
813
4
    number_of_sessions: u32,
814
4
    para_id: ParaId,
815
4
) -> Balance {
816
4
    let collator_assignment_cost = CollatorAssignmentCost::collator_assignment_cost(&para_id).0;
817
4
    u128::from(number_of_sessions).saturating_mul(collator_assignment_cost)
818
4
}
819

            
820
pub const ALICE: [u8; 32] = [4u8; 32];
821
pub const BOB: [u8; 32] = [5u8; 32];
822
pub const CHARLIE: [u8; 32] = [6u8; 32];
823
pub const DAVE: [u8; 32] = [7u8; 32];
824
pub const EVE: [u8; 32] = [8u8; 32];
825
pub const FERDIE: [u8; 32] = [9u8; 32];
826

            
827
3582
fn take_new_inherent_data() -> Option<cumulus_primitives_core::relay_chain::InherentData> {
828
3582
    let data: Option<cumulus_primitives_core::relay_chain::InherentData> =
829
3582
        frame_support::storage::unhashed::take(b"ParasInherent");
830
3582

            
831
3582
    data
832
3582
}
833

            
834
9
pub fn set_new_inherent_data(data: cumulus_primitives_core::relay_chain::InherentData) {
835
9
    frame_support::storage::unhashed::put(b"ParasInherent", &data);
836
9
}
837

            
838
1
pub fn set_new_randomness_data(data: Option<[u8; 32]>) {
839
1
    pallet_babe::AuthorVrfRandomness::<Runtime>::set(data);
840
1
}
841

            
842
/// Mock the inherent that sets validation data in ParachainSystem, which
843
/// contains the `relay_chain_block_number`, which is used in `collator-assignment` as a
844
/// source of randomness.
845
9
pub fn set_paras_inherent(data: cumulus_primitives_core::relay_chain::InherentData) {
846
9
    // In order for this inherent to work, we need to match the parent header
847
9
    // the parent header does not play a significant role in the rest of the framework so
848
9
    // we are simply going to mock it
849
9
    System::set_parent_hash(data.parent_header.hash());
850
9
    assert_ok!(
851
9
        RuntimeCall::ParaInherent(parachains_paras_inherent::Call::<Runtime>::enter { data })
852
9
            .dispatch(inherent_origin())
853
9
    );
854
5
    frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix(
855
5
        b"ParaInherent",
856
5
        b"Included",
857
5
    ));
858
5
}
859

            
860
pub(crate) struct ParasInherentTestBuilder<T: runtime_parachains::paras_inherent::Config> {
861
    /// Starting block number; we expect it to get incremented on session setup.
862
    block_number: BlockNumberFor<T>,
863
    /// Paras here will both be backed in the inherent data and already occupying a core (which is
864
    /// freed via bitfields).
865
    ///
866
    /// Map from para id to number of validity votes. Core indices are generated based on
867
    /// `elastic_paras` configuration. Each para id in `elastic_paras` gets the
868
    /// specified amount of consecutive cores assigned to it. If a para id is not present
869
    /// in `elastic_paras` it get assigned to a single core.
870
    backed_and_concluding_paras: BTreeMap<u32, u32>,
871

            
872
    /// Paras which don't yet occupy a core, but will after the inherent has been processed.
873
    backed_in_inherent_paras: BTreeMap<u32, u32>,
874
    _phantom: core::marker::PhantomData<T>,
875
}
876

            
877
183
pub fn mock_validation_code() -> ValidationCode {
878
183
    ValidationCode(vec![1; 10])
879
183
}
880

            
881
#[allow(dead_code)]
882
impl<T: runtime_parachains::paras_inherent::Config> ParasInherentTestBuilder<T> {
883
    /// Create a new `BenchBuilder` with some opinionated values that should work with the rest
884
    /// of the functions in this implementation.
885
9
    pub(crate) fn new() -> Self {
886
9
        ParasInherentTestBuilder {
887
9
            block_number: Zero::zero(),
888
9
            backed_and_concluding_paras: Default::default(),
889
9
            backed_in_inherent_paras: Default::default(),
890
9
            _phantom: core::marker::PhantomData::<T>,
891
9
        }
892
9
    }
893

            
894
    /// Set a map from para id seed to number of validity votes.
895
9
    pub(crate) fn set_backed_and_concluding_paras(
896
9
        mut self,
897
9
        backed_and_concluding_paras: BTreeMap<u32, u32>,
898
9
    ) -> Self {
899
9
        self.backed_and_concluding_paras = backed_and_concluding_paras;
900
9
        self
901
9
    }
902

            
903
    /// Set a map from para id seed to number of validity votes for votes in inherent data.
904
    pub(crate) fn set_backed_in_inherent_paras(mut self, backed: BTreeMap<u32, u32>) -> Self {
905
        self.backed_in_inherent_paras = backed;
906
        self
907
    }
908

            
909
    /// Mock header.
910
47
    pub(crate) fn header(block_number: BlockNumberFor<T>) -> HeaderFor<T> {
911
47
        HeaderFor::<T>::new(
912
47
            block_number,       // `block_number`,
913
47
            Default::default(), // `extrinsics_root`,
914
47
            Default::default(), // `storage_root`,
915
47
            Default::default(), // `parent_hash`,
916
47
            Default::default(), // digest,
917
47
        )
918
47
    }
919

            
920
    /// Maximum number of validators that may be part of a validator group.
921
9
    pub(crate) fn fallback_max_validators() -> u32 {
922
9
        runtime_parachains::configuration::ActiveConfig::<T>::get()
923
9
            .max_validators
924
9
            .unwrap_or(200)
925
9
    }
926

            
927
    /// Maximum number of validators participating in parachains consensus (a.k.a. active
928
    /// validators).
929
9
    fn max_validators(&self) -> u32 {
930
9
        Self::fallback_max_validators()
931
9
    }
932

            
933
    /// Maximum number of validators per core (a.k.a. max validators per group). This value is used
934
    /// if none is explicitly set on the builder.
935
9
    pub(crate) fn fallback_max_validators_per_core() -> u32 {
936
9
        runtime_parachains::configuration::ActiveConfig::<T>::get()
937
9
            .scheduler_params
938
9
            .max_validators_per_core
939
9
            .unwrap_or(5)
940
9
    }
941

            
942
    /// Get the maximum number of validators per core.
943
9
    fn max_validators_per_core(&self) -> u32 {
944
9
        Self::fallback_max_validators_per_core()
945
9
    }
946

            
947
    /// Get the maximum number of cores we expect from this configuration.
948
9
    pub(crate) fn max_cores(&self) -> u32 {
949
9
        self.max_validators() / self.max_validators_per_core()
950
9
    }
951

            
952
    /// Create an `AvailabilityBitfield` where `concluding` is a map where each key is a core index
953
    /// that is concluding and `cores` is the total number of cores in the system.
954
9
    fn availability_bitvec(used_cores: usize, cores: usize) -> AvailabilityBitfield {
955
9
        let mut bitfields = bitvec::bitvec![u8, bitvec::order::Lsb0; 0; 0];
956
360
        for i in 0..cores {
957
360
            if i < used_cores {
958
10
                bitfields.push(true);
959
10
            } else {
960
350
                bitfields.push(false)
961
            }
962
        }
963

            
964
9
        bitfields.into()
965
9
    }
966

            
967
    /// Create a bitvec of `validators` length with all yes votes.
968
    fn validator_availability_votes_yes(validators: usize) -> BitVec<u8, bitvec::order::Lsb0> {
969
        // every validator confirms availability.
970
        bitvec::bitvec![u8, bitvec::order::Lsb0; 1; validators]
971
    }
972

            
973
20
    pub fn mock_head_data() -> HeadData {
974
20
        let max_head_size =
975
20
            runtime_parachains::configuration::ActiveConfig::<T>::get().max_head_data_size;
976
20
        HeadData(vec![0xFF; max_head_size as usize])
977
20
    }
978

            
979
    /// Number of the relay parent block.
980
20
    fn relay_parent_number(&self) -> u32 {
981
20
        (Self::block_number() - One::one())
982
20
            .try_into()
983
20
            .map_err(|_| ())
984
20
            .expect("Self::block_number() is u32")
985
20
    }
986

            
987
    /// Create backed candidates for `cores_with_backed_candidates`. You need these cores to be
988
    /// scheduled _within_ paras inherent, which requires marking the available bitfields as fully
989
    /// available.
990
    /// - `cores_with_backed_candidates` Mapping of `para_id` seed to number of
991
    /// validity votes.
992
    /// Important! this uses a BtreeMap, which means that elements will use increasing core orders
993
    /// example: if we have parachains 1000, 1001, and 1002, they will use respectively cores
994
    /// 0 1 and 2. There is no way in which we force 1002 to use core 0 in this setup
995
9
    fn create_backed_candidates(
996
9
        &self,
997
9
        paras_with_backed_candidates: &BTreeMap<u32, u32>,
998
9
    ) -> Vec<BackedCandidate<T::Hash>> {
999
9
        let current_session = runtime_parachains::shared::CurrentSessionIndex::<T>::get();
9
        // We need to refetch validators since they have been shuffled.
9
        let validators_shuffled =
9
            runtime_parachains::session_info::Sessions::<T>::get(current_session)
9
                .unwrap()
9
                .validators
9
                .clone();
9

            
9
        let config = runtime_parachains::configuration::ActiveConfig::<T>::get();
9
        let mut current_core_idx = 0u32;
9
        paras_with_backed_candidates
9
            .iter()
10
            .flat_map(|(seed, num_votes)| {
10
                assert!(*num_votes <= validators_shuffled.len() as u32);
10
                let para_id = ParaId::from(*seed);
10
                let prev_head_non_mut = runtime_parachains::paras::Heads::<T>::get(para_id);
10
                let prev_head = prev_head_non_mut.unwrap_or(Self::mock_head_data());
10
                // How many chained candidates we want to build ?
10
                (0..1)
10
                    .map(|chain_idx| {
10
                        let core_idx = CoreIndex::from(current_core_idx);
10
                        // Advance core index.
10
                        current_core_idx += 1;
10
                        let group_idx =
10
                            Self::group_assigned_to_core(core_idx, Self::block_number())
10
                                .unwrap_or_else(|| {
                                    panic!("Validator group not assigned to core {:?}", core_idx)
10
                                });
10

            
10
                        let header = Self::header(Self::block_number());
10
                        let relay_parent = header.hash();
10

            
10
                        // Set the head data so it can be used while validating the signatures on
10
                        // the candidate receipt.
10
                        let mut head_data = Self::mock_head_data();
10

            
10
                        if chain_idx == 0 {
10
                            // Only first parahead of the chain needs to be set in storage.
10
                            Self::heads_insert(&para_id, prev_head.clone());
10
                        } else {
                            // Make each candidate head data unique to avoid cycles.
                            head_data.0[0] = chain_idx;
                        }
10
                        let persisted_validation_data = PersistedValidationData::<T::Hash> {
10
                            // To form a chain we set parent head to previous block if any, or
10
                            // default to what is in storage already setup.
10
                            parent_head: prev_head.clone(),
10
                            relay_parent_number: self.relay_parent_number() + 1,
10
                            relay_parent_storage_root: Default::default(),
10
                            max_pov_size: config.max_pov_size,
10
                        };
10

            
10
                        let persisted_validation_data_hash = persisted_validation_data.hash();
10

            
10
                        let pov_hash = Default::default();
10
                        let validation_code_hash = mock_validation_code().hash();
10
                        let payload =
10
                            cumulus_primitives_core::relay_chain::collator_signature_payload(
10
                                &relay_parent,
10
                                &para_id,
10
                                &persisted_validation_data_hash,
10
                                &pov_hash,
10
                                &validation_code_hash,
10
                            );
10

            
10
                        let collator_pair = CollatorPair::generate().0;
10

            
10
                        let signature = collator_pair.sign(&payload);
10

            
10
                        let group_validators = Self::group_validators(group_idx).unwrap();
10

            
10
                        let candidate = CommittedCandidateReceipt::<T::Hash> {
10
                            descriptor: CandidateDescriptor::<T::Hash> {
10
                                para_id,
10
                                relay_parent,
10
                                collator: collator_pair.public(),
10
                                persisted_validation_data_hash,
10
                                pov_hash,
10
                                erasure_root: Default::default(),
10
                                signature,
10
                                para_head: prev_head.hash(),
10
                                validation_code_hash,
10
                            },
10
                            commitments: CandidateCommitments::<u32> {
10
                                upward_messages: Default::default(),
10
                                horizontal_messages: Default::default(),
10
                                new_validation_code: None,
10
                                head_data: prev_head.clone(),
10
                                processed_downward_messages: 0,
10
                                hrmp_watermark: self.relay_parent_number() + 1,
10
                            },
10
                        };
10

            
10
                        let candidate_hash = candidate.hash();
10

            
10
                        let validity_votes: Vec<_> = group_validators
10
                            .iter()
10
                            .take(*num_votes as usize)
10
                            .map(|val_idx| {
10
                                let public = validators_shuffled.get(*val_idx).unwrap();
10

            
10
                                let signature_ctx = SigningContext {
10
                                    parent_hash: Self::header(Self::block_number()).hash(),
10
                                    session_index: Session::current_index(),
10
                                };
10
                                let sig = UncheckedSigned::<CompactStatement>::benchmark_sign(
10
                                    public,
10
                                    CompactStatement::Valid(candidate_hash),
10
                                    &signature_ctx,
10
                                    *val_idx,
10
                                )
10
                                .benchmark_signature();
10

            
10
                                ValidityAttestation::Explicit(sig.clone())
10
                            })
10
                            .collect();
10

            
10
                        // Check if the elastic scaling bit is set, if so we need to supply the core
10
                        // index in the generated candidate.
10
                        let core_idx = runtime_parachains::configuration::ActiveConfig::<T>::get()
10
                            .node_features
10
                            .get(FeatureIndex::ElasticScalingMVP as usize)
10
                            .map(|_the_bit| core_idx);
10

            
10
                        BackedCandidate::<T::Hash>::new(
10
                            candidate,
10
                            validity_votes,
10
                            bitvec::bitvec![u8, bitvec::order::Lsb0; 1; group_validators.len()],
10
                            core_idx,
10
                        )
10
                    })
10
                    .collect::<Vec<_>>()
10
            })
9
            .collect()
9
    }
    /// Get the group assigned to a specific core by index at the current block number. Result
    /// undefined if the core index is unknown or the block number is less than the session start
    /// index.
10
    pub(crate) fn group_assigned_to_core(
10
        core: CoreIndex,
10
        at: BlockNumberFor<T>,
10
    ) -> Option<GroupIndex> {
10
        let config = runtime_parachains::configuration::ActiveConfig::<T>::get();
10
        let session_start_block = runtime_parachains::scheduler::SessionStartBlock::<T>::get();
10

            
10
        if at < session_start_block {
            return None;
10
        }
10

            
10
        let validator_groups = runtime_parachains::scheduler::ValidatorGroups::<T>::get();
10

            
10
        if core.0 as usize >= validator_groups.len() {
            return None;
10
        }
10

            
10
        let rotations_since_session_start: BlockNumberFor<T> =
10
            (at - session_start_block) / config.scheduler_params.group_rotation_frequency;
10

            
10
        let rotations_since_session_start =
10
            <BlockNumberFor<T> as TryInto<u32>>::try_into(rotations_since_session_start)
10
                .unwrap_or(0);
10
        // Error case can only happen if rotations occur only once every u32::max(),
10
        // so functionally no difference in behavior.
10

            
10
        let group_idx =
10
            (core.0 as usize + rotations_since_session_start as usize) % validator_groups.len();
10
        Some(GroupIndex(group_idx as u32))
10
    }
    /// Get the validators in the given group, if the group index is valid for this session.
10
    pub(crate) fn group_validators(group_index: GroupIndex) -> Option<Vec<ValidatorIndex>> {
10
        runtime_parachains::scheduler::ValidatorGroups::<T>::get()
10
            .get(group_index.0 as usize)
10
            .cloned()
10
    }
10
    pub fn heads_insert(para_id: &ParaId, head_data: HeadData) {
10
        runtime_parachains::paras::Heads::<T>::insert(para_id, head_data);
10
    }
    /// Build a scenario for testing.
    ///
    /// Note that this API only allows building scenarios where the `backed_and_concluding_paras`
    /// are mutually exclusive with the cores for disputes. So
    /// `backed_and_concluding_paras.len() + dispute_sessions.len() + backed_in_inherent_paras` must
    /// be less than the max number of cores.
9
    pub(crate) fn build(self) -> ParachainsInherentData<HeaderFor<T>> {
9
        let current_session = runtime_parachains::shared::CurrentSessionIndex::<T>::get();
9
        // We need to refetch validators since they have been shuffled.
9
        let validators = runtime_parachains::session_info::Sessions::<T>::get(current_session)
9
            .unwrap()
9
            .validators
9
            .clone();
9

            
9
        let max_cores = self.max_cores() as usize;
9

            
9
        let used_cores =
9
            self.backed_and_concluding_paras.len() + self.backed_in_inherent_paras.len();
9
        assert!(used_cores <= max_cores);
9
        let mut backed_in_inherent = BTreeMap::new();
9
        backed_in_inherent.append(&mut self.backed_and_concluding_paras.clone());
9
        backed_in_inherent.append(&mut self.backed_in_inherent_paras.clone());
9
        let backed_candidates = self.create_backed_candidates(&backed_in_inherent);
9

            
9
        let availability_bitvec = Self::availability_bitvec(used_cores, max_cores);
9

            
9
        let bitfields: Vec<UncheckedSigned<AvailabilityBitfield>> = validators
9
            .iter()
9
            .enumerate()
18
            .map(|(i, public)| {
18
                UncheckedSigned::<AvailabilityBitfield>::benchmark_sign(
18
                    public,
18
                    availability_bitvec.clone(),
18
                    &SigningContext {
18
                        parent_hash: Self::header(Self::block_number()).hash(),
18
                        session_index: Session::current_index(),
18
                    },
18
                    ValidatorIndex(i as u32),
18
                )
18
            })
9
            .collect();
9

            
9
        ParachainsInherentData {
9
            bitfields,
9
            backed_candidates,
9
            disputes: vec![],
9
            parent_header: Self::header(Self::block_number()),
9
        }
9
    }
77
    pub(crate) fn block_number() -> BlockNumberFor<T> {
77
        frame_system::Pallet::<T>::block_number()
77
    }
}
use {
    cumulus_primitives_core::relay_chain::SchedulerParams, frame_support::StorageHasher,
    tp_traits::ParathreadParams,
};
2
pub fn storage_map_final_key<H: frame_support::StorageHasher>(
2
    pallet_prefix: &str,
2
    map_name: &str,
2
    key: &[u8],
2
) -> Vec<u8> {
2
    let key_hashed = H::hash(key);
2
    let pallet_prefix_hashed = frame_support::Twox128::hash(pallet_prefix.as_bytes());
2
    let storage_prefix_hashed = frame_support::Twox128::hash(map_name.as_bytes());
2

            
2
    let mut final_key = Vec::with_capacity(
2
        pallet_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len(),
2
    );
2

            
2
    final_key.extend_from_slice(&pallet_prefix_hashed[..]);
2
    final_key.extend_from_slice(&storage_prefix_hashed[..]);
2
    final_key.extend_from_slice(key_hashed.as_ref());
2

            
2
    final_key
2
}
23
pub fn set_dummy_boot_node(para_manager: RuntimeOrigin, para_id: ParaId) {
    use {
        crate::{PreserversAssignmentPaymentExtra, PreserversAssignmentPaymentRequest},
        pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode},
    };
23
    let profile = Profile {
23
        url:
23
            b"/ip4/127.0.0.1/tcp/33049/ws/p2p/12D3KooWHVMhQDHBpj9vQmssgyfspYecgV6e3hH1dQVDUkUbCYC9"
23
                .to_vec()
23
                .try_into()
23
                .expect("to fit in BoundedVec"),
23
        para_ids: ParaIdsFilter::AnyParaId,
23
        mode: ProfileMode::Bootnode,
23
        assignment_request: PreserversAssignmentPaymentRequest::Free,
23
    };
23

            
23
    let profile_id = pallet_data_preservers::NextProfileId::<Runtime>::get();
23
    let profile_owner = AccountId::new([1u8; 32]);
23
    DataPreservers::force_create_profile(RuntimeOrigin::root(), profile, profile_owner)
23
        .expect("profile create to succeed");
23

            
23
    DataPreservers::start_assignment(
23
        para_manager,
23
        profile_id,
23
        para_id,
23
        PreserversAssignmentPaymentExtra::Free,
23
    )
23
    .expect("assignment to work");
23

            
23
    assert!(
23
        pallet_data_preservers::Assignments::<Runtime>::get(para_id).contains(&profile_id),
        "profile should be correctly assigned"
    );
23
}
use milagro_bls::Keypair;
1
pub fn generate_ethereum_pub_keys(n: u32) -> Vec<Keypair> {
1
    let mut keys = vec![];
512
    for _i in 0..n {
512
        let keypair = Keypair::random(&mut rand::thread_rng());
512
        keys.push(keypair);
512
    }
1
    keys
1
}
use babe_primitives::AuthorityPair as BabeAuthorityPair;
use grandpa_primitives::{
    AuthorityPair as GrandpaAuthorityPair, Equivocation, EquivocationProof, RoundNumber, SetId,
};
use sp_core::H256;
3
pub fn generate_grandpa_equivocation_proof(
3
    set_id: SetId,
3
    vote1: (RoundNumber, H256, u32, &GrandpaAuthorityPair),
3
    vote2: (RoundNumber, H256, u32, &GrandpaAuthorityPair),
3
) -> EquivocationProof<H256, u32> {
6
    let signed_prevote = |round, hash, number, authority_pair: &GrandpaAuthorityPair| {
6
        let prevote = finality_grandpa::Prevote {
6
            target_hash: hash,
6
            target_number: number,
6
        };
6

            
6
        let prevote_msg = finality_grandpa::Message::Prevote(prevote.clone());
6
        let payload = grandpa_primitives::localized_payload(round, set_id, &prevote_msg);
6
        let signed = authority_pair.sign(&payload);
6
        (prevote, signed)
6
    };
3
    let (prevote1, signed1) = signed_prevote(vote1.0, vote1.1, vote1.2, vote1.3);
3
    let (prevote2, signed2) = signed_prevote(vote2.0, vote2.1, vote2.2, vote2.3);
3

            
3
    EquivocationProof::new(
3
        set_id,
3
        Equivocation::Prevote(finality_grandpa::Equivocation {
3
            round_number: vote1.0,
3
            identity: vote1.3.public(),
3
            first: (prevote1, signed1),
3
            second: (prevote2, signed2),
3
        }),
3
    )
3
}
/// Creates an equivocation at the current block, by generating two headers.
8
pub fn generate_babe_equivocation_proof(
8
    offender_authority_pair: &BabeAuthorityPair,
8
) -> babe_primitives::EquivocationProof<crate::Header> {
    use babe_primitives::digests::CompatibleDigestItem;
8
    let current_digest = System::digest();
8
    let babe_predigest = current_digest
8
        .clone()
8
        .logs()
8
        .iter()
8
        .find_map(|log| log.as_babe_pre_digest());
8
    let slot_proof = babe_predigest.expect("babe should be presesnt").slot();
8

            
8
    let make_headers = || {
8
        (
8
            HeaderFor::<Runtime>::new(
8
                0,
8
                H256::default(),
8
                H256::default(),
8
                H256::default(),
8
                current_digest.clone(),
8
            ),
8
            HeaderFor::<Runtime>::new(
8
                1,
8
                H256::default(),
8
                H256::default(),
8
                H256::default(),
8
                current_digest.clone(),
8
            ),
8
        )
8
    };
    // sign the header prehash and sign it, adding it to the block as the seal
    // digest item
16
    let seal_header = |header: &mut crate::Header| {
16
        let prehash = header.hash();
16
        let seal = <DigestItem as CompatibleDigestItem>::babe_seal(
16
            offender_authority_pair.sign(prehash.as_ref()),
16
        );
16
        header.digest_mut().push(seal);
16
    };
    // generate two headers at the current block
8
    let (mut h1, mut h2) = make_headers();
8

            
8
    seal_header(&mut h1);
8
    seal_header(&mut h2);
8

            
8
    babe_primitives::EquivocationProof {
8
        slot: slot_proof,
8
        offender: offender_authority_pair.public(),
8
        first_header: h1,
8
        second_header: h2,
8
    }
8
}
use sp_core::Public;
/// Helper function to generate a crypto pair from seed
11
pub fn get_pair_from_seed<TPublic: Public>(seed: &str) -> TPublic::Pair {
11
    let secret_uri = format!("//{}", seed);
11
    let pair = TPublic::Pair::from_string(&secret_uri, None).expect("static values are valid; qed");
11

            
11
    pair
11
}
3
pub fn mock_snowbridge_message_proof() -> Proof {
3
    Proof {
3
        receipt_proof: (vec![], vec![]),
3
        execution_proof: ExecutionProof {
3
            header: Default::default(),
3
            ancestry_proof: None,
3
            execution_header: VersionedExecutionPayloadHeader::Deneb(
3
                deneb::ExecutionPayloadHeader {
3
                    parent_hash: Default::default(),
3
                    fee_recipient: Default::default(),
3
                    state_root: Default::default(),
3
                    receipts_root: Default::default(),
3
                    logs_bloom: vec![],
3
                    prev_randao: Default::default(),
3
                    block_number: 0,
3
                    gas_limit: 0,
3
                    gas_used: 0,
3
                    timestamp: 0,
3
                    extra_data: vec![],
3
                    base_fee_per_gas: Default::default(),
3
                    block_hash: Default::default(),
3
                    transactions_root: Default::default(),
3
                    withdrawals_root: Default::default(),
3
                    blob_gas_used: 0,
3
                    excess_blob_gas: 0,
3
                },
3
            ),
3
            execution_branch: vec![],
3
        },
3
    }
3
}