diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 98bb64c263..2535ccb947 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -1209,7 +1209,7 @@ mod pallet_benchmarks { fn register_network_with_identity() { let coldkey: T::AccountId = whitelisted_caller(); let hotkey: T::AccountId = account("Alice", 0, 1); - let identity: Option = None; + let identity: Option = None; Subtensor::::set_network_registration_allowed(1.into(), true); Subtensor::::set_network_rate_limit(1); @@ -1315,6 +1315,7 @@ mod pallet_benchmarks { let descr = vec![]; let logo_url = vec![]; let add = vec![]; + let agent_docs_url = vec![]; SubnetOwner::::insert(netuid, coldkey.clone()); SubtokenEnabled::::insert(netuid, true); @@ -1331,6 +1332,7 @@ mod pallet_benchmarks { descr.clone(), logo_url.clone(), add.clone(), + agent_docs_url.clone(), ); } diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index e2714fba1b..73cb4bbefd 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -393,8 +393,8 @@ impl Pallet { let _ = LastHotkeySwapOnNetuid::::clear_prefix(netuid, u32::MAX, None); // --- 20. Identity maps across versions (netuid-scoped). - if SubnetIdentitiesV3::::contains_key(netuid) { - SubnetIdentitiesV3::::remove(netuid); + if SubnetIdentitiesV4::::contains_key(netuid) { + SubnetIdentitiesV4::::remove(netuid); Self::deposit_event(Event::SubnetIdentityRemoved(netuid)); } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index f27019989a..e4221b7b44 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -289,9 +289,9 @@ pub mod pallet { pub additional: Vec, } - /// Struct for SubnetIdentitiesV3. + /// Struct for SubnetIdentitiesV3. (DEPRECATED for V4) pub type SubnetIdentityOfV3 = SubnetIdentityV3; - /// Data structure for Subnet Identities + /// Data structure for Subnet Identities (DEPRECATED for V4) #[crate::freeze_struct("6a441335f985a0b")] #[derive( Encode, Decode, DecodeWithMemTracking, Default, TypeInfo, Clone, PartialEq, Eq, Debug, @@ -315,6 +315,34 @@ pub mod pallet { pub additional: Vec, } + /// Struct for SubnetIdentitiesV4. + pub type SubnetIdentityOfV4 = SubnetIdentityV4; + /// Data structure for Subnet Identities + #[crate::freeze_struct("4b9718ba1a9cb75f")] + #[derive( + Encode, Decode, DecodeWithMemTracking, Default, TypeInfo, Clone, PartialEq, Eq, Debug, + )] + pub struct SubnetIdentityV4 { + /// The name of the subnet + pub subnet_name: Vec, + /// The github repository associated with the subnet + pub github_repo: Vec, + /// The subnet's contact + pub subnet_contact: Vec, + /// The subnet's website + pub subnet_url: Vec, + /// The subnet's discord + pub discord: Vec, + /// The subnet's description + pub description: Vec, + /// The subnet's logo + pub logo_url: Vec, + /// Additional information about the subnet + pub additional: Vec, + /// The subnet's agent documentation URL + pub agent_docs_url: Vec, + } + /// Enum for recycle or burn for the owner_uid(s) #[derive(TypeInfo, Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug)] pub enum RecycleOrBurnEnum { @@ -2122,11 +2150,16 @@ pub mod pallet { pub type IdentitiesV2 = StorageMap<_, Blake2_128Concat, T::AccountId, ChainIdentityOfV2, OptionQuery>; - /// --- MAP ( netuid ) --> SubnetIdentityOfV3 + /// --- MAP ( netuid ) --> SubnetIdentityOfV3 (DEPRECATED for V4) #[pallet::storage] pub type SubnetIdentitiesV3 = StorageMap<_, Blake2_128Concat, NetUid, SubnetIdentityOfV3, OptionQuery>; + /// --- MAP ( netuid ) --> SubnetIdentityOfV4 + #[pallet::storage] + pub type SubnetIdentitiesV4 = + StorageMap<_, Blake2_128Concat, NetUid, SubnetIdentityOfV4, OptionQuery>; + /// ================================= /// ==== Axon / Promo Endpoints ===== /// ================================= diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index c53b5a1570..6ddfad450b 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1438,6 +1438,7 @@ mod dispatches { description: Vec, logo_url: Vec, additional: Vec, + agent_docs_url: Vec, ) -> DispatchResult { Self::do_set_subnet_identity( origin, @@ -1450,6 +1451,7 @@ mod dispatches { description, logo_url, additional, + agent_docs_url, ) } @@ -1461,7 +1463,7 @@ mod dispatches { pub fn register_network_with_identity( origin: OriginFor, hotkey: T::AccountId, - identity: Option, + identity: Option, ) -> DispatchResult { Self::do_register_network(origin, &hotkey, 1, identity) } diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 899e8d32f2..28c5f49b0e 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -166,7 +166,9 @@ mod hooks { // Fix staking hot keys .saturating_add(migrations::migrate_fix_staking_hot_keys::migrate_fix_staking_hot_keys::()) // Migrate coldkey swap scheduled to announcements - .saturating_add(migrations::migrate_coldkey_swap_scheduled_to_announcements::migrate_coldkey_swap_scheduled_to_announcements::()); + .saturating_add(migrations::migrate_coldkey_swap_scheduled_to_announcements::migrate_coldkey_swap_scheduled_to_announcements::()) + // Migrate SubnetIdentitiesV3 to SubnetIdentitiesV4 + .saturating_add(migrations::migrate_subnet_identity_v3_to_v4::migrate_subnet_identity_v3_to_v4::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_subnet_identity_v3_to_v4.rs b/pallets/subtensor/src/migrations/migrate_subnet_identity_v3_to_v4.rs new file mode 100644 index 0000000000..f3a0cf01ac --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_subnet_identity_v3_to_v4.rs @@ -0,0 +1,56 @@ +use super::*; +use crate::HasMigrationRun; +use frame_support::{traits::Get, weights::Weight}; +use scale_info::prelude::string::String; + +pub fn migrate_subnet_identity_v3_to_v4() -> Weight { + let migration_name = b"migrate_subnet_identity_v3_to_v4".to_vec(); + let mut weight = T::DbWeight::get().reads(1); + + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + String::from_utf8_lossy(&migration_name) + ); + return weight; + } + + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name), + ); + + let mut migrated_count: u64 = 0; + + for (netuid, v3_identity) in SubnetIdentitiesV3::::iter() { + let v4_identity = SubnetIdentityOfV4 { + subnet_name: v3_identity.subnet_name, + github_repo: v3_identity.github_repo, + subnet_contact: v3_identity.subnet_contact, + subnet_url: v3_identity.subnet_url, + discord: v3_identity.discord, + description: v3_identity.description, + logo_url: v3_identity.logo_url, + additional: v3_identity.additional, + agent_docs_url: vec![], + }; + SubnetIdentitiesV4::::insert(netuid, v4_identity); + migrated_count += 1; + } + + weight = weight.saturating_add(T::DbWeight::get().reads(migrated_count)); + weight = weight.saturating_add(T::DbWeight::get().writes(migrated_count)); + + // Remove old V3 entries + remove_prefix::("SubtensorModule", "SubnetIdentitiesV3", &mut weight); + + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed successfully. Migrated {migrated_count:?} subnet identities.", + String::from_utf8_lossy(&migration_name) + ); + + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index 23a2899b94..1923a11121 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -55,6 +55,7 @@ pub mod migrate_stake_threshold; pub mod migrate_subnet_limit_to_default; pub mod migrate_subnet_locked; pub mod migrate_subnet_symbols; +pub mod migrate_subnet_identity_v3_to_v4; pub mod migrate_subnet_volume; pub mod migrate_to_v1_separate_emission; pub mod migrate_to_v2_fixed_total_stake; diff --git a/pallets/subtensor/src/rpc_info/dynamic_info.rs b/pallets/subtensor/src/rpc_info/dynamic_info.rs index b143295425..9665b7ca83 100644 --- a/pallets/subtensor/src/rpc_info/dynamic_info.rs +++ b/pallets/subtensor/src/rpc_info/dynamic_info.rs @@ -6,7 +6,7 @@ use substrate_fixed::types::I96F32; use subtensor_macros::freeze_struct; use subtensor_runtime_common::{AlphaBalance, NetUid, TaoBalance}; -#[freeze_struct("cf677afa654c96a6")] +#[freeze_struct("1caba5f448641f8a")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct DynamicInfo { netuid: Compact, @@ -28,7 +28,7 @@ pub struct DynamicInfo { pending_root_emission: Compact, subnet_volume: Compact, network_registered_at: Compact, - subnet_identity: Option, + subnet_identity: Option, moving_price: I96F32, } @@ -68,7 +68,7 @@ impl Pallet { pending_root_emission: TaoBalance::ZERO.into(), subnet_volume: SubnetVolume::::get(netuid).into(), network_registered_at: NetworkRegisteredAt::::get(netuid).into(), - subnet_identity: SubnetIdentitiesV3::::get(netuid), + subnet_identity: SubnetIdentitiesV4::::get(netuid), moving_price: SubnetMovingPrice::::get(netuid), }) } diff --git a/pallets/subtensor/src/rpc_info/metagraph.rs b/pallets/subtensor/src/rpc_info/metagraph.rs index 4d82af629a..081ec463b2 100644 --- a/pallets/subtensor/src/rpc_info/metagraph.rs +++ b/pallets/subtensor/src/rpc_info/metagraph.rs @@ -10,7 +10,7 @@ use substrate_fixed::types::I96F32; use subtensor_macros::freeze_struct; use subtensor_runtime_common::{AlphaBalance, MechId, NetUid, NetUidStorageIndex, TaoBalance}; -#[freeze_struct("fbab6d1e7f3c69ae")] +#[freeze_struct("ef0a499c338d0215")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct Metagraph { // Subnet index @@ -19,7 +19,7 @@ pub struct Metagraph { // Name and symbol name: Vec>, // name symbol: Vec>, // token symbol - identity: Option, // identity information. + identity: Option, // identity information. network_registered_at: Compact, // block at registration // Keys for owner. @@ -110,7 +110,7 @@ pub struct Metagraph { alpha_dividends_per_hotkey: Vec<(AccountId, Compact)>, // List of dividend payout in alpha via subnet. } -#[freeze_struct("3ff2befdb7b393ea")] +#[freeze_struct("25b9044298e38eeb")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SelectiveMetagraph { // Subnet index @@ -119,7 +119,7 @@ pub struct SelectiveMetagraph { // Name and symbol name: Option>>, // name symbol: Option>>, // token symbol - identity: Option>, // identity information + identity: Option>, // identity information network_registered_at: Option>, // block at registration // Keys for owner. @@ -673,7 +673,7 @@ impl Pallet { .into_iter() .map(Compact) .collect(), // Symbol. - identity: SubnetIdentitiesV3::::get(netuid), // identity information. + identity: SubnetIdentitiesV4::::get(netuid), // identity information. network_registered_at: NetworkRegisteredAt::::get(netuid).into(), // block at registration // Keys for owner. @@ -916,7 +916,7 @@ impl Pallet { }, Some(SelectiveMetagraphIndex::Identity) => SelectiveMetagraph { netuid: netuid.into(), - identity: Some(SubnetIdentitiesV3::::get(netuid)), + identity: Some(SubnetIdentitiesV4::::get(netuid)), ..Default::default() }, Some(SelectiveMetagraphIndex::NetworkRegisteredAt) => SelectiveMetagraph { diff --git a/pallets/subtensor/src/rpc_info/subnet_info.rs b/pallets/subtensor/src/rpc_info/subnet_info.rs index db595eb98e..f56ba47657 100644 --- a/pallets/subtensor/src/rpc_info/subnet_info.rs +++ b/pallets/subtensor/src/rpc_info/subnet_info.rs @@ -29,7 +29,7 @@ pub struct SubnetInfo { owner: AccountId, } -#[freeze_struct("e8e028bf4fbc6741")] +#[freeze_struct("ab2a1adcd6970bc9")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct SubnetInfov2 { netuid: Compact, @@ -50,7 +50,7 @@ pub struct SubnetInfov2 { emission_value: Compact, burn: Compact, owner: AccountId, - identity: Option, + identity: Option, } #[freeze_struct("fd2db338b156d251")] @@ -210,7 +210,7 @@ impl Pallet { let blocks_since_last_step = Self::get_blocks_since_last_step(netuid); let tempo = Self::get_tempo(netuid); let burn = Compact::from(Self::get_burn(netuid)); - let identity: Option = SubnetIdentitiesV3::::get(netuid); + let identity: Option = SubnetIdentitiesV4::::get(netuid); // DEPRECATED let network_connect: Vec<[u16; 2]> = Vec::<[u16; 2]>::new(); diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index 769db17ebe..1ca4383d68 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -92,7 +92,7 @@ impl Pallet { /// * **`origin`** – `T::RuntimeOrigin`  Must be **signed** by the coldkey. /// * **`hotkey`** – `&T::AccountId`  First neuron of the new subnet. /// * **`mechid`** – `u16`  Only the dynamic mechanism (`1`) is currently supported. - /// * **`identity`** – `Option`  Optional metadata for the subnet. + /// * **`identity`** – `Option`  Optional metadata for the subnet. /// /// ### Events /// * `NetworkAdded(netuid, mechid)` – always. @@ -112,7 +112,7 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: &T::AccountId, mechid: u16, - identity: Option, + identity: Option, ) -> DispatchResult { // --- 1. Ensure the caller is a signed user. let coldkey = ensure_signed(origin)?; @@ -242,7 +242,7 @@ impl Pallet { Error::::InvalidIdentity ); - SubnetIdentitiesV3::::insert(netuid_to_register, identity_value); + SubnetIdentitiesV4::::insert(netuid_to_register, identity_value); Self::deposit_event(Event::SubnetIdentitySet(netuid_to_register)); } diff --git a/pallets/subtensor/src/subnets/symbols.rs b/pallets/subtensor/src/subnets/symbols.rs index 6fd3e82f56..ee1c31443e 100644 --- a/pallets/subtensor/src/subnets/symbols.rs +++ b/pallets/subtensor/src/subnets/symbols.rs @@ -470,7 +470,7 @@ pub static SYMBOLS: [&[u8]; 439] = [ /// Returns the Unicode symbol as a Vec for a given netuid. impl Pallet { pub fn get_name_for_subnet(netuid: NetUid) -> Vec { - SubnetIdentitiesV3::::try_get(netuid) + SubnetIdentitiesV4::::try_get(netuid) .and_then(|identity| { if !identity.subnet_name.is_empty() { Ok(identity.subnet_name) diff --git a/pallets/subtensor/src/tests/serving.rs b/pallets/subtensor/src/tests/serving.rs index 2979d4438c..6263583fb5 100644 --- a/pallets/subtensor/src/tests/serving.rs +++ b/pallets/subtensor/src/tests/serving.rs @@ -945,11 +945,12 @@ fn test_do_set_subnet_identity() { description.clone(), logo_url.clone(), additional.clone(), + vec![], )); // Check if subnet identity is set correctly let stored_identity = - SubnetIdentitiesV3::::get(netuid).expect("Subnet identity should be set"); + SubnetIdentitiesV4::::get(netuid).expect("Subnet identity should be set"); assert_eq!(stored_identity.subnet_name, subnet_name); assert_eq!(stored_identity.github_repo, github_repo); assert_eq!(stored_identity.subnet_contact, subnet_contact); @@ -969,6 +970,7 @@ fn test_do_set_subnet_identity() { description.clone(), logo_url.clone(), additional.clone(), + vec![], ), Error::::NotSubnetOwner ); @@ -987,10 +989,11 @@ fn test_do_set_subnet_identity() { description.clone(), logo_url.clone(), additional.clone(), + vec![], )); let updated_identity = - SubnetIdentitiesV3::::get(netuid).expect("Updated subnet identity should be set"); + SubnetIdentitiesV4::::get(netuid).expect("Updated subnet identity should be set"); assert_eq!(updated_identity.subnet_name, new_subnet_name); assert_eq!(updated_identity.github_repo, new_github_repo); assert_eq!(updated_identity.logo_url, logo_url); @@ -1009,6 +1012,7 @@ fn test_do_set_subnet_identity() { long_data.clone(), long_data.clone(), long_data.clone(), + long_data.clone(), ), Error::::InvalidIdentity ); @@ -1020,7 +1024,7 @@ fn test_do_set_subnet_identity() { fn test_is_valid_subnet_identity() { new_test_ext(1).execute_with(|| { // Test valid subnet identity - let valid_identity = SubnetIdentityV3 { + let valid_identity = SubnetIdentityV4 { subnet_name: vec![0; 256], github_repo: vec![0; 1024], subnet_contact: vec![0; 1024], @@ -1029,11 +1033,12 @@ fn test_is_valid_subnet_identity() { description: vec![0; 1024], logo_url: vec![0; 1024], additional: vec![0; 1024], + agent_docs_url: vec![0; 1024], }; assert!(SubtensorModule::is_valid_subnet_identity(&valid_identity)); // Test subnet identity with total length exactly at the maximum - let max_length_identity = SubnetIdentityV3 { + let max_length_identity = SubnetIdentityV4 { subnet_name: vec![0; 256], github_repo: vec![0; 1024], subnet_contact: vec![0; 1024], @@ -1042,13 +1047,14 @@ fn test_is_valid_subnet_identity() { description: vec![0; 1024], logo_url: vec![0; 1024], additional: vec![0; 1024], + agent_docs_url: vec![0; 1024], }; assert!(SubtensorModule::is_valid_subnet_identity( &max_length_identity )); // Test subnet identity with total length exceeding the maximum - let invalid_length_identity = SubnetIdentityV3 { + let invalid_length_identity = SubnetIdentityV4 { subnet_name: vec![0; 257], github_repo: vec![0; 1024], subnet_contact: vec![0; 1024], @@ -1057,13 +1063,14 @@ fn test_is_valid_subnet_identity() { description: vec![0; 1024], logo_url: vec![0; 1024], additional: vec![0; 1024], + agent_docs_url: vec![0; 1024], }; assert!(!SubtensorModule::is_valid_subnet_identity( &invalid_length_identity )); // Test subnet identity with one field exceeding its maximum - let invalid_field_identity = SubnetIdentityV3 { + let invalid_field_identity = SubnetIdentityV4 { subnet_name: vec![0; 257], github_repo: vec![0; 1024], subnet_contact: vec![0; 1024], @@ -1072,13 +1079,14 @@ fn test_is_valid_subnet_identity() { description: vec![0; 1024], logo_url: vec![0; 1024], additional: vec![0; 1024], + agent_docs_url: vec![0; 1024], }; assert!(!SubtensorModule::is_valid_subnet_identity( &invalid_field_identity )); // Test subnet identity with empty fields - let empty_identity = SubnetIdentityV3 { + let empty_identity = SubnetIdentityV4 { subnet_name: vec![], github_repo: vec![], subnet_contact: vec![], @@ -1087,11 +1095,12 @@ fn test_is_valid_subnet_identity() { description: vec![], logo_url: vec![], additional: vec![], + agent_docs_url: vec![], }; assert!(SubtensorModule::is_valid_subnet_identity(&empty_identity)); // Test subnet identity with some empty and some filled fields - let mixed_identity = SubnetIdentityV3 { + let mixed_identity = SubnetIdentityV4 { subnet_name: b"Test Subnet".to_vec(), github_repo: vec![], subnet_contact: b"contact@testsubnet.com".to_vec(), @@ -1100,8 +1109,25 @@ fn test_is_valid_subnet_identity() { description: b"A description".to_vec(), logo_url: vec![], additional: vec![], + agent_docs_url: vec![], }; assert!(SubtensorModule::is_valid_subnet_identity(&mixed_identity)); + + // Test subnet identity with agent_docs_url exceeding max + let invalid_agent_docs = SubnetIdentityV4 { + subnet_name: vec![], + github_repo: vec![], + subnet_contact: vec![], + subnet_url: vec![], + discord: vec![], + description: vec![], + logo_url: vec![], + additional: vec![], + agent_docs_url: vec![0; 1025], + }; + assert!(!SubtensorModule::is_valid_subnet_identity( + &invalid_agent_docs + )); }); } @@ -1134,6 +1160,7 @@ fn test_set_identity_for_non_existent_subnet() { description.clone(), logo_url.clone(), additional.clone(), + vec![], ), Error::::NotSubnetOwner // Since there's no owner, it should fail ); @@ -1163,6 +1190,7 @@ fn test_set_subnet_identity_dispatch_info_ok() { description, logo_url, additional, + agent_docs_url: vec![], }); let dispatch_info: DispatchInfo = call.get_dispatch_info(); diff --git a/pallets/subtensor/src/utils/identity.rs b/pallets/subtensor/src/utils/identity.rs index 1904d0e682..e0b9ec3dab 100644 --- a/pallets/subtensor/src/utils/identity.rs +++ b/pallets/subtensor/src/utils/identity.rs @@ -106,6 +106,7 @@ impl Pallet { description: Vec, logo_url: Vec, additional: Vec, + agent_docs_url: Vec, ) -> dispatch::DispatchResult { // Ensure the call is signed and get the signer's (coldkey) account let coldkey = ensure_signed(origin)?; @@ -117,7 +118,7 @@ impl Pallet { ); // Create the identity struct with the provided information - let identity: SubnetIdentityOfV3 = SubnetIdentityOfV3 { + let identity: SubnetIdentityOfV4 = SubnetIdentityOfV4 { subnet_name, github_repo, subnet_contact, @@ -126,6 +127,7 @@ impl Pallet { description, logo_url, additional, + agent_docs_url, }; // Validate the created identity @@ -135,7 +137,7 @@ impl Pallet { ); // Store the validated identity in the blockchain state - SubnetIdentitiesV3::::insert(netuid, identity.clone()); + SubnetIdentitiesV4::::insert(netuid, identity.clone()); // Log the identity set event log::debug!("SubnetIdentitySet( netuid:{netuid:?} ) "); @@ -188,20 +190,20 @@ impl Pallet { && identity.additional.len() <= 1024 } - /// Validates the given SubnetIdentityOfV3 struct. + /// Validates the given SubnetIdentityOfV4 struct. /// - /// This function checks if the total length of all fields in the SubnetIdentityOfV3 struct - /// is less than or equal to 2304 bytes, and if each individual field is also - /// within its respective maximum byte limit. + /// This function checks if the total length of all fields in the SubnetIdentityOfV4 struct + /// is within limits, and if each individual field is also within its respective maximum + /// byte limit. /// /// # Arguments /// - /// * `identity` - A reference to the SubnetIdentityOfV3 struct to be validated. + /// * `identity` - A reference to the SubnetIdentityOfV4 struct to be validated. /// /// # Returns /// - /// * `bool` - Returns true if the SubnetIdentityV3 is valid, false otherwise. - pub fn is_valid_subnet_identity(identity: &SubnetIdentityOfV3) -> bool { + /// * `bool` - Returns true if the SubnetIdentityV4 is valid, false otherwise. + pub fn is_valid_subnet_identity(identity: &SubnetIdentityOfV4) -> bool { let total_length = identity .subnet_name .len() @@ -215,6 +217,7 @@ impl Pallet { .saturating_add(256) .saturating_add(1024) .saturating_add(1024) + .saturating_add(1024) .saturating_add(1024); total_length <= max_length @@ -226,5 +229,6 @@ impl Pallet { && identity.description.len() <= 1024 && identity.logo_url.len() <= 1024 && identity.additional.len() <= 1024 + && identity.agent_docs_url.len() <= 1024 } } diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index 79c08c2625..4114dd4333 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -99,7 +99,7 @@ where additional: BoundedString>, ) -> EvmResult<()> { let hotkey = R::AccountId::from(hotkey.0); - let identity = pallet_subtensor::SubnetIdentityOfV3 { + let identity = pallet_subtensor::SubnetIdentityOfV4 { subnet_name: subnet_name.into(), github_repo: github_repo.into(), subnet_contact: subnet_contact.into(), @@ -108,6 +108,7 @@ where description: description.into(), logo_url: vec![], additional: additional.into(), + agent_docs_url: vec![], }; let call = pallet_subtensor::Call::::register_network_with_identity { @@ -139,7 +140,7 @@ where logo_url: BoundedString>, ) -> EvmResult<()> { let hotkey = R::AccountId::from(hotkey.0); - let identity = pallet_subtensor::SubnetIdentityOfV3 { + let identity = pallet_subtensor::SubnetIdentityOfV4 { subnet_name: subnet_name.into(), github_repo: github_repo.into(), subnet_contact: subnet_contact.into(), @@ -148,6 +149,7 @@ where description: description.into(), logo_url: logo_url.into(), additional: additional.into(), + agent_docs_url: vec![], }; let call = pallet_subtensor::Call::::register_network_with_identity { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 4bbb6a88c8..72529057e9 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -268,7 +268,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 391, + spec_version: 392, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 1da1c4cdcc..1b01f9ffe6 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -82,6 +82,7 @@ fn call_set_subnet_identity() -> RuntimeCall { description: vec![], logo_url: vec![], additional: vec![], + agent_docs_url: vec![], }) }