integration_tests.rs 34.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

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

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

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

//! Mocking utilities for testing with real pallets.

use sp_std::sync::Arc;
use sp_io::TestExternalities;
use sp_core::{H256, crypto::KeyTypeId};
use sp_runtime::{
	traits::{
		BlakeTwo256, IdentityLookup, One,
	},
};
use sp_keystore::{KeystoreExt, testing::KeyStore};
28
use primitives::v1::{BlockNumber, Header, Id as ParaId, ValidationCode, HeadData, LOWEST_PUBLIC_ID};
29
use frame_support::{
Shawn Tabrizi's avatar
Shawn Tabrizi committed
30
	parameter_types, assert_ok, assert_noop, PalletId,
31
32
33
34
35
36
37
38
39
40
41
	storage::StorageMap,
	traits::{Currency, OnInitialize, OnFinalize, KeyOwnerProofSystem},
};
use frame_system::EnsureRoot;
use runtime_parachains::{
	ParaLifecycle, Origin as ParaOrigin,
	paras, configuration, shared,
};
use frame_support_test::TestRandomness;
use crate::{
	auctions, crowdloan, slots, paras_registrar,
42
	slot_range::SlotRange,
43
	traits::{
44
		Registrar as RegistrarT, Auctioneer, AuctionStatus,
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
	},
};

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;

type AccountId = u32;
type Balance = u32;
type Moment = u32;

frame_support::construct_runtime!(
	pub enum Test where
		Block = Block,
		NodeBlock = Block,
		UncheckedExtrinsic = UncheckedExtrinsic,
	{
		// System Stuff
62
63
64
		System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
		Babe: pallet_babe::{Pallet, Call, Storage, Config, ValidateUnsigned},
65
66

		// Parachains Runtime
67
		Configuration: configuration::{Pallet, Call, Storage, Config<T>},
68
		Paras: paras::{Pallet, Origin, Call, Storage, Event, Config<T>},
69
70

		// Para Onboarding Pallets
71
72
73
74
		Registrar: paras_registrar::{Pallet, Call, Storage, Event<T>},
		Auctions: auctions::{Pallet, Call, Storage, Event<T>},
		Crowdloan: crowdloan::{Pallet, Call, Storage, Event<T>},
		Slots: slots::{Pallet, Call, Storage, Event<T>},
75
76
77
78
	}
);

use crate::crowdloan::Error as CrowdloanError;
79
use crate::auctions::Error as AuctionsError;
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

parameter_types! {
	pub const BlockHashCount: u32 = 250;
	pub BlockWeights: frame_system::limits::BlockWeights =
		frame_system::limits::BlockWeights::simple_max(4 * 1024 * 1024);
}

impl frame_system::Config for Test {
	type BaseCallFilter = ();
	type BlockWeights = BlockWeights;
	type BlockLength = ();
	type DbWeight = ();
	type Origin = Origin;
	type Call = Call;
	type Index = u64;
	type BlockNumber = BlockNumber;
	type Hash = H256;
	type Hashing = BlakeTwo256;
	type AccountId = AccountId;
	type Lookup = IdentityLookup<AccountId>;
	type Header = Header;
	type Event = Event;
	type BlockHashCount = BlockHashCount;
	type Version = ();
	type PalletInfo = PalletInfo;
	type AccountData = pallet_balances::AccountData<Balance>;
	type OnNewAccount = ();
	type OnKilledAccount = ();
	type SystemWeightInfo = ();
	type SS58Prefix = ();
110
	type OnSetCode = ();
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
}

parameter_types! {
	pub const EpochDuration: u64 = 10;
	pub const ExpectedBlockTime: Moment = 6_000;
	pub const ReportLongevity: u64 = 10;
}

impl pallet_babe::Config for Test {
	type EpochDuration = EpochDuration;
	type ExpectedBlockTime = ExpectedBlockTime;
	type EpochChangeTrigger = pallet_babe::ExternalTrigger;
	type KeyOwnerProofSystem = ();
	type KeyOwnerProof =
		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, pallet_babe::AuthorityId)>>::Proof;
	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
		KeyTypeId,
		pallet_babe::AuthorityId,
	)>>::IdentificationTuple;
	type HandleEquivocation = ();
	type WeightInfo = ();
}

parameter_types! {
	pub const MinimumPeriod: Moment = 6_000 / 2;
}

impl pallet_timestamp::Config for Test {
	type Moment = Moment;
	type OnTimestampSet = ();
	type MinimumPeriod = MinimumPeriod;
	type WeightInfo = ();
}

parameter_types! {
	pub static ExistentialDeposit: Balance = 1;
Gavin Wood's avatar
Gavin Wood committed
147
	pub const MaxReserves: u32 = 50;
148
149
150
151
152
153
154
155
156
157
}

impl pallet_balances::Config for Test {
	type MaxLocks = ();
	type Balance = Balance;
	type Event = Event;
	type DustRemoval = ();
	type ExistentialDeposit = ExistentialDeposit;
	type AccountStore = System;
	type WeightInfo = ();
Gavin Wood's avatar
Gavin Wood committed
158
159
	type MaxReserves = MaxReserves;
	type ReserveIdentifier = [u8; 8];
160
161
162
163
164
165
166
167
}

impl configuration::Config for Test { }

impl shared::Config for Test { }

impl paras::Config for Test {
	type Origin = Origin;
168
	type Event = Event;
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
}

parameter_types! {
	pub const ParaDeposit: Balance = 500;
	pub const DataDepositPerByte: Balance = 1;
}

impl paras_registrar::Config for Test {
	type Event = Event;
	type OnSwap = (Crowdloan, Slots);
	type ParaDeposit = ParaDeposit;
	type DataDepositPerByte = DataDepositPerByte;
	type Currency = Balances;
	type Origin = Origin;
	type WeightInfo = crate::paras_registrar::TestWeightInfo;
}

parameter_types! {
	pub const EndingPeriod: BlockNumber = 10;
188
	pub const SampleLength: BlockNumber = 1;
189
190
191
192
193
}

impl auctions::Config for Test {
	type Event = Event;
	type Leaser = Slots;
194
	type Registrar = Registrar;
195
	type EndingPeriod = EndingPeriod;
196
	type SampleLength = SampleLength;
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
	type Randomness = TestRandomness<Self>;
	type InitiateOrigin = EnsureRoot<AccountId>;
	type WeightInfo = crate::auctions::TestWeightInfo;
}

parameter_types! {
	pub const LeasePeriod: BlockNumber = 100;
}

impl slots::Config for Test {
	type Event = Event;
	type Currency = Balances;
	type Registrar = Registrar;
	type LeasePeriod = LeasePeriod;
	type WeightInfo = crate::slots::TestWeightInfo;
}

parameter_types! {
Shawn Tabrizi's avatar
Shawn Tabrizi committed
215
	pub const CrowdloanId: PalletId = PalletId(*b"py/cfund");
216
217
218
	pub const SubmissionDeposit: Balance = 100;
	pub const MinContribution: Balance = 1;
	pub const RemoveKeysLimit: u32 = 100;
219
	pub const MaxMemoLength: u8 = 32;
220
221
222
223
}

impl crowdloan::Config for Test {
	type Event = Event;
Shawn Tabrizi's avatar
Shawn Tabrizi committed
224
	type PalletId = CrowdloanId;
225
226
227
228
229
	type SubmissionDeposit = SubmissionDeposit;
	type MinContribution = MinContribution;
	type RemoveKeysLimit = RemoveKeysLimit;
	type Registrar = Registrar;
	type Auctioneer = Auctions;
230
	type MaxMemoLength = MaxMemoLength;
231
232
233
234
235
	type WeightInfo = crate::crowdloan::TestWeightInfo;
}

/// Create a new set of test externalities.
pub fn new_test_ext() -> TestExternalities {
236
237
238
239
240
241
242
243
	let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
	configuration::GenesisConfig::<Test> {
		config: configuration::HostConfiguration {
			max_code_size: 2 * 1024 * 1024, // 2 MB
			max_head_data_size: 1 * 1024 * 1024, // 1 MB
			..Default::default()
		},
	}.assimilate_storage(&mut t).unwrap();
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
	let keystore = KeyStore::new();
	let mut ext: sp_io::TestExternalities = t.into();
	ext.register_extension(KeystoreExt(Arc::new(keystore)));
	ext.execute_with(|| System::set_block_number(1));
	ext
}

const BLOCKS_PER_SESSION: u32 = 10;

fn maybe_new_session(n: u32) {
	if n % BLOCKS_PER_SESSION == 0 {
		shared::Module::<Test>::set_session_index(
			shared::Module::<Test>::session_index() + 1
		);
		Paras::test_on_new_session();
	}
}

fn test_genesis_head(size: usize) -> HeadData {
	HeadData(vec![0u8; size])
}

fn test_validation_code(size: usize) -> ValidationCode {
asynchronous rob's avatar
asynchronous rob committed
267
	let validation_code = vec![0u8; size as usize];
268
269
270
271
272
273
274
275
276
277
278
	ValidationCode(validation_code)
}

fn para_origin(id: u32) -> ParaOrigin {
	ParaOrigin::Parachain(id.into())
}

fn run_to_block(n: u32) {
	assert!(System::block_number() < n);
	while System::block_number() < n {
		let block_number = System::block_number();
279
		AllPallets::on_finalize(block_number);
280
281
282
283
		System::on_finalize(block_number);
		System::set_block_number(block_number + 1);
		System::on_initialize(block_number + 1);
		maybe_new_session(block_number + 1);
284
		AllPallets::on_initialize(block_number + 1);
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
	}
}

fn run_to_session(n: u32) {
	let block_number = BLOCKS_PER_SESSION * n;
	run_to_block(block_number);
}

fn last_event() -> Event {
	System::events().pop().expect("Event expected").event
}

#[test]
fn basic_end_to_end_works() {
	new_test_ext().execute_with(|| {
300
301
		let para_1 = LOWEST_PUBLIC_ID;
		let para_2 = LOWEST_PUBLIC_ID + 1;
302
303
		assert!(System::block_number().is_one());
		// User 1 and 2 will own parachains
304
305
		Balances::make_free_balance_be(&1, 1_000_000_000);
		Balances::make_free_balance_be(&2, 1_000_000_000);
306
307
308
		// First register 2 parathreads
		let genesis_head = Registrar::worst_head_data();
		let validation_code = Registrar::worst_validation_code();
309
		assert_ok!(Registrar::reserve(Origin::signed(1)));
310
311
		assert_ok!(Registrar::register(
			Origin::signed(1),
312
			ParaId::from(para_1),
313
314
315
			genesis_head.clone(),
			validation_code.clone(),
		));
316
		assert_ok!(Registrar::reserve(Origin::signed(2)));
317
318
		assert_ok!(Registrar::register(
			Origin::signed(2),
319
			ParaId::from(2001),
320
321
322
323
324
			genesis_head,
			validation_code,
		));

		// Paras should be onboarding
325
326
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Onboarding));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Onboarding));
327
328
329
330
331
332
333
334

		// Start a new auction in the future
		let duration = 99u32;
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));

		// 2 sessions later they are parathreads
		run_to_session(2);
335
336
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread));
337
338
339
340
341

		// Para 1 will bid directly for slot 1, 2
		// Open a crowdloan for Para 2 for slot 3, 4
		assert_ok!(Crowdloan::create(
			Origin::signed(2),
342
			ParaId::from(para_2),
343
344
345
346
347
348
			1_000, // Cap
			lease_period_index_start + 2, // First Slot
			lease_period_index_start + 3, // Last Slot
			200, // Block End
			None,
		));
349
		let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(para_2));
350
351
352
353

		// Auction ending begins on block 100, so we make a bid before then.
		run_to_block(90);

354
355
		Balances::make_free_balance_be(&10, 1_000_000_000);
		Balances::make_free_balance_be(&20, 1_000_000_000);
356
357
358
359

		// User 10 will bid directly for parachain 1
		assert_ok!(Auctions::bid(
			Origin::signed(10),
360
			ParaId::from(para_1),
361
362
363
364
365
366
			1, // Auction Index
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 1, // Last slot
			910, // Amount
		));

367
		// User 2 will be a contribute to crowdloan for parachain 2
368
		Balances::make_free_balance_be(&2, 1_000_000_000);
369
		assert_ok!(Crowdloan::contribute(Origin::signed(2), ParaId::from(para_2), 920, None));
370
371
372
373
374

		// Auction ends at block 110
		run_to_block(109);
		assert_eq!(
			last_event(),
375
			crowdloan::Event::<Test>::HandleBidResult(ParaId::from(para_2), Ok(())).into(),
376
377
378
379
		);
		run_to_block(110);
		assert_eq!(
			last_event(),
380
			auctions::Event::<Test>::AuctionClosed(1).into(),
381
382
383
384
		);

		// Paras should have won slots
		assert_eq!(
385
			slots::Leases::<Test>::get(ParaId::from(para_1)),
386
387
388
389
			// -- 1 --- 2 --- 3 --------- 4 ------------ 5 --------
			vec![None, None, None, Some((10, 910)), Some((10, 910))],
		);
		assert_eq!(
390
			slots::Leases::<Test>::get(ParaId::from(para_2)),
391
392
393
394
			// -- 1 --- 2 --- 3 --- 4 --- 5 ---------------- 6 --------------------------- 7 ----------------
			vec![None, None, None, None, None, Some((crowdloan_account, 920)), Some((crowdloan_account, 920))],
		);

395
		// Should not be able to contribute to a winning crowdloan
396
		Balances::make_free_balance_be(&3, 1_000_000_000);
397
		assert_noop!(Crowdloan::contribute(Origin::signed(3), ParaId::from(2001), 10, None), CrowdloanError::<Test>::BidOrLeaseActive);
398

399
400
401
402
403
		// New leases will start on block 400
		let lease_start_block = 400;
		run_to_block(lease_start_block);

		// First slot, Para 1 should be transitioning to Parachain
404
405
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::UpgradingParathread));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread));
406
407
408

		// Two sessions later, it has upgraded
		run_to_block(lease_start_block + 20);
409
410
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parachain));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread));
411
412
413

		// Second slot nothing happens :)
		run_to_block(lease_start_block + 100);
414
415
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parachain));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread));
416
417
418

		// Third slot, Para 2 should be upgrading, and Para 1 is downgrading
		run_to_block(lease_start_block + 200);
419
420
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::DowngradingParachain));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::UpgradingParathread));
421
422
423

		// Two sessions later, they have transitioned
		run_to_block(lease_start_block + 220);
424
425
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parachain));
426
427
428

		// Fourth slot nothing happens :)
		run_to_block(lease_start_block + 300);
429
430
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parachain));
431
432
433

		// Fifth slot, Para 2 is downgrading
		run_to_block(lease_start_block + 400);
434
435
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::DowngradingParachain));
436
437
438

		// Two sessions later, Para 2 is downgraded
		run_to_block(lease_start_block + 420);
439
440
		assert_eq!(Paras::lifecycle(ParaId::from(para_1)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(para_2)), Some(ParaLifecycle::Parathread));
441
442
443
444
445
446
447
	});
}

#[test]
fn basic_errors_fail() {
	new_test_ext().execute_with(|| {
		assert!(System::block_number().is_one());
448
		let para_id = LOWEST_PUBLIC_ID;
449
		// Can't double register
450
451
		Balances::make_free_balance_be(&1, 1_000_000_000);
		Balances::make_free_balance_be(&2, 1_000_000_000);
452
453
454

		let genesis_head = Registrar::worst_head_data();
		let validation_code = Registrar::worst_validation_code();
455
		assert_ok!(Registrar::reserve(Origin::signed(1)));
456
457
		assert_ok!(Registrar::register(
			Origin::signed(1),
458
			para_id,
459
460
461
			genesis_head.clone(),
			validation_code.clone(),
		));
462
		assert_ok!(Registrar::reserve(Origin::signed(2)));
463
464
		assert_noop!(Registrar::register(
			Origin::signed(2),
465
			para_id,
466
467
			genesis_head,
			validation_code,
468
		), paras_registrar::Error::<Test>::NotOwner);
469
470
471
472
473
474
475
476
477

		// Start an auction
		let duration = 99u32;
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));

		// Cannot create a crowdloan if you do not own the para
		assert_noop!(Crowdloan::create(
			Origin::signed(2),
478
			para_id,
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
			1_000, // Cap
			lease_period_index_start + 2, // First Slot
			lease_period_index_start + 3, // Last Slot
			200, // Block End
			None,
		), crowdloan::Error::<Test>::InvalidOrigin);
	});
}

#[test]
fn competing_slots() {
	// This test will verify that competing slots, from different sources will resolve appropriately.
	new_test_ext().execute_with(|| {
		assert!(System::block_number().is_one());
		let max_bids = 10u32;
494
		let para_id = LOWEST_PUBLIC_ID;
495
496
497

		// Create n paras and owners
		for n in 1 ..= max_bids {
498
			Balances::make_free_balance_be(&n, 1_000_000_000);
499
500
			let genesis_head = Registrar::worst_head_data();
			let validation_code = Registrar::worst_validation_code();
501
			assert_ok!(Registrar::reserve(Origin::signed(n)));
502
503
			assert_ok!(Registrar::register(
				Origin::signed(n),
504
				para_id + n - 1,
505
506
507
508
509
510
				genesis_head,
				validation_code,
			));
		}

		// Start a new auction in the future
511
		let duration = 149u32;
512
513
514
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));

515
516
517
		// Paras should be onboarded
		run_to_block(20); // session 2

518
519
		for n in 1 ..= max_bids {
			// Increment block number
520
			run_to_block(System::block_number() + 10);
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537

			Balances::make_free_balance_be(&(n * 10), n * 1_000);

			let (start, end) = match n {
				1  => (0, 0),
				2  => (0, 1),
				3  => (0, 2),
				4  => (0, 3),
				5  => (1, 1),
				6  => (1, 2),
				7  => (1, 3),
				8  => (2, 2),
				9  => (2, 3),
				10 => (3, 3),
				_ => panic!("test not meant for this"),
			};

538
			// Users will bid directly for parachain
539
540
			assert_ok!(Auctions::bid(
				Origin::signed(n * 10),
541
				para_id + n - 1,
542
543
544
545
546
547
548
				1, // Auction Index
				lease_period_index_start + start, // First Slot
				lease_period_index_start + end, // Last slot
				n * 900, // Amount
			));
		}

549
550
		// Auction should be done after ending period
		run_to_block(160);
551
552
553
554
555

		// Appropriate Paras should have won slots
		// 900 + 4500 + 2x 8100 = 21,600
		// 900 + 4500 + 7200 + 9000 = 21,600
		assert_eq!(
556
			slots::Leases::<Test>::get(para_id),
557
558
559
560
			// -- 1 --- 2 --- 3 ---------- 4 ------
			vec![None, None, None, Some((10, 900))],
		);
		assert_eq!(
561
			slots::Leases::<Test>::get(para_id + 4),
562
563
564
565
566
			// -- 1 --- 2 --- 3 --- 4 ---------- 5 -------
			vec![None, None, None, None, Some((50, 4500))],
		);
		// TODO: Is this right?
		assert_eq!(
567
			slots::Leases::<Test>::get(para_id + 8),
568
569
570
571
572
573
574
575
576
577
578
579
			// -- 1 --- 2 --- 3 --- 4 --- 5 ---------- 6 --------------- 7 -------
			vec![None, None, None, None, None, Some((90, 8100)), Some((90, 8100))],
		);
	});
}

#[test]
fn competing_bids() {
	// This test will verify that competing bids, from different sources will resolve appropriately.
	new_test_ext().execute_with(|| {
		assert!(System::block_number().is_one());

580
		let start_para = LOWEST_PUBLIC_ID - 1;
581
582
		// Create 3 paras and owners
		for n in 1 ..= 3 {
583
			Balances::make_free_balance_be(&n, 1_000_000_000);
584
585
			let genesis_head = Registrar::worst_head_data();
			let validation_code = Registrar::worst_validation_code();
586
			assert_ok!(Registrar::reserve(Origin::signed(n)));
587
588
			assert_ok!(Registrar::register(
				Origin::signed(n),
589
				ParaId::from(start_para + n),
590
591
592
				genesis_head,
				validation_code,
			));
593
594
595
596
		}

		// Finish registration of paras.
		run_to_session(2);
597

598
599
600
601
602
603
604
		// Start a new auction in the future
		let starting_block = System::block_number();
		let duration = 99u32;
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));

		for n in 1 ..= 3 {
605
606
607
			// Create a crowdloan for each para
			assert_ok!(Crowdloan::create(
				Origin::signed(n),
608
				ParaId::from(start_para + n),
609
610
611
612
613
614
615
616
617
618
				100_000, // Cap
				lease_period_index_start + 2, // First Slot
				lease_period_index_start + 3, // Last Slot
				200, // Block End,
				None,
			));
		}

		for n in 1 ..= 9 {
			// Increment block number
619
			run_to_block(starting_block + n * 10);
620
621
622

			Balances::make_free_balance_be(&(n * 10), n * 1_000);

623
			let para = start_para + n % 3 + 1;
624
625
626
627
628
629
630
631
632
633
634
635

			if n % 2 == 0 {
				// User 10 will bid directly for parachain 1
				assert_ok!(Auctions::bid(
					Origin::signed(n * 10),
					ParaId::from(para),
					1, // Auction Index
					lease_period_index_start + 0, // First Slot
					lease_period_index_start + 1, // Last slot
					n * 900, // Amount
				));
			} else {
636
				// User 20 will be a contribute to crowdloan for parachain 2
637
638
639
640
641
642
643
644
645
646
				assert_ok!(Crowdloan::contribute(
					Origin::signed(n * 10),
					ParaId::from(para),
					n + 900,
					None,
				));
			}
		}

		// Auction should be done
647
		run_to_block(starting_block + 110);
648
649

		// Appropriate Paras should have won slots
650
		let crowdloan_2 = Crowdloan::fund_account_id(ParaId::from(2001));
651
		assert_eq!(
652
			slots::Leases::<Test>::get(ParaId::from(2000)),
653
654
655
656
			// -- 1 --- 2 --- 3 --- 4 --- 5 ------------- 6 ------------------------ 7 -------------
			vec![None, None, None, None, None, Some((crowdloan_2, 1812)), Some((crowdloan_2, 1812))],
		);
		assert_eq!(
657
			slots::Leases::<Test>::get(ParaId::from(2002)),
658
659
660
661
662
663
664
665
666
667
668
669
			// -- 1 --- 2 --- 3 ---------- 4 --------------- 5 -------
			vec![None, None, None, Some((80, 7200)), Some((80, 7200))],
		);
	});
}

#[test]
fn basic_swap_works() {
	// This test will test a swap between a parachain and parathread works successfully.
	new_test_ext().execute_with(|| {
		assert!(System::block_number().is_one()); // So events are emitted
		// User 1 and 2 will own paras
670
671
		Balances::make_free_balance_be(&1, 1_000_000_000);
		Balances::make_free_balance_be(&2, 1_000_000_000);
672
		// First register 2 parathreads with different data
673
		assert_ok!(Registrar::reserve(Origin::signed(1)));
674
675
		assert_ok!(Registrar::register(
			Origin::signed(1),
676
			ParaId::from(2000),
677
678
679
			test_genesis_head(10),
			test_validation_code(10),
		));
680
		assert_ok!(Registrar::reserve(Origin::signed(2)));
681
682
		assert_ok!(Registrar::register(
			Origin::signed(2),
683
			ParaId::from(2001),
684
685
686
687
688
			test_genesis_head(20),
			test_validation_code(20),
		));

		// Paras should be onboarding
689
690
		assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding));
		assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding));
691
692
693
694
695
696
697
698

		// Start a new auction in the future
		let duration = 99u32;
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));

		// 2 sessions later they are parathreads
		run_to_session(2);
699
700
		assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread));
701
702
703
704

		// Open a crowdloan for Para 1 for slots 0-3
		assert_ok!(Crowdloan::create(
			Origin::signed(1),
705
			ParaId::from(2000),
706
707
708
709
710
711
			1_000_000, // Cap
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 3, // Last Slot
			200, // Block End
			None,
		));
712
		let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000));
713
714
715
716

		// Bunch of contributions
		let mut total = 0;
		for i in 10 .. 20 {
717
			Balances::make_free_balance_be(&i, 1_000_000_000);
718
			assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None));
719
720
721
722
723
724
725
726
727
728
729
730
731
732
			total += 900 - i;
		}
		assert!(total > 0);
		assert_eq!(Balances::free_balance(&crowdloan_account), total);

		// Go to end of auction where everyone won their slots
		run_to_block(200);

		// Deposit is appropriately taken
		// ----------------------------------------- para deposit --- crowdloan
		assert_eq!(Balances::reserved_balance(&1), (500 + 10 * 2 * 1) + 100);
		assert_eq!(Balances::reserved_balance(&2), 500 + 20 * 2 * 1);
		assert_eq!(Balances::reserved_balance(&crowdloan_account), total);
		// Crowdloan is appropriately set
733
734
		assert!(Crowdloan::funds(ParaId::from(2000)).is_some());
		assert!(Crowdloan::funds(ParaId::from(2001)).is_none());
735
736
737
738
739
740

		// New leases will start on block 400
		let lease_start_block = 400;
		run_to_block(lease_start_block);

		// Slots are won by Para 1
741
742
		assert!(!Slots::lease(ParaId::from(2000)).is_empty());
		assert!(Slots::lease(ParaId::from(2001)).is_empty());
743
744
745

		// 2 sessions later it is a parachain
		run_to_block(lease_start_block + 20);
746
747
		assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parachain));
		assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread));
748
749

		// Initiate a swap
750
751
		assert_ok!(Registrar::swap(para_origin(2000).into(), ParaId::from(2000), ParaId::from(2001)));
		assert_ok!(Registrar::swap(para_origin(2001).into(), ParaId::from(2001), ParaId::from(2000)));
752

753
754
		assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::DowngradingParachain));
		assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::UpgradingParathread));
755
756
757

		// 2 session later they have swapped
		run_to_block(lease_start_block + 40);
758
759
		assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parachain));
760
761

		// Deregister parathread
762
		assert_ok!(Registrar::deregister(para_origin(2000).into(), ParaId::from(2000)));
763
764
765
766
		// Correct deposit is unreserved
		assert_eq!(Balances::reserved_balance(&1), 100); // crowdloan deposit left over
		assert_eq!(Balances::reserved_balance(&2), 500 + 20 * 2 * 1);
		// Crowdloan ownership is swapped
767
768
		assert!(Crowdloan::funds(ParaId::from(2000)).is_none());
		assert!(Crowdloan::funds(ParaId::from(2001)).is_some());
769
		// Slot is swapped
770
771
		assert!(Slots::lease(ParaId::from(2000)).is_empty());
		assert!(!Slots::lease(ParaId::from(2001)).is_empty());
772
773

		// Cant dissolve
774
775
		assert_noop!(Crowdloan::dissolve(Origin::signed(1), ParaId::from(2000)), CrowdloanError::<Test>::InvalidParaId);
		assert_noop!(Crowdloan::dissolve(Origin::signed(2), ParaId::from(2001)), CrowdloanError::<Test>::NotReadyToDissolve);
776
777
778
779
780
781
782

		// Go way in the future when the para is offboarded
		run_to_block(lease_start_block + 1000);

		// Withdraw of contributions works
		assert_eq!(Balances::free_balance(&crowdloan_account), total);
		for i in 10 .. 20 {
783
			assert_ok!(Crowdloan::withdraw(Origin::signed(i), i, ParaId::from(2001)));
784
785
786
787
		}
		assert_eq!(Balances::free_balance(&crowdloan_account), 0);

		// Dissolve returns the balance of the person who put a deposit for crowdloan
788
		assert_ok!(Crowdloan::dissolve(Origin::signed(1), ParaId::from(2001)));
789
790
791
792
		assert_eq!(Balances::reserved_balance(&1), 0);
		assert_eq!(Balances::reserved_balance(&2), 500 + 20 * 2 * 1);

		// Final deregister sets everything back to the start
793
		assert_ok!(Registrar::deregister(para_origin(2001).into(), ParaId::from(2001)));
794
795
796
797
798
799
800
801
802
		assert_eq!(Balances::reserved_balance(&2), 0);
	})
}

#[test]
fn crowdloan_ending_period_bid() {
	new_test_ext().execute_with(|| {
		assert!(System::block_number().is_one()); // So events are emitted
		// User 1 and 2 will own paras
803
804
		Balances::make_free_balance_be(&1, 1_000_000_000);
		Balances::make_free_balance_be(&2, 1_000_000_000);
805
		// First register 2 parathreads
806
		assert_ok!(Registrar::reserve(Origin::signed(1)));
807
808
		assert_ok!(Registrar::register(
			Origin::signed(1),
809
			ParaId::from(2000),
810
811
812
			test_genesis_head(10),
			test_validation_code(10),
		));
813
		assert_ok!(Registrar::reserve(Origin::signed(2)));
814
815
		assert_ok!(Registrar::register(
			Origin::signed(2),
816
			ParaId::from(2001),
817
818
819
820
821
			test_genesis_head(20),
			test_validation_code(20),
		));

		// Paras should be onboarding
822
823
		assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Onboarding));
		assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Onboarding));
824
825
826
827
828
829
830
831

		// Start a new auction in the future
		let duration = 99u32;
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));

		// 2 sessions later they are parathreads
		run_to_session(2);
832
833
		assert_eq!(Paras::lifecycle(ParaId::from(2000)), Some(ParaLifecycle::Parathread));
		assert_eq!(Paras::lifecycle(ParaId::from(2001)), Some(ParaLifecycle::Parathread));
834
835
836
837

		// Open a crowdloan for Para 1 for slots 0-3
		assert_ok!(Crowdloan::create(
			Origin::signed(1),
838
			ParaId::from(2000),
839
840
841
842
843
844
			1_000_000, // Cap
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 3, // Last Slot
			200, // Block End
			None,
		));
845
		let crowdloan_account = Crowdloan::fund_account_id(ParaId::from(2000));
846
847
848
849

		// Bunch of contributions
		let mut total = 0;
		for i in 10 .. 20 {
850
			Balances::make_free_balance_be(&i, 1_000_000_000);
851
			assert_ok!(Crowdloan::contribute(Origin::signed(i), ParaId::from(2000), 900 - i, None));
852
853
854
855
856
857
			total += 900 - i;
		}
		assert!(total > 0);
		assert_eq!(Balances::free_balance(&crowdloan_account), total);

		// Bid for para 2 directly
858
		Balances::make_free_balance_be(&2, 1_000_000_000);
859
860
		assert_ok!(Auctions::bid(
			Origin::signed(2),
861
			ParaId::from(2001),
862
863
864
865
866
867
868
869
870
			1, // Auction Index
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 1, // Last slot
			900, // Amount
		));

		// Go to beginning of ending period
		run_to_block(100);

871
		assert_eq!(Auctions::auction_status(100), AuctionStatus::<u32>::EndingPeriod(0, 0));
872
		let mut winning = [None; SlotRange::SLOT_RANGE_COUNT];
873
874
		winning[SlotRange::ZeroOne as u8 as usize] = Some((2, ParaId::from(2001), 900));
		winning[SlotRange::ZeroThree as u8 as usize] = Some((crowdloan_account, ParaId::from(2000), total));
875

876
		assert_eq!(Auctions::winning(0), Some(winning));
877
878
879

		run_to_block(101);

880
		Balances::make_free_balance_be(&1234, 1_000_000_000);
881
		assert_ok!(Crowdloan::contribute(Origin::signed(1234), ParaId::from(2000), 900, None));
882
883
884

		// Data propagates correctly
		run_to_block(102);
885
		let mut winning = [None; SlotRange::SLOT_RANGE_COUNT];
886
887
		winning[SlotRange::ZeroOne as u8 as usize] = Some((2, ParaId::from(2001), 900));
		winning[SlotRange::ZeroThree as u8 as usize] = Some((crowdloan_account, ParaId::from(2000), total + 900));
888
		assert_eq!(Auctions::winning(2), Some(winning));
889
890
	})
}
891
892
893
894
895
896
897
898
899
900
901
902

#[test]
fn auction_bid_requires_registered_para() {
	new_test_ext().execute_with(|| {
		assert!(System::block_number().is_one()); // So events are emitted

		// Start a new auction in the future
		let duration = 99u32;
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));

		// Can't bid with non-registered paras
903
		Balances::make_free_balance_be(&1, 1_000_000_000);
904
905
		assert_noop!(Auctions::bid(
			Origin::signed(1),
906
			ParaId::from(2000),
907
908
909
910
911
912
913
			1, // Auction Index
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 1, // Last slot
			900, // Amount
		), AuctionsError::<Test>::ParaNotRegistered);

		// Now we register the para
914
		assert_ok!(Registrar::reserve(Origin::signed(1)));
915
916
		assert_ok!(Registrar::register(
			Origin::signed(1),
917
			ParaId::from(2000),
918
919
920
921
922
923
924
			test_genesis_head(10),
			test_validation_code(10),
		));

		// Still can't bid until it is fully onboarded
		assert_noop!(Auctions::bid(
			Origin::signed(1),
925
			ParaId::from(2000),
926
927
928
929
930
931
932
933
934
935
			1, // Auction Index
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 1, // Last slot
			900, // Amount
		), AuctionsError::<Test>::ParaNotRegistered);

		// Onboarded on Session 2
		run_to_session(2);

		// Success
936
		Balances::make_free_balance_be(&1, 1_000_000_000);
937
938
		assert_ok!(Auctions::bid(
			Origin::signed(1),
939
			ParaId::from(2000),
940
941
942
943
944
945
946
			1, // Auction Index
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 1, // Last slot
			900, // Amount
		));
	});
}
947
948
949
950
951
952
953
954
955
956

#[test]
fn gap_bids_work() {
	new_test_ext().execute_with(|| {
		assert!(System::block_number().is_one()); // So events are emitted

		// Start a new auction in the future
		let duration = 99u32;
		let lease_period_index_start = 4u32;
		assert_ok!(Auctions::new_auction(Origin::root(), duration, lease_period_index_start));
957
958
		Balances::make_free_balance_be(&1, 1_000_000_000);
		Balances::make_free_balance_be(&2, 1_000_000_000);
959
960

		// Now register 2 paras
961
		assert_ok!(Registrar::reserve(Origin::signed(1)));
962
963
		assert_ok!(Registrar::register(
			Origin::signed(1),
964
			ParaId::from(2000),
965
966
967
			test_genesis_head(10),
			test_validation_code(10),
		));
968
		assert_ok!(Registrar::reserve(Origin::signed(2)));
969
970
		assert_ok!(Registrar::register(
			Origin::signed(2),
971
			ParaId::from(2001),
972
973
974
975
976
977
978
979
			test_genesis_head(10),
			test_validation_code(10),
		));

		// Onboarded on Session 2
		run_to_session(2);

		// Make bids
980
981
		Balances::make_free_balance_be(&10, 1_000_000_000);
		Balances::make_free_balance_be(&20, 1_000_000_000);
982
983
984
		// Slot 1 for 100 from 10
		assert_ok!(Auctions::bid(
			Origin::signed(10),
985
			ParaId::from(2000),
986
987
988
989
990
991
992
993
			1, // Auction Index
			lease_period_index_start + 0, // First Slot
			lease_period_index_start + 0, // Last slot
			100, // Amount
		));
		// Slot 4 for 400 from 10
		assert_ok!(Auctions::bid(
			Origin::signed(10),
994
			ParaId::from(2000),
995
996
997
998
999
1000
			1, // Auction Index
			lease_period_index_start + 3, // First Slot
			lease_period_index_start + 3, // Last slot
			400, // Amount
		));

For faster browsing, not all history is shown. View entire blame