git.delta.rocks / unique-network / refs/commits / 313a9f3da734

difftreelog

feat(collator-selection) licenses + onboarding

Fahrrader2022-12-22parent: #218082e.patch.diff
in: master

8 files changed

modifiednode/cli/src/chain_spec.rsdiffbeforeafterboth
--- a/node/cli/src/chain_spec.rs
+++ b/node/cli/src/chain_spec.rs
@@ -24,7 +24,7 @@
 use serde_json::map::Map;
 
 use up_common::types::opaque::*;
-use up_common::constants::{GENESIS_CANDIDACY_BOND, SESSION_LENGTH};
+use up_common::constants::{GENESIS_LICENSE_BOND, SESSION_LENGTH};
 
 #[cfg(feature = "unique-runtime")]
 pub use unique_runtime as default_runtime;
@@ -196,7 +196,7 @@
 					.cloned()
 					.map(|(acc, _)| acc)
 					.collect(),
-				candidacy_bond: GENESIS_CANDIDACY_BOND,
+				license_bond: GENESIS_LICENSE_BOND,
 				kick_threshold: SESSION_LENGTH,
 				..Default::default()
 			},
modifiedpallets/collator-selection/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/collator-selection/src/benchmarking.rs
+++ b/pallets/collator-selection/src/benchmarking.rs
@@ -116,12 +116,12 @@
 		.map(|c| account("candidate", c, SEED))
 		.collect::<Vec<_>>();
 	assert!(
-		<CandidacyBond<T>>::get() > 0u32.into(),
+		<LicenseBond<T>>::get() > 0u32.into(),
 		"Bond cannot be zero!"
 	);
 
 	for who in candidates {
-		T::Currency::make_free_balance_be(&who, <CandidacyBond<T>>::get() * 2u32.into());
+		T::Currency::make_free_balance_be(&who, <LicenseBond<T>>::get() * 2u32.into());
 		<CollatorSelection<T>>::register_as_candidate(RawOrigin::Signed(who).into()).unwrap();
 	}
 }
@@ -154,16 +154,16 @@
 		assert_last_event::<T>(Event::NewDesiredCandidates{desired_candidates: max}.into());
 	}
 
-	set_candidacy_bond {
+	set_license_bond {
 		let bond_amount: BalanceOf<T> = T::Currency::minimum_balance() * 10u32.into();
 		let origin = T::UpdateOrigin::successful_origin();
 	}: {
 		assert_ok!(
-			<CollatorSelection<T>>::set_candidacy_bond(origin, bond_amount.clone())
+			<CollatorSelection<T>>::set_license_bond(origin, bond_amount.clone())
 		);
 	}
 	verify {
-		assert_last_event::<T>(Event::NewCandidacyBond{bond_amount}.into());
+		assert_last_event::<T>(Event::NewLicenseBond{bond_amount}.into());
 	}
 
 	// worse case is when we have all the max-candidate slots filled except one, and we fill that
@@ -171,7 +171,7 @@
 	register_as_candidate {
 		let c in 1 .. T::MaxCandidates::get();
 
-		<CandidacyBond<T>>::put(T::Currency::minimum_balance());
+		<LicenseBond<T>>::put(T::Currency::minimum_balance());
 		<DesiredCandidates<T>>::put(c + 1);
 
 		register_validators::<T>(c);
@@ -195,7 +195,7 @@
 	// worse case is the last candidate leaving.
 	leave_intent {
 		let c in (T::MinCandidates::get() + 1) .. T::MaxCandidates::get();
-		<CandidacyBond<T>>::put(T::Currency::minimum_balance());
+		<LicenseBond<T>>::put(T::Currency::minimum_balance());
 		<DesiredCandidates<T>>::put(c);
 
 		register_validators::<T>(c);
@@ -211,7 +211,7 @@
 
 	// worse case is paying a non-existing candidate account.
 	note_author {
-		<CandidacyBond<T>>::put(T::Currency::minimum_balance());
+		<LicenseBond<T>>::put(T::Currency::minimum_balance());
 		T::Currency::make_free_balance_be(
 			&<CollatorSelection<T>>::account_id(),
 			T::Currency::minimum_balance() * 4u32.into(),
@@ -233,7 +233,7 @@
 		let r in 1 .. T::MaxCandidates::get();
 		let c in 1 .. T::MaxCandidates::get();
 
-		<CandidacyBond<T>>::put(T::Currency::minimum_balance());
+		<LicenseBond<T>>::put(T::Currency::minimum_balance());
 		<DesiredCandidates<T>>::put(c);
 		frame_system::Pallet::<T>::set_block_number(0u32.into());
 
modifiedpallets/collator-selection/src/lib.rsdiffbeforeafterboth
181 #[derive(181 #[derive(
182 PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen,182 PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, scale_info::TypeInfo, MaxEncodedLen,
183 )]183 )]
184 pub struct CandidateInfo<AccountId, Balance> {184 pub struct LicenseInfo<AccountId, Balance> {
185 /// Account identifier.185 /// Account identifier.
186 pub who: AccountId,186 pub who: AccountId,
187 /// Reserved deposit.187 /// Reserved deposit.
198 pub type Invulnerables<T: Config> =198 pub type Invulnerables<T: Config> =
199 StorageValue<_, BoundedVec<T::AccountId, T::MaxInvulnerables>, ValueQuery>;199 StorageValue<_, BoundedVec<T::AccountId, T::MaxInvulnerables>, ValueQuery>;
200
201 /// The (community) collation license holders.
202 #[pallet::storage]
203 #[pallet::getter(fn licenses)]
204 pub type Licenses<T: Config> =
205 StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf<T>, ValueQuery>;
200206
201 /// The (community, limited) collation candidates.207 /// The (community, limited) collation candidates.
202 #[pallet::storage]208 #[pallet::storage]
203 #[pallet::getter(fn candidates)]209 #[pallet::getter(fn candidates)]
204 pub type Candidates<T: Config> = StorageValue<210 pub type Candidates<T: Config> = StorageValue<
205 _,211 _,
206 BoundedVec<CandidateInfo<T::AccountId, BalanceOf<T>>, T::MaxCandidates>,212 BoundedVec<T::AccountId, T::MaxCandidates>, //LicenseInfo<T::AccountId, BalanceOf<T>>, T::MaxCandidates>, // license ID?
207 ValueQuery,213 ValueQuery,
208 >;214 >;
209215
231 ///237 ///
232 /// When a collator calls `leave_intent` they immediately receive the deposit back.238 /// When a collator calls `leave_intent` they immediately receive the deposit back.
233 #[pallet::storage]239 #[pallet::storage]
234 #[pallet::getter(fn candidacy_bond)]240 #[pallet::getter(fn license_bond)]
235 pub type CandidacyBond<T> = StorageValue<_, BalanceOf<T>, ValueQuery>;241 pub type LicenseBond<T> = StorageValue<_, BalanceOf<T>, ValueQuery>;
236242
237 #[pallet::genesis_config]243 #[pallet::genesis_config]
238 pub struct GenesisConfig<T: Config> {244 pub struct GenesisConfig<T: Config> {
239 pub invulnerables: Vec<T::AccountId>,245 pub invulnerables: Vec<T::AccountId>,
240 pub candidacy_bond: BalanceOf<T>,246 pub license_bond: BalanceOf<T>,
241 pub kick_threshold: T::BlockNumber,247 pub kick_threshold: T::BlockNumber,
242 pub desired_candidates: u32,248 pub desired_candidates: u32,
243 }249 }
247 fn default() -> Self {253 fn default() -> Self {
248 Self {254 Self {
249 invulnerables: Default::default(),255 invulnerables: Default::default(),
250 candidacy_bond: Default::default(),256 license_bond: Default::default(),
251 kick_threshold: T::BlockNumber::one(),257 kick_threshold: T::BlockNumber::one(),
252 desired_candidates: Default::default(),258 desired_candidates: Default::default(),
253 }259 }
275 );281 );
276282
277 <DesiredCandidates<T>>::put(&self.desired_candidates);283 <DesiredCandidates<T>>::put(&self.desired_candidates);
278 <CandidacyBond<T>>::put(&self.candidacy_bond);284 <LicenseBond<T>>::put(&self.license_bond);
279 <KickThreshold<T>>::put(&self.kick_threshold);285 <KickThreshold<T>>::put(&self.kick_threshold);
280 <Invulnerables<T>>::put(bounded_invulnerables);286 <Invulnerables<T>>::put(bounded_invulnerables);
281 }287 }
287 NewDesiredCandidates {293 NewDesiredCandidates {
288 desired_candidates: u32,294 desired_candidates: u32,
289 },295 },
290 NewCandidacyBond {296 NewLicenseBond {
291 bond_amount: BalanceOf<T>,297 bond_amount: BalanceOf<T>,
292 },298 },
293 NewKickThreshold {299 NewKickThreshold {
299 InvulnerableRemoved {305 InvulnerableRemoved {
300 invulnerable: T::AccountId,306 invulnerable: T::AccountId,
301 },307 },
302 CandidateAdded {308 LicenseObtained {
303 account_id: T::AccountId,309 account_id: T::AccountId,
304 deposit: BalanceOf<T>,310 deposit: BalanceOf<T>,
305 },311 },
306 CandidateRemoved {312 LicenseForfeited {
307 account_id: T::AccountId,313 account_id: T::AccountId,
308 deposit_returned: BalanceOf<T>,314 deposit_returned: BalanceOf<T>,
309 },315 },
316 CandidateAdded {
317 account_id: T::AccountId,
318 },
319 CandidateRemoved {
320 account_id: T::AccountId,
321 },
310 }322 }
311323
312 // Errors inform users that something went wrong.324 // Errors inform users that something went wrong.
320 Unknown,332 Unknown,
321 /// Permission issue333 /// Permission issue
322 Permission,334 Permission,
335 /// User already holds license to collate
336 AlreadyLicenseHolder,
337 /// User does not hold a license to collate
338 NoLicense,
323 /// User is already a candidate339 /// User is already a candidate
324 AlreadyCandidate,340 AlreadyCandidate,
325 /// User is not a candidate341 /// User is not a candidate
363 return Ok(().into());379 return Ok(().into());
364 }380 }
381
382 // todo:collator check license holders, release moneys, promotion!
383 // force_release_license? Error::<T>::lreadyLicenseHolder?
365384
366 <Invulnerables<T>>::try_append(new.clone())385 <Invulnerables<T>>::try_append(new.clone())
367 .map_err(|_| Error::<T>::TooManyInvulnerables)?;386 .map_err(|_| Error::<T>::TooManyInvulnerables)?;
419 }438 }
420439
421 /// Set the candidacy bond amount.440 /// Set the candidacy bond amount.
422 #[pallet::weight(T::WeightInfo::set_candidacy_bond())]441 #[pallet::weight(T::WeightInfo::set_license_bond())]
423 pub fn set_candidacy_bond(442 pub fn set_license_bond(
424 origin: OriginFor<T>,443 origin: OriginFor<T>,
425 bond: BalanceOf<T>,444 bond: BalanceOf<T>,
426 ) -> DispatchResultWithPostInfo {445 ) -> DispatchResultWithPostInfo {
427 T::UpdateOrigin::ensure_origin(origin)?;446 T::UpdateOrigin::ensure_origin(origin)?;
428 <CandidacyBond<T>>::put(&bond);447 <LicenseBond<T>>::put(&bond);
429 Self::deposit_event(Event::NewCandidacyBond { bond_amount: bond });448 Self::deposit_event(Event::NewLicenseBond { bond_amount: bond });
430 Ok(().into())449 Ok(().into())
431 }450 }
432451
433 /// Set the length of the kick threshold.452 /// Set the length of the kick threshold.
434 /// Note that if the length is not a multiple of the session period, it might get inconsistent.453 /// Note that if the length is not a multiple of the session period, it might get inconsistent.
435 #[pallet::weight(T::WeightInfo::set_candidacy_bond())] // todo:collator weight454 #[pallet::weight(T::WeightInfo::set_license_bond())] // todo:collator weight
436 pub fn set_kick_threshold(455 pub fn set_kick_threshold(
437 origin: OriginFor<T>,456 origin: OriginFor<T>,
438 kick_threshold: T::BlockNumber,457 kick_threshold: T::BlockNumber,
446 Ok(().into())465 Ok(().into())
447 }466 }
448467
449 /// Register this account as a collator candidate. The account must (a) already have468 /// Purchase a license on block collation for this account.
469 /// It does not make it a collator candidate, use `onboard` afterward. The account must
450 /// registered session keys and (b) be able to reserve the `CandidacyBond`.470 /// (a) already have registered session keys and (b) be able to reserve the `LicenseBond`.
451 ///471 ///
452 /// This call is not available to `Invulnerable` collators.472 /// This call is not available to `Invulnerable` collators.
453 #[pallet::weight(T::WeightInfo::register_as_candidate(T::MaxCandidates::get()))]473 #[pallet::weight(T::WeightInfo::register_as_candidate(T::MaxCandidates::get()))] // todo:collator weight
454 pub fn register_as_candidate(origin: OriginFor<T>) -> DispatchResultWithPostInfo {474 pub fn get_license(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
475 // register_as_candidate
476 let who = ensure_signed(origin)?;
477
478 if Licenses::<T>::contains_key(&who) {
479 return Ok(().into());
480 }
481
482 ensure!(
483 !Self::invulnerables().contains(&who),
484 Error::<T>::AlreadyInvulnerable
485 );
486
487 let validator_key = T::ValidatorIdOf::convert(who.clone())
488 .ok_or(Error::<T>::NoAssociatedValidatorId)?;
489 ensure!(
490 T::ValidatorRegistration::is_registered(&validator_key),
491 Error::<T>::ValidatorNotRegistered
492 );
493
494 let deposit = Self::license_bond();
495 // First authored block is current block plus kick threshold to handle session delay
496 /*let incoming = LicenseInfo {
497 who: who.clone(),
498 deposit,
499 };*/
500
501 T::Currency::reserve(&who, deposit)?;
502 Licenses::<T>::insert(who.clone(), deposit);
503
504 /*let current_count =
505 <Licenses<T>>::try_mutate(|licenses| -> Result<usize, DispatchError> {
506 if T::OriginPrivilegeCmp::cmp_privilege(&origin, &scheduled.origin) {
507 return Err(BadOrigin.into());
508 }
509 if candidates.iter().any(|candidate| *candidate == who) {
510 Err(Error::<T>::AlreadyLicenseHolder)?
511 } else {
512 T::Currency::reserve(&who, deposit)?;
513 candidates
514 .try_push(incoming)
515 .map_err(|_| Error::<T>::TooManyCandidates)?;
516 <LastAuthoredBlock<T>>::insert(
517 who.clone(),
518 frame_system::Pallet::<T>::block_number() + Self::kick_threshold(),
519 );
520 Ok(candidates.len())
521 }
522 })?;*/
523
524 Self::deposit_event(Event::LicenseObtained {
525 account_id: who,
526 deposit,
527 });
528 Ok(().into()) // Some(T::WeightInfo::register_as_candidate(current_count as u32)).into())
529 }
530
531 /// Register this account as a candidate for collators for next sessions.
532 /// The account must already hold a license, and cannot offboard immediately during a session.
533 ///
534 /// This call is not available to `Invulnerable` collators.
535 #[pallet::weight(T::WeightInfo::register_as_candidate(T::MaxCandidates::get()))] // todo:collator weight
536 pub fn onboard(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
537 // register_as_candidate
455 let who = ensure_signed(origin)?;538 let who = ensure_signed(origin)?;
456539
540 // ensure the user obtained the license.
541 ensure!(Licenses::<T>::contains_key(&who), Error::<T>::NoLicense);
457 // ensure we are below limit.542 // ensure we are below limit.
458 let length = <Candidates<T>>::decode_len().unwrap_or_default();543 let length = <Candidates<T>>::decode_len().unwrap_or_default();
459 ensure!(544 ensure!(
466 Error::<T>::AlreadyInvulnerable551 Error::<T>::AlreadyInvulnerable
467 );552 );
468
469 let validator_key = T::ValidatorIdOf::convert(who.clone())
470 .ok_or(Error::<T>::NoAssociatedValidatorId)?;
471 ensure!(
472 T::ValidatorRegistration::is_registered(&validator_key),
473 Error::<T>::ValidatorNotRegistered
474 );
475553
476 let deposit = Self::candidacy_bond();554 let deposit = Self::license_bond();
477 // First authored block is current block plus kick threshold to handle session delay555 // First authored block is current block plus kick threshold to handle session delay
478 let incoming = CandidateInfo {556 /*let incoming = LicenseInfo {
479 who: who.clone(),557 who: who.clone(),
480 deposit,558 deposit,
481 };559 };*/
482560
483 let current_count =561 let current_count =
484 <Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {562 <Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {
485 if candidates.iter().any(|candidate| candidate.who == who) {563 if candidates.iter().any(|candidate| *candidate == who) {
486 Err(Error::<T>::AlreadyCandidate)?564 Err(Error::<T>::AlreadyCandidate)?
487 } else {565 } else {
488 T::Currency::reserve(&who, deposit)?;566 T::Currency::reserve(&who, deposit)?;
489 candidates567 candidates
490 .try_push(incoming)568 .try_push(who.clone())
491 .map_err(|_| Error::<T>::TooManyCandidates)?;569 .map_err(|_| Error::<T>::TooManyCandidates)?;
492 <LastAuthoredBlock<T>>::insert(570 <LastAuthoredBlock<T>>::insert(
493 who.clone(),571 who.clone(),
498 })?;576 })?;
499577
500 Self::deposit_event(Event::CandidateAdded {578 Self::deposit_event(Event::CandidateAdded { account_id: who });
501 account_id: who,
502 deposit,
503 });
504 Ok(Some(T::WeightInfo::register_as_candidate(current_count as u32)).into())579 Ok(Some(T::WeightInfo::register_as_candidate(current_count as u32)).into())
505 }580 }
506581
507 /// Deregister `origin` as a collator candidate. Note that the collator can only leave on582 /// Deregister `origin` as a collator candidate. Note that the collator can only leave on
508 /// session change. The `CandidacyBond` will be unreserved immediately.583 /// session change. The license to `onboard` later at any other time will remain.
509 ///584 ///
510 /// This call will fail if the total number of candidates would drop below `MinCandidates`.585 /// This call will fail if the total number of candidates would drop below `MinCandidates`. todo:collator maybe not
511 ///
512 /// This call is not available to `Invulnerable` collators.
513 #[pallet::weight(T::WeightInfo::leave_intent(T::MaxCandidates::get()))]586 #[pallet::weight(T::WeightInfo::leave_intent(T::MaxCandidates::get()))] // todo:collator weight
514 pub fn leave_intent(origin: OriginFor<T>) -> DispatchResultWithPostInfo {587 pub fn offboard(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
588 // leave_intent
515 let who = ensure_signed(origin)?;589 let who = ensure_signed(origin)?;
516 // todo:collator invulnerables and candidates should count against min candidates together590 // todo:collator invulnerables and candidates should count against min candidates together
517 ensure!(591 ensure!(
518 Self::candidates().len() as u32 > T::MinCandidates::get(),592 Self::candidates().len() as u32 > T::MinCandidates::get(),
519 Error::<T>::TooFewCandidates593 Error::<T>::TooFewCandidates
520 );594 );
521 let current_count = Self::try_remove_candidate(&who, false)?;595 let current_count = Self::try_remove_candidate(&who)?;
522596
523 Ok(Some(T::WeightInfo::leave_intent(current_count as u32)).into())597 Ok(Some(T::WeightInfo::leave_intent(current_count as u32)).into())
524 }598 }
599
600 /// Forfeit `origin`'s own license. The `LicenseBond` will be unreserved immediately.
601 ///
602 /// This call is not available to `Invulnerable` collators.
603 #[pallet::weight(T::WeightInfo::leave_intent(T::MaxCandidates::get()))] // todo:collator weight
604 pub fn release_license(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
605 // leave_intent
606 let who = ensure_signed(origin)?;
607 // let current_count = Self::try_remove_candidate(&who, false)?;
608 Self::try_release_license(&who, false)?;
609
610 Ok(().into())
611 }
612
613 /// Force deregister `origin` as a collator candidate as a governing authority, and revoke its license.
614 /// Note that the collator can only leave on session change.
615 /// The `LicenseBond` will be unreserved and returned immediately.
616 ///
617 /// This call is not available to `Invulnerable` collators.
618 #[pallet::weight(T::WeightInfo::leave_intent(T::MaxCandidates::get()))] // todo:collator weight
619 pub fn force_release_license(
620 origin: OriginFor<T>,
621 who: T::AccountId,
622 ) -> DispatchResultWithPostInfo {
623 // leave_intent
624 T::UpdateOrigin::ensure_origin(origin)?;
625
626 let current_count = Self::try_remove_candidate(&who)?;
627 Self::try_release_license(&who, false)?;
628
629 Ok(Some(T::WeightInfo::leave_intent(current_count as u32)).into()) // todo:collator weight
630 }
525 }631 }
526632
527 impl<T: Config> Pallet<T> {633 impl<T: Config> Pallet<T> {
530 T::PotId::get().into_account_truncating()636 T::PotId::get().into_account_truncating()
531 }637 }
638
639 /// Removes a candidate from the collator pool for the next session if they exist.
640 fn try_remove_candidate(who: &T::AccountId) -> Result<usize, DispatchError> {
641 let current_count =
642 <Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {
643 let index = candidates
644 .iter()
645 .position(|candidate| *candidate == *who)
646 .ok_or(Error::<T>::NotCandidate)?;
647 candidates.remove(index);
648 <LastAuthoredBlock<T>>::remove(who.clone());
649 Ok(candidates.len())
650 })?;
651 Self::deposit_event(Event::CandidateRemoved {
652 account_id: who.clone(),
653 });
654 Ok(current_count)
655 }
532656
533 /// Removes a candidate if they exist and sends them back their deposit, optionally slashed.657 /// Removes a candidate if they exist and sends them back their deposit, optionally slashed.
534 fn try_remove_candidate(658 fn try_release_license(who: &T::AccountId, should_slash: bool) -> DispatchResult {
535 who: &T::AccountId,
536 should_slash: bool,
537 ) -> Result<usize, DispatchError> {
538 let mut deposit_returned = BalanceOf::<T>::default();659 let mut deposit_returned = BalanceOf::<T>::default();
539 let current_count =
540 <Candidates<T>>::try_mutate(|candidates| -> Result<usize, DispatchError> {660 Licenses::<T>::try_mutate_exists(&who, |deposit| -> DispatchResult {
541 let index = candidates
542 .iter()
543 .position(|candidate| candidate.who == *who)
544 .ok_or(Error::<T>::NotCandidate)?;
545 let candidate = candidates.remove(index);661 if let Some(deposit) = deposit.take() {
546 let deposit = candidate.deposit;
547
548 if should_slash {662 if should_slash {
549 let slashed = T::SlashRatio::get() * deposit;663 let slashed = T::SlashRatio::get() * deposit;
555669
556 T::Currency::resolve_creating(&T::TreasuryAccountId::get(), imbalance);670 T::Currency::resolve_creating(&T::TreasuryAccountId::get(), imbalance);
557
558 // Self::deposit_event(Event::CandidateSlashed(who.clone()));
559 } else {671 } else {
560 //T::Currency::unreserve(who, deposit);672 //T::Currency::unreserve(who, deposit);
561 deposit_returned = deposit;673 deposit_returned = deposit;
562 }674 }
563675
564 T::Currency::unreserve(who, deposit_returned);676 T::Currency::unreserve(who, deposit_returned);
565 // candidates.remove(index);
566 <LastAuthoredBlock<T>>::remove(who.clone());677 Ok(())
678 } else {
567 Ok(candidates.len())679 Err(Error::<T>::NoLicense.into())
680 }
568 })?;681 })?;
569 Self::deposit_event(Event::CandidateRemoved {682 Self::deposit_event(Event::LicenseForfeited {
570 account_id: who.clone(),683 account_id: who.clone(),
571 deposit_returned,684 deposit_returned,
572 });685 });
573 Ok(current_count)686 Ok(())
574 }687 }
575688
576 /// Assemble the current set of candidates and invulnerables into the next collator set.689 /// Assemble the current set of candidates and invulnerables into the next collator set.
587 /// Kicks out candidates that did not produce a block in the kick threshold700 /// Kicks out candidates that did not produce a block in the kick threshold
588 /// and **confiscates** their deposits to the treasury.701 /// and **confiscates** their deposits to the treasury.
589 pub fn kick_stale_candidates(702 pub fn kick_stale_candidates(
590 candidates: BoundedVec<CandidateInfo<T::AccountId, BalanceOf<T>>, T::MaxCandidates>,703 candidates: BoundedVec<T::AccountId, T::MaxCandidates>, //LicenseInfo<T::AccountId, BalanceOf<T>>
591 ) -> BoundedVec<T::AccountId, T::MaxCandidates> {704 ) -> BoundedVec<T::AccountId, T::MaxCandidates> {
592 let now = frame_system::Pallet::<T>::block_number();705 let now = frame_system::Pallet::<T>::block_number();
593 let kick_threshold = Self::kick_threshold();706 let kick_threshold = Self::kick_threshold();
594 candidates707 candidates
595 .into_iter()708 .into_iter()
596 .filter_map(|c| {709 .filter_map(|c| {
597 let last_block = <LastAuthoredBlock<T>>::get(c.who.clone());710 let last_block = <LastAuthoredBlock<T>>::get(c.clone());
598 let since_last = now.saturating_sub(last_block);711 let since_last = now.saturating_sub(last_block);
599 if since_last < kick_threshold ||712 if since_last < kick_threshold ||
600 Self::candidates().len() as u32 <= T::MinCandidates::get()713 Self::candidates().len() as u32 <= T::MinCandidates::get()
601 {714 {
602 Some(c.who)715 Some(c)
603 } else {716 } else {
604 let outcome = Self::try_remove_candidate(&c.who, true);717 let outcome = Self::try_remove_candidate(&c);
605 if let Err(why) = outcome {718 if let Err(why) = outcome {
606 log::warn!("Failed to remove candidate {:?}", why);719 log::warn!("Failed to remove candidate {:?}", why);
607 debug_assert!(false, "failed to remove candidate {:?}", why);720 debug_assert!(false, "failed to remove candidate {:?}", why);
721 return None;
608 }722 }
723 let outcome = Self::try_release_license(&c, true);
724 if let Err(why) = outcome {
725 log::warn!("Failed to release license {:?}", why);
726 debug_assert!(false, "failed to release license {:?}", why);
727 }
609 None728 None
610 }729 }
611 })730 })
modifiedpallets/collator-selection/src/mock.rsdiffbeforeafterboth
--- a/pallets/collator-selection/src/mock.rs
+++ b/pallets/collator-selection/src/mock.rs
@@ -264,7 +264,7 @@
 		.collect::<Vec<_>>();
 	let collator_selection = collator_selection::GenesisConfig::<Test> {
 		desired_candidates: 2,
-		candidacy_bond: 10,
+		license_bond: 10,
 		kick_threshold: 1,
 		invulnerables,
 	};
modifiedpallets/collator-selection/src/tests.rsdiffbeforeafterboth
--- a/pallets/collator-selection/src/tests.rs
+++ b/pallets/collator-selection/src/tests.rs
@@ -31,7 +31,7 @@
 // limitations under the License.
 
 use crate as collator_selection;
-use crate::{mock::*, CandidateInfo, Error};
+use crate::{mock::*, LicenseInfo, Error};
 use frame_support::{
 	assert_noop, assert_ok,
 	traits::{Currency, GenesisBuild, OnInitialize},
@@ -43,7 +43,7 @@
 fn basic_setup_works() {
 	new_test_ext().execute_with(|| {
 		assert_eq!(CollatorSelection::desired_candidates(), 2);
-		assert_eq!(CollatorSelection::candidacy_bond(), 10);
+		assert_eq!(CollatorSelection::license_bond(), 10);
 
 		assert!(CollatorSelection::candidates().is_empty());
 		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
@@ -133,21 +133,21 @@
 }
 
 #[test]
-fn set_candidacy_bond() {
+fn set_license_bond() {
 	new_test_ext().execute_with(|| {
 		// given
-		assert_eq!(CollatorSelection::candidacy_bond(), 10);
+		assert_eq!(CollatorSelection::license_bond(), 10);
 
 		// can set
-		assert_ok!(CollatorSelection::set_candidacy_bond(
+		assert_ok!(CollatorSelection::set_license_bond(
 			RuntimeOrigin::signed(RootAccount::get()),
 			7
 		));
-		assert_eq!(CollatorSelection::candidacy_bond(), 7);
+		assert_eq!(CollatorSelection::license_bond(), 7);
 
 		// rejects bad origin.
 		assert_noop!(
-			CollatorSelection::set_candidacy_bond(RuntimeOrigin::signed(1), 8),
+			CollatorSelection::set_license_bond(RuntimeOrigin::signed(1), 8),
 			BadOrigin
 		);
 	});
@@ -227,7 +227,7 @@
 		assert_ok!(CollatorSelection::register_as_candidate(
 			RuntimeOrigin::signed(3)
 		));
-		let addition = CandidateInfo {
+		let addition = LicenseInfo {
 			who: 3,
 			deposit: 10,
 		};
@@ -267,7 +267,7 @@
 	new_test_ext().execute_with(|| {
 		// given
 		assert_eq!(CollatorSelection::desired_candidates(), 2);
-		assert_eq!(CollatorSelection::candidacy_bond(), 10);
+		assert_eq!(CollatorSelection::license_bond(), 10);
 		assert_eq!(CollatorSelection::candidates(), Vec::new());
 		assert_eq!(CollatorSelection::invulnerables(), vec![1, 2]);
 
@@ -331,7 +331,7 @@
 		// triggers `note_author`
 		Authorship::on_initialize(1);
 
-		let collator = CandidateInfo {
+		let collator = LicenseInfo {
 			who: 4,
 			deposit: 10,
 		};
@@ -361,7 +361,7 @@
 		// triggers `note_author`
 		Authorship::on_initialize(1);
 
-		let collator = CandidateInfo {
+		let collator = LicenseInfo {
 			who: 4,
 			deposit: 10,
 		};
@@ -432,7 +432,7 @@
 		assert_eq!(CollatorSelection::candidates().len(), 1);
 		// 3 will be kicked after 1 session delay
 		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 4]);
-		let collator = CandidateInfo {
+		let collator = LicenseInfo {
 			who: 4,
 			deposit: 10,
 		};
@@ -465,7 +465,7 @@
 		assert_eq!(CollatorSelection::candidates().len(), 1);
 		// 3 will be kicked after 1 session delay
 		assert_eq!(SessionHandlerCollators::get(), vec![1, 2, 3, 5]);
-		let collator = CandidateInfo {
+		let collator = LicenseInfo {
 			who: 5,
 			deposit: 10,
 		};
@@ -490,7 +490,7 @@
 
 	let collator_selection = collator_selection::GenesisConfig::<Test> {
 		desired_candidates: 2,
-		candidacy_bond: 10,
+		license_bond: 10,
 		kick_threshold: 1,
 		invulnerables,
 	};
modifiedpallets/collator-selection/src/weights.rsdiffbeforeafterboth
--- a/pallets/collator-selection/src/weights.rs
+++ b/pallets/collator-selection/src/weights.rs
@@ -46,7 +46,7 @@
 pub trait WeightInfo {
 	fn set_invulnerables(_b: u32) -> Weight;
 	fn set_desired_candidates() -> Weight;
-	fn set_candidacy_bond() -> Weight;
+	fn set_license_bond() -> Weight;
 	fn register_as_candidate(_c: u32) -> Weight;
 	fn leave_intent(_c: u32) -> Weight;
 	fn note_author() -> Weight;
@@ -65,7 +65,7 @@
 	fn set_desired_candidates() -> Weight {
 		Weight::from_ref_time(16_363_000 as u64).saturating_add(T::DbWeight::get().writes(1 as u64))
 	}
-	fn set_candidacy_bond() -> Weight {
+	fn set_license_bond() -> Weight {
 		Weight::from_ref_time(16_840_000 as u64).saturating_add(T::DbWeight::get().writes(1 as u64))
 	}
 	fn register_as_candidate(c: u32) -> Weight {
@@ -112,7 +112,7 @@
 		Weight::from_ref_time(16_363_000 as u64)
 			.saturating_add(RocksDbWeight::get().writes(1 as u64))
 	}
-	fn set_candidacy_bond() -> Weight {
+	fn set_license_bond() -> Weight {
 		Weight::from_ref_time(16_840_000 as u64)
 			.saturating_add(RocksDbWeight::get().writes(1 as u64))
 	}
modifiedprimitives/common/src/constants.rsdiffbeforeafterboth
--- a/primitives/common/src/constants.rs
+++ b/primitives/common/src/constants.rs
@@ -45,9 +45,9 @@
 /// Minimum balance required to create or keep an account open.
 pub const EXISTENTIAL_DEPOSIT: u128 = 0;
 /// Amount of Balance reserved for candidate registration.
-pub const GENESIS_CANDIDACY_BOND: u128 = EXISTENTIAL_DEPOSIT;
+pub const GENESIS_LICENSE_BOND: u128 = EXISTENTIAL_DEPOSIT;
 /// How long a periodic session lasts in blocks.
-pub const SESSION_LENGTH: BlockNumber = HOURS;
+pub const SESSION_LENGTH: BlockNumber = MINUTES;
 
 // Targeting 0.1 UNQ per transfer
 pub const WEIGHT_TO_FEE_COEFF: u32 = /*<weight2fee>*/175_199_920/*</weight2fee>*/;
modifiedruntime/common/mod.rsdiffbeforeafterboth
--- a/runtime/common/mod.rs
+++ b/runtime/common/mod.rs
@@ -191,7 +191,7 @@
 				RuntimeAppPublic,
 			};
 			use pallet_session::SessionManager;
-			use up_common::constants::GENESIS_CANDIDACY_BOND;
+			use up_common::constants::GENESIS_LICENSE_BOND;
 			use crate::config::pallets::collator_selection::MaxInvulnerables;
 
 			let mut weight = <Runtime as frame_system::Config>::DbWeight::get().reads(1);
@@ -242,7 +242,7 @@
 
 				<pallet_collator_selection::Invulnerables<Runtime>>::put(bounded_invulnerables);
 				<pallet_collator_selection::DesiredCandidates<Runtime>>::put(0);
-				<pallet_collator_selection::CandidacyBond<Runtime>>::put(GENESIS_CANDIDACY_BOND);
+				<pallet_collator_selection::LicenseBond<Runtime>>::put(GENESIS_LICENSE_BOND);
 
 				let keys = invulnerables
 					.into_iter()