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

Feat/dyn tier thresholds #1306

Merged
merged 23 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
815ed11
remove number_of_slots from TiersConfiguration
ipapandinas Jul 22, 2024
04ea0df
remove use of TierThreshold enum in TiersConfiguration
ipapandinas Jul 22, 2024
26dd611
percentage variants added to TierThreshold for values derivation from…
ipapandinas Jul 23, 2024
13001f6
dyn tier percentages adjusted
ipapandinas Jul 24, 2024
24a09ae
sanity checks for total issuance percentages customisable via config
ipapandinas Jul 24, 2024
5b5affa
storage migration
ipapandinas Jul 24, 2024
68887d7
storage version checks added
ipapandinas Jul 25, 2024
27a6d32
storage version checks adjusted
ipapandinas Jul 26, 2024
9276ffd
new threshold calculation adjusted
ipapandinas Jul 29, 2024
f735aea
field renamed
ipapandinas Jul 29, 2024
5195002
try-runtime sanity check to ensure same number of slots
ipapandinas Jul 29, 2024
fbb0bda
add small tolerance to try-runtime sanity check
ipapandinas Jul 29, 2024
ce58e5c
README updated
ipapandinas Jul 29, 2024
5fbb35d
remove configurable min/max percentage checks for extra safety
ipapandinas Jul 30, 2024
ca710c8
preserve not applied migrations
ipapandinas Jul 30, 2024
657b658
useless procedural macros removed
ipapandinas Jul 30, 2024
32dd3f0
tvl amount variants removed from TierThreshold
ipapandinas Jul 30, 2024
aa4d147
from conversion
ipapandinas Jul 31, 2024
18725d0
field renamed
ipapandinas Jul 31, 2024
c87cdaa
versioned migration used for static tier params
ipapandinas Aug 1, 2024
853bc6e
PR review fixes
ipapandinas Aug 5, 2024
352eaaf
adjust percentages
ipapandinas Aug 6, 2024
d2d4287
review feedbacks
ipapandinas Aug 6, 2024
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
2 changes: 1 addition & 1 deletion bin/collator/src/local/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn testnet_genesis(
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
required_percentage: Perbill::from_parts(600_000), // 0.06%
},
],
slots_per_tier: vec![10, 20, 30, 40],
Expand Down
6 changes: 3 additions & 3 deletions bin/collator/src/parachain/chain_spec/astar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ fn make_genesis(
minimum_required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(23_800_000), // 2.38%
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
percentage: Perbill::from_parts(2_380_000), // 0.238%
minimum_required_percentage: Perbill::from_parts(1_790_000), // 0.179%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
required_percentage: Perbill::from_parts(200_000), // 0.02%
},
],
slots_per_tier: vec![10, 20, 30, 40],
Expand Down
4 changes: 2 additions & 2 deletions bin/collator/src/parachain/chain_spec/shibuya.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ fn make_genesis(
minimum_required_percentage: Perbill::from_parts(17_000), // 0.0017%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(10_000), // 0.0010%
minimum_required_percentage: Perbill::from_parts(6_800), // 0.00068%
percentage: Perbill::from_parts(13_000), // 0.0013%
minimum_required_percentage: Perbill::from_parts(10_000), // 0.0010%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(5_400), // 0.00054%
Expand Down
6 changes: 3 additions & 3 deletions bin/collator/src/parachain/chain_spec/shiden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ fn make_genesis(
minimum_required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(23_800_000), // 2.38%
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
percentage: Perbill::from_parts(2_380_000), // 0.238%
minimum_required_percentage: Perbill::from_parts(1_790_000), // 0.179%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
required_percentage: Perbill::from_parts(600_000), // 0.06%
},
],
slots_per_tier: vec![10, 20, 30, 40],
Expand Down
2 changes: 1 addition & 1 deletion pallets/dapp-staking-v3/src/benchmarking/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pub(super) fn init_tier_settings<T: Config>() {
.unwrap(),
};

let total_issuance = SEED as u128 * UNIT;
let total_issuance = 1000 * MIN_TIER_THRESHOLD;
let tier_thresholds = tier_params
.tier_thresholds
.iter()
Expand Down
1 change: 1 addition & 0 deletions pallets/dapp-staking-v3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ pub mod pallet {
reward_portion: vec![Permill::from_percent(100 / num_tiers); num_tiers as usize],
slot_distribution: vec![Permill::from_percent(100 / num_tiers); num_tiers as usize],
tier_thresholds: (0..num_tiers)
.rev()
.map(|i| TierThreshold::FixedPercentage {
required_percentage: Perbill::from_percent(i),
})
Expand Down
10 changes: 10 additions & 0 deletions pallets/dapp-staking-v3/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ mod v8 {

if result.is_err() {
log::error!("Failed to translate StaticTierParams from previous V7 type to current V8 type. Check TierParametersV7 decoding.");
// Enable maintenance mode.
ActiveProtocolState::<T>::mutate(|state| {
state.maintenance = true;
});
log::warn!("Maintenance mode enabled.");
return T::DbWeight::get().reads_writes(1, 0);
}

Expand Down Expand Up @@ -133,6 +138,11 @@ mod v8 {

if result.is_err() {
log::error!("Failed to translate TierConfig from previous V7 type to current V8 type. Check TiersConfigurationV7 decoding.");
// Enable maintenance mode.
ActiveProtocolState::<T>::mutate(|state| {
state.maintenance = true;
});
log::warn!("Maintenance mode enabled.");
return T::DbWeight::get().reads_writes(2, 1);
}

Expand Down
104 changes: 44 additions & 60 deletions pallets/dapp-staking-v3/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1662,17 +1662,54 @@ impl<NT: Get<u32>, T: TierSlotsFunc, P: Get<FixedU128>> TiersConfiguration<NT, T
)
};

// Update tier thresholds.
// In case number of slots increase, we decrease thresholds required to enter the tier.
// In case number of slots decrease, we increase the threshold required to enter the tier.
//
// According to formula: %delta_threshold = (100% / (100% - delta_%_slots) - 1) * 100%
//
// where delta_%_slots is simply: (base_num_slots - new_num_slots) / base_num_slots
//
// `base_num_slots` is the number of slots at the base native currency price.
//
// When these entries are put into the threshold formula, we get:
// = 1 / ( 1 - (base_num_slots - new_num_slots) / base_num_slots ) - 1
// = 1 / ( new / base) - 1
// = base / new - 1
// = (base - new) / new
//
// This number can be negative. In order to keep all operations in unsigned integer domain,
// formulas are adjusted like:
//
// 1. Number of slots has increased, threshold is expected to decrease
// %delta_threshold = (new_num_slots - base_num_slots) / new_num_slots
// new_threshold = base_threshold * (1 - %delta_threshold)
//
// 2. Number of slots has decreased, threshold is expected to increase
// %delta_threshold = (base_num_slots - new_num_slots) / new_num_slots
// new_threshold = base_threshold * (1 + %delta_threshold)
//
let new_tier_thresholds: BoundedVec<Balance, NT> = params
.tier_thresholds
.clone()
.iter()
.map(|threshold| {
Self::adjust_threshold(
threshold,
delta_threshold,
total_issuance,
new_number_of_slots >= base_number_of_slots,
)
.map(|threshold| match threshold {
TierThreshold::DynamicPercentage {
percentage,
minimum_required_percentage,
} => {
let amount = *percentage * total_issuance;
let adjusted_amount = if new_number_of_slots >= base_number_of_slots {
amount.saturating_sub(delta_threshold.saturating_mul_int(amount))
} else {
amount.saturating_add(delta_threshold.saturating_mul_int(amount))
};
let minimum_amount = *minimum_required_percentage * total_issuance;
adjusted_amount.max(minimum_amount)
}
TierThreshold::FixedPercentage {
required_percentage,
} => *required_percentage * total_issuance,
})
.collect::<Vec<_>>()
.try_into()
Expand All @@ -1685,59 +1722,6 @@ impl<NT: Get<u32>, T: TierSlotsFunc, P: Get<FixedU128>> TiersConfiguration<NT, T
_phantom: Default::default(),
}
}

// Update tier thresholds.
// In case number of slots increase, we decrease thresholds required to enter the tier.
// In case number of slots decrease, we increase the threshold required to enter the tier.
//
// According to formula: %delta_threshold = (100% / (100% - delta_%_slots) - 1) * 100%
//
// where delta_%_slots is simply: (base_num_slots - new_num_slots) / base_num_slots
//
// `base_num_slots` is the number of slots at the base native currency price.
//
// When these entries are put into the threshold formula, we get:
// = 1 / ( 1 - (base_num_slots - new_num_slots) / base_num_slots ) - 1
// = 1 / ( new / base) - 1
// = base / new - 1
// = (base - new) / new
//
// This number can be negative. In order to keep all operations in unsigned integer domain,
// formulas are adjusted like:
//
// 1. Number of slots has increased, threshold is expected to decrease
// %delta_threshold = (new_num_slots - base_num_slots) / new_num_slots
// new_threshold = base_threshold * (1 - %delta_threshold)
//
// 2. Number of slots has decreased, threshold is expected to increase
// %delta_threshold = (base_num_slots - new_num_slots) / new_num_slots
// new_threshold = base_threshold * (1 + %delta_threshold)
//
fn adjust_threshold(
threshold: &TierThreshold,
delta_threshold: FixedU128,
total_issuance: Balance,
slots_increased: bool,
) -> Balance {
match threshold {
TierThreshold::DynamicPercentage {
percentage,
minimum_required_percentage,
} => {
let amount = *percentage * total_issuance;
let adjusted_amount = if slots_increased {
amount.saturating_sub(delta_threshold.saturating_mul_int(amount))
} else {
amount.saturating_add(delta_threshold.saturating_mul_int(amount))
};
let minimum_amount = *minimum_required_percentage * total_issuance;
adjusted_amount.max(minimum_amount)
}
TierThreshold::FixedPercentage {
required_percentage,
} => *required_percentage * total_issuance,
}
}
}

/// Information about all of the dApps that got into tiers, and tier rewards
Expand Down
7 changes: 4 additions & 3 deletions runtime/astar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,7 @@ pub type Executive = frame_executive::Executive<
>;

parameter_types! {
// percentages below are calulated based on total issuance at the time when dApp staking v3 was launched (8.4B)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth considering adding more checks for this into the try-runtime check 🙂

For another PR though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you thinking of sanity checks in pre_upgrade, like:

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
    let tier_thresholds: Result<BoundedVec<TierThreshold, T::NumberOfTiers>, _> =
        BoundedVec::try_from(TierThresholds::get().to_vec());
    assert!(tier_thresholds.is_ok());

    ...
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both pre & post.

E.g. take current thresholds (active ones) in pre-upgrade, send them to post upgrade.

In post-upgrade, after you derive the new thresholds, ensure they are e.g. within 10% of the old ones.

pub const TierThresholds: [TierThreshold; 4] = [
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(35_700_000), // 3.57%
Expand All @@ -1268,11 +1269,11 @@ parameter_types! {
minimum_required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(23_800_000), // 2.38%
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
percentage: Perbill::from_parts(2_380_000), // 0.238%
minimum_required_percentage: Perbill::from_parts(1_790_000), // 0.179%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
required_percentage: Perbill::from_parts(200_000), // 0.02%
},
];
}
Expand Down
5 changes: 3 additions & 2 deletions runtime/shibuya/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1613,14 +1613,15 @@ pub type Executive = frame_executive::Executive<
>;

parameter_types! {
// percentages below are calulated based on a total issuance at the time when dApp staking v3 was launched (147M)
pub const TierThresholds: [TierThreshold; 4] = [
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(20_000), // 0.0020%
minimum_required_percentage: Perbill::from_parts(17_000), // 0.0017%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(10_000), // 0.0010%
minimum_required_percentage: Perbill::from_parts(6_800), // 0.00068%
percentage: Perbill::from_parts(13_000), // 0.0013%
minimum_required_percentage: Perbill::from_parts(10_000), // 0.0010%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(5_400), // 0.00054%
Expand Down
7 changes: 4 additions & 3 deletions runtime/shiden/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,7 @@ pub type Executive = frame_executive::Executive<
>;

parameter_types! {
// percentages below are calulated based on a total issuance at the time when dApp staking v3 was launched (84.3M)
pub const TierThresholds: [TierThreshold; 4] = [
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(35_700_000), // 3.57%
Expand All @@ -1270,11 +1271,11 @@ parameter_types! {
minimum_required_percentage: Perbill::from_parts(6_000_000), // 0.6%
},
TierThreshold::DynamicPercentage {
percentage: Perbill::from_parts(23_800_000), // 2.38%
minimum_required_percentage: Perbill::from_parts(17_900_000), // 1.79%
percentage: Perbill::from_parts(2_380_000), // 0.238%
minimum_required_percentage: Perbill::from_parts(1_790_000), // 0.179%
},
TierThreshold::FixedPercentage {
required_percentage: Perbill::from_parts(6_000_000), // 0.6%
required_percentage: Perbill::from_parts(600_000), // 0.06%
},
];
}
Expand Down
Loading