Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix kick lottery #1328

Merged
merged 8 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ strip = "symbols"
panic = "unwind"

[profile.test]
debug = true
inherits = "release"
debug = 1

[workspace.dependencies]
anyhow = { version = "1.0.55", default-features = false }
Expand Down
3 changes: 2 additions & 1 deletion pallets/pallet-lottery/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ rand = { workspace = true }
similar-asserts = { workspace = true }
sp-staking = { workspace = true, features = ["std"] }
xcm = { workspace = true, features = ["std"] }
# env_logger = "0.8.3"
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved

[features]
default = ["std"]
Expand All @@ -69,6 +70,7 @@ runtime-benchmarks = [
'rand/std_rng',
]
std = [
"log/std",
"manta-primitives/std",
"pallet-parachain-staking/std",
"pallet-randomness/std",
Expand All @@ -87,7 +89,6 @@ std = [
"runtime-common/std",
"codec/std",
"scale-info/std",
"log/std",
"sp-staking/std",
]
try-runtime = [
Expand Down
20 changes: 18 additions & 2 deletions pallets/pallet-lottery/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ pub const BOB: AccountId = 2;
pub const CHARLIE: AccountId = 3;
pub const DAVE: AccountId = 4;
pub const EVE: AccountId = 5;
pub const DELEGATOR1: AccountId = 6;
pub const DELEGATOR2: AccountId = 7;
pub const DELEGATOR3: AccountId = 8;
pub const DELEGATOR4: AccountId = 9;
pub const DELEGATOR5: AccountId = 11;
pub const DELEGATOR6: AccountId = 12;
pub const DELEGATOR7: AccountId = 13;
pub const DELEGATOR8: AccountId = 14;
pub const TREASURY_ACCOUNT: AccountId = 10;

pub const JUMBO: Balance = 1_000_000_000_000;
Expand Down Expand Up @@ -287,9 +295,9 @@ impl pallet_parachain_staking::Config for Test {
/// Minimum collators selected per round, default at genesis and minimum forever after
type MinSelectedCandidates = ConstU32<5>;
/// Maximum top delegations per candidate
type MaxTopDelegationsPerCandidate = ConstU32<100>;
type MaxTopDelegationsPerCandidate = ConstU32<4>;
/// Maximum bottom delegations per candidate
type MaxBottomDelegationsPerCandidate = ConstU32<50>;
type MaxBottomDelegationsPerCandidate = ConstU32<4>;
/// Maximum delegations per delegator
type MaxDelegationsPerDelegator = ConstU32<25>;
type DefaultCollatorCommission = DefaultCollatorCommission;
Expand Down Expand Up @@ -607,6 +615,14 @@ impl ExtBuilder {
self
}

pub(crate) fn with_delegations(
mut self,
delegations: Vec<(AccountId, AccountId, Balance)>,
) -> Self {
self.delegations = delegations;
self
}

#[allow(dead_code)]
pub(crate) fn with_inflation(mut self, inflation: InflationInfo<Balance>) -> Self {
self.inflation = inflation;
Expand Down
33 changes: 33 additions & 0 deletions pallets/pallet-lottery/src/staking/deposit_strategies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,45 @@ pub(super) fn reactivate_bottom_collators<T: Config>(
let staked = StakedCollators::<T>::get(collator.clone());
let info = pallet_parachain_staking::Pallet::<T>::candidate_info(collator.clone())
.expect("is active collator, therefore it has collator info. qed");

// If collator not exist in delegatorState(PotAccount).delegations, ignore
Dengjianping marked this conversation as resolved.
Show resolved Hide resolved
if let Some(state) =
pallet_parachain_staking::Pallet::<T>::delegator_state(crate::Pallet::<T>::account_id())
{
let mut is_kick = true;
for x in &state.delegations.0 {
if x.owner == collator {
is_kick = false;
break;
}
}
if is_kick {
log::debug!(
"Staked collator:{:?} is kicked off from delegator state, ignore.",
collator
);
continue;
}
}
zqhxuyuan marked this conversation as resolved.
Show resolved Hide resolved
log::debug!(
"check collator:{:?} staked:{:?}, lowest top: {:?}",
collator,
staked,
info.lowest_top_delegation_amount
);

if staked < info.lowest_top_delegation_amount {
// TODO: Small optimization: sort collators ascending by missing amount so we get the largest amount of collators active before running out of funds
let this_deposit = core::cmp::min(
remaining_deposit,
info.lowest_top_delegation_amount - staked + 1u32.into(),
);
log::debug!(
"remaining:{:?}, deposit:{:?}, diff:{:?}",
remaining_deposit,
this_deposit,
remaining_deposit - this_deposit
);
// Ensure we don't try to stake a smaller than allowed delegation to a collator
if remaining_deposit.saturating_sub(this_deposit) < crate::Pallet::<T>::min_deposit() {
deposits.push((collator, remaining_deposit)); // put the full remaining balance in this collator
Expand Down
43 changes: 42 additions & 1 deletion pallets/pallet-lottery/src/staking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ impl<T: Config> Pallet<T> {
.cloned()
.collect::<Vec<_>>();

log::debug!(
"deposit_eligible_collators size: {:?}",
deposit_eligible_collators.len()
);
// first concern: If we fell out of the active set on one or more collators, we need to get back into it
deposits.append(&mut deposit_strategies::reactivate_bottom_collators::<T>(
deposit_eligible_collators.as_slice(),
Expand All @@ -89,21 +93,46 @@ impl<T: Config> Pallet<T> {
.reduce(|sum, elem| sum + elem)
.unwrap_or_else(|| 0u32.into());

log::debug!(
"after reactivate_bottom_collators deposits: {:?}, remaining: ${:?}",
deposits.len(),
remaining_deposit
);
// If we have re-activated any collators and have leftover funds, we just distribute all surplus tokens to them evenly and call it a day
if !deposits.is_empty() {
if !remaining_deposit.is_zero() {
log::debug!(
"deposits:{:?} not null and remaining:{:?} not zero",
deposits,
remaining_deposit
);
let deposit_per_collator =
Percent::from_rational(1, deposits.len() as u32).mul_ceil(remaining_deposit); // this overshoots the amount if there's a remainder
for deposit in &mut deposits {
let add = remaining_deposit.saturating_sub(deposit_per_collator); // we correct the overshoot here
log::debug!(
"deposit_per_collator:{:?}, add:{:?}",
deposit_per_collator,
add
);
deposit.1 += add;
remaining_deposit -= add;
}
}
log::debug!(
"deposits:{:?} not null and remaining:{:?}",
deposits,
remaining_deposit
);
return deposits;
}

// second concern: We want to maximize staking APY earned, so we want to balance the staking pools with our deposits while conserving gas
log::debug!(
"deposit_eligible_collators size:{:?}, remaining_deposit:{:?}",
deposit_eligible_collators.len(),
remaining_deposit
);
deposits.append(
&mut deposit_strategies::split_to_underallocated_collators::<T>(
deposit_eligible_collators.as_slice(),
Expand All @@ -115,6 +144,10 @@ impl<T: Config> Pallet<T> {
.map(|deposit| deposit.1)
.reduce(|sum, elem| sum + elem)
.unwrap_or_else(|| 0u32.into());
log::debug!(
"after split_to_underallocated_collators, remain: ${:?}",
remaining_deposit
);
// fallback: just assign to a random active collator ( choose a different collator for each invocation )
if !remaining_deposit.is_zero() {
log::warn!(
Expand Down Expand Up @@ -238,8 +271,12 @@ impl<T: Config> Pallet<T> {
};
let delegation_count = StakedCollators::<T>::iter_keys().count() as u32;

// If we're already delegated to this collator, we must call `delegate_more`
// If we're already delegated to this collator, we must call `delegator_bond_more`.
if StakedCollators::<T>::get(&collator).is_zero() {
log::debug!(
"delegator not staked on collator:{:?}, use delegate",
collator
);
// Ensure the pallet has enough gas to pay for this
let fee_estimate: BalanceOf<T> = T::EstimateCallFee::estimate_call_fee(
&pallet_parachain_staking::Call::delegate {
Expand Down Expand Up @@ -271,6 +308,10 @@ impl<T: Config> Pallet<T> {
e.error
})?;
} else {
log::debug!(
"delegator already staked on collator:{:?}, use delegator_bond_more",
collator
);
// Ensure the pallet has enough gas to pay for this
let fee_estimate: BalanceOf<T> = T::EstimateCallFee::estimate_call_fee(
&pallet_parachain_staking::Call::delegator_bond_more {
Expand Down
2 changes: 1 addition & 1 deletion pallets/pallet-lottery/src/staking/withdraw_strategies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub(super) fn unstake_least_apy_collators<T: Config>(
binfo.total_counted.cmp(&ainfo.total_counted)
});
log::debug!(
"Active collators: {:?}",
"Active collators size: {:?}",
apy_ordered_active_collators_we_are_staked_with.len()
);
for c in apy_ordered_active_collators_we_are_staked_with {
Expand Down
Loading
Loading