From 3672db812d8add5fe38fdb961f527bd706339c62 Mon Sep 17 00:00:00 2001 From: hayotensor Date: Tue, 11 Mar 2025 17:16:45 -0400 Subject: [PATCH] registration periods --- pallets/network/src/lib.rs | 114 ++++---- .../src/stake/node_delegate_staking.rs | 2 - pallets/network/src/tests/mod.rs | 4 +- .../src/tests/node_delegate_staking.rs | 111 ++++++-- pallets/network/src/tests/subnet.rs | 25 +- pallets/network/src/tests/subnet_node.rs | 4 +- pallets/network/src/tests/test_utils.rs | 10 + pallets/network/src/tests/utils.rs | 249 ++++++++++++++---- pallets/network/src/utilities/subnet.rs | 90 +++++-- 9 files changed, 448 insertions(+), 161 deletions(-) diff --git a/pallets/network/src/lib.rs b/pallets/network/src/lib.rs index 00a9506..b9b9a29 100644 --- a/pallets/network/src/lib.rs +++ b/pallets/network/src/lib.rs @@ -306,6 +306,8 @@ pub mod pallet { InvalidSubnetId, /// Maximum amount of subnet entries surpassed, see subnet `entry_interval` for more information + MaxSubnetEntryIntervalReached, + /// Maximum `entry_interval` parameter entered during subnet registration MaxSubnetEntryInterval, DelegateStakeTransferPeriodExceeded, @@ -904,7 +906,7 @@ pub mod pallet { 100 } #[pallet::type_value] - pub fn DefaultMaxLastSubnetEntry() -> u64 { + pub fn DefaultMaxSubnetEntryInterval() -> u64 { // 1 week based on 6s blocks 100800 } @@ -924,7 +926,7 @@ pub mod pallet { pub type SubnetsData = StorageMap<_, Blake2_128Concat, u32, SubnetData>; #[pallet::storage] // subnet_id => block_interval - pub type MaxLastSubnetEntry = StorageValue<_, u64, ValueQuery, DefaultMaxLastSubnetEntry>; + pub type MaxSubnetEntryInterval = StorageValue<_, u64, ValueQuery, DefaultMaxSubnetEntryInterval>; /// The maximum a single node can enter a subnet per blocks interval #[pallet::storage] // subnet_id => block @@ -2896,6 +2898,11 @@ pub mod pallet { Error::::MaxSubnetMemory ); + ensure!( + subnet_data.entry_interval <= MaxSubnetEntryInterval::::get(), + Error::::MaxSubnetEntryInterval + ); + let block: u64 = Self::get_current_block_as_u64(); let subnet_fee: u128 = Self::registration_cost(epoch); @@ -3114,7 +3121,7 @@ pub mod pallet { let block: u64 = Self::get_current_block_as_u64(); ensure!( block >= LastSubnetEntry::::get(subnet_id) + subnet.entry_interval, - Error::::MaxSubnetEntryInterval + Error::::MaxSubnetEntryIntervalReached ); // Ensure hotkey either has no owner or is the origins hotkey @@ -3605,61 +3612,66 @@ pub mod pallet { return } - let subnet_id = 1; + // let subnet_id = 1; - let base_node_memory: u128 = BaseSubnetNodeMemoryMB::::get(); + // let base_node_memory: u128 = BaseSubnetNodeMemoryMB::::get(); - // --- Get min nodes based on default memory settings - let real_min_subnet_nodes: u128 = self.memory_mb.clone() / base_node_memory; - let mut min_subnet_nodes: u32 = MinSubnetNodes::::get(); - if real_min_subnet_nodes as u32 > min_subnet_nodes { - min_subnet_nodes = real_min_subnet_nodes as u32; - } + // // --- Get min nodes based on default memory settings + // let real_min_subnet_nodes: u128 = self.memory_mb.clone() / base_node_memory; + // let mut min_subnet_nodes: u32 = MinSubnetNodes::::get(); + // if real_min_subnet_nodes as u32 > min_subnet_nodes { + // min_subnet_nodes = real_min_subnet_nodes as u32; + // } - let target_subnet_nodes: u32 = (min_subnet_nodes as u128).saturating_mul(TargetSubnetNodesMultiplier::::get()).saturating_div(1000000000) as u32 + min_subnet_nodes; - - let subnet_data = SubnetData { - id: subnet_id, - path: self.subnet_path.clone(), - min_nodes: min_subnet_nodes, - target_nodes: target_subnet_nodes, - memory_mb: self.memory_mb.clone(), - registration_blocks: MinSubnetRegistrationBlocks::::get(), - initialized: 1, - activated: 0, - entry_interval: 0, - }; + // let target_subnet_nodes: u32 = (min_subnet_nodes as u128).saturating_mul(TargetSubnetNodesMultiplier::::get()).saturating_div(1000000000) as u32 + min_subnet_nodes; + + // let subnet_data = SubnetData { + // id: subnet_id, + // path: self.subnet_path.clone(), + // min_nodes: min_subnet_nodes, + // target_nodes: target_subnet_nodes, + // memory_mb: self.memory_mb.clone(), + // registration_blocks: MinSubnetRegistrationBlocks::::get(), + // initialized: 1, + // activated: 0, + // entry_interval: 0, + // }; - // Increase total subnet memory - TotalSubnetMemoryMB::::mutate(|n: &mut u128| *n += subnet_data.memory_mb); - // Store unique path - SubnetPaths::::insert(self.subnet_path.clone(), subnet_id); - // Store subnet data - SubnetsData::::insert(subnet_id, subnet_data.clone()); - // Increase total subnets count - TotalSubnets::::mutate(|n: &mut u32| *n += 1); + // // Increase total subnet memory + // TotalSubnetMemoryMB::::mutate(|n: &mut u128| *n += subnet_data.memory_mb); + // // Store unique path + // SubnetPaths::::insert(self.subnet_path.clone(), subnet_id); + // // Store subnet data + // SubnetsData::::insert(subnet_id, subnet_data.clone()); + // // Increase total subnets count + // TotalSubnets::::mutate(|n: &mut u32| *n += 1); + + // // Increase delegate stake to allow activation of subnet model + // let min_stake_balance = MinStakeBalance::::get(); + // // --- Get minimum subnet stake balance + // let min_subnet_stake_balance = min_stake_balance * min_subnet_nodes as u128; + // // --- Get required delegate stake balance for a subnet to have to stay live + // let mut min_subnet_delegate_stake_balance = (min_subnet_stake_balance as u128).saturating_mul(MinSubnetDelegateStakePercentage::::get()).saturating_div(1000000000); + + // // --- Get absolute minimum required subnet delegate stake balance + // let min_subnet_delegate_stake = MinSubnetDelegateStake::::get(); + // // --- Return here if the absolute minimum required subnet delegate stake balance is greater + // // than the calculated minimum requirement + // if min_subnet_delegate_stake > min_subnet_delegate_stake_balance { + // min_subnet_delegate_stake_balance = min_subnet_delegate_stake + // } + // TotalSubnetDelegateStakeBalance::::insert(subnet_id, min_subnet_delegate_stake_balance); + + // // --- Initialize subnet nodes + // // Only initialize to test using subnet nodes + // // If testing using subnet nodes in a subnet, comment out the ``for`` loop - // Increase delegate stake to allow activation of subnet model - let min_stake_balance = MinStakeBalance::::get(); - // --- Get minimum subnet stake balance - let min_subnet_stake_balance = min_stake_balance * min_subnet_nodes as u128; - // --- Get required delegate stake balance for a subnet to have to stay live - let mut min_subnet_delegate_stake_balance = (min_subnet_stake_balance as u128).saturating_mul(MinSubnetDelegateStakePercentage::::get()).saturating_div(1000000000); - - // --- Get absolute minimum required subnet delegate stake balance - let min_subnet_delegate_stake = MinSubnetDelegateStake::::get(); - // --- Return here if the absolute minimum required subnet delegate stake balance is greater - // than the calculated minimum requirement - if min_subnet_delegate_stake > min_subnet_delegate_stake_balance { - min_subnet_delegate_stake_balance = min_subnet_delegate_stake - } - TotalSubnetDelegateStakeBalance::::insert(subnet_id, min_subnet_delegate_stake_balance); + // let mut stake_amount: u128 = MinStakeBalance::::get(); - // --- Initialize subnet nodes - // Only initialize to test using subnet nodes - // If testing using subnet nodes in a subnet, comment out the ``for`` loop - let mut stake_amount: u128 = MinStakeBalance::::get(); + // + // + // // let mut count = 0; // for (account_id, peer_id) in &self.subnet_nodes { diff --git a/pallets/network/src/stake/node_delegate_staking.rs b/pallets/network/src/stake/node_delegate_staking.rs index 827e14a..7b8efcc 100644 --- a/pallets/network/src/stake/node_delegate_staking.rs +++ b/pallets/network/src/stake/node_delegate_staking.rs @@ -142,8 +142,6 @@ impl Pallet { total_node_delegated_stake_balance ); - log::error!("delegate_stake_to_be_removed {:?}", delegate_stake_to_be_removed); - // --- Ensure that we can convert this u128 to a balance. // Redunant let delegate_stake_to_be_added_as_currency = Self::u128_to_balance(delegate_stake_to_be_removed); diff --git a/pallets/network/src/tests/mod.rs b/pallets/network/src/tests/mod.rs index 8e5cc38..3d881c2 100644 --- a/pallets/network/src/tests/mod.rs +++ b/pallets/network/src/tests/mod.rs @@ -1,5 +1,5 @@ -mod test_utils; mod mock; +mod test_utils; mod subnet; mod subnet_node; mod staking; @@ -9,5 +9,5 @@ mod incentives_protocol; mod proposals; mod math; mod randomization; +mod steps; mod utils; -mod steps; \ No newline at end of file diff --git a/pallets/network/src/tests/node_delegate_staking.rs b/pallets/network/src/tests/node_delegate_staking.rs index 4599041..7820d02 100644 --- a/pallets/network/src/tests/node_delegate_staking.rs +++ b/pallets/network/src/tests/node_delegate_staking.rs @@ -130,16 +130,12 @@ fn test_remove_node_delegate_stake() { let account_node_delegate_stake_shares = AccountNodeDelegateStakeShares::::get((account(total_subnet_nodes+1), subnet_id, 0)); let total_node_delegate_stake_balance = TotalNodeDelegateStakeBalance::::get(subnet_id, 0); let total_node_delegate_stake_shares = TotalNodeDelegateStakeShares::::get(subnet_id, 0); - log::error!("account_node_delegate_stake_shares {:?}", account_node_delegate_stake_shares); - log::error!("total_node_delegate_stake_balance {:?}", total_node_delegate_stake_balance); - log::error!("total_node_delegate_stake_shares {:?}", total_node_delegate_stake_shares); let account_node_delegate_stake_balance = Network::convert_to_balance( account_node_delegate_stake_shares, total_node_delegate_stake_shares, total_node_delegate_stake_balance ); - log::error!("account_node_delegate_stake_balance {:?}", account_node_delegate_stake_balance); assert!( (account_node_delegate_stake_balance >= Network::percent_mul(amount, 9999)) && @@ -147,17 +143,18 @@ fn test_remove_node_delegate_stake() { ); let account_node_delegate_stake_shares_to_be_removed = account_node_delegate_stake_shares / 2; - log::error!("account_node_delegate_stake_shares_to_be_removed {:?}", account_node_delegate_stake_shares_to_be_removed); let expected_balance_to_be_removed = Network::convert_to_balance( account_node_delegate_stake_shares_to_be_removed, total_node_delegate_stake_shares, total_node_delegate_stake_balance ); - log::error!("expected_balance_to_be_removed {:?}", expected_balance_to_be_removed); - let expected_post_balance = account_node_delegate_stake_balance - expected_balance_to_be_removed; - log::error!("expected_post_balance {:?}", expected_post_balance); + let expected_post_balance = Network::convert_to_balance( + account_node_delegate_stake_shares_to_be_removed, + total_node_delegate_stake_shares - account_node_delegate_stake_shares_to_be_removed, + total_node_delegate_stake_balance - expected_balance_to_be_removed + ); assert_ok!( Network::remove_node_delegate_stake( @@ -171,9 +168,6 @@ fn test_remove_node_delegate_stake() { let account_node_delegate_stake_shares = AccountNodeDelegateStakeShares::::get((account(total_subnet_nodes+1), subnet_id, 0)); let total_node_delegate_stake_balance = TotalNodeDelegateStakeBalance::::get(subnet_id, 0); let total_node_delegate_stake_shares = TotalNodeDelegateStakeShares::::get(subnet_id, 0); - log::error!("post account_node_delegate_stake_shares {:?}", account_node_delegate_stake_shares); - log::error!("post total_node_delegate_stake_balance {:?}", total_node_delegate_stake_balance); - log::error!("post total_node_delegate_stake_shares {:?}", total_node_delegate_stake_shares); assert_eq!(account_node_delegate_stake_shares, account_node_delegate_stake_shares_to_be_removed); @@ -182,25 +176,90 @@ fn test_remove_node_delegate_stake() { total_node_delegate_stake_shares, total_node_delegate_stake_balance ); - log::error!("post_account_node_delegate_stake_balance {:?}", post_account_node_delegate_stake_balance); - - // assert_eq!(expected_post_balance, post_account_node_delegate_stake_balance); - - // let expected_balance = Network::percent_mul(account_node_delegate_stake_balance/2, 9999); - // log::error!("expected_balance {:?}", expected_balance); - - // assert!( - // post_account_node_delegate_stake_balance >= expected_balance - // ); - - // assert!( - // (post_account_node_delegate_stake_balance >= expected_balance) && - // (post_account_node_delegate_stake_balance <= (account_node_delegate_stake_balance/2)) - // ); + assert_eq!(expected_post_balance, post_account_node_delegate_stake_balance); }) } +// #[test] +// fn test_transfer_node_delegate_stake() { +// new_test_ext().execute_with(|| { +// let subnet_path: Vec = "petals-team/StableBeluga2".into(); +// let deposit_amount: u128 = 10000000000000000000000; +// let amount: u128 = 1000000000000000000000; + +// build_activated_subnet_with_delegator_rewards( +// subnet_path.clone(), +// 0, +// 16, +// deposit_amount, +// amount, +// DEFAULT_DELEGATE_REWARD_RATE, +// ); + +// let from_subnet_id = SubnetPaths::::get(subnet_path.clone()).unwrap(); +// let total_from_subnet_nodes = TotalSubnetNodes::::get(from_subnet_id); + +// let to_subnet_path: Vec = "petals-team/StableBeluga3".into(); + +// build_activated_subnet_with_delegator_rewards( +// to_subnet_path.clone(), +// 0, +// 16, +// deposit_amount, +// amount, +// DEFAULT_DELEGATE_REWARD_RATE, +// ); + +// let to_subnet_id = SubnetPaths::::get(to_subnet_path.clone()).unwrap(); + +// let _ = Balances::deposit_creating(&account(total_from_subnet_nodes+1), amount+500); + +// assert_ok!( +// Network::add_to_node_delegate_stake( +// RuntimeOrigin::signed(account(total_from_subnet_nodes+1)), +// from_subnet_id, +// 0, +// amount, +// ) +// ); + +// let account_node_delegate_stake_shares = AccountNodeDelegateStakeShares::::get((account(total_from_subnet_nodes+1), from_subnet_id, 0)); +// let total_node_delegate_stake_balance = TotalNodeDelegateStakeBalance::::get(from_subnet_id, 0); +// let total_node_delegate_stake_shares = TotalNodeDelegateStakeShares::::get(from_subnet_id, 0); + +// let account_node_delegate_stake_balance = Network::convert_to_balance( +// account_node_delegate_stake_shares, +// total_node_delegate_stake_shares, +// total_node_delegate_stake_balance +// ); + +// assert!( +// (account_node_delegate_stake_balance >= Network::percent_mul(amount, 9999)) && +// (account_node_delegate_stake_balance <= amount) +// ); + +// let account_node_delegate_stake_shares_to_be_removed = account_node_delegate_stake_shares / 2; + +// let expected_balance_to_be_removed = Network::convert_to_balance( +// account_node_delegate_stake_shares_to_be_removed, +// total_node_delegate_stake_shares, +// total_node_delegate_stake_balance +// ); + +// assert_ok!( +// Network::transfer_node_delegate_stake( +// RuntimeOrigin::signed(account(total_from_subnet_nodes+1)), +// from_subnet_id, +// 0, +// to_subnet_id, +// 0, +// account_node_delegate_stake_shares_to_be_removed, +// ) +// ); +// }) +// } + #[test] fn test_validate_with_delegate_rewards_rate() { new_test_ext().execute_with(|| { diff --git a/pallets/network/src/tests/subnet.rs b/pallets/network/src/tests/subnet.rs index 8b57fd6..2436506 100644 --- a/pallets/network/src/tests/subnet.rs +++ b/pallets/network/src/tests/subnet.rs @@ -83,6 +83,8 @@ fn test_register_subnet_subnet_registration_cooldown() { new_test_ext().execute_with(|| { let subnet_path: Vec = "petals-team/StableBeluga2".into(); + increase_epochs(1); + let epoch_length = EpochLength::get(); let block_number = System::block_number(); let epoch = System::block_number().saturating_div(epoch_length); @@ -104,7 +106,7 @@ fn test_register_subnet_subnet_registration_cooldown() { let block_number = System::block_number(); let epoch = System::block_number().saturating_div(epoch_length); let next_registration_epoch = Network::get_next_registration_epoch(epoch as u32); - increase_epochs(next_registration_epoch - epoch as u32); + // increase_epochs(next_registration_epoch - epoch as u32); // --- Register subnet for activation assert_ok!( @@ -126,7 +128,6 @@ fn test_register_subnet_subnet_registration_cooldown() { entry_interval: 0, }; - // --- Register subnet for activation assert_err!( Network::register_subnet( RuntimeOrigin::signed(account(0)), @@ -139,7 +140,7 @@ fn test_register_subnet_subnet_registration_cooldown() { let block_number = System::block_number(); let epoch = System::block_number().saturating_div(epoch_length); let next_registration_epoch = Network::get_next_registration_epoch(epoch as u32); - increase_epochs(next_registration_epoch - epoch as u32); + increase_epochs(next_registration_epoch); let epoch_length = EpochLength::get(); let block_number = System::block_number(); @@ -156,6 +157,24 @@ fn test_register_subnet_subnet_registration_cooldown() { add_subnet_data.clone(), ) ); + + + let subnet_path: Vec = "petals-team/StableBeluga4".into(); + + let add_subnet_data = RegistrationSubnetData { + path: subnet_path.clone().into(), + memory_mb: DEFAULT_MEM_MB, + registration_blocks: registration_blocks, + entry_interval: 0, + }; + + assert_err!( + Network::register_subnet( + RuntimeOrigin::signed(account(0)), + add_subnet_data.clone(), + ), + Error::::SubnetRegistrationCooldown + ); }) } diff --git a/pallets/network/src/tests/subnet_node.rs b/pallets/network/src/tests/subnet_node.rs index ba8e60f..3f7aa9c 100644 --- a/pallets/network/src/tests/subnet_node.rs +++ b/pallets/network/src/tests/subnet_node.rs @@ -2355,8 +2355,8 @@ fn test_update_delegate_reward_rate() { let subnet_node = SubnetNodesData::::get(subnet_id, subnet_node_id); assert_eq!(subnet_node.delegate_reward_rate, 0); - // build_activated_subnet increases blocks by 10,000 - assert_eq!(subnet_node.last_delegate_reward_rate_update, 10000); + // build_activated_subnet increases blocks by 10,000 (not anymore) + assert_eq!(subnet_node.last_delegate_reward_rate_update, 0); let max_reward_rate_decrease = MaxRewardRateDecrease::::get(); diff --git a/pallets/network/src/tests/test_utils.rs b/pallets/network/src/tests/test_utils.rs index b9766ee..01ab8df 100644 --- a/pallets/network/src/tests/test_utils.rs +++ b/pallets/network/src/tests/test_utils.rs @@ -57,6 +57,7 @@ pub fn build_activated_subnet(subnet_path: Vec, start: u32, mut end: u32, de let block_number = System::block_number(); let epoch = System::block_number().saturating_div(epoch_length); let next_registration_epoch = Network::get_next_registration_epoch(epoch as u32); + log::error!("next_registration_epoch {:?}", next_registration_epoch); increase_epochs(next_registration_epoch - epoch as u32); let cost = Network::registration_cost(epoch as u32); @@ -422,12 +423,21 @@ pub fn post_subnet_removal_ensures(subnet_id: u32, start: u32, end: u32) { // } pub fn increase_epochs(epochs: u32) { + if epochs == 0 { + return + } let block = System::block_number(); let epoch_length = EpochLength::get(); let next_epoch_start_block = (epoch_length * epochs as u64) + block - (block % (epoch_length * epochs as u64)); System::set_block_number(next_epoch_start_block); } +pub fn set_epoch(epoch: u32) { + let epoch_length = EpochLength::get(); + System::set_block_number(epoch as u64 * epoch_length); +} + + pub fn make_subnet_submittable() { // increase blocks // let epoch_length = Network::EpochLength::get(); diff --git a/pallets/network/src/tests/utils.rs b/pallets/network/src/tests/utils.rs index bee0794..addbd6d 100644 --- a/pallets/network/src/tests/utils.rs +++ b/pallets/network/src/tests/utils.rs @@ -19,68 +19,189 @@ use crate::{ SubnetRegistrationInterval, }; -#[test] -fn test_get_min_subnet_nodes_scaled() { - new_test_ext().execute_with(|| { - let base_node_memory: u128 = BaseSubnetNodeMemoryMB::::get(); - let max_subnet_memory: u128 = MaxSubnetMemoryMB::::get(); - - let step = max_subnet_memory / 100; - let mut i = step; - - let mut last_min_subnet_nodes = 0; - - while i < max_subnet_memory { - let min_subnet_nodes = Network::get_min_subnet_nodes(base_node_memory, i); - log::error!( - "Min: {:?} Last Min: {:?} step: {:?}", - min_subnet_nodes, - last_min_subnet_nodes, - step - ); - - assert!( - min_subnet_nodes >= last_min_subnet_nodes, - "Min: {:?} Last Min: {:?} step: {:?}", - min_subnet_nodes, - last_min_subnet_nodes, - step - ); - last_min_subnet_nodes = min_subnet_nodes; - i += step; - } - }); -} +// #[test] +// fn test_get_min_subnet_nodes_scaled() { +// new_test_ext().execute_with(|| { +// let base_node_memory: u128 = BaseSubnetNodeMemoryMB::::get(); +// let max_subnet_memory: u128 = MaxSubnetMemoryMB::::get(); + +// let step = max_subnet_memory / 100; +// let mut i = step; + +// let mut last_min_subnet_nodes = 0; + +// while i < max_subnet_memory { +// let min_subnet_nodes = Network::get_min_subnet_nodes(base_node_memory, i); +// log::error!( +// "Min: {:?} Last Min: {:?} step: {:?}", +// min_subnet_nodes, +// last_min_subnet_nodes, +// step +// ); + +// assert!( +// min_subnet_nodes >= last_min_subnet_nodes, +// "Min: {:?} Last Min: {:?} step: {:?}", +// min_subnet_nodes, +// last_min_subnet_nodes, +// step +// ); +// last_min_subnet_nodes = min_subnet_nodes; +// i += step; +// } +// }); +// } + +// #[test] +// fn test_registration_cost() { +// new_test_ext().execute_with(|| { +// let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); +// let fee_min: u128 = MinSubnetRegistrationFee::::get(); +// let fee_max: u128 = MaxSubnetRegistrationFee::::get(); +// let period: u32 = SubnetRegistrationInterval::::get(); +// // increase_epochs(period); + +// let epoch_length = EpochLength::get(); +// let block_number = System::block_number(); +// let epoch = System::block_number().saturating_div(epoch_length); + +// // division is not perfect due to epoch values being so little +// let half_cycle_epoch = (period/2) as u32 % period; +// let half_decrease_per_epoch = (fee_max.saturating_sub(fee_min)) / period as u128; +// let half_fee = fee_max.saturating_sub(half_decrease_per_epoch * half_cycle_epoch as u128); + +// let cost = Network::registration_cost(0); +// assert_eq!(cost, fee_min); + +// // Period is 100 +// LastSubnetRegistrationEpoch::::set(period-1); +// let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); +// let next_registration_epoch = Network::get_next_registration_epoch(last_registration_epoch); + +// // At 100, fee should be max +// let cost = Network::registration_cost(next_registration_epoch); +// assert_eq!(cost, fee_max); + +// // middle of registration period +// let cost = Network::registration_cost(next_registration_epoch + (period/2)); +// assert_eq!(cost, half_fee); + +// // no registratin in current peroid, next period start should be min +// let cost = Network::registration_cost(next_registration_epoch + period); +// assert_eq!(cost, fee_min); + +// let cost = Network::registration_cost(next_registration_epoch + period + period/10); +// assert_eq!(cost, fee_min); + + +// // set to 150 +// LastSubnetRegistrationEpoch::::set(period+period/2); +// let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); +// let next_registration_epoch = Network::get_next_registration_epoch(last_registration_epoch); // 200 + +// // Between 150-200 shouldn't be able to register + + +// // At 200, fee should be max +// let cost = Network::registration_cost(next_registration_epoch); +// assert_eq!(cost, fee_max); + +// // middle of registration period +// let cost = Network::registration_cost(next_registration_epoch + (period/2)); +// assert_eq!(cost, half_fee); + +// // no registratin in current peroid, next period start should be min +// let cost = Network::registration_cost(next_registration_epoch + period); +// assert_eq!(cost, fee_min); + +// let cost = Network::registration_cost(next_registration_epoch + period + period/10); +// assert_eq!(cost, fee_min); + + +// }) +// } #[test] -fn test_registration_cost() { +fn test_registration_cost2() { new_test_ext().execute_with(|| { let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); let fee_min: u128 = MinSubnetRegistrationFee::::get(); let fee_max: u128 = MaxSubnetRegistrationFee::::get(); let period: u32 = SubnetRegistrationInterval::::get(); - increase_epochs(period); + // increase_epochs(period); let epoch_length = EpochLength::get(); let block_number = System::block_number(); let epoch = System::block_number().saturating_div(epoch_length); + // division is not perfect due to epoch values being so little + let half_cycle_epoch = (period/2) as u32 % period; + let half_decrease_per_epoch = (fee_max.saturating_sub(fee_min)) / period as u128; + let half_fee = fee_max.saturating_sub(half_decrease_per_epoch * half_cycle_epoch as u128); + let cost = Network::registration_cost(0); assert_eq!(cost, fee_max); - log::error!("cost is: {:?}", cost); - let cost = Network::registration_cost(epoch as u32 + period); + let cost = Network::registration_cost(period/2); + assert_eq!(cost, half_fee); + + let cost = Network::registration_cost(period); assert_eq!(cost, fee_min); - let cost = Network::registration_cost(period*100); + let cost = Network::registration_cost(period+1); assert_eq!(cost, fee_min); - // division is not perfect due to epoch values being so little - let cycle_epoch = (epoch as u32 + period/2) as u32 % period; - let decrease_per_epoch = (fee_max.saturating_sub(fee_min)) / period as u128; - - let cost = Network::registration_cost(epoch as u32 + period/2); - assert_eq!(cost, fee_max.saturating_sub(decrease_per_epoch * cycle_epoch as u128)); + let cost = Network::registration_cost(period+period/2); + assert_eq!(cost, fee_min); + + let cost = Network::registration_cost(period+period); + assert_eq!(cost, fee_min); + + // Period is 100 + LastSubnetRegistrationEpoch::::set(period-1); + let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); + let next_registration_epoch = Network::get_next_registration_epoch(last_registration_epoch); + + // At 100, fee should be max + let cost = Network::registration_cost(next_registration_epoch); + assert_eq!(cost, fee_max); + + // middle of registration period + let cost = Network::registration_cost(next_registration_epoch + (period/2)); + assert_eq!(cost, half_fee); + + // no registratin in current peroid, next period start should be min + let cost = Network::registration_cost(next_registration_epoch + period); + assert_eq!(cost, fee_min); + + let cost = Network::registration_cost(next_registration_epoch + period + period/10); + assert_eq!(cost, fee_min); + + + // set to 150 + LastSubnetRegistrationEpoch::::set(period+period/2); + let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); + let next_registration_epoch = Network::get_next_registration_epoch(last_registration_epoch); // 200 + + // Between 150-200 shouldn't be able to register + + + // At 200, fee should be max + let cost = Network::registration_cost(next_registration_epoch); + assert_eq!(cost, fee_max); + + // middle of registration period + let cost = Network::registration_cost(next_registration_epoch + (period/2)); + assert_eq!(cost, half_fee); + + // no registratin in current peroid, next period start should be min + let cost = Network::registration_cost(next_registration_epoch + period); + assert_eq!(cost, fee_min); + + let cost = Network::registration_cost(next_registration_epoch + period + period/10); + assert_eq!(cost, fee_min); + + }) } @@ -88,23 +209,41 @@ fn test_registration_cost() { fn test_get_next_registration_epoch() { new_test_ext().execute_with(|| { let last_registration_epoch: u32 = LastSubnetRegistrationEpoch::::get(); - let subnet_registration_fee_period: u32 = SubnetRegistrationInterval::::get(); + let period: u32 = SubnetRegistrationInterval::::get(); + // If no registrations yet, should return 0 to allow registration up to the SubnetRegistrationInterval let next_registration_epoch = Network::get_next_registration_epoch(0); - assert_eq!(next_registration_epoch, subnet_registration_fee_period); + assert_eq!(next_registration_epoch, 0); + + + LastSubnetRegistrationEpoch::::set(1); + + let next_registration_epoch = Network::get_next_registration_epoch(1); + assert_eq!(next_registration_epoch, period); + - let next_registration_epoch = Network::get_next_registration_epoch(subnet_registration_fee_period-1); - assert_eq!(next_registration_epoch, subnet_registration_fee_period); + LastSubnetRegistrationEpoch::::set(period); + let next_registration_epoch = Network::get_next_registration_epoch(period); + assert_eq!(next_registration_epoch, period*2); + + let next_registration_epoch = Network::get_next_registration_epoch(period-1); + assert_eq!(next_registration_epoch, period*2); + + + LastSubnetRegistrationEpoch::::set(period + period/2); + + let next_registration_epoch = Network::get_next_registration_epoch(period + period/2); + assert_eq!(next_registration_epoch, period*2); }) } -#[test] -fn test_get_target_subnet_nodes() { - new_test_ext().execute_with(|| { - let target_nodes = Network::get_target_subnet_nodes(10); - log::error!("target_nodes: {:?}", target_nodes); - assert!(target_nodes < 100); - }); -} +// #[test] +// fn test_get_target_subnet_nodes() { +// new_test_ext().execute_with(|| { +// let target_nodes = Network::get_target_subnet_nodes(10); +// log::error!("target_nodes: {:?}", target_nodes); +// assert!(target_nodes < 100); +// }); +// } diff --git a/pallets/network/src/utilities/subnet.rs b/pallets/network/src/utilities/subnet.rs index e3dae7b..b43599a 100644 --- a/pallets/network/src/utilities/subnet.rs +++ b/pallets/network/src/utilities/subnet.rs @@ -101,42 +101,92 @@ impl Pallet { } pub fn registration_cost(epoch: u32) -> u128 { - let period: u32 = SubnetRegistrationInterval::::get(); let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); - let next_registration_epoch = Self::get_next_registration_epoch(last_registration_epoch); let fee_min: u128 = MinSubnetRegistrationFee::::get(); + let fee_max: u128 = MaxSubnetRegistrationFee::::get(); + let period: u32 = SubnetRegistrationInterval::::get(); + + // Calculate the start of the next registration period + let next_registration_lower_bound_epoch = Self::get_next_registration_epoch(last_registration_epoch); + let next_registration_upper_bound_epoch = next_registration_lower_bound_epoch + period; - // If no registration within period, keep at `fee_min` - if epoch >= next_registration_epoch + period { - return fee_min + // If the current epoch is beyond the next registration period, return min fee + if epoch >= next_registration_upper_bound_epoch { + return fee_min; } - let fee_max: u128 = MaxSubnetRegistrationFee::::get(); + // Calculate the current position within the registration period + let cycle_epoch = epoch - next_registration_lower_bound_epoch; - // Epoch within the cycle - let cycle_epoch = epoch % period; - let decrease_per_epoch = (fee_max.saturating_sub(fee_min)).saturating_div(period as u128); - - let cost = fee_max.saturating_sub(decrease_per_epoch.saturating_mul(cycle_epoch as u128)); - // Ensures cost doesn't go below min + // Calculate the fee decrease per epoch + let decrease_per_epoch = (fee_max - fee_min) / period as u128; + + // Calculate the current fee + let cost = fee_max - (decrease_per_epoch * cycle_epoch as u128); + + // Ensure the fee doesn't go below the minimum cost.max(fee_min) } + // pub fn registration_cost(epoch: u32) -> u128 { + // let last_registration_epoch = LastSubnetRegistrationEpoch::::get(); + // let fee_min: u128 = MinSubnetRegistrationFee::::get(); + + // // First registration is min fee (possibly fix this) + // if last_registration_epoch == 0 { + // return fee_min + // } + + // // --- Get the nexr registration epoch based on the last subnet registered epoch + // // This can be lower than the current epoch if no registrations were in the previous period or prior to the previous period + // let next_registration_lower_bound_epoch = Self::get_next_registration_epoch(last_registration_epoch); + // let period: u32 = SubnetRegistrationInterval::::get(); + // let next_registration_upper_bound_epoch = next_registration_lower_bound_epoch + period; + + // // If no registration within period or previous periods, keep at `fee_min` + // // # Example + // // *`epoch`: 100 + // // *`next_registration_upper_bound_epoch`: 200 + // // *`period`: 100 + // if next_registration_upper_bound_epoch <= epoch { + // return fee_min + // } + + // let fee_max: u128 = MaxSubnetRegistrationFee::::get(); + + // // Epoch within the cycle + // let cycle_epoch = epoch % period; + // let decrease_per_epoch = (fee_max.saturating_sub(fee_min)).saturating_div(period as u128); + // let cost = fee_max.saturating_sub(decrease_per_epoch.saturating_mul(cycle_epoch as u128)); + + // // Ensures cost doesn't go below min + // cost.max(fee_min) + // } + + fn get_registration_cost( + current_epoch: u32, + last_registration_epoch: u32, + fee_min: u128, + fee_max: u128 + ) { + let next_registration_lower_bound_epoch = Self::get_next_registration_epoch(last_registration_epoch); + + } + pub fn can_subnet_register(current_epoch: u32) -> bool { current_epoch >= Self::get_next_registration_epoch(current_epoch) } + /// Get the next registration epoch based on an epoch pub fn get_next_registration_epoch(current_epoch: u32) -> u32 { let last_registration_epoch: u32 = LastSubnetRegistrationEpoch::::get(); + // --- Handle genesis + if last_registration_epoch == 0 { + return 0 + } let period: u32 = SubnetRegistrationInterval::::get(); - // // --- Genesis handling - // if last_registration_epoch < subnet_registration_fee_period { - // return 0 - // } - let next_valid_epoch = last_registration_epoch + ( + last_registration_epoch + ( period - (last_registration_epoch % period) - ); - next_valid_epoch + ) } - } \ No newline at end of file