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, vstaging::BackedCandidate,
33
            vstaging::CandidateDescriptorV2, vstaging::CommittedCandidateReceiptV2,
34
            vstaging::InherentData as ParachainsInherentData, AvailabilityBitfield,
35
            CandidateCommitments, CompactStatement, CoreIndex, GroupIndex, HeadData,
36
            PersistedValidationData, SigningContext, UncheckedSigned, ValidationCode,
37
            ValidatorIndex, ValidityAttestation,
38
        },
39
        ParaId,
40
    },
41
    frame_support::{
42
        assert_ok,
43
        traits::{OnFinalize, OnInitialize},
44
        BoundedVec,
45
    },
46
    frame_system::pallet_prelude::{BlockNumberFor, HeaderFor},
47
    nimbus_primitives::NimbusId,
48
    pallet_registrar_runtime_api::ContainerChainGenesisData,
49
    pallet_services_payment::{ProvideBlockProductionCost, ProvideCollatorAssignmentCost},
50
    parity_scale_codec::{Decode, Encode, MaxEncodedLen},
51
    runtime_parachains::{
52
        paras::{ParaGenesisArgs, ParaKind},
53
        paras_inherent as parachains_paras_inherent,
54
    },
55
    snowbridge_beacon_primitives::{types::deneb, ExecutionProof, VersionedExecutionPayloadHeader},
56
    snowbridge_core::inbound::Proof,
57
    sp_core::Pair,
58
    sp_core::Public,
59
    sp_keystore::{KeystoreExt, KeystorePtr},
60
    sp_runtime::{
61
        traits::{Dispatchable, Header, One, SaturatedConversion, Zero},
62
        BuildStorage, Digest, DigestItem,
63
    },
64
    sp_std::collections::btree_map::BTreeMap,
65
    sp_storage::well_known_keys,
66
    std::collections::BTreeSet,
67
    test_relay_sproof_builder::ParaHeaderSproofBuilder,
68
};
69

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

            
77
pub const UNIT: Balance = 1_000_000_000_000;
78

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

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

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

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

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

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

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

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

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

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

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

            
151
264
    let mut summaries = BTreeMap::new();
152

            
153
3668
    while System::block_number() < n {
154
3404
        let summary = run_block();
155
3404
        let block_number = System::block_number();
156
3404
        summaries.insert(block_number, summary);
157
3404
    }
158

            
159
264
    summaries
160
264
}
161

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

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

            
188
3616
    System::reset_events();
189
3616
    System::initialize(
190
3616
        &(System::block_number() + 1),
191
3616
        &System::parent_hash(),
192
3616
        &pre_digest,
193
3616
    );
194
3616
}
195

            
196
#[derive(Debug, Clone, Eq, PartialEq)]
197
pub struct RunSummary {
198
    pub inflation: Balance,
199
}
200

            
201
#[derive(Clone, Encode, Decode, PartialEq, Debug, scale_info::TypeInfo, MaxEncodedLen)]
202
enum RunBlockState {
203
3441
    Start(u32),
204
3441
    End(u32),
205
}
206

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

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

            
248
3616
pub fn start_block() -> RunSummary {
249
    // we inject empty data
250
    // We need to create it here, because otherwise the block number increases
251
    // on-initialize.
252
    // This requires signatures so we should not run it unless we have a keystore
253
3616
    let mock_inherent_data: Option<cumulus_primitives_core::relay_chain::vstaging::InherentData> =
254
3616
        if is_para_inherent_enabled() {
255
            // We check the inherent data in storage else we construct an empty one
256
96
            Some(
257
96
                take_new_inherent_data()
258
96
                    .unwrap_or(ParasInherentTestBuilder::<Runtime>::new().build()),
259
96
            )
260
        } else {
261
3520
            None
262
        };
263

            
264
3616
    let block_number = System::block_number();
265
3616
    advance_block_state_machine(RunBlockState::Start(block_number + 1));
266
3616

            
267
3616
    insert_authorities_and_slot_digests(current_slot() + 1);
268
3616

            
269
3616
    // Initialize the new block
270
3616
    Babe::on_initialize(System::block_number());
271
3616
    Authorship::on_initialize(System::block_number());
272
3616
    ContainerRegistrar::on_initialize(System::block_number());
273
3616
    ExternalValidatorSlashes::on_initialize(System::block_number());
274
3616
    Session::on_initialize(System::block_number());
275
3616

            
276
3616
    Initializer::on_initialize(System::block_number());
277
3616
    TanssiCollatorAssignment::on_initialize(System::block_number());
278
3616
    MessageQueue::on_initialize(System::block_number());
279
3616

            
280
3616
    let current_issuance = Balances::total_issuance();
281
3616
    InflationRewards::on_initialize(System::block_number());
282
3616
    let new_issuance = Balances::total_issuance();
283

            
284
3616
    if let Some(mock_inherent_data) = mock_inherent_data {
285
96
        set_paras_inherent(mock_inherent_data);
286
3520
    }
287

            
288
3616
    Beefy::on_initialize(System::block_number());
289
3616
    Mmr::on_initialize(System::block_number());
290
3616
    BeefyMmrLeaf::on_initialize(System::block_number());
291
3616
    RunSummary {
292
3616
        inflation: new_issuance - current_issuance,
293
3616
    }
294
3616
}
295

            
296
3441
pub fn end_block() {
297
3441
    let block_number = System::block_number();
298
3441
    advance_block_state_machine(RunBlockState::End(block_number));
299
3441
    // Finalize the block
300
3441
    Babe::on_finalize(System::block_number());
301
3441
    Authorship::on_finalize(System::block_number());
302
3441
    Session::on_finalize(System::block_number());
303
3441
    Grandpa::on_finalize(System::block_number());
304
3441
    TransactionPayment::on_finalize(System::block_number());
305
3441
    Initializer::on_finalize(System::block_number());
306
3441
    ContainerRegistrar::on_finalize(System::block_number());
307
3441
    TanssiCollatorAssignment::on_finalize(System::block_number());
308
3441
    Beefy::on_finalize(System::block_number());
309
3441
    Mmr::on_finalize(System::block_number());
310
3441
    BeefyMmrLeaf::on_finalize(System::block_number());
311
3441
}
312

            
313
3439
pub fn run_block() -> RunSummary {
314
3439
    end_block();
315
3439

            
316
3439
    start_block()
317
3439
}
318

            
319
#[derive(Default, Clone)]
320
pub struct ParaRegistrationParams {
321
    pub para_id: u32,
322
    pub genesis_data: ContainerChainGenesisData,
323
    pub block_production_credits: u32,
324
    pub collator_assignment_credits: u32,
325
    pub parathread_params: Option<tp_traits::ParathreadParams>,
326
}
327

            
328
impl From<(u32, ContainerChainGenesisData, u32, u32)> for ParaRegistrationParams {
329
10
    fn from(value: (u32, ContainerChainGenesisData, u32, u32)) -> Self {
330
10
        Self {
331
10
            para_id: value.0,
332
10
            genesis_data: value.1,
333
10
            block_production_credits: value.2,
334
10
            collator_assignment_credits: value.3,
335
10
            parathread_params: None,
336
10
        }
337
10
    }
338
}
339

            
340
175
pub fn default_config() -> pallet_configuration::HostConfiguration {
341
175
    pallet_configuration::HostConfiguration {
342
175
        max_collators: 100,
343
175
        min_orchestrator_collators: 2,
344
175
        max_orchestrator_collators: 2,
345
175
        collators_per_container: 2,
346
175
        full_rotation_period: 0,
347
175
        ..Default::default()
348
175
    }
349
175
}
350

            
351
#[derive(Clone)]
352
pub struct ExtBuilder {
353
    // endowed accounts with balances
354
    balances: Vec<(AccountId, Balance)>,
355
    // [validator, amount]
356
    validators: Vec<(AccountId, Balance)>,
357
    // [validator, amount]
358
    external_validators: Vec<(AccountId, Balance)>,
359
    // [collator, amount]
360
    collators: Vec<(AccountId, Balance)>,
361
    // sudo key
362
    sudo: Option<AccountId>,
363
    // list of registered para ids: para_id, genesis_data, boot_nodes, block_credits, session_credits
364
    para_ids: Vec<ParaRegistrationParams>,
365
    // configuration to apply
366
    config: pallet_configuration::HostConfiguration,
367
    relay_config: runtime_parachains::configuration::HostConfiguration<BlockNumberFor<Runtime>>,
368
    own_para_id: Option<ParaId>,
369
    next_free_para_id: ParaId,
370
    keystore: Option<KeystorePtr>,
371
    safe_xcm_version: Option<u32>,
372
    inherent_data_enabled: bool,
373
}
374

            
375
impl Default for ExtBuilder {
376
175
    fn default() -> Self {
377
175
        Self {
378
175
            balances: vec![
379
175
                // Alice gets 10k extra tokens for her mapping deposit
380
175
                (AccountId::from(ALICE), 210_000 * UNIT),
381
175
                (AccountId::from(BOB), 100_000 * UNIT),
382
175
            ],
383
175
            validators: vec![
384
175
                (AccountId::from(ALICE), 210 * UNIT),
385
175
                (AccountId::from(BOB), 100 * UNIT),
386
175
            ],
387
175
            external_validators: vec![],
388
175
            collators: Default::default(),
389
175
            sudo: Default::default(),
390
175
            para_ids: Default::default(),
391
175
            config: default_config(),
392
175
            relay_config: runtime_parachains::configuration::HostConfiguration {
393
175
                scheduler_params: SchedulerParams {
394
175
                    num_cores: 6,
395
175
                    ..Default::default()
396
175
                },
397
175
                max_head_data_size: 20500,
398
175
                ..Default::default()
399
175
            },
400
175
            own_para_id: Default::default(),
401
175
            next_free_para_id: Default::default(),
402
175
            keystore: None,
403
175
            safe_xcm_version: Default::default(),
404
175
            inherent_data_enabled: false,
405
175
        }
406
175
    }
407
}
408

            
409
impl ExtBuilder {
410
143
    pub fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
411
143
        self.balances = balances;
412
143
        self
413
143
    }
414

            
415
1
    pub fn with_sudo(mut self, sudo: AccountId) -> Self {
416
1
        self.sudo = Some(sudo);
417
1
        self
418
1
    }
419

            
420
13
    pub fn with_validators(mut self, validators: Vec<(AccountId, Balance)>) -> Self {
421
13
        self.validators = validators;
422
13
        self
423
13
    }
424

            
425
6
    pub fn with_external_validators(mut self, validators: Vec<(AccountId, Balance)>) -> Self {
426
6
        self.external_validators = validators;
427
6
        self
428
6
    }
429

            
430
77
    pub fn with_collators(mut self, collators: Vec<(AccountId, Balance)>) -> Self {
431
77
        self.collators = collators;
432
77
        self
433
77
    }
434

            
435
13
    pub fn with_para_ids(mut self, para_ids: Vec<ParaRegistrationParams>) -> Self {
436
13
        self.para_ids = para_ids;
437
13
        self
438
13
    }
439

            
440
    /// Helper function like `with_para_ids` but registering parachains with an empty genesis data,
441
    /// and max amount of credits.
442
46
    pub fn with_empty_parachains(mut self, para_ids: Vec<u32>) -> Self {
443
46
        self.para_ids = para_ids
444
46
            .into_iter()
445
101
            .map(|para_id| ParaRegistrationParams {
446
101
                para_id,
447
101
                genesis_data: empty_genesis_data(),
448
101
                block_production_credits: u32::MAX,
449
101
                collator_assignment_credits: u32::MAX,
450
101
                parathread_params: None,
451
101
            })
452
46
            .collect();
453
46
        self
454
46
    }
455

            
456
5
    pub fn with_additional_empty_parathreads(mut self, para_ids: Vec<u32>) -> Self {
457
5
        self.para_ids = self
458
5
            .para_ids
459
5
            .iter()
460
5
            .cloned()
461
14
            .chain(para_ids.into_iter().map(|para_id| ParaRegistrationParams {
462
14
                para_id,
463
14
                genesis_data: empty_genesis_data(),
464
14
                block_production_credits: u32::MAX,
465
14
                collator_assignment_credits: u32::MAX,
466
14
                parathread_params: Some(ParathreadParams {
467
14
                    slot_frequency: Default::default(),
468
14
                }),
469
14
            }))
470
5
            .collect();
471
5
        self
472
5
    }
473

            
474
    // Maybe change to with_collators_config?
475
19
    pub fn with_config(mut self, config: pallet_configuration::HostConfiguration) -> Self {
476
19
        self.config = config;
477
19
        self
478
19
    }
479

            
480
    pub fn with_safe_xcm_version(mut self, safe_xcm_version: u32) -> Self {
481
        self.safe_xcm_version = Some(safe_xcm_version);
482
        self
483
    }
484

            
485
    // Maybe change to with_collators_config?
486
13
    pub fn with_relay_config(
487
13
        mut self,
488
13
        relay_config: runtime_parachains::configuration::HostConfiguration<BlockNumberFor<Runtime>>,
489
13
    ) -> Self {
490
13
        self.relay_config = relay_config;
491
13
        self
492
13
    }
493

            
494
    // Maybe change to with_collators_config?
495
1
    pub fn with_next_free_para_id(mut self, para_id: ParaId) -> Self {
496
1
        self.next_free_para_id = para_id;
497
1
        self
498
1
    }
499

            
500
    // Maybe change to with_collators_config?
501
8
    pub fn with_keystore(mut self, keystore: KeystorePtr) -> Self {
502
8
        self.keystore = Some(keystore);
503
8
        self
504
8
    }
505

            
506
8
    pub fn with_inherent_data_enabled(mut self) -> Self {
507
8
        self.inherent_data_enabled = true;
508
8
        self
509
8
    }
510

            
511
175
    pub fn build_storage(self) -> sp_core::storage::Storage {
512
175
        let mut t = frame_system::GenesisConfig::<Runtime>::default()
513
175
            .build_storage()
514
175
            .unwrap();
515
175

            
516
175
        pallet_babe::GenesisConfig::<Runtime> {
517
175
            ..Default::default()
518
175
        }
519
175
        .assimilate_storage(&mut t)
520
175
        .unwrap();
521
175

            
522
175
        pallet_balances::GenesisConfig::<Runtime> {
523
175
            balances: self.balances,
524
175
        }
525
175
        .assimilate_storage(&mut t)
526
175
        .unwrap();
527
175

            
528
175
        // We need to initialize these pallets first. When initializing pallet-session,
529
175
        // these values will be taken into account for collator-assignment.
530
175

            
531
175
        pallet_registrar::GenesisConfig::<Runtime> {
532
175
            para_ids: self
533
175
                .para_ids
534
175
                .iter()
535
175
                .cloned()
536
175
                .map(|registered_para| {
537
134
                    (
538
134
                        registered_para.para_id.into(),
539
134
                        registered_para.genesis_data,
540
134
                        registered_para.parathread_params,
541
134
                    )
542
175
                })
543
175
                .collect(),
544
175
            ..Default::default()
545
175
        }
546
175
        .assimilate_storage(&mut t)
547
175
        .unwrap();
548
175

            
549
175
        // We register mock wasm
550
175
        runtime_parachains::paras::GenesisConfig::<Runtime> {
551
175
            paras: self
552
175
                .para_ids
553
175
                .iter()
554
175
                .cloned()
555
175
                .map(|registered_para| {
556
134
                    let para_kind = if registered_para.parathread_params.is_some() {
557
18
                        ParaKind::Parathread
558
                    } else {
559
116
                        ParaKind::Parachain
560
                    };
561
134
                    (
562
134
                        registered_para.para_id.into(),
563
134
                        ParaGenesisArgs {
564
134
                            validation_code: mock_validation_code(),
565
134
                            para_kind,
566
134
                            genesis_head: HeadData::from(vec![0u8]),
567
134
                        },
568
134
                    )
569
175
                })
570
175
                .collect(),
571
175
            ..Default::default()
572
175
        }
573
175
        .assimilate_storage(&mut t)
574
175
        .unwrap();
575
175

            
576
175
        pallet_services_payment::GenesisConfig::<Runtime> {
577
175
            para_id_credits: self
578
175
                .para_ids
579
175
                .clone()
580
175
                .into_iter()
581
175
                .map(|registered_para| {
582
134
                    (
583
134
                        registered_para.para_id.into(),
584
134
                        registered_para.block_production_credits,
585
134
                        registered_para.collator_assignment_credits,
586
134
                    )
587
134
                        .into()
588
175
                })
589
175
                .collect(),
590
175
        }
591
175
        .assimilate_storage(&mut t)
592
175
        .unwrap();
593
175

            
594
175
        runtime_common::paras_registrar::GenesisConfig::<Runtime> {
595
175
            next_free_para_id: self.next_free_para_id,
596
175
            ..Default::default()
597
175
        }
598
175
        .assimilate_storage(&mut t)
599
175
        .unwrap();
600
175

            
601
175
        // TODO: add here pallet_services_payment::GenesisConfig
602
175

            
603
175
        pallet_configuration::GenesisConfig::<Runtime> {
604
175
            config: self.config,
605
175
            ..Default::default()
606
175
        }
607
175
        .assimilate_storage(&mut t)
608
175
        .unwrap();
609
175

            
610
175
        pallet_xcm::GenesisConfig::<Runtime> {
611
175
            safe_xcm_version: self.safe_xcm_version,
612
175
            ..Default::default()
613
175
        }
614
175
        .assimilate_storage(&mut t)
615
175
        .unwrap();
616
175

            
617
175
        runtime_parachains::configuration::GenesisConfig::<Runtime> {
618
175
            config: self.relay_config,
619
175
        }
620
175
        .assimilate_storage(&mut t)
621
175
        .unwrap();
622
175

            
623
175
        let mut keys: Vec<_> = Vec::new();
624
175
        let mut non_authority_keys: Vec<_> = Vec::new();
625
175
        if !self.validators.is_empty() {
626
169
            let validator_keys: Vec<_> = self
627
169
                .validators
628
169
                .clone()
629
169
                .into_iter()
630
353
                .map(|(account, _balance)| {
631
353
                    let authority_keys = get_authority_keys_from_seed(&account.to_string());
632
353
                    if let Some(keystore) = self.keystore.as_ref() {
633
16
                        insert_authority_keys_into_keystore(&account.to_string(), keystore)
634
337
                    }
635
353
                    (
636
353
                        account.clone(),
637
353
                        account,
638
353
                        crate::SessionKeys {
639
353
                            babe: authority_keys.babe.clone(),
640
353
                            grandpa: authority_keys.grandpa.clone(),
641
353
                            para_validator: authority_keys.para_validator.clone(),
642
353
                            para_assignment: authority_keys.para_assignment.clone(),
643
353
                            authority_discovery: authority_keys.authority_discovery.clone(),
644
353
                            beefy: authority_keys.beefy.clone(),
645
353
                            nimbus: authority_keys.nimbus.clone(),
646
353
                        },
647
353
                    )
648
353
                })
649
169
                .collect();
650
169
            keys.extend(validator_keys)
651
6
        }
652

            
653
175
        if !self.external_validators.is_empty() {
654
6
            let validator_keys: Vec<_> = self
655
6
                .external_validators
656
6
                .clone()
657
6
                .into_iter()
658
12
                .map(|(account, _balance)| {
659
12
                    let authority_keys = get_authority_keys_from_seed(&account.to_string());
660
12
                    if let Some(keystore) = self.keystore.as_ref() {
661
                        insert_authority_keys_into_keystore(&account.to_string(), keystore)
662
12
                    }
663
12
                    (
664
12
                        account.clone(),
665
12
                        account,
666
12
                        crate::SessionKeys {
667
12
                            babe: authority_keys.babe.clone(),
668
12
                            grandpa: authority_keys.grandpa.clone(),
669
12
                            para_validator: authority_keys.para_validator.clone(),
670
12
                            para_assignment: authority_keys.para_assignment.clone(),
671
12
                            authority_discovery: authority_keys.authority_discovery.clone(),
672
12
                            beefy: authority_keys.beefy.clone(),
673
12
                            nimbus: authority_keys.nimbus.clone(),
674
12
                        },
675
12
                    )
676
12
                })
677
6
                .collect();
678
6
            keys.extend(validator_keys)
679
169
        }
680

            
681
175
        if !self.collators.is_empty() {
682
            // We set invulnerables in pallet_invulnerables
683
77
            let invulnerables: Vec<AccountId> = self
684
77
                .collators
685
77
                .clone()
686
77
                .into_iter()
687
247
                .map(|(account, _balance)| account)
688
77
                .collect();
689
77

            
690
77
            pallet_invulnerables::GenesisConfig::<Runtime> {
691
77
                invulnerables: invulnerables.clone(),
692
77
            }
693
77
            .assimilate_storage(&mut t)
694
77
            .unwrap();
695
77

            
696
77
            // But we also initialize their keys in the session pallet
697
77
            // We discard those that had the key initialized already
698
77
            // from the validator list
699
77
            // in other words, for testing purposes we allow to inject a validator account
700
77
            // in the collator list
701
77
            let validator_unique_accounts: Vec<_> = self
702
77
                .validators
703
77
                .iter()
704
154
                .map(|(account, _)| account.clone())
705
77
                .collect();
706
77
            let collator_keys: Vec<_> = self
707
77
                .collators
708
77
                .into_iter()
709
247
                .filter_map(|(account, _balance)| {
710
247
                    if validator_unique_accounts.contains(&account) {
711
152
                        None
712
                    } else {
713
95
                        let authority_keys = get_authority_keys_from_seed(&account.to_string());
714
95
                        if let Some(keystore) = self.keystore.as_ref() {
715
                            insert_authority_keys_into_keystore(&account.to_string(), keystore)
716
95
                        }
717
95
                        Some((
718
95
                            account.clone(),
719
95
                            account,
720
95
                            crate::SessionKeys {
721
95
                                babe: authority_keys.babe.clone(),
722
95
                                grandpa: authority_keys.grandpa.clone(),
723
95
                                para_validator: authority_keys.para_validator.clone(),
724
95
                                para_assignment: authority_keys.para_assignment.clone(),
725
95
                                authority_discovery: authority_keys.authority_discovery.clone(),
726
95
                                beefy: authority_keys.beefy.clone(),
727
95
                                nimbus: authority_keys.nimbus.clone(),
728
95
                            },
729
95
                        ))
730
                    }
731
247
                })
732
77
                .collect();
733
77
            non_authority_keys.extend(collator_keys)
734
98
        }
735

            
736
175
        pallet_external_validators::GenesisConfig::<Runtime> {
737
175
            skip_external_validators: false,
738
175
            whitelisted_validators: self
739
175
                .validators
740
175
                .iter()
741
353
                .map(|(account, _)| account.clone())
742
175
                .collect(),
743
175
            external_validators: self
744
175
                .external_validators
745
175
                .iter()
746
175
                .map(|(account, _)| account.clone())
747
175
                .collect(),
748
175
        }
749
175
        .assimilate_storage(&mut t)
750
175
        .unwrap();
751
175

            
752
175
        pallet_session::GenesisConfig::<Runtime> {
753
175
            keys,
754
175
            non_authority_keys,
755
175
        }
756
175
        .assimilate_storage(&mut t)
757
175
        .unwrap();
758
175

            
759
175
        pallet_sudo::GenesisConfig::<Runtime> { key: self.sudo }
760
175
            .assimilate_storage(&mut t)
761
175
            .unwrap();
762
175

            
763
175
        snowbridge_pallet_system::GenesisConfig::<Runtime> {
764
175
            // This is irrelevant, we can put any number here
765
175
            // as long as it is a non-used para id
766
175
            para_id: 1000u32.into(),
767
175
            asset_hub_para_id: 1001u32.into(),
768
175
            ..Default::default()
769
175
        }
770
175
        .assimilate_storage(&mut t)
771
175
        .unwrap();
772
175

            
773
175
        if self.safe_xcm_version.is_some() {
774
            // Disable run_block checks in XCM tests, because the XCM emulator runs on_initialize and
775
            // on_finalize automatically
776
            t.top.insert(b"__mock_is_xcm_test".to_vec(), b"1".to_vec());
777
175
        }
778

            
779
        // Indicate that we should always (for every block) inject the paras_inherent.
780
        // Wether we inject an empty one or not its decided by b'ParasInherentData
781
175
        t.top.insert(
782
175
            b"ParasInherentEnabled".to_vec(),
783
175
            self.inherent_data_enabled.encode(),
784
175
        );
785
175

            
786
175
        t
787
175
    }
788

            
789
175
    pub fn build(self) -> sp_io::TestExternalities {
790
175
        let keystore = self.keystore.clone();
791
175
        let t = self.build_storage();
792
175
        let mut ext = sp_io::TestExternalities::new(t);
793
175
        if let Some(keystore) = keystore {
794
8
            ext.register_extension(KeystoreExt(keystore));
795
167
        }
796
175
        ext.execute_with(|| {
797
175
            // Start block 1
798
175
            start_block();
799
175
        });
800
175
        ext
801
175
    }
802
}
803

            
804
163
pub fn root_origin() -> <Runtime as frame_system::Config>::RuntimeOrigin {
805
163
    <Runtime as frame_system::Config>::RuntimeOrigin::root()
806
163
}
807

            
808
349
pub fn origin_of(account_id: AccountId) -> <Runtime as frame_system::Config>::RuntimeOrigin {
809
349
    <Runtime as frame_system::Config>::RuntimeOrigin::signed(account_id)
810
349
}
811

            
812
104
pub fn inherent_origin() -> <Runtime as frame_system::Config>::RuntimeOrigin {
813
104
    <Runtime as frame_system::Config>::RuntimeOrigin::none()
814
104
}
815

            
816
/// This function is different in solochains: instead of creating a storage proof and calling the
817
/// `set_latest_author_data` inherent with that proof as argument, this writes to storage directly.
818
8
pub fn set_author_noting_inherent_data(builder: ParaHeaderSproofBuilder) {
819
8
    for (k, v) in builder.key_values() {
820
8
        frame_support::storage::unhashed::put_raw(&k, &v);
821
8
    }
822

            
823
8
    assert_ok!(RuntimeCall::AuthorNoting(
824
8
        pallet_author_noting::Call::<Runtime>::set_latest_author_data { data: () }
825
8
    )
826
8
    .dispatch(inherent_origin()));
827
8
}
828

            
829
134
pub fn empty_genesis_data() -> ContainerChainGenesisData {
830
134
    ContainerChainGenesisData {
831
134
        storage: Default::default(),
832
134
        name: Default::default(),
833
134
        id: Default::default(),
834
134
        fork_id: Default::default(),
835
134
        extensions: Default::default(),
836
134
        properties: Default::default(),
837
134
    }
838
134
}
839

            
840
3616
pub fn current_slot() -> u64 {
841
3616
    Babe::current_slot().into()
842
3616
}
843

            
844
21
pub fn block_credits_to_required_balance(number_of_blocks: u32, para_id: ParaId) -> Balance {
845
21
    let block_cost = BlockProductionCost::block_cost(&para_id).0;
846
21
    u128::from(number_of_blocks).saturating_mul(block_cost)
847
21
}
848

            
849
4
pub fn collator_assignment_credits_to_required_balance(
850
4
    number_of_sessions: u32,
851
4
    para_id: ParaId,
852
4
) -> Balance {
853
4
    let collator_assignment_cost = CollatorAssignmentCost::collator_assignment_cost(&para_id).0;
854
4
    u128::from(number_of_sessions).saturating_mul(collator_assignment_cost)
855
4
}
856

            
857
pub const ALICE: [u8; 32] = [4u8; 32];
858
pub const BOB: [u8; 32] = [5u8; 32];
859
pub const CHARLIE: [u8; 32] = [6u8; 32];
860
pub const DAVE: [u8; 32] = [7u8; 32];
861
pub const EVE: [u8; 32] = [8u8; 32];
862
pub const FERDIE: [u8; 32] = [9u8; 32];
863

            
864
// Whether we have custom data to inject in paras inherent
865
96
fn take_new_inherent_data() -> Option<cumulus_primitives_core::relay_chain::vstaging::InherentData>
866
96
{
867
96
    let data: Option<cumulus_primitives_core::relay_chain::vstaging::InherentData> =
868
96
        frame_support::storage::unhashed::take(b"ParasInherentData");
869
96

            
870
96
    data
871
96
}
872

            
873
// Whether we should inject the paras inherent.
874
3616
fn is_para_inherent_enabled() -> bool {
875
3616
    let enabled: Option<bool> = frame_support::storage::unhashed::get(b"ParasInherentEnabled");
876
3616
    enabled.unwrap_or(false)
877
3616
}
878

            
879
// Set new data to inject in paras inherent
880
8
pub fn set_new_inherent_data(data: cumulus_primitives_core::relay_chain::vstaging::InherentData) {
881
8
    frame_support::storage::unhashed::put(b"ParasInherentData", &data);
882
8
}
883

            
884
1
pub fn set_new_randomness_data(data: Option<[u8; 32]>) {
885
1
    pallet_babe::AuthorVrfRandomness::<Runtime>::set(data);
886
1
}
887

            
888
/// Mock the inherent that sets validation data in ParachainSystem, which
889
/// contains the `relay_chain_block_number`, which is used in `collator-assignment` as a
890
/// source of randomness.
891
96
pub fn set_paras_inherent(data: cumulus_primitives_core::relay_chain::vstaging::InherentData) {
892
96
    // In order for this inherent to work, we need to match the parent header
893
96
    // the parent header does not play a significant role in the rest of the framework so
894
96
    // we are simply going to mock it
895
96
    System::set_parent_hash(data.parent_header.hash());
896
96
    assert_ok!(
897
96
        RuntimeCall::ParaInherent(parachains_paras_inherent::Call::<Runtime>::enter { data })
898
96
            .dispatch(inherent_origin())
899
96
    );
900
    // Error: InherentDataFilteredDuringExecution
901
92
    frame_support::storage::unhashed::kill(&frame_support::storage::storage_prefix(
902
92
        b"ParaInherent",
903
92
        b"Included",
904
92
    ));
905
92
}
906

            
907
pub(crate) struct ParasInherentTestBuilder<T: runtime_parachains::paras_inherent::Config> {
908
    /// Starting block number; we expect it to get incremented on session setup.
909
    block_number: BlockNumberFor<T>,
910
    /// Paras here will both be backed in the inherent data and already occupying a core (which is
911
    /// freed via bitfields).
912
    ///
913
    /// Map from para id to number of validity votes. Core indices are generated based on
914
    /// `elastic_paras` configuration. Each para id in `elastic_paras` gets the
915
    /// specified amount of consecutive cores assigned to it. If a para id is not present
916
    /// in `elastic_paras` it get assigned to a single core.
917
    backed_and_concluding_paras: BTreeMap<u32, u32>,
918

            
919
    /// Paras which don't yet occupy a core, but will after the inherent has been processed.
920
    backed_in_inherent_paras: BTreeMap<u32, u32>,
921
    _phantom: core::marker::PhantomData<T>,
922
}
923

            
924
188
pub fn mock_validation_code() -> ValidationCode {
925
188
    ValidationCode(vec![1; 10])
926
188
}
927

            
928
/// Create a dummy collator id suitable to be used in a V1 candidate descriptor.
929
pub fn junk_collator() -> CollatorId {
930
    CollatorId::from_slice(&mut (0..32).collect::<Vec<_>>().as_slice()).expect("32 bytes; qed")
931
}
932

            
933
/// Creates a dummy collator signature suitable to be used in a V1 candidate descriptor.
934
pub fn junk_collator_signature() -> CollatorSignature {
935
    CollatorSignature::from_slice(&mut (0..64).collect::<Vec<_>>().as_slice())
936
        .expect("64 bytes; qed")
937
}
938

            
939
#[allow(dead_code)]
940
impl<T: runtime_parachains::paras_inherent::Config> ParasInherentTestBuilder<T> {
941
    /// Create a new `BenchBuilder` with some opinionated values that should work with the rest
942
    /// of the functions in this implementation.
943
104
    pub(crate) fn new() -> Self {
944
104
        ParasInherentTestBuilder {
945
104
            block_number: Zero::zero(),
946
104
            backed_and_concluding_paras: Default::default(),
947
104
            backed_in_inherent_paras: Default::default(),
948
104
            _phantom: core::marker::PhantomData::<T>,
949
104
        }
950
104
    }
951

            
952
    /// Set a map from para id seed to number of validity votes.
953
8
    pub(crate) fn set_backed_and_concluding_paras(
954
8
        mut self,
955
8
        backed_and_concluding_paras: BTreeMap<u32, u32>,
956
8
    ) -> Self {
957
8
        self.backed_and_concluding_paras = backed_and_concluding_paras;
958
8
        self
959
8
    }
960

            
961
    /// Set a map from para id seed to number of validity votes for votes in inherent data.
962
    pub(crate) fn set_backed_in_inherent_paras(mut self, backed: BTreeMap<u32, u32>) -> Self {
963
        self.backed_in_inherent_paras = backed;
964
        self
965
    }
966

            
967
    /// Mock header.
968
330
    pub(crate) fn header(block_number: BlockNumberFor<T>) -> HeaderFor<T> {
969
330
        HeaderFor::<T>::new(
970
330
            block_number,       // `block_number`,
971
330
            Default::default(), // `extrinsics_root`,
972
330
            Default::default(), // `storage_root`,
973
330
            Default::default(), // `parent_hash`,
974
330
            Default::default(), // digest,
975
330
        )
976
330
    }
977

            
978
    /// Maximum number of validators that may be part of a validator group.
979
    pub(crate) fn fallback_max_validators() -> u32 {
980
        runtime_parachains::configuration::ActiveConfig::<T>::get()
981
            .max_validators
982
            .unwrap_or(200)
983
    }
984

            
985
    /// Maximum number of validators participating in parachains consensus (a.k.a. active
986
    /// validators).
987
    fn max_validators(&self) -> u32 {
988
        Self::fallback_max_validators()
989
    }
990

            
991
    /// Maximum number of validators per core (a.k.a. max validators per group). This value is used
992
    /// if none is explicitly set on the builder.
993
    pub(crate) fn fallback_max_validators_per_core() -> u32 {
994
        runtime_parachains::configuration::ActiveConfig::<T>::get()
995
            .scheduler_params
996
            .max_validators_per_core
997
            .unwrap_or(5)
998
    }
999

            
    /// Get the maximum number of validators per core.
    fn max_validators_per_core(&self) -> u32 {
        Self::fallback_max_validators_per_core()
    }
    /// Get the maximum number of cores we expect from this configuration.
    pub(crate) fn max_cores(&self) -> u32 {
        self.max_validators() / self.max_validators_per_core()
    }
    /// Create an `AvailabilityBitfield` where `concluding` is a map where each key is a core index
    /// that is concluding and `cores` is the total number of cores in the system.
104
    fn availability_bitvec(concluding_cores: &BTreeSet<u32>, cores: usize) -> AvailabilityBitfield {
104
        let mut bitfields = bitvec::bitvec![u8, bitvec::order::Lsb0; 0; 0];
208
        for i in 0..cores {
208
            if concluding_cores.contains(&(i as u32)) {
9
                bitfields.push(true);
9
            } else {
199
                bitfields.push(false)
            }
        }
104
        bitfields.into()
104
    }
    /// Create a bitvec of `validators` length with all yes votes.
    fn validator_availability_votes_yes(validators: usize) -> BitVec<u8, bitvec::order::Lsb0> {
        // every validator confirms availability.
        bitvec::bitvec![u8, bitvec::order::Lsb0; 1; validators]
    }
18
    pub fn mock_head_data() -> HeadData {
18
        let max_head_size =
18
            runtime_parachains::configuration::ActiveConfig::<T>::get().max_head_data_size;
18
        HeadData(vec![0xFF; max_head_size as usize])
18
    }
    fn candidate_descriptor_mock(
        para_id: ParaId,
        candidate_descriptor_v2: bool,
    ) -> CandidateDescriptorV2<T::Hash> {
        if candidate_descriptor_v2 {
            CandidateDescriptorV2::new(
                para_id,
                Default::default(),
                CoreIndex(200),
                2,
                Default::default(),
                Default::default(),
                Default::default(),
                Default::default(),
                mock_validation_code().hash(),
            )
        } else {
            // Convert v1 to v2.
            CandidateDescriptor::<T::Hash> {
                para_id,
                relay_parent: Default::default(),
                collator: junk_collator(),
                persisted_validation_data_hash: Default::default(),
                pov_hash: Default::default(),
                erasure_root: Default::default(),
                signature: junk_collator_signature(),
                para_head: Default::default(),
                validation_code_hash: mock_validation_code().hash(),
            }
            .into()
        }
    }
    /*
    /// Create a mock of `CandidatePendingAvailability`.
    fn candidate_availability_mock(
        para_id: ParaId,
        group_idx: GroupIndex,
        core_idx: CoreIndex,
        candidate_hash: CandidateHash,
        availability_votes: BitVec<u8, bitvec::order::Lsb0>,
        commitments: CandidateCommitments,
        candidate_descriptor_v2: bool,
    ) -> CandidatePendingAvailability<T::Hash, BlockNumberFor<T>> {
        CandidatePendingAvailability::<T::Hash, BlockNumberFor<T>>::new(
            core_idx,                                                          // core
            candidate_hash,                                                    // hash
            Self::candidate_descriptor_mock(para_id, candidate_descriptor_v2), /* candidate descriptor */
            commitments,                                                       // commitments
            availability_votes,                                                /* availability
                                                                                            * votes */
            Default::default(), // backers
            Zero::zero(),       // relay parent
            One::one(),         /* relay chain block this
                                             * was backed in */
            group_idx, // backing group
        )
    }
     */
    /*
    /// Add `CandidatePendingAvailability` and `CandidateCommitments` to the relevant storage items.
    ///
    /// NOTE: the default `CandidateCommitments` used does not include any data that would lead to
    /// heavy code paths in `enact_candidate`. But enact_candidates does return a weight which will
    /// get taken into account.
    fn add_availability(
        para_id: ParaId,
        core_idx: CoreIndex,
        group_idx: GroupIndex,
        availability_votes: BitVec<u8, bitvec::order::Lsb0>,
        candidate_hash: CandidateHash,
        candidate_descriptor_v2: bool,
    ) {
        let commitments = CandidateCommitments::<u32> {
            upward_messages: Default::default(),
            horizontal_messages: Default::default(),
            new_validation_code: None,
            head_data: Self::mock_head_data(),
            processed_downward_messages: 0,
            hrmp_watermark: 0u32.into(),
        };
        let candidate_availability = Self::candidate_availability_mock(
            para_id,
            group_idx,
            core_idx,
            candidate_hash,
            availability_votes,
            commitments,
            candidate_descriptor_v2,
        );
        inclusion::PendingAvailability::<T>::mutate(para_id, |maybe_candidates| {
            if let Some(candidates) = maybe_candidates {
                candidates.push_back(candidate_availability);
            } else {
                *maybe_candidates =
                    Some([candidate_availability].into_iter().collect::<VecDeque<_>>());
            }
        });
    }
     */
    /// Number of the relay parent block.
18
    fn relay_parent_number(&self) -> u32 {
18
        (Self::block_number() - One::one())
18
            .try_into()
18
            .map_err(|_| ())
18
            .expect("Self::block_number() is u32")
18
    }
    /// Create backed candidates for `cores_with_backed_candidates`. You need these cores to be
    /// scheduled _within_ paras inherent, which requires marking the available bitfields as fully
    /// available.
    /// - `cores_with_backed_candidates` Mapping of `para_id` seed to number of
    /// validity votes.
    /// Important! this uses a BtreeMap, which means that elements will use increasing core orders
    /// example: if we have parachains 1000, 1001, and 1002, they will use respectively cores
    /// 0 1 and 2. There is no way in which we force 1002 to use core 0 in this setup
104
    fn create_backed_candidates(
104
        &self,
104
        paras_with_backed_candidates: &BTreeMap<u32, u32>,
104
    ) -> Vec<BackedCandidate<T::Hash>> {
104
        let current_session = runtime_parachains::shared::CurrentSessionIndex::<T>::get();
104
        // We need to refetch validators since they have been shuffled.
104
        let validators_shuffled =
104
            runtime_parachains::session_info::Sessions::<T>::get(current_session)
104
                .unwrap()
104
                .validators
104
                .clone();
104

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

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

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

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

            
9
                        let persisted_validation_data_hash = persisted_validation_data.hash();
9

            
9
                        let pov_hash = Default::default();
9
                        let validation_code_hash = mock_validation_code().hash();
9

            
9
                        /*
9
                        let mut past_code_meta =
9
                            paras::ParaPastCodeMeta::<BlockNumberFor<T>>::default();
9
                        past_code_meta.note_replacement(0u32.into(), 0u32.into());
9
                         */
9

            
9
                        let group_validators = Self::group_validators(group_idx).unwrap();
9
                        let descriptor = if true
                        /* self.candidate_descriptor_v2 */
                        {
9
                            CandidateDescriptorV2::new(
9
                                para_id,
9
                                relay_parent,
9
                                core_idx,
9
                                current_session,
9
                                persisted_validation_data_hash,
9
                                pov_hash,
9
                                Default::default(),
9
                                prev_head.hash(),
9
                                validation_code_hash,
9
                            )
                        } else {
                            todo!()
                        };
9
                        let mut candidate = CommittedCandidateReceiptV2::<T::Hash> {
9
                            descriptor,
9
                            commitments: CandidateCommitments::<u32> {
9
                                upward_messages: Default::default(),
9
                                horizontal_messages: Default::default(),
9
                                new_validation_code: None,
9
                                head_data: prev_head.clone(),
9
                                processed_downward_messages: 0,
9
                                hrmp_watermark: self.relay_parent_number() + 1,
9
                            },
9
                        };
9

            
9
                        if true
                        /* self.candidate_descriptor_v2 */
9
                        {
9
                            // `UMPSignal` separator.
9
                            candidate
9
                                .commitments
9
                                .upward_messages
9
                                .force_push(UMP_SEPARATOR);
9

            
9
                            // `SelectCore` commitment.
9
                            // Claim queue offset must be `0` so this candidate is for the very
9
                            // next block.
9
                            candidate.commitments.upward_messages.force_push(
9
                                UMPSignal::SelectCore(CoreSelector(chain_idx), ClaimQueueOffset(0))
9
                                    .encode(),
9
                            );
9
                        }
9
                        let candidate_hash = candidate.hash();
9

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

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

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

            
9
                        // Check if the elastic scaling bit is set, if so we need to supply the core
9
                        // index in the generated candidate.
9
                        let core_idx = runtime_parachains::configuration::ActiveConfig::<T>::get()
9
                            .node_features
9
                            .get(FeatureIndex::ElasticScalingMVP as usize)
9
                            .and_then(|the_bit| if *the_bit { Some(core_idx) } else { None });
9

            
9
                        assert_eq!(group_validators.len(), 1);
9
                        BackedCandidate::<T::Hash>::new(
9
                            candidate,
9
                            validity_votes,
9
                            bitvec::bitvec![u8, bitvec::order::Lsb0; 1; group_validators.len()],
9
                            core_idx,
9
                        )
9
                    })
9
                    .collect::<Vec<_>>()
104
            })
104
            .collect()
104
    }
    /// 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.
9
    pub(crate) fn group_assigned_to_core(
9
        core: CoreIndex,
9
        at: BlockNumberFor<T>,
9
    ) -> Option<GroupIndex> {
9
        let config = runtime_parachains::configuration::ActiveConfig::<T>::get();
9
        let session_start_block = runtime_parachains::scheduler::SessionStartBlock::<T>::get();
9

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

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

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

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

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

            
9
        let group_idx =
9
            (core.0 as usize + rotations_since_session_start as usize) % validator_groups.len();
9
        Some(GroupIndex(group_idx as u32))
9
    }
    /// Get the validators in the given group, if the group index is valid for this session.
9
    pub(crate) fn group_validators(group_index: GroupIndex) -> Option<Vec<ValidatorIndex>> {
9
        runtime_parachains::scheduler::ValidatorGroups::<T>::get()
9
            .get(group_index.0 as usize)
9
            .cloned()
9
    }
9
    pub fn heads_insert(para_id: &ParaId, head_data: HeadData) {
9
        runtime_parachains::paras::Heads::<T>::insert(para_id, head_data);
9
    }
    /// 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.
104
    pub(crate) fn build(self) -> ParachainsInherentData<HeaderFor<T>> {
104
        let current_session = runtime_parachains::shared::CurrentSessionIndex::<T>::get();
104
        // We need to refetch validators since they have been shuffled.
104
        let validators = runtime_parachains::session_info::Sessions::<T>::get(current_session)
104
            .unwrap()
104
            .validators
104
            .clone();
104

            
104
        //let max_cores = self.max_cores() as usize;
104
        let max_cores = 2;
104

            
104
        let used_cores =
104
            self.backed_and_concluding_paras.len() + self.backed_in_inherent_paras.len();
104
        assert!(used_cores <= max_cores);
104
        let mut backed_in_inherent = BTreeMap::new();
104
        backed_in_inherent.append(&mut self.backed_and_concluding_paras.clone());
104
        backed_in_inherent.append(&mut self.backed_in_inherent_paras.clone());
104
        let backed_candidates = self.create_backed_candidates(&backed_in_inherent);
104
        let used_cores_set = (0..used_cores).map(|x| x as u32).collect();
104

            
104
        let availability_bitvec = Self::availability_bitvec(&used_cores_set, max_cores);
104

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

            
104
        let data = ParachainsInherentData {
104
            bitfields,
104
            backed_candidates,
104
            disputes: vec![],
104
            parent_header: Self::header(Self::block_number()),
104
        };
104

            
104
        data
104
    }
357
    pub(crate) fn block_number() -> BlockNumberFor<T> {
357
        frame_system::Pallet::<T>::block_number()
357
    }
}
use {
    cumulus_primitives_core::relay_chain::SchedulerParams, frame_support::StorageHasher,
    tp_traits::ParathreadParams,
};
3
pub fn storage_map_final_key<H: frame_support::StorageHasher>(
3
    pallet_prefix: &str,
3
    map_name: &str,
3
    key: &[u8],
3
) -> Vec<u8> {
3
    let key_hashed = H::hash(key);
3
    let pallet_prefix_hashed = frame_support::Twox128::hash(pallet_prefix.as_bytes());
3
    let storage_prefix_hashed = frame_support::Twox128::hash(map_name.as_bytes());
3

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

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

            
3
    final_key
3
}
23
pub fn set_dummy_boot_node(para_manager: RuntimeOrigin, para_id: ParaId) {
    use {
        pallet_data_preservers::{ParaIdsFilter, Profile, ProfileMode},
        tp_data_preservers_common::{AssignerExtra, ProviderRequest},
    };
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: ProviderRequest::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(para_manager, profile_id, para_id, AssignerExtra::Free)
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 primitives::vstaging::{ClaimQueueOffset, CoreSelector, UMPSignal, UMP_SEPARATOR};
use primitives::{CandidateDescriptor, CollatorId, CollatorSignature};
use sp_core::ByteArray;
use {
    babe_primitives::AuthorityPair as BabeAuthorityPair,
    grandpa_primitives::{
        AuthorityPair as GrandpaAuthorityPair, Equivocation, EquivocationProof, RoundNumber, SetId,
    },
    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
}
/// 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
}
7
pub fn mock_snowbridge_message_proof() -> Proof {
7
    Proof {
7
        receipt_proof: (vec![], vec![]),
7
        execution_proof: ExecutionProof {
7
            header: Default::default(),
7
            ancestry_proof: None,
7
            execution_header: VersionedExecutionPayloadHeader::Deneb(
7
                deneb::ExecutionPayloadHeader {
7
                    parent_hash: Default::default(),
7
                    fee_recipient: Default::default(),
7
                    state_root: Default::default(),
7
                    receipts_root: Default::default(),
7
                    logs_bloom: vec![],
7
                    prev_randao: Default::default(),
7
                    block_number: 0,
7
                    gas_limit: 0,
7
                    gas_used: 0,
7
                    timestamp: 0,
7
                    extra_data: vec![],
7
                    base_fee_per_gas: Default::default(),
7
                    block_hash: Default::default(),
7
                    transactions_root: Default::default(),
7
                    withdrawals_root: Default::default(),
7
                    blob_gas_used: 0,
7
                    excess_blob_gas: 0,
7
                },
7
            ),
7
            execution_branch: vec![],
7
        },
7
    }
7
}