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, Preimage, RuntimeCall, Scheduler,
23
    },
24
    alloc::collections::btree_map::BTreeMap,
25
    babe_primitives::{
26
        digests::{PreDigest, SecondaryPlainPreDigest},
27
        BABE_ENGINE_ID,
28
    },
29
    beefy_primitives::{ecdsa_crypto::AuthorityId as BeefyId, ConsensusLog, BEEFY_ENGINE_ID},
30
    bitvec::prelude::BitVec,
31
    cumulus_primitives_core::{
32
        relay_chain::{
33
            node_features::FeatureIndex, vstaging::BackedCandidate,
34
            vstaging::CandidateDescriptorV2, vstaging::CommittedCandidateReceiptV2,
35
            vstaging::InherentData as ParachainsInherentData, AvailabilityBitfield,
36
            CandidateCommitments, CompactStatement, CoreIndex, GroupIndex, HeadData,
37
            PersistedValidationData, SigningContext, UncheckedSigned, ValidationCode,
38
            ValidatorIndex, ValidityAttestation,
39
        },
40
        ParaId,
41
    },
42
    frame_support::{
43
        assert_ok,
44
        traits::{OnFinalize, OnInitialize, QueryPreimage},
45
        BoundedVec,
46
    },
47
    frame_system::pallet_prelude::{BlockNumberFor, HeaderFor},
48
    nimbus_primitives::NimbusId,
49
    pallet_referenda::{DecidingStatus, ReferendumStatus},
50
    pallet_registrar_runtime_api::ContainerChainGenesisData,
51
    pallet_services_payment::{ProvideBlockProductionCost, ProvideCollatorAssignmentCost},
52
    parity_scale_codec::{Decode, Encode, MaxEncodedLen},
53
    runtime_parachains::{
54
        paras::{ParaGenesisArgs, ParaKind},
55
        paras_inherent as parachains_paras_inherent,
56
    },
57
    snowbridge_beacon_primitives::{types::deneb, ExecutionProof, VersionedExecutionPayloadHeader},
58
    snowbridge_verification_primitives::Proof,
59
    sp_core::Pair,
60
    sp_core::Public,
61
    sp_keystore::{KeystoreExt, KeystorePtr},
62
    sp_runtime::{
63
        traits::{BlakeTwo256, Dispatchable, Hash, Header, One, SaturatedConversion, Zero},
64
        BuildStorage, Digest, DigestItem,
65
    },
66
    sp_storage::well_known_keys,
67
    std::collections::BTreeSet,
68
    test_relay_sproof_builder::ParaHeaderSproofBuilder,
69
};
70

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

            
79
pub const UNIT: Balance = 1_000_000_000_000;
80

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

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

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

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

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

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

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

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

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

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

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

            
153
922
    let mut summaries = BTreeMap::new();
154

            
155
6147
    while System::block_number() < n {
156
5225
        let summary = run_block();
157
5225
        let block_number = System::block_number();
158
5225
        summaries.insert(block_number, summary);
159
5225
    }
160

            
161
922
    summaries
162
922
}
163

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

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

            
190
5569
    System::reset_events();
191
5569
    System::initialize(
192
5569
        &(System::block_number() + 1),
193
5569
        &System::parent_hash(),
194
5569
        &pre_digest,
195
    );
196
5569
}
197

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

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

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

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

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

            
266
5569
    let block_number = System::block_number();
267
5569
    advance_block_state_machine(RunBlockState::Start(block_number + 1));
268

            
269
5569
    insert_authorities_and_slot_digests(current_slot() + 1);
270

            
271
    // Initialize the new block
272
5569
    Babe::on_initialize(System::block_number());
273
5569
    Authorship::on_initialize(System::block_number());
274
5569
    ContainerRegistrar::on_initialize(System::block_number());
275
5569
    ExternalValidatorSlashes::on_initialize(System::block_number());
276
5569
    Session::on_initialize(System::block_number());
277

            
278
5569
    Initializer::on_initialize(System::block_number());
279
5569
    TanssiCollatorAssignment::on_initialize(System::block_number());
280
5569
    MessageQueue::on_initialize(System::block_number());
281

            
282
5569
    let current_issuance = Balances::total_issuance();
283
5569
    InflationRewards::on_initialize(System::block_number());
284
5569
    let new_issuance = Balances::total_issuance();
285

            
286
5569
    if let Some(mock_inherent_data) = mock_inherent_data {
287
92
        set_paras_inherent(mock_inherent_data);
288
5477
    }
289

            
290
5569
    Scheduler::on_initialize(System::block_number());
291

            
292
5569
    Beefy::on_initialize(System::block_number());
293
5569
    Mmr::on_initialize(System::block_number());
294
5569
    BeefyMmrLeaf::on_initialize(System::block_number());
295
5569
    InactivityTracking::on_initialize(System::block_number());
296
5569
    RunSummary {
297
5569
        inflation: new_issuance - current_issuance,
298
5569
    }
299
5569
}
300

            
301
5282
pub fn end_block() {
302
5282
    let block_number = System::block_number();
303
5282
    advance_block_state_machine(RunBlockState::End(block_number));
304
    // Finalize the block
305
5282
    Babe::on_finalize(System::block_number());
306
5282
    Authorship::on_finalize(System::block_number());
307
5282
    Session::on_finalize(System::block_number());
308
5282
    Grandpa::on_finalize(System::block_number());
309
5282
    TransactionPayment::on_finalize(System::block_number());
310
5282
    Initializer::on_finalize(System::block_number());
311
5282
    ContainerRegistrar::on_finalize(System::block_number());
312
5282
    TanssiCollatorAssignment::on_finalize(System::block_number());
313
5282
    Scheduler::on_finalize(System::block_number());
314
5282
    Beefy::on_finalize(System::block_number());
315
5282
    Mmr::on_finalize(System::block_number());
316
5282
    BeefyMmrLeaf::on_finalize(System::block_number());
317
5282
    InactivityTracking::on_finalize(System::block_number());
318
5282
}
319

            
320
5280
pub fn run_block() -> RunSummary {
321
5280
    end_block();
322

            
323
5280
    start_block()
324
5280
}
325

            
326
#[derive(Default, Clone)]
327
pub struct ParaRegistrationParams {
328
    pub para_id: u32,
329
    pub genesis_data: ContainerChainGenesisData,
330
    pub block_production_credits: u32,
331
    pub collator_assignment_credits: u32,
332
    pub parathread_params: Option<tp_traits::ParathreadParams>,
333
}
334

            
335
impl From<(u32, ContainerChainGenesisData, u32, u32)> for ParaRegistrationParams {
336
10
    fn from(value: (u32, ContainerChainGenesisData, u32, u32)) -> Self {
337
10
        Self {
338
10
            para_id: value.0,
339
10
            genesis_data: value.1,
340
10
            block_production_credits: value.2,
341
10
            collator_assignment_credits: value.3,
342
10
            parathread_params: None,
343
10
        }
344
10
    }
345
}
346

            
347
287
pub fn default_config() -> pallet_configuration::HostConfiguration {
348
287
    pallet_configuration::HostConfiguration {
349
287
        max_collators: 100,
350
287
        min_orchestrator_collators: 2,
351
287
        max_orchestrator_collators: 2,
352
287
        collators_per_container: 2,
353
287
        full_rotation_period: 0,
354
287
        ..Default::default()
355
287
    }
356
287
}
357

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

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

            
417
impl ExtBuilder {
418
214
    pub fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
419
214
        self.balances = balances;
420
214
        self
421
214
    }
422

            
423
6
    pub fn with_sudo(mut self, sudo: AccountId) -> Self {
424
6
        self.sudo = Some(sudo);
425
6
        self
426
6
    }
427

            
428
32
    pub fn with_validators(mut self, validators: Vec<(AccountId, Balance)>) -> Self {
429
32
        self.validators = validators;
430
32
        self
431
32
    }
432

            
433
25
    pub fn with_external_validators(mut self, validators: Vec<(AccountId, Balance)>) -> Self {
434
25
        self.external_validators = validators;
435
25
        self
436
25
    }
437

            
438
83
    pub fn with_collators(mut self, collators: Vec<(AccountId, Balance)>) -> Self {
439
83
        self.collators = collators;
440
83
        self
441
83
    }
442

            
443
12
    pub fn with_para_ids(mut self, para_ids: Vec<ParaRegistrationParams>) -> Self {
444
12
        self.para_ids = para_ids;
445
12
        self
446
12
    }
447

            
448
    /// Helper function like `with_para_ids` but registering parachains with an empty genesis data,
449
    /// and max amount of credits.
450
53
    pub fn with_empty_parachains(mut self, para_ids: Vec<u32>) -> Self {
451
53
        self.para_ids = para_ids
452
53
            .into_iter()
453
53
            .map(|para_id| ParaRegistrationParams {
454
115
                para_id,
455
115
                genesis_data: empty_genesis_data(),
456
                block_production_credits: u32::MAX,
457
                collator_assignment_credits: u32::MAX,
458
115
                parathread_params: None,
459
115
            })
460
53
            .collect();
461
53
        self
462
53
    }
463

            
464
3
    pub fn with_additional_empty_parathreads(mut self, para_ids: Vec<u32>) -> Self {
465
3
        self.para_ids = self
466
3
            .para_ids
467
3
            .iter()
468
3
            .cloned()
469
3
            .chain(para_ids.into_iter().map(|para_id| ParaRegistrationParams {
470
6
                para_id,
471
6
                genesis_data: empty_genesis_data(),
472
                block_production_credits: u32::MAX,
473
                collator_assignment_credits: u32::MAX,
474
6
                parathread_params: Some(ParathreadParams {
475
6
                    slot_frequency: Default::default(),
476
6
                }),
477
6
            }))
478
3
            .collect();
479
3
        self
480
3
    }
481

            
482
    // Maybe change to with_collators_config?
483
18
    pub fn with_config(mut self, config: pallet_configuration::HostConfiguration) -> Self {
484
18
        self.config = config;
485
18
        self
486
18
    }
487

            
488
    pub fn with_safe_xcm_version(mut self, safe_xcm_version: u32) -> Self {
489
        self.safe_xcm_version = Some(safe_xcm_version);
490
        self
491
    }
492

            
493
    // Maybe change to with_collators_config?
494
10
    pub fn with_relay_config(
495
10
        mut self,
496
10
        relay_config: runtime_parachains::configuration::HostConfiguration<BlockNumberFor<Runtime>>,
497
10
    ) -> Self {
498
10
        self.relay_config = relay_config;
499
10
        self
500
10
    }
501

            
502
    // Maybe change to with_collators_config?
503
1
    pub fn with_next_free_para_id(mut self, para_id: ParaId) -> Self {
504
1
        self.next_free_para_id = para_id;
505
1
        self
506
1
    }
507

            
508
    // Maybe change to with_collators_config?
509
7
    pub fn with_keystore(mut self, keystore: KeystorePtr) -> Self {
510
7
        self.keystore = Some(keystore);
511
7
        self
512
7
    }
513

            
514
7
    pub fn with_inherent_data_enabled(mut self) -> Self {
515
7
        self.inherent_data_enabled = true;
516
7
        self
517
7
    }
518

            
519
287
    pub fn build_storage(self) -> sp_core::storage::Storage {
520
287
        let mut t = frame_system::GenesisConfig::<Runtime>::default()
521
287
            .build_storage()
522
287
            .unwrap();
523

            
524
287
        pallet_babe::GenesisConfig::<Runtime> {
525
287
            ..Default::default()
526
287
        }
527
287
        .assimilate_storage(&mut t)
528
287
        .unwrap();
529

            
530
287
        pallet_balances::GenesisConfig::<Runtime> {
531
287
            balances: self.balances,
532
287
            ..Default::default()
533
287
        }
534
287
        .assimilate_storage(&mut t)
535
287
        .unwrap();
536

            
537
        // We need to initialize these pallets first. When initializing pallet-session,
538
        // these values will be taken into account for collator-assignment.
539

            
540
        pallet_registrar::GenesisConfig::<Runtime> {
541
287
            para_ids: self
542
287
                .para_ids
543
287
                .iter()
544
287
                .cloned()
545
287
                .map(|registered_para| {
546
139
                    (
547
139
                        registered_para.para_id.into(),
548
139
                        registered_para.genesis_data,
549
139
                        registered_para.parathread_params,
550
139
                    )
551
139
                })
552
287
                .collect(),
553
287
            ..Default::default()
554
        }
555
287
        .assimilate_storage(&mut t)
556
287
        .unwrap();
557

            
558
        // We register mock wasm
559
        runtime_parachains::paras::GenesisConfig::<Runtime> {
560
287
            paras: self
561
287
                .para_ids
562
287
                .iter()
563
287
                .cloned()
564
287
                .map(|registered_para| {
565
139
                    let para_kind = if registered_para.parathread_params.is_some() {
566
10
                        ParaKind::Parathread
567
                    } else {
568
129
                        ParaKind::Parachain
569
                    };
570
139
                    (
571
139
                        registered_para.para_id.into(),
572
139
                        ParaGenesisArgs {
573
139
                            validation_code: mock_validation_code(),
574
139
                            para_kind,
575
139
                            genesis_head: HeadData::from(vec![0u8]),
576
139
                        },
577
139
                    )
578
139
                })
579
287
                .collect(),
580
287
            ..Default::default()
581
        }
582
287
        .assimilate_storage(&mut t)
583
287
        .unwrap();
584

            
585
        pallet_services_payment::GenesisConfig::<Runtime> {
586
287
            para_id_credits: self
587
287
                .para_ids
588
287
                .clone()
589
287
                .into_iter()
590
287
                .map(|registered_para| {
591
139
                    (
592
139
                        registered_para.para_id.into(),
593
139
                        registered_para.block_production_credits,
594
139
                        registered_para.collator_assignment_credits,
595
139
                    )
596
139
                        .into()
597
139
                })
598
287
                .collect(),
599
        }
600
287
        .assimilate_storage(&mut t)
601
287
        .unwrap();
602

            
603
287
        runtime_common::paras_registrar::GenesisConfig::<Runtime> {
604
287
            next_free_para_id: self.next_free_para_id,
605
287
            ..Default::default()
606
287
        }
607
287
        .assimilate_storage(&mut t)
608
287
        .unwrap();
609

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

            
617
287
        pallet_xcm::GenesisConfig::<Runtime> {
618
287
            safe_xcm_version: self.safe_xcm_version,
619
287
            ..Default::default()
620
287
        }
621
287
        .assimilate_storage(&mut t)
622
287
        .unwrap();
623

            
624
287
        runtime_parachains::configuration::GenesisConfig::<Runtime> {
625
287
            config: self.relay_config,
626
287
        }
627
287
        .assimilate_storage(&mut t)
628
287
        .unwrap();
629

            
630
287
        let mut keys: Vec<_> = Vec::new();
631
287
        let mut non_authority_keys: Vec<_> = Vec::new();
632
287
        if !self.validators.is_empty() {
633
264
            let validator_keys: Vec<_> = self
634
264
                .validators
635
264
                .clone()
636
264
                .into_iter()
637
541
                .map(|(account, _balance)| {
638
541
                    let authority_keys = get_authority_keys_from_seed(&account.to_string());
639
541
                    if let Some(keystore) = self.keystore.as_ref() {
640
14
                        insert_authority_keys_into_keystore(&account.to_string(), keystore)
641
527
                    }
642
541
                    (
643
541
                        account.clone(),
644
541
                        account,
645
541
                        crate::SessionKeys {
646
541
                            babe: authority_keys.babe.clone(),
647
541
                            grandpa: authority_keys.grandpa.clone(),
648
541
                            para_validator: authority_keys.para_validator.clone(),
649
541
                            para_assignment: authority_keys.para_assignment.clone(),
650
541
                            authority_discovery: authority_keys.authority_discovery.clone(),
651
541
                            beefy: authority_keys.beefy.clone(),
652
541
                            nimbus: authority_keys.nimbus.clone(),
653
541
                        },
654
541
                    )
655
541
                })
656
264
                .collect();
657
264
            keys.extend(validator_keys)
658
23
        }
659

            
660
287
        if !self.external_validators.is_empty() {
661
23
            let validator_keys: Vec<_> = self
662
23
                .external_validators
663
23
                .clone()
664
23
                .into_iter()
665
46
                .map(|(account, _balance)| {
666
46
                    let authority_keys = get_authority_keys_from_seed(&account.to_string());
667
46
                    if let Some(keystore) = self.keystore.as_ref() {
668
                        insert_authority_keys_into_keystore(&account.to_string(), keystore)
669
46
                    }
670
46
                    (
671
46
                        account.clone(),
672
46
                        account,
673
46
                        crate::SessionKeys {
674
46
                            babe: authority_keys.babe.clone(),
675
46
                            grandpa: authority_keys.grandpa.clone(),
676
46
                            para_validator: authority_keys.para_validator.clone(),
677
46
                            para_assignment: authority_keys.para_assignment.clone(),
678
46
                            authority_discovery: authority_keys.authority_discovery.clone(),
679
46
                            beefy: authority_keys.beefy.clone(),
680
46
                            nimbus: authority_keys.nimbus.clone(),
681
46
                        },
682
46
                    )
683
46
                })
684
23
                .collect();
685
23
            keys.extend(validator_keys)
686
264
        }
687

            
688
287
        if !self.collators.is_empty() {
689
            // We set invulnerables in pallet_invulnerables
690
83
            let invulnerables: Vec<AccountId> = self
691
83
                .collators
692
83
                .clone()
693
83
                .into_iter()
694
83
                .map(|(account, _balance)| account)
695
83
                .collect();
696

            
697
83
            pallet_invulnerables::GenesisConfig::<Runtime> {
698
83
                invulnerables: invulnerables.clone(),
699
83
            }
700
83
            .assimilate_storage(&mut t)
701
83
            .unwrap();
702

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

            
743
        pallet_external_validators::GenesisConfig::<Runtime> {
744
            skip_external_validators: false,
745
287
            whitelisted_validators: self
746
287
                .validators
747
287
                .iter()
748
541
                .map(|(account, _)| account.clone())
749
287
                .collect(),
750
287
            external_validators: self
751
287
                .external_validators
752
287
                .iter()
753
287
                .map(|(account, _)| account.clone())
754
287
                .collect(),
755
        }
756
287
        .assimilate_storage(&mut t)
757
287
        .unwrap();
758

            
759
287
        pallet_session::GenesisConfig::<Runtime> {
760
287
            keys,
761
287
            non_authority_keys,
762
287
        }
763
287
        .assimilate_storage(&mut t)
764
287
        .unwrap();
765

            
766
287
        pallet_sudo::GenesisConfig::<Runtime> { key: self.sudo }
767
287
            .assimilate_storage(&mut t)
768
287
            .unwrap();
769

            
770
287
        snowbridge_pallet_system::GenesisConfig::<Runtime> {
771
287
            // This is irrelevant, we can put any number here
772
287
            // as long as it is a non-used para id
773
287
            para_id: 1000u32.into(),
774
287
            asset_hub_para_id: 1001u32.into(),
775
287
            ..Default::default()
776
287
        }
777
287
        .assimilate_storage(&mut t)
778
287
        .unwrap();
779

            
780
287
        if self.safe_xcm_version.is_some() {
781
            // Disable run_block checks in XCM tests, because the XCM emulator runs on_initialize and
782
            // on_finalize automatically
783
            t.top.insert(b"__mock_is_xcm_test".to_vec(), b"1".to_vec());
784
287
        }
785

            
786
        // Indicate that we should always (for every block) inject the paras_inherent.
787
        // Wether we inject an empty one or not its decided by b'ParasInherentData
788
287
        t.top.insert(
789
287
            b"ParasInherentEnabled".to_vec(),
790
287
            self.inherent_data_enabled.encode(),
791
        );
792

            
793
287
        t
794
287
    }
795

            
796
287
    pub fn build(self) -> sp_io::TestExternalities {
797
287
        let keystore = self.keystore.clone();
798
287
        let t = self.build_storage();
799
287
        let mut ext = sp_io::TestExternalities::new(t);
800
287
        if let Some(keystore) = keystore {
801
7
            ext.register_extension(KeystoreExt(keystore));
802
280
        }
803
287
        ext.execute_with(|| {
804
            // Start block 1
805
287
            start_block();
806
287
        });
807
287
        ext
808
287
    }
809
}
810

            
811
269
pub fn root_origin() -> <Runtime as frame_system::Config>::RuntimeOrigin {
812
269
    <Runtime as frame_system::Config>::RuntimeOrigin::root()
813
269
}
814

            
815
374
pub fn origin_of(account_id: AccountId) -> <Runtime as frame_system::Config>::RuntimeOrigin {
816
374
    <Runtime as frame_system::Config>::RuntimeOrigin::signed(account_id)
817
374
}
818

            
819
104
pub fn inherent_origin() -> <Runtime as frame_system::Config>::RuntimeOrigin {
820
104
    <Runtime as frame_system::Config>::RuntimeOrigin::none()
821
104
}
822

            
823
/// This function is different in solochains: instead of creating a storage proof and calling the
824
/// `set_latest_author_data` inherent with that proof as argument, this writes to storage directly.
825
12
pub fn set_author_noting_inherent_data(builder: ParaHeaderSproofBuilder) {
826
33
    for (k, v) in builder.key_values() {
827
33
        frame_support::storage::unhashed::put_raw(&k, &v);
828
33
    }
829

            
830
12
    assert_ok!(RuntimeCall::AuthorNoting(
831
12
        pallet_author_noting::Call::<Runtime>::set_latest_author_data { data: () }
832
12
    )
833
12
    .dispatch(inherent_origin()));
834
12
}
835

            
836
139
pub fn empty_genesis_data() -> ContainerChainGenesisData {
837
139
    ContainerChainGenesisData {
838
139
        storage: Default::default(),
839
139
        name: Default::default(),
840
139
        id: Default::default(),
841
139
        fork_id: Default::default(),
842
139
        extensions: Default::default(),
843
139
        properties: Default::default(),
844
139
    }
845
139
}
846

            
847
5569
pub fn current_slot() -> u64 {
848
5569
    Babe::current_slot().into()
849
5569
}
850

            
851
21
pub fn block_credits_to_required_balance(number_of_blocks: u32, para_id: ParaId) -> Balance {
852
21
    let block_cost = BlockProductionCost::block_cost(&para_id).0;
853
21
    u128::from(number_of_blocks).saturating_mul(block_cost)
854
21
}
855

            
856
4
pub fn collator_assignment_credits_to_required_balance(
857
4
    number_of_sessions: u32,
858
4
    para_id: ParaId,
859
4
) -> Balance {
860
4
    let collator_assignment_cost = CollatorAssignmentCost::collator_assignment_cost(&para_id).0;
861
4
    u128::from(number_of_sessions).saturating_mul(collator_assignment_cost)
862
4
}
863

            
864
pub const ALICE: [u8; 32] = [4u8; 32];
865
pub const BOB: [u8; 32] = [5u8; 32];
866
pub const CHARLIE: [u8; 32] = [6u8; 32];
867
pub const DAVE: [u8; 32] = [7u8; 32];
868
pub const EVE: [u8; 32] = [8u8; 32];
869
pub const FERDIE: [u8; 32] = [9u8; 32];
870

            
871
// Whether we have custom data to inject in paras inherent
872
92
fn take_new_inherent_data() -> Option<cumulus_primitives_core::relay_chain::vstaging::InherentData>
873
{
874
92
    let data: Option<cumulus_primitives_core::relay_chain::vstaging::InherentData> =
875
92
        frame_support::storage::unhashed::take(b"ParasInherentData");
876

            
877
92
    data
878
92
}
879

            
880
// Whether we should inject the paras inherent.
881
5569
fn is_para_inherent_enabled() -> bool {
882
5569
    let enabled: Option<bool> = frame_support::storage::unhashed::get(b"ParasInherentEnabled");
883
5569
    enabled.unwrap_or(false)
884
5569
}
885

            
886
// Set new data to inject in paras inherent
887
7
pub fn set_new_inherent_data(data: cumulus_primitives_core::relay_chain::vstaging::InherentData) {
888
7
    frame_support::storage::unhashed::put(b"ParasInherentData", &data);
889
7
}
890

            
891
1
pub fn set_new_randomness_data(data: Option<[u8; 32]>) {
892
1
    pallet_babe::AuthorVrfRandomness::<Runtime>::set(data);
893
1
}
894

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

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

            
926
    /// Paras which don't yet occupy a core, but will after the inherent has been processed.
927
    backed_in_inherent_paras: BTreeMap<u32, u32>,
928
    _phantom: core::marker::PhantomData<T>,
929
}
930

            
931
192
pub fn mock_validation_code() -> ValidationCode {
932
192
    ValidationCode(vec![1; 10])
933
192
}
934

            
935
/// Create a dummy collator id suitable to be used in a V1 candidate descriptor.
936
pub fn junk_collator() -> CollatorId {
937
    CollatorId::from_slice((0..32).collect::<Vec<_>>().as_slice()).expect("32 bytes; qed")
938
}
939

            
940
/// Creates a dummy collator signature suitable to be used in a V1 candidate descriptor.
941
pub fn junk_collator_signature() -> CollatorSignature {
942
    CollatorSignature::from_slice((0..64).collect::<Vec<_>>().as_slice()).expect("64 bytes; qed")
943
}
944

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

            
958
    /// Set a map from para id seed to number of validity votes.
959
7
    pub(crate) fn set_backed_and_concluding_paras(
960
7
        mut self,
961
7
        backed_and_concluding_paras: BTreeMap<u32, u32>,
962
7
    ) -> Self {
963
7
        self.backed_and_concluding_paras = backed_and_concluding_paras;
964
7
        self
965
7
    }
966

            
967
    /// Set a map from para id seed to number of validity votes for votes in inherent data.
968
    pub(crate) fn set_backed_in_inherent_paras(mut self, backed: BTreeMap<u32, u32>) -> Self {
969
        self.backed_in_inherent_paras = backed;
970
        self
971
    }
972

            
973
    /// Mock header.
974
313
    pub(crate) fn header(block_number: BlockNumberFor<T>) -> HeaderFor<T> {
975
313
        HeaderFor::<T>::new(
976
313
            block_number,       // `block_number`,
977
313
            Default::default(), // `extrinsics_root`,
978
313
            Default::default(), // `storage_root`,
979
313
            Default::default(), // `parent_hash`,
980
313
            Default::default(), // digest,
981
        )
982
313
    }
983

            
984
    /// Maximum number of validators that may be part of a validator group.
985
    pub(crate) fn fallback_max_validators() -> u32 {
986
        runtime_parachains::configuration::ActiveConfig::<T>::get()
987
            .max_validators
988
            .unwrap_or(200)
989
    }
990

            
991
    /// Maximum number of validators participating in parachains consensus (a.k.a. active
992
    /// validators).
993
    fn max_validators(&self) -> u32 {
994
        Self::fallback_max_validators()
995
    }
996

            
997
    /// Maximum number of validators per core (a.k.a. max validators per group). This value is used
998
    /// if none is explicitly set on the builder.
999
    pub(crate) fn fallback_max_validators_per_core() -> u32 {
        runtime_parachains::configuration::ActiveConfig::<T>::get()
            .scheduler_params
            .max_validators_per_core
            .unwrap_or(5)
    }
    /// 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.
99
    fn availability_bitvec(concluding_cores: &BTreeSet<u32>, cores: usize) -> AvailabilityBitfield {
99
        let mut bitfields = bitvec::bitvec![u8, bitvec::order::Lsb0; 0; 0];
198
        for i in 0..cores {
198
            if concluding_cores.contains(&(i as u32)) {
8
                bitfields.push(true);
8
            } else {
190
                bitfields.push(false)
            }
        }
99
        bitfields.into()
99
    }
    /// 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]
    }
16
    pub fn mock_head_data() -> HeadData {
16
        let max_head_size =
16
            runtime_parachains::configuration::ActiveConfig::<T>::get().max_head_data_size;
16
        HeadData(vec![0xFF; max_head_size as usize])
16
    }
    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.
16
    fn relay_parent_number(&self) -> u32 {
16
        (Self::block_number() - One::one())
16
            .try_into()
16
            .map_err(|_| ())
16
            .expect("Self::block_number() is u32")
16
    }
    /// 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
99
    fn create_backed_candidates(
99
        &self,
99
        paras_with_backed_candidates: &BTreeMap<u32, u32>,
99
    ) -> Vec<BackedCandidate<T::Hash>> {
99
        let current_session = runtime_parachains::shared::CurrentSessionIndex::<T>::get();
        // We need to refetch validators since they have been shuffled.
99
        let validators_shuffled =
99
            runtime_parachains::session_info::Sessions::<T>::get(current_session)
99
                .unwrap()
99
                .validators
99
                .clone();
99
        let config = runtime_parachains::configuration::ActiveConfig::<T>::get();
99
        let mut current_core_idx = 0u32;
99
        paras_with_backed_candidates
99
            .iter()
99
            .flat_map(|(seed, num_votes)| {
8
                assert!(*num_votes <= validators_shuffled.len() as u32);
8
                let para_id = ParaId::from(*seed);
8
                let prev_head_non_mut = runtime_parachains::paras::Heads::<T>::get(para_id);
8
                let prev_head = prev_head_non_mut.unwrap_or(Self::mock_head_data());
                // How many chained candidates we want to build ?
8
                (0..1)
8
                    .map(|chain_idx| {
8
                        let core_idx = CoreIndex::from(current_core_idx);
                        // Advance core index.
8
                        current_core_idx += 1;
8
                        let group_idx =
8
                            Self::group_assigned_to_core(core_idx, Self::block_number())
8
                                .unwrap_or_else(|| {
                                    panic!("Validator group not assigned to core {:?}", core_idx)
                                });
8
                        let header = Self::header(Self::block_number());
8
                        let relay_parent = header.hash();
                        // Set the head data so it can be used while validating the signatures on
                        // the candidate receipt.
8
                        let mut head_data = Self::mock_head_data();
8
                        if chain_idx == 0 {
8
                            // Only first parahead of the chain needs to be set in storage.
8
                            Self::heads_insert(&para_id, prev_head.clone());
8
                        } else {
                            // Make each candidate head data unique to avoid cycles.
                            head_data.0[0] = chain_idx;
                        }
8
                        let persisted_validation_data = PersistedValidationData::<T::Hash> {
8
                            // To form a chain we set parent head to previous block if any, or
8
                            // default to what is in storage already setup.
8
                            parent_head: prev_head.clone(),
8
                            relay_parent_number: self.relay_parent_number() + 1,
8
                            relay_parent_storage_root: Default::default(),
8
                            max_pov_size: config.max_pov_size,
8
                        };
8
                        let persisted_validation_data_hash = persisted_validation_data.hash();
8
                        let pov_hash = Default::default();
8
                        let validation_code_hash = mock_validation_code().hash();
                        /*
                        let mut past_code_meta =
                            paras::ParaPastCodeMeta::<BlockNumberFor<T>>::default();
                        past_code_meta.note_replacement(0u32.into(), 0u32.into());
                         */
8
                        let group_validators = Self::group_validators(group_idx).unwrap();
8
                        let descriptor = if true
                        /* self.candidate_descriptor_v2 */
                        {
8
                            CandidateDescriptorV2::new(
8
                                para_id,
8
                                relay_parent,
8
                                core_idx,
8
                                current_session,
8
                                persisted_validation_data_hash,
8
                                pov_hash,
8
                                Default::default(),
8
                                prev_head.hash(),
8
                                validation_code_hash,
                            )
                        } else {
                            todo!()
                        };
8
                        let mut candidate = CommittedCandidateReceiptV2::<T::Hash> {
8
                            descriptor,
8
                            commitments: CandidateCommitments::<u32> {
8
                                upward_messages: Default::default(),
8
                                horizontal_messages: Default::default(),
8
                                new_validation_code: None,
8
                                head_data: prev_head.clone(),
8
                                processed_downward_messages: 0,
8
                                hrmp_watermark: self.relay_parent_number() + 1,
8
                            },
8
                        };
8
                        if true
                        /* self.candidate_descriptor_v2 */
8
                        {
8
                            // `UMPSignal` separator.
8
                            candidate
8
                                .commitments
8
                                .upward_messages
8
                                .force_push(UMP_SEPARATOR);
8

            
8
                            // `SelectCore` commitment.
8
                            // Claim queue offset must be `0` so this candidate is for the very
8
                            // next block.
8
                            candidate.commitments.upward_messages.force_push(
8
                                UMPSignal::SelectCore(CoreSelector(chain_idx), ClaimQueueOffset(0))
8
                                    .encode(),
8
                            );
8
                        }
8
                        let candidate_hash = candidate.hash();
8
                        let validity_votes: Vec<_> = group_validators
8
                            .iter()
8
                            .take(*num_votes as usize)
8
                            .map(|val_idx| {
8
                                let public = validators_shuffled.get(*val_idx).unwrap();
8
                                let signature_ctx = SigningContext {
8
                                    parent_hash: Self::header(Self::block_number()).hash(),
8
                                    session_index: Session::current_index(),
8
                                };
8
                                let sig = UncheckedSigned::<CompactStatement>::benchmark_sign(
8
                                    public,
8
                                    CompactStatement::Valid(candidate_hash),
8
                                    &signature_ctx,
8
                                    *val_idx,
8
                                )
8
                                .benchmark_signature();
8
                                ValidityAttestation::Explicit(sig.clone())
8
                            })
8
                            .collect();
                        // Check if the elastic scaling bit is set, if so we need to supply the core
                        // index in the generated candidate.
8
                        let core_idx = runtime_parachains::configuration::ActiveConfig::<T>::get()
8
                            .node_features
8
                            .get(FeatureIndex::ElasticScalingMVP as usize)
8
                            .and_then(|the_bit| if *the_bit { Some(core_idx) } else { None })
8
                            .expect("ElasticScalingMVP feature index should be present");
8
                        assert_eq!(group_validators.len(), 1);
8
                        BackedCandidate::<T::Hash>::new(
8
                            candidate,
8
                            validity_votes,
8
                            bitvec::bitvec![u8, bitvec::order::Lsb0; 1; group_validators.len()],
8
                            core_idx,
                        )
8
                    })
8
                    .collect::<Vec<_>>()
8
            })
99
            .collect()
99
    }
    /// 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.
8
    pub(crate) fn group_assigned_to_core(
8
        core: CoreIndex,
8
        at: BlockNumberFor<T>,
8
    ) -> Option<GroupIndex> {
8
        let config = runtime_parachains::configuration::ActiveConfig::<T>::get();
8
        let session_start_block = runtime_parachains::scheduler::SessionStartBlock::<T>::get();
8
        if at < session_start_block {
            return None;
8
        }
8
        let validator_groups = runtime_parachains::scheduler::ValidatorGroups::<T>::get();
8
        if core.0 as usize >= validator_groups.len() {
            return None;
8
        }
8
        let rotations_since_session_start: BlockNumberFor<T> =
8
            (at - session_start_block) / config.scheduler_params.group_rotation_frequency;
8
        let rotations_since_session_start =
8
            <BlockNumberFor<T> as TryInto<u32>>::try_into(rotations_since_session_start)
8
                .unwrap_or(0);
        // Error case can only happen if rotations occur only once every u32::max(),
        // so functionally no difference in behavior.
8
        let group_idx =
8
            (core.0 as usize + rotations_since_session_start as usize) % validator_groups.len();
8
        Some(GroupIndex(group_idx as u32))
8
    }
    /// Get the validators in the given group, if the group index is valid for this session.
8
    pub(crate) fn group_validators(group_index: GroupIndex) -> Option<Vec<ValidatorIndex>> {
8
        runtime_parachains::scheduler::ValidatorGroups::<T>::get()
8
            .get(group_index.0 as usize)
8
            .cloned()
8
    }
8
    pub fn heads_insert(para_id: &ParaId, head_data: HeadData) {
8
        runtime_parachains::paras::Heads::<T>::insert(para_id, head_data);
8
    }
    /// 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.
99
    pub(crate) fn build(self) -> ParachainsInherentData<HeaderFor<T>> {
99
        let current_session = runtime_parachains::shared::CurrentSessionIndex::<T>::get();
        // We need to refetch validators since they have been shuffled.
99
        let validators = runtime_parachains::session_info::Sessions::<T>::get(current_session)
99
            .unwrap()
99
            .validators
99
            .clone();
        //let max_cores = self.max_cores() as usize;
99
        let max_cores = 2;
99
        let used_cores =
99
            self.backed_and_concluding_paras.len() + self.backed_in_inherent_paras.len();
99
        assert!(used_cores <= max_cores);
99
        let mut backed_in_inherent = BTreeMap::new();
99
        backed_in_inherent.append(&mut self.backed_and_concluding_paras.clone());
99
        backed_in_inherent.append(&mut self.backed_in_inherent_paras.clone());
99
        let backed_candidates = self.create_backed_candidates(&backed_in_inherent);
99
        let used_cores_set = (0..used_cores).map(|x| x as u32).collect();
99
        let availability_bitvec = Self::availability_bitvec(&used_cores_set, max_cores);
99
        let bitfields: Vec<UncheckedSigned<AvailabilityBitfield>> = validators
99
            .iter()
99
            .enumerate()
198
            .map(|(i, public)| {
198
                UncheckedSigned::<AvailabilityBitfield>::benchmark_sign(
198
                    public,
198
                    availability_bitvec.clone(),
198
                    &SigningContext {
198
                        parent_hash: Self::header(Self::block_number()).hash(),
198
                        session_index: Session::current_index(),
198
                    },
198
                    ValidatorIndex(i as u32),
                )
198
            })
99
            .collect();
99
        ParachainsInherentData {
99
            bitfields,
99
            backed_candidates,
99
            disputes: vec![],
99
            parent_header: Self::header(Self::block_number()),
99
        }
99
    }
337
    pub(crate) fn block_number() -> BlockNumberFor<T> {
337
        frame_system::Pallet::<T>::block_number()
337
    }
}
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
    let mut final_key = Vec::with_capacity(
3
        pallet_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.as_ref().len(),
    );
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
    final_key
3
}
23
pub fn set_dummy_boot_node(para_manager: RuntimeOrigin, para_id: ParaId) {
    use {
        pallet_data_preservers::{NodeType, ParaIdsFilter, Profile},
        tp_data_preservers_common::{AssignerExtra, ProviderRequest},
    };
23
    let profile = Profile {
23
        bootnode_url: Some(
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
        ),
23
        direct_rpc_urls: Default::default(),
23
        proxy_rpc_urls: Default::default(),
23
        para_ids: ParaIdsFilter::AnyParaId,
23
        node_type: NodeType::Substrate,
23
        assignment_request: ProviderRequest::Free,
23
        additional_info: Default::default(),
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
    DataPreservers::start_assignment(para_manager, profile_id, para_id, AssignerExtra::Free)
23
        .expect("assignment to work");
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,
};
4
pub fn generate_grandpa_equivocation_proof(
4
    set_id: SetId,
4
    vote1: (RoundNumber, H256, u32, &GrandpaAuthorityPair),
4
    vote2: (RoundNumber, H256, u32, &GrandpaAuthorityPair),
4
) -> EquivocationProof<H256, u32> {
8
    let signed_prevote = |round, hash, number, authority_pair: &GrandpaAuthorityPair| {
8
        let prevote = finality_grandpa::Prevote {
8
            target_hash: hash,
8
            target_number: number,
8
        };
8
        let prevote_msg = finality_grandpa::Message::Prevote(prevote.clone());
8
        let payload = grandpa_primitives::localized_payload(round, set_id, &prevote_msg);
8
        let signed = authority_pair.sign(&payload);
8
        (prevote, signed)
8
    };
4
    let (prevote1, signed1) = signed_prevote(vote1.0, vote1.1, vote1.2, vote1.3);
4
    let (prevote2, signed2) = signed_prevote(vote2.0, vote2.1, vote2.2, vote2.3);
4
    EquivocationProof::new(
4
        set_id,
4
        Equivocation::Prevote(finality_grandpa::Equivocation {
4
            round_number: vote1.0,
4
            identity: vote1.3.public(),
4
            first: (prevote1, signed1),
4
            second: (prevote2, signed2),
4
        }),
    )
4
}
/// Creates an equivocation at the current block, by generating two headers.
10
pub fn generate_babe_equivocation_proof(
10
    offender_authority_pair: &BabeAuthorityPair,
10
) -> babe_primitives::EquivocationProof<crate::Header> {
    use babe_primitives::digests::CompatibleDigestItem;
10
    let current_digest = System::digest();
10
    let babe_predigest = current_digest
10
        .clone()
10
        .logs()
10
        .iter()
10
        .find_map(|log| log.as_babe_pre_digest());
10
    let slot_proof = babe_predigest.expect("babe should be presesnt").slot();
10
    let make_headers = || {
10
        (
10
            HeaderFor::<Runtime>::new(
10
                0,
10
                H256::default(),
10
                H256::default(),
10
                H256::default(),
10
                current_digest.clone(),
10
            ),
10
            HeaderFor::<Runtime>::new(
10
                1,
10
                H256::default(),
10
                H256::default(),
10
                H256::default(),
10
                current_digest.clone(),
10
            ),
10
        )
10
    };
    // sign the header prehash and sign it, adding it to the block as the seal
    // digest item
20
    let seal_header = |header: &mut crate::Header| {
20
        let prehash = header.hash();
20
        let seal = <DigestItem as CompatibleDigestItem>::babe_seal(
20
            offender_authority_pair.sign(prehash.as_ref()),
        );
20
        header.digest_mut().push(seal);
20
    };
    // generate two headers at the current block
10
    let (mut h1, mut h2) = make_headers();
10
    seal_header(&mut h1);
10
    seal_header(&mut h2);
10
    babe_primitives::EquivocationProof {
10
        slot: slot_proof,
10
        offender: offender_authority_pair.public(),
10
        first_header: h1,
10
        second_header: h2,
10
    }
10
}
/// Helper function to generate a crypto pair from seed
14
pub fn get_pair_from_seed<TPublic: Public>(seed: &str) -> TPublic::Pair {
14
    let secret_uri = format!("//{}", seed);
14
    TPublic::Pair::from_string(&secret_uri, None).expect("static values are valid; qed")
14
}
39
pub fn mock_snowbridge_message_proof() -> Proof {
39
    Proof {
39
        receipt_proof: (vec![], vec![]),
39
        execution_proof: ExecutionProof {
39
            header: Default::default(),
39
            ancestry_proof: None,
39
            execution_header: VersionedExecutionPayloadHeader::Deneb(
39
                deneb::ExecutionPayloadHeader {
39
                    parent_hash: Default::default(),
39
                    fee_recipient: Default::default(),
39
                    state_root: Default::default(),
39
                    receipts_root: Default::default(),
39
                    logs_bloom: vec![],
39
                    prev_randao: Default::default(),
39
                    block_number: 0,
39
                    gas_limit: 0,
39
                    gas_used: 0,
39
                    timestamp: 0,
39
                    extra_data: vec![],
39
                    base_fee_per_gas: Default::default(),
39
                    block_hash: Default::default(),
39
                    transactions_root: Default::default(),
39
                    withdrawals_root: Default::default(),
39
                    blob_gas_used: 0,
39
                    excess_blob_gas: 0,
39
                },
39
            ),
39
            execution_branch: vec![],
39
        },
39
    }
39
}
/// note a new preimage without registering.
1
pub fn note_preimage(who: AccountId, call: &[u8]) -> <Runtime as frame_system::Config>::Hash {
1
    assert_ok!(Preimage::note_preimage(
1
        RuntimeOrigin::signed(who),
1
        call.to_vec()
    ));
1
    let hash = BlakeTwo256::hash(&call);
1
    assert!(!Preimage::is_requested(&hash));
1
    hash
1
}
3
pub fn wait_for_democracy_to_pass(proposal_index: pallet_referenda::ReferendumIndex) {
283
    while !is_deciding(proposal_index) {
280
        run_to_block(System::block_number() + 1);
280
    }
3
    if is_confirming(proposal_index) {
3
        let confirming_until = confirming_until(proposal_index);
3
        let current_block_number = System::block_number();
3
        if current_block_number < confirming_until {
323
            while System::block_number() < confirming_until {
320
                run_to_block(System::block_number() + 1);
320
            }
        }
    }
3
    if is_approved(proposal_index) {
3
        run_to_block(System::block_number() + 1);
3
    }
3
}
283
fn is_deciding(i: pallet_referenda::ReferendumIndex) -> bool {
280
    matches!(
283
        pallet_referenda::ReferendumInfoFor::<Runtime>::get(i),
        Some(pallet_referenda::ReferendumInfo::Ongoing(
            ReferendumStatus {
                deciding: Some(_),
                ..
            }
        ))
    )
283
}
3
fn is_confirming(i: pallet_referenda::ReferendumIndex) -> bool {
    matches!(
3
        pallet_referenda::ReferendumInfoFor::<Runtime>::get(i),
        Some(pallet_referenda::ReferendumInfo::Ongoing(
            ReferendumStatus {
                deciding: Some(DecidingStatus {
3
                    confirming: Some(_until),
                    ..
                }),
                ..
            }
        ))
    )
3
}
3
fn confirming_until(i: pallet_referenda::ReferendumIndex) -> u32 {
3
    match pallet_referenda::ReferendumInfoFor::<Runtime>::get(i).unwrap() {
        pallet_referenda::ReferendumInfo::Ongoing(ReferendumStatus {
            deciding:
                Some(DecidingStatus {
3
                    confirming: Some(until),
                    ..
                }),
            ..
3
        }) => until,
        _ => panic!("Not confirming"),
    }
3
}
3
fn is_approved(i: pallet_referenda::ReferendumIndex) -> bool {
    matches!(
3
        pallet_referenda::ReferendumInfoFor::<Runtime>::get(i),
        Some(pallet_referenda::ReferendumInfo::Approved(..))
    )
3
}
fn is_rejected(i: pallet_referenda::ReferendumIndex) -> bool {
    matches!(
        pallet_referenda::ReferendumInfoFor::<Runtime>::get(i),
        Some(pallet_referenda::ReferendumInfo::Rejected(..))
    )
}