diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index c62d1dcec..a2cd078c4 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -1355,4 +1355,20 @@ mod pallet_benchmarks { #[extrinsic_call] _(RawOrigin::Signed(coldkey), hotkey); } + + #[benchmark] + fn update_symbol() { + let coldkey: T::AccountId = whitelisted_caller(); + let netuid = NetUid::from(1); + let tempo: u16 = 1; + Subtensor::::init_new_network(netuid, tempo); + SubnetOwner::::insert(netuid, coldkey.clone()); + + let new_symbol = Subtensor::::get_symbol_for_subnet(NetUid::from(42)); + + #[extrinsic_call] + _(RawOrigin::Signed(coldkey), netuid, new_symbol.clone()); + + assert_eq!(TokenSymbol::::get(netuid), new_symbol); + } } diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 8ceccc5fa..a9254e840 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -6,6 +6,7 @@ use frame_support::pallet_macros::pallet_section; /// This can later be imported into the pallet using [`import_section`]. #[pallet_section] mod dispatches { + use crate::subnets::symbols::SYMBOLS; use frame_support::traits::schedule::DispatchTime; use frame_support::traits::schedule::v3::Anon as ScheduleAnon; use frame_system::pallet_prelude::BlockNumberFor; @@ -2069,5 +2070,53 @@ mod dispatches { PendingChildKeyCooldown::::put(cooldown); Ok(()) } + + /// Updates the symbol for a subnet. + /// + /// # Arguments + /// * `origin` - The origin of the call, which must be the subnet owner or root. + /// * `netuid` - The unique identifier of the subnet on which the symbol is being set. + /// * `symbol` - The symbol to set for the subnet. + /// + /// # Errors + /// Returns an error if: + /// * The transaction is not signed by the subnet owner. + /// * The symbol does not exist. + /// * The symbol is already in use by another subnet. + /// + /// # Events + /// Emits a `SymbolUpdated` event on success. + #[pallet::call_index(110)] + #[pallet::weight(( + Weight::from_parts(10_000, 0).saturating_add(T::DbWeight::get().reads_writes(2, 1)), + DispatchClass::Operational, + Pays::Yes + ))] + pub fn update_symbol( + origin: OriginFor, + netuid: NetUid, + symbol: Vec, + ) -> DispatchResult { + Self::ensure_subnet_owner_or_root(origin, netuid)?; + + if SYMBOLS + .iter() + .skip(1) // Skip the root symbol + .find(|s| *s == &symbol) + .is_none() + { + return Err(Error::::SymbolDoesNotExist.into()); + } + + let used_symbols = TokenSymbol::::iter_values().collect::>(); + if used_symbols.contains(&symbol) { + return Err(Error::::SymbolAlreadyInUse.into()); + } + + TokenSymbol::::insert(netuid, symbol.clone()); + + Self::deposit_event(Event::SymbolUpdated { netuid, symbol }); + Ok(()) + } } } diff --git a/pallets/subtensor/src/macros/errors.rs b/pallets/subtensor/src/macros/errors.rs index fd7bc12e1..08793bafa 100644 --- a/pallets/subtensor/src/macros/errors.rs +++ b/pallets/subtensor/src/macros/errors.rs @@ -218,5 +218,9 @@ mod errors { SameNetuid, /// The caller does not have enough balance for the operation. InsufficientBalance, + /// Symbol does not exist. + SymbolDoesNotExist, + /// Symbol already in use. + SymbolAlreadyInUse, } } diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index 3f3c71860..82bc7003a 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -353,5 +353,13 @@ mod events { /// the subnet ID netuid: NetUid, }, + + /// The symbol for a subnet has been updated. + SymbolUpdated { + /// The subnet ID + netuid: NetUid, + /// The symbol that has been updated + symbol: Vec, + }, } } diff --git a/pallets/subtensor/src/rpc_info/dynamic_info.rs b/pallets/subtensor/src/rpc_info/dynamic_info.rs index e6838404d..e4d83cb2c 100644 --- a/pallets/subtensor/src/rpc_info/dynamic_info.rs +++ b/pallets/subtensor/src/rpc_info/dynamic_info.rs @@ -48,7 +48,7 @@ impl Pallet { .into_iter() .map(Compact) .collect(), - token_symbol: Self::get_symbol_for_subnet(netuid) + token_symbol: TokenSymbol::::get(netuid) .into_iter() .map(Compact) .collect(), diff --git a/pallets/subtensor/src/rpc_info/metagraph.rs b/pallets/subtensor/src/rpc_info/metagraph.rs index d910bbaff..0cce4856f 100644 --- a/pallets/subtensor/src/rpc_info/metagraph.rs +++ b/pallets/subtensor/src/rpc_info/metagraph.rs @@ -659,7 +659,7 @@ impl Pallet { .into_iter() .map(Compact) .collect(), // Name - symbol: Self::get_symbol_for_subnet(netuid) + symbol: TokenSymbol::::get(netuid) .into_iter() .map(Compact) .collect(), // Symbol. @@ -835,7 +835,7 @@ impl Pallet { Some(SelectiveMetagraphIndex::Symbol) => SelectiveMetagraph { netuid: netuid.into(), symbol: Some( - Self::get_symbol_for_subnet(netuid) + TokenSymbol::::get(netuid) .into_iter() .map(Compact) .collect(), diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index db3e31995..70855c69a 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -148,23 +148,23 @@ impl Pallet { Error::::NotEnoughBalanceToStake ); - // --- 5. Determine the netuid to register. + // --- 6. Determine the netuid to register. let netuid_to_register = Self::get_next_netuid(); - // --- 6. Perform the lock operation. + // --- 7. Perform the lock operation. let actual_tao_lock_amount: u64 = Self::remove_balance_from_coldkey_account(&coldkey, lock_amount)?; log::debug!("actual_tao_lock_amount: {:?}", actual_tao_lock_amount); - // --- 7. Set the lock amount for use to determine pricing. + // --- 8. Set the lock amount for use to determine pricing. Self::set_network_last_lock(actual_tao_lock_amount); - // --- 8. Set initial and custom parameters for the network. + // --- 9. Set initial and custom parameters for the network. let default_tempo = DefaultTempo::::get(); Self::init_new_network(netuid_to_register, default_tempo); log::debug!("init_new_network: {:?}", netuid_to_register); - // --- 9 . Add the caller to the neuron set. + // --- 10. Add the caller to the neuron set. Self::create_account_if_non_existent(&coldkey, hotkey); Self::append_neuron(netuid_to_register, hotkey, current_block); log::debug!( @@ -173,7 +173,7 @@ impl Pallet { hotkey ); - // --- 10. Set the mechanism. + // --- 11. Set the mechanism. SubnetMechanism::::insert(netuid_to_register, mechid); log::debug!( "SubnetMechanism for netuid {:?} set to: {:?}", @@ -181,16 +181,15 @@ impl Pallet { mechid ); - // --- 11. Set the creation terms. + // --- 12. Set the creation terms. NetworkLastRegistered::::set(current_block); NetworkRegisteredAt::::insert(netuid_to_register, current_block); - // --- 14. Init the pool by putting the lock as the initial alpha. - TokenSymbol::::insert( - netuid_to_register, - Self::get_symbol_for_subnet(netuid_to_register), - ); // Set subnet token symbol. + // --- 13. Set the symbol. + let symbol = Self::get_next_available_symbol(netuid_to_register); + TokenSymbol::::insert(netuid_to_register, symbol); + // --- 14. Init the pool by putting the lock as the initial alpha. // Put initial TAO from lock into subnet TAO and produce numerically equal amount of Alpha // The initial TAO is the locked amount, with a minimum of 1 RAO and a cap of 100 TAO. let pool_initial_tao = Self::get_network_min_lock(); diff --git a/pallets/subtensor/src/subnets/symbols.rs b/pallets/subtensor/src/subnets/symbols.rs index bd88839a6..7bbc160b1 100644 --- a/pallets/subtensor/src/subnets/symbols.rs +++ b/pallets/subtensor/src/subnets/symbols.rs @@ -1,6 +1,472 @@ use super::*; +use sp_std::collections::btree_set::BTreeSet; use subtensor_runtime_common::NetUid; +// TODO: default symbol should be different from the root symbol? +pub static DEFAULT_SYMBOL: &[u8] = b"\xCE\xA4"; // TAO uppercase symbol + +pub static SYMBOLS: [&[u8]; 439] = [ + // Greek Alphabet (Lowercase) + DEFAULT_SYMBOL, // Τ (Upper case Tau, 0) + b"\xCE\xB1", // α (Alpha, 1) + b"\xCE\xB2", // β (Beta, 2) + b"\xCE\xB3", // γ (Gamma, 3) + b"\xCE\xB4", // δ (Delta, 4) + b"\xCE\xB5", // ε (Epsilon, 5) + b"\xCE\xB6", // ζ (Zeta, 6) + b"\xCE\xB7", // η (Eta, 7) + b"\xCE\xB8", // θ (Theta, 8) + b"\xCE\xB9", // ι (Iota, 9) + b"\xCE\xBA", // κ (Kappa, 10) + b"\xCE\xBB", // λ (Lambda, 11) + b"\xCE\xBC", // μ (Mu, 12) + b"\xCE\xBD", // ν (Nu, 13) + b"\xCE\xBE", // ξ (Xi, 14) + b"\xCE\xBF", // ο (Omicron, 15) + b"\xCF\x80", // π (Pi, 16) + b"\xCF\x81", // ρ (Rho, 17) + b"\xCF\x83", // σ (Sigma, 18) + b"t", // t (Tau, 19) + b"\xCF\x85", // υ (Upsilon, 20) + b"\xCF\x86", // φ (Phi, 21) + b"\xCF\x87", // χ (Chi, 22) + b"\xCF\x88", // ψ (Psi, 23) + b"\xCF\x89", // ω (Omega, 24) + // Hebrew Alphabet (Including Final Forms) + b"\xD7\x90", // א (Aleph, 25) + b"\xD7\x91", // ב (Bet, 26) + b"\xD7\x92", // ג (Gimel, 27) + b"\xD7\x93", // ד (Dalet, 28) + b"\xD7\x94", // ה (He, 29) + b"\xD7\x95", // ו (Vav, 30) + b"\xD7\x96", // ז (Zayin, 31) + b"\xD7\x97", // ח (Het, 32) + b"\xD7\x98", // ט (Tet, 33) + b"\xD7\x99", // י (Yod, 34) + b"\xD7\x9A", // ך (Final Kaf, 35) + b"\xD7\x9B", // כ (Kaf, 36) + b"\xD7\x9C", // ל (Lamed, 37) + b"\xD7\x9D", // ם (Final Mem, 38) + b"\xD7\x9E", // מ (Mem, 39) + b"\xD7\x9F", // ן (Final Nun, 40) + b"\xD7\xA0", // נ (Nun, 41) + b"\xD7\xA1", // ס (Samekh, 42) + b"\xD7\xA2", // ע (Ayin, 43) + b"\xD7\xA3", // ף (Final Pe, 44) + b"\xD7\xA4", // פ (Pe, 45) + b"\xD7\xA5", // ץ (Final Tsadi, 46) + b"\xD7\xA6", // צ (Tsadi, 47) + b"\xD7\xA7", // ק (Qof, 48) + b"\xD7\xA8", // ר (Resh, 49) + b"\xD7\xA9", // ש (Shin, 50) + b"\xD7\xAA", // ת (Tav, 51) + // Arabic Alphabet + b"\xD8\xA7", // ا (Alif, 52) + b"\xD8\xA8", // ب (Ba, 53) + b"\xD8\xAA", // ت (Ta, 54) + b"\xD8\xAB", // ث (Tha, 55) + b"\xD8\xAC", // ج (Jim, 56) + b"\xD8\xAD", // ح (Ha, 57) + b"\xD8\xAE", // خ (Kha, 58) + b"\xD8\xAF", // د (Dal, 59) + b"\xD8\xB0", // ذ (Dhal, 60) + b"\xD8\xB1", // ر (Ra, 61) + b"\xD8\xB2", // ز (Zay, 62) + b"\xD8\xB3", // س (Sin, 63) + b"\xD8\xB4", // ش (Shin, 64) + b"\xD8\xB5", // ص (Sad, 65) + b"\xD8\xB6", // ض (Dad, 66) + b"\xD8\xB7", // ط (Ta, 67) + b"\xD8\xB8", // ظ (Dha, 68) + b"\xD8\xB9", // ع (Ain, 69) + b"\xD8\xBA", // غ (Ghayn, 70) + b"\xD9\x81", // ف (Fa, 71) + b"\xD9\x82", // ق (Qaf, 72) + b"\xD9\x83", // ك (Kaf, 73) + b"\xD9\x84", // ل (Lam, 74) + b"\xD9\x85", // م (Mim, 75) + b"\xD9\x86", // ن (Nun, 76) + b"\xD9\x87", // ه (Ha, 77) + b"\xD9\x88", // و (Waw, 78) + b"\xD9\x8A", // ي (Ya, 79) + b"\xD9\x89", // ى (Alef Maksura, 80) + // Runic Alphabet + b"\xE1\x9A\xA0", // ᚠ (Fehu, wealth, 81) + b"\xE1\x9A\xA2", // ᚢ (Uruz, strength, 82) + b"\xE1\x9A\xA6", // ᚦ (Thurisaz, giant, 83) + b"\xE1\x9A\xA8", // ᚨ (Ansuz, god, 84) + b"\xE1\x9A\xB1", // ᚱ (Raidho, ride, 85) + b"\xE1\x9A\xB3", // ᚲ (Kaunan, ulcer, 86) + b"\xD0\xAB", // Ы (Cyrillic Yeru, 87) + b"\xE1\x9B\x89", // ᛉ (Algiz, protection, 88) + b"\xE1\x9B\x92", // ᛒ (Berkanan, birch, 89) + // Ogham Alphabet + b"\xE1\x9A\x80", //   (Space, 90) + b"\xE1\x9A\x81", // ᚁ (Beith, birch, 91) + b"\xE1\x9A\x82", // ᚂ (Luis, rowan, 92) + b"\xE1\x9A\x83", // ᚃ (Fearn, alder, 93) + b"\xE1\x9A\x84", // ᚄ (Sail, willow, 94) + b"\xE1\x9A\x85", // ᚅ (Nion, ash, 95) + b"\xE1\x9A\x9B", // ᚛ (Forfeda, 96) + // Georgian Alphabet (Mkhedruli) + b"\xE1\x83\x90", // ა (Ani, 97) + b"\xE1\x83\x91", // ბ (Bani, 98) + b"\xE1\x83\x92", // გ (Gani, 99) + b"\xE1\x83\x93", // დ (Doni, 100) + b"\xE1\x83\x94", // ე (Eni, 101) + b"\xE1\x83\x95", // ვ (Vini, 102) + // Armenian Alphabet + b"\xD4\xB1", // Ա (Ayp, 103) + b"\xD4\xB2", // Բ (Ben, 104) + b"\xD4\xB3", // Գ (Gim, 105) + b"\xD4\xB4", // Դ (Da, 106) + b"\xD4\xB5", // Ե (Ech, 107) + b"\xD4\xB6", // Զ (Za, 108) + b"\xD5\x9E", // ՞ (Question mark, 109) + // Cyrillic Alphabet + b"\xD0\x80", // Ѐ (Ie with grave, 110) + b"\xD0\x81", // Ё (Io, 111) + b"\xD0\x82", // Ђ (Dje, 112) + b"\xD0\x83", // Ѓ (Gje, 113) + b"\xD0\x84", // Є (Ukrainian Ie, 114) + b"\xD0\x85", // Ѕ (Dze, 115) + b"\xD1\x8A", // Ъ (Hard sign, 116) + // Coptic Alphabet + b"\xE2\xB2\x80", // Ⲁ (Alfa, 117) + b"\xE2\xB2\x81", // ⲁ (Small Alfa, 118) + b"\xE2\xB2\x82", // Ⲃ (Vida, 119) + b"\xE2\xB2\x83", // ⲃ (Small Vida, 120) + b"\xE2\xB2\x84", // Ⲅ (Gamma, 121) + b"\xE2\xB2\x85", // ⲅ (Small Gamma, 122) + // Brahmi Script + b"\xF0\x91\x80\x80", // 𑀀 (A, 123) + b"\xF0\x91\x80\x81", // 𑀁 (Aa, 124) + b"\xF0\x91\x80\x82", // 𑀂 (I, 125) + b"\xF0\x91\x80\x83", // 𑀃 (Ii, 126) + b"\xF0\x91\x80\x85", // 𑀅 (U, 127) + // End of Sinhala Alphabet + b"\xE0\xB6\xB1", // ඲ (La, 128) + b"\xE0\xB6\xB2", // ඳ (Va, 129) + b"\xE0\xB6\xB3", // ප (Sha, 130) + b"\xE0\xB6\xB4", // ඵ (Ssa, 131) + b"\xE0\xB6\xB5", // බ (Sa, 132) + b"\xE0\xB6\xB6", // භ (Ha, 133) + // Glagolitic Alphabet + b"\xE2\xB0\x80", // Ⰰ (Az, 134) + b"\xE2\xB0\x81", // Ⰱ (Buky, 135) + b"\xE2\xB0\x82", // Ⰲ (Vede, 136) + b"\xE2\xB0\x83", // Ⰳ (Glagoli, 137) + b"\xE2\xB0\x84", // Ⰴ (Dobro, 138) + b"\xE2\xB0\x85", // Ⰵ (Yest, 139) + b"\xE2\xB0\x86", // Ⰶ (Zhivete, 140) + b"\xE2\xB0\x87", // Ⰷ (Zemlja, 141) + b"\xE2\xB0\x88", // Ⰸ (Izhe, 142) + b"\xE2\xB0\x89", // Ⰹ (Initial Izhe, 143) + b"\xE2\xB0\x8A", // Ⰺ (I, 144) + b"\xE2\xB0\x8B", // Ⰻ (Djerv, 145) + b"\xE2\xB0\x8C", // Ⰼ (Kako, 146) + b"\xE2\xB0\x8D", // Ⰽ (Ljudije, 147) + b"\xE2\xB0\x8E", // Ⰾ (Myse, 148) + b"\xE2\xB0\x8F", // Ⰿ (Nash, 149) + b"\xE2\xB0\x90", // Ⱀ (On, 150) + b"\xE2\xB0\x91", // Ⱁ (Pokoj, 151) + b"\xE2\xB0\x92", // Ⱂ (Rtsy, 152) + b"\xE2\xB0\x93", // Ⱃ (Slovo, 153) + b"\xE2\xB0\x94", // Ⱄ (Tvrido, 154) + b"\xE2\xB0\x95", // Ⱅ (Uku, 155) + b"\xE2\xB0\x96", // Ⱆ (Fert, 156) + b"\xE2\xB0\x97", // Ⱇ (Xrivi, 157) + b"\xE2\xB0\x98", // Ⱈ (Ot, 158) + b"\xE2\xB0\x99", // Ⱉ (Cy, 159) + b"\xE2\xB0\x9A", // Ⱊ (Shcha, 160) + b"\xE2\xB0\x9B", // Ⱋ (Er, 161) + b"\xE2\xB0\x9C", // Ⱌ (Yeru, 162) + b"\xE2\xB0\x9D", // Ⱍ (Small Yer, 163) + b"\xE2\xB0\x9E", // Ⱎ (Yo, 164) + b"\xE2\xB0\x9F", // Ⱏ (Yu, 165) + b"\xE2\xB0\xA0", // Ⱐ (Ja, 166) + // Thai Alphabet + b"\xE0\xB8\x81", // ก (Ko Kai, 167) + b"\xE0\xB8\x82", // ข (Kho Khai, 168) + b"\xE0\xB8\x83", // ฃ (Kho Khuat, 169) + b"\xE0\xB8\x84", // ค (Kho Khon, 170) + b"\xE0\xB8\x85", // ฅ (Kho Rakhang, 171) + b"\xE0\xB8\x86", // ฆ (Kho Khwai, 172) + b"\xE0\xB8\x87", // ง (Ngo Ngu, 173) + b"\xE0\xB8\x88", // จ (Cho Chan, 174) + b"\xE0\xB8\x89", // ฉ (Cho Ching, 175) + b"\xE0\xB8\x8A", // ช (Cho Chang, 176) + b"\xE0\xB8\x8B", // ซ (So So, 177) + b"\xE0\xB8\x8C", // ฌ (Cho Choe, 178) + b"\xE0\xB8\x8D", // ญ (Yo Ying, 179) + b"\xE0\xB8\x8E", // ฎ (Do Chada, 180) + b"\xE0\xB8\x8F", // ฏ (To Patak, 181) + b"\xE0\xB8\x90", // ฐ (Tho Than, 182) + b"\xE0\xB8\x91", // ฑ (Tho Nangmontho, 183) + b"\xE0\xB8\x92", // ฒ (Tho Phuthao, 184) + b"\xE0\xB8\x93", // ณ (No Nen, 185) + b"\xE0\xB8\x94", // ด (Do Dek, 186) + b"\xE0\xB8\x95", // ต (To Tao, 187) + b"\xE0\xB8\x96", // ถ (Tho Thung, 188) + b"\xE0\xB8\x97", // ท (Tho Thahan, 189) + b"\xE0\xB8\x98", // ธ (Tho Thong, 190) + b"\xE0\xB8\x99", // น (No Nu, 191) + b"\xE0\xB8\x9A", // บ (Bo Baimai, 192) + b"\xE0\xB8\x9B", // ป (Po Pla, 193) + b"\xE0\xB8\x9C", // ผ (Pho Phung, 194) + b"\xE0\xB8\x9D", // ฝ (Fo Fa, 195) + b"\xE0\xB8\x9E", // พ (Pho Phan, 196) + b"\xE0\xB8\x9F", // ฟ (Fo Fan, 197) + b"\xE0\xB8\xA0", // ภ (Pho Samphao, 198) + b"\xE0\xB8\xA1", // ม (Mo Ma, 199) + b"\xE0\xB8\xA2", // ย (Yo Yak, 200) + b"\xE0\xB8\xA3", // ร (Ro Rua, 201) + b"\xE0\xB8\xA5", // ล (Lo Ling, 202) + b"\xE0\xB8\xA7", // ว (Wo Waen, 203) + b"\xE0\xB8\xA8", // ศ (So Sala, 204) + b"\xE0\xB8\xA9", // ษ (So Rusi, 205) + b"\xE0\xB8\xAA", // ส (So Sua, 206) + b"\xE0\xB8\xAB", // ห (Ho Hip, 207) + b"\xE0\xB8\xAC", // ฬ (Lo Chula, 208) + b"\xE0\xB8\xAD", // อ (O Ang, 209) + b"\xE0\xB8\xAE", // ฮ (Ho Nokhuk, 210) + // Hangul Alphabet (Korean) + b"\xE1\x84\x80", // ㄱ (Giyeok, 211) + b"\xE1\x84\x81", // ㄴ (Nieun, 212) + b"\xE1\x84\x82", // ㄷ (Digeut, 213) + b"\xE1\x84\x83", // ㄹ (Rieul, 214) + b"\xE1\x84\x84", // ㅁ (Mieum, 215) + b"\xE1\x84\x85", // ㅂ (Bieup, 216) + b"\xE1\x84\x86", // ㅅ (Siot, 217) + b"\xE1\x84\x87", // ㅇ (Ieung, 218) + b"\xE1\x84\x88", // ㅈ (Jieut, 219) + b"\xE1\x84\x89", // ㅊ (Chieut, 220) + b"\xE1\x84\x8A", // ㅋ (Kieuk, 221) + b"\xE1\x84\x8B", // ㅌ (Tieut, 222) + b"\xE1\x84\x8C", // ㅍ (Pieup, 223) + b"\xE1\x84\x8D", // ㅎ (Hieut, 224) + // Hangul Vowels + b"\xE1\x85\xA1", // ㅏ (A, 225) + b"\xE1\x85\xA2", // ㅐ (Ae, 226) + b"\xE1\x85\xA3", // ㅑ (Ya, 227) + b"\xE1\x85\xA4", // ㅒ (Yae, 228) + b"\xE1\x85\xA5", // ㅓ (Eo, 229) + b"\xE1\x85\xA6", // ㅔ (E, 230) + b"\xE1\x85\xA7", // ㅕ (Yeo, 231) + b"\xE1\x85\xA8", // ㅖ (Ye, 232) + b"\xE1\x85\xA9", // ㅗ (O, 233) + b"\xE1\x85\xAA", // ㅘ (Wa, 234) + b"\xE1\x85\xAB", // ㅙ (Wae, 235) + b"\xE1\x85\xAC", // ㅚ (Oe, 236) + b"\xE1\x85\xAD", // ㅛ (Yo, 237) + b"\xE1\x85\xAE", // ㅜ (U, 238) + b"\xE1\x85\xAF", // ㅝ (Weo, 239) + b"\xE1\x85\xB0", // ㅞ (We, 240) + b"\xE1\x85\xB1", // ㅟ (Wi, 241) + b"\xE1\x85\xB2", // ㅠ (Yu, 242) + b"\xE1\x85\xB3", // ㅡ (Eu, 243) + b"\xE1\x85\xB4", // ㅢ (Ui, 244) + b"\xE1\x85\xB5", // ㅣ (I, 245) + // Ethiopic Alphabet + b"\xE1\x8A\xA0", // አ (Glottal A, 246) + b"\xE1\x8A\xA1", // ኡ (Glottal U, 247) + b"\xE1\x8A\xA2", // ኢ (Glottal I, 248) + b"\xE1\x8A\xA3", // ኣ (Glottal Aa, 249) + b"\xE1\x8A\xA4", // ኤ (Glottal E, 250) + b"\xE1\x8A\xA5", // እ (Glottal Ie, 251) + b"\xE1\x8A\xA6", // ኦ (Glottal O, 252) + b"\xE1\x8A\xA7", // ኧ (Glottal Wa, 253) + b"\xE1\x8B\x88", // ወ (Wa, 254) + b"\xE1\x8B\x89", // ዉ (Wu, 255) + b"\xE1\x8B\x8A", // ዊ (Wi, 256) + b"\xE1\x8B\x8B", // ዋ (Waa, 257) + b"\xE1\x8B\x8C", // ዌ (We, 258) + b"\xE1\x8B\x8D", // ው (Wye, 259) + b"\xE1\x8B\x8E", // ዎ (Wo, 260) + b"\xE1\x8A\xB0", // ኰ (Ko, 261) + b"\xE1\x8A\xB1", // ኱ (Ku, 262) + b"\xE1\x8A\xB2", // ኲ (Ki, 263) + b"\xE1\x8A\xB3", // ኳ (Kua, 264) + b"\xE1\x8A\xB4", // ኴ (Ke, 265) + b"\xE1\x8A\xB5", // ኵ (Kwe, 266) + b"\xE1\x8A\xB6", // ኶ (Ko, 267) + b"\xE1\x8A\x90", // ጐ (Go, 268) + b"\xE1\x8A\x91", // ጑ (Gu, 269) + b"\xE1\x8A\x92", // ጒ (Gi, 270) + b"\xE1\x8A\x93", // መ (Gua, 271) + b"\xE1\x8A\x94", // ጔ (Ge, 272) + b"\xE1\x8A\x95", // ጕ (Gwe, 273) + b"\xE1\x8A\x96", // ጖ (Go, 274) + // Devanagari Alphabet + b"\xE0\xA4\x85", // अ (A, 275) + b"\xE0\xA4\x86", // आ (Aa, 276) + b"\xE0\xA4\x87", // इ (I, 277) + b"\xE0\xA4\x88", // ई (Ii, 278) + b"\xE0\xA4\x89", // उ (U, 279) + b"\xE0\xA4\x8A", // ऊ (Uu, 280) + b"\xE0\xA4\x8B", // ऋ (R, 281) + b"\xE0\xA4\x8F", // ए (E, 282) + b"\xE0\xA4\x90", // ऐ (Ai, 283) + b"\xE0\xA4\x93", // ओ (O, 284) + b"\xE0\xA4\x94", // औ (Au, 285) + b"\xE0\xA4\x95", // क (Ka, 286) + b"\xE0\xA4\x96", // ख (Kha, 287) + b"\xE0\xA4\x97", // ग (Ga, 288) + b"\xE0\xA4\x98", // घ (Gha, 289) + b"\xE0\xA4\x99", // ङ (Nga, 290) + b"\xE0\xA4\x9A", // च (Cha, 291) + b"\xE0\xA4\x9B", // छ (Chha, 292) + b"\xE0\xA4\x9C", // ज (Ja, 293) + b"\xE0\xA4\x9D", // झ (Jha, 294) + b"\xE0\xA4\x9E", // ञ (Nya, 295) + b"\xE0\xA4\x9F", // ट (Ta, 296) + b"\xE0\xA4\xA0", // ठ (Tha, 297) + b"\xE0\xA4\xA1", // ड (Da, 298) + b"\xE0\xA4\xA2", // ढ (Dha, 299) + b"\xE0\xA4\xA3", // ण (Na, 300) + b"\xE0\xA4\xA4", // त (Ta, 301) + b"\xE0\xA4\xA5", // थ (Tha, 302) + b"\xE0\xA4\xA6", // द (Da, 303) + b"\xE0\xA4\xA7", // ध (Dha, 304) + b"\xE0\xA4\xA8", // न (Na, 305) + b"\xE0\xA4\xAA", // प (Pa, 306) + b"\xE0\xA4\xAB", // फ (Pha, 307) + b"\xE0\xA4\xAC", // ब (Ba, 308) + b"\xE0\xA4\xAD", // भ (Bha, 309) + b"\xE0\xA4\xAE", // म (Ma, 310) + b"\xE0\xA4\xAF", // य (Ya, 311) + b"\xE0\xA4\xB0", // र (Ra, 312) + b"\xE0\xA4\xB2", // ल (La, 313) + b"\xE0\xA4\xB5", // व (Va, 314) + b"\xE0\xA4\xB6", // श (Sha, 315) + b"\xE0\xA4\xB7", // ष (Ssa, 316) + b"\xE0\xA4\xB8", // स (Sa, 317) + b"\xE0\xA4\xB9", // ह (Ha, 318) + // Katakana Alphabet + b"\xE3\x82\xA2", // ア (A, 319) + b"\xE3\x82\xA4", // イ (I, 320) + b"\xE3\x82\xA6", // ウ (U, 321) + b"\xE3\x82\xA8", // エ (E, 322) + b"\xE3\x82\xAA", // オ (O, 323) + b"\xE3\x82\xAB", // カ (Ka, 324) + b"\xE3\x82\xAD", // キ (Ki, 325) + b"\xE3\x82\xAF", // ク (Ku, 326) + b"\xE3\x82\xB1", // ケ (Ke, 327) + b"\xE3\x82\xB3", // コ (Ko, 328) + b"\xE3\x82\xB5", // サ (Sa, 329) + b"\xE3\x82\xB7", // シ (Shi, 330) + b"\xE3\x82\xB9", // ス (Su, 331) + b"\xE3\x82\xBB", // セ (Se, 332) + b"\xE3\x82\xBD", // ソ (So, 333) + b"\xE3\x82\xBF", // タ (Ta, 334) + b"\xE3\x83\x81", // チ (Chi, 335) + b"\xE3\x83\x84", // ツ (Tsu, 336) + b"\xE3\x83\x86", // テ (Te, 337) + b"\xE3\x83\x88", // ト (To, 338) + b"\xE3\x83\x8A", // ナ (Na, 339) + b"\xE3\x83\x8B", // ニ (Ni, 340) + b"\xE3\x83\x8C", // ヌ (Nu, 341) + b"\xE3\x83\x8D", // ネ (Ne, 342) + b"\xE3\x83\x8E", // ノ (No, 343) + b"\xE3\x83\x8F", // ハ (Ha, 344) + b"\xE3\x83\x92", // ヒ (Hi, 345) + b"\xE3\x83\x95", // フ (Fu, 346) + b"\xE3\x83\x98", // ヘ (He, 347) + b"\xE3\x83\x9B", // ホ (Ho, 348) + b"\xE3\x83\x9E", // マ (Ma, 349) + b"\xE3\x83\x9F", // ミ (Mi, 350) + b"\xE3\x83\xA0", // ム (Mu, 351) + b"\xE3\x83\xA1", // メ (Me, 352) + b"\xE3\x83\xA2", // モ (Mo, 353) + b"\xE3\x83\xA4", // ヤ (Ya, 354) + b"\xE3\x83\xA6", // ユ (Yu, 355) + b"\xE3\x83\xA8", // ヨ (Yo, 356) + b"\xE3\x83\xA9", // ラ (Ra, 357) + b"\xE3\x83\xAA", // リ (Ri, 358) + b"\xE3\x83\xAB", // ル (Ru, 359) + b"\xE3\x83\xAC", // レ (Re, 360) + b"\xE3\x83\xAD", // ロ (Ro, 361) + b"\xE3\x83\xAF", // ワ (Wa, 362) + b"\xE3\x83\xB2", // ヲ (Wo, 363) + b"\xE3\x83\xB3", // ン (N, 364) + // Tifinagh Alphabet + b"\xE2\xB4\xB0", // ⴰ (Ya, 365) + b"\xE2\xB4\xB1", // ⴱ (Yab, 366) + b"\xE2\xB4\xB2", // ⴲ (Yabh, 367) + b"\xE2\xB4\xB3", // ⴳ (Yag, 368) + b"\xE2\xB4\xB4", // ⴴ (Yagh, 369) + b"\xE2\xB4\xB5", // ⴵ (Yaj, 370) + b"\xE2\xB4\xB6", // ⴶ (Yach, 371) + b"\xE2\xB4\xB7", // ⴷ (Yad, 372) + b"\xE2\xB4\xB8", // ⴸ (Yadh, 373) + b"\xE2\xB4\xB9", // ⴹ (Yadh, emphatic, 374) + b"\xE2\xB4\xBA", // ⴺ (Yaz, 375) + b"\xE2\xB4\xBB", // ⴻ (Yazh, 376) + b"\xE2\xB4\xBC", // ⴼ (Yaf, 377) + b"\xE2\xB4\xBD", // ⴽ (Yak, 378) + b"\xE2\xB4\xBE", // ⴾ (Yak, variant, 379) + b"\xE2\xB4\xBF", // ⴿ (Yaq, 380) + b"\xE2\xB5\x80", // ⵀ (Yah, 381) + b"\xE2\xB5\x81", // ⵁ (Yahh, 382) + b"\xE2\xB5\x82", // ⵂ (Yahl, 383) + b"\xE2\xB5\x83", // ⵃ (Yahm, 384) + b"\xE2\xB5\x84", // ⵄ (Yayn, 385) + b"\xE2\xB5\x85", // ⵅ (Yakh, 386) + b"\xE2\xB5\x86", // ⵆ (Yakl, 387) + b"\xE2\xB5\x87", // ⵇ (Yahq, 388) + b"\xE2\xB5\x88", // ⵈ (Yash, 389) + b"\xE2\xB5\x89", // ⵉ (Yi, 390) + b"\xE2\xB5\x8A", // ⵊ (Yij, 391) + b"\xE2\xB5\x8B", // ⵋ (Yizh, 392) + b"\xE2\xB5\x8C", // ⵌ (Yink, 393) + b"\xE2\xB5\x8D", // ⵍ (Yal, 394) + b"\xE2\xB5\x8E", // ⵎ (Yam, 395) + b"\xE2\xB5\x8F", // ⵏ (Yan, 396) + b"\xE2\xB5\x90", // ⵐ (Yang, 397) + b"\xE2\xB5\x91", // ⵑ (Yany, 398) + b"\xE2\xB5\x92", // ⵒ (Yap, 399) + b"\xE2\xB5\x93", // ⵓ (Yu, 400) + // Sinhala Alphabet + b"\xE0\xB6\x85", // අ (A, 401) + b"\xE0\xB6\x86", // ආ (Aa, 402) + b"\xE0\xB6\x87", // ඉ (I, 403) + b"\xE0\xB6\x88", // ඊ (Ii, 404) + b"\xE0\xB6\x89", // උ (U, 405) + b"\xE0\xB6\x8A", // ඌ (Uu, 406) + b"\xE0\xB6\x8B", // ඍ (R, 407) + b"\xE0\xB6\x8C", // ඎ (Rr, 408) + b"\xE0\xB6\x8F", // ඏ (L, 409) + b"\xE0\xB6\x90", // ඐ (Ll, 410) + b"\xE0\xB6\x91", // එ (E, 411) + b"\xE0\xB6\x92", // ඒ (Ee, 412) + b"\xE0\xB6\x93", // ඓ (Ai, 413) + b"\xE0\xB6\x94", // ඔ (O, 414) + b"\xE0\xB6\x95", // ඕ (Oo, 415) + b"\xE0\xB6\x96", // ඖ (Au, 416) + b"\xE0\xB6\x9A", // ක (Ka, 417) + b"\xE0\xB6\x9B", // ඛ (Kha, 418) + b"\xE0\xB6\x9C", // ග (Ga, 419) + b"\xE0\xB6\x9D", // ඝ (Gha, 420) + b"\xE0\xB6\x9E", // ඞ (Nga, 421) + b"\xE0\xB6\x9F", // ච (Cha, 422) + b"\xE0\xB6\xA0", // ඡ (Chha, 423) + b"\xE0\xB6\xA1", // ජ (Ja, 424) + b"\xE0\xB6\xA2", // ඣ (Jha, 425) + b"\xE0\xB6\xA3", // ඤ (Nya, 426) + b"\xE0\xB6\xA4", // ට (Ta, 427) + b"\xE0\xB6\xA5", // ඥ (Tha, 428) + b"\xE0\xB6\xA6", // ඦ (Da, 429) + b"\xE0\xB6\xA7", // ට (Dha, 430) + b"\xE0\xB6\xA8", // ඨ (Na, 431) + b"\xE0\xB6\xAA", // ඪ (Pa, 432) + b"\xE0\xB6\xAB", // ණ (Pha, 433) + b"\xE0\xB6\xAC", // ඬ (Ba, 434) + b"\xE0\xB6\xAD", // ත (Bha, 435) + b"\xE0\xB6\xAE", // ථ (Ma, 436) + b"\xE0\xB6\xAF", // ද (Ya, 437) + b"\xE0\xB6\xB0", // ධ (Ra, 438) +]; + /// Returns the Unicode symbol as a Vec for a given netuid. impl Pallet { pub fn get_name_for_subnet(netuid: NetUid) -> Vec { @@ -459,487 +925,36 @@ impl Pallet { } pub fn get_symbol_for_subnet(netuid: NetUid) -> Vec { - match u16::from(netuid) { - // Greek Alphabet (Lowercase) - 0 => b"\xCE\xA4".to_vec(), // Τ (Upper case Tau) - 1 => b"\xCE\xB1".to_vec(), // α (Alpha) - 2 => b"\xCE\xB2".to_vec(), // β (Beta) - 3 => b"\xCE\xB3".to_vec(), // γ (Gamma) - 4 => b"\xCE\xB4".to_vec(), // δ (Delta) - 5 => b"\xCE\xB5".to_vec(), // ε (Epsilon) - 6 => b"\xCE\xB6".to_vec(), // ζ (Zeta) - 7 => b"\xCE\xB7".to_vec(), // η (Eta) - 8 => b"\xCE\xB8".to_vec(), // θ (Theta) - 9 => b"\xCE\xB9".to_vec(), // ι (Iota) - 10 => b"\xCE\xBA".to_vec(), // κ (Kappa) - 11 => b"\xCE\xBB".to_vec(), // λ (Lambda) - 12 => b"\xCE\xBC".to_vec(), // μ (Mu) - 13 => b"\xCE\xBD".to_vec(), // ν (Nu) - 14 => b"\xCE\xBE".to_vec(), // ξ (Xi) - 15 => b"\xCE\xBF".to_vec(), // ο (Omicron) - 16 => b"\xCF\x80".to_vec(), // π (Pi) - 17 => b"\xCF\x81".to_vec(), // ρ (Rho) - 18 => b"\xCF\x83".to_vec(), // σ (Sigma) - 19 => b"t".to_vec(), // t (Tau) - 20 => b"\xCF\x85".to_vec(), // υ (Upsilon) - 21 => b"\xCF\x86".to_vec(), // φ (Phi) - 22 => b"\xCF\x87".to_vec(), // χ (Chi) - 23 => b"\xCF\x88".to_vec(), // ψ (Psi) - 24 => b"\xCF\x89".to_vec(), // ω (Omega) - // Hebrew Alphabet (Including Final Forms) - 25 => b"\xD7\x90".to_vec(), // א (Aleph) - 26 => b"\xD7\x91".to_vec(), // ב (Bet) - 27 => b"\xD7\x92".to_vec(), // ג (Gimel) - 28 => b"\xD7\x93".to_vec(), // ד (Dalet) - 29 => b"\xD7\x94".to_vec(), // ה (He) - 30 => b"\xD7\x95".to_vec(), // ו (Vav) - 31 => b"\xD7\x96".to_vec(), // ז (Zayin) - 32 => b"\xD7\x97".to_vec(), // ח (Het) - 33 => b"\xD7\x98".to_vec(), // ט (Tet) - 34 => b"\xD7\x99".to_vec(), // י (Yod) - 35 => b"\xD7\x9A".to_vec(), // ך (Final Kaf) - 36 => b"\xD7\x9B".to_vec(), // כ (Kaf) - 37 => b"\xD7\x9C".to_vec(), // ל (Lamed) - 38 => b"\xD7\x9D".to_vec(), // ם (Final Mem) - 39 => b"\xD7\x9E".to_vec(), // מ (Mem) - 40 => b"\xD7\x9F".to_vec(), // ן (Final Nun) - 41 => b"\xD7\xA0".to_vec(), // נ (Nun) - 42 => b"\xD7\xA1".to_vec(), // ס (Samekh) - 43 => b"\xD7\xA2".to_vec(), // ע (Ayin) - 44 => b"\xD7\xA3".to_vec(), // ף (Final Pe) - 45 => b"\xD7\xA4".to_vec(), // פ (Pe) - 46 => b"\xD7\xA5".to_vec(), // ץ (Final Tsadi) - 47 => b"\xD7\xA6".to_vec(), // צ (Tsadi) - 48 => b"\xD7\xA7".to_vec(), // ק (Qof) - 49 => b"\xD7\xA8".to_vec(), // ר (Resh) - 50 => b"\xD7\xA9".to_vec(), // ש (Shin) - 51 => b"\xD7\xAA".to_vec(), // ת (Tav) - - // Arabic Alphabet - 52 => b"\xD8\xA7".to_vec(), // ا (Alif) - 53 => b"\xD8\xA8".to_vec(), // ب (Ba) - 54 => b"\xD8\xAA".to_vec(), // ت (Ta) - 55 => b"\xD8\xAB".to_vec(), // ث (Tha) - 56 => b"\xD8\xAC".to_vec(), // ج (Jim) - 57 => b"\xD8\xAD".to_vec(), // ح (Ha) - 58 => b"\xD8\xAE".to_vec(), // خ (Kha) - 59 => b"\xD8\xAF".to_vec(), // د (Dal) - 60 => b"\xD8\xB0".to_vec(), // ذ (Dhal) - 61 => b"\xD8\xB1".to_vec(), // ر (Ra) - 62 => b"\xD8\xB2".to_vec(), // ز (Zay) - 63 => b"\xD8\xB3".to_vec(), // س (Sin) - 64 => b"\xD8\xB4".to_vec(), // ش (Shin) - 65 => b"\xD8\xB5".to_vec(), // ص (Sad) - 66 => b"\xD8\xB6".to_vec(), // ض (Dad) - 67 => b"\xD8\xB7".to_vec(), // ط (Ta) - 68 => b"\xD8\xB8".to_vec(), // ظ (Dha) - 69 => b"\xD8\xB9".to_vec(), // ع (Ain) - 70 => b"\xD8\xBA".to_vec(), // غ (Ghayn) - 71 => b"\xD9\x81".to_vec(), // ف (Fa) - 72 => b"\xD9\x82".to_vec(), // ق (Qaf) - 73 => b"\xD9\x83".to_vec(), // ك (Kaf) - 74 => b"\xD9\x84".to_vec(), // ل (Lam) - 75 => b"\xD9\x85".to_vec(), // م (Mim) - 76 => b"\xD9\x86".to_vec(), // ن (Nun) - 77 => b"\xD9\x87".to_vec(), // ه (Ha) - 78 => b"\xD9\x88".to_vec(), // و (Waw) - 79 => b"\xD9\x8A".to_vec(), // ي (Ya) - 80 => b"\xD9\x89".to_vec(), // ى (Alef Maksura, 80) - - // Runic Alphabet - 81 => b"\xE1\x9A\xA0".to_vec(), // ᚠ (Fehu, wealth, 81) - 82 => b"\xE1\x9A\xA2".to_vec(), // ᚢ (Uruz, strength, 82) - 83 => b"\xE1\x9A\xA6".to_vec(), // ᚦ (Thurisaz, giant, 83) - 84 => b"\xE1\x9A\xA8".to_vec(), // ᚨ (Ansuz, god, 84) - 85 => b"\xE1\x9A\xB1".to_vec(), // ᚱ (Raidho, ride, 85) - 86 => b"\xE1\x9A\xB3".to_vec(), // ᚲ (Kaunan, ulcer, 86) - 87 => b"\xD0\xAB".to_vec(), // Ы (Cyrillic Yeru, 87) - 88 => b"\xE1\x9B\x89".to_vec(), // ᛉ (Algiz, protection, 88) - 89 => b"\xE1\x9B\x92".to_vec(), // ᛒ (Berkanan, birch, 89) - - // Ogham Alphabet - 90 => b"\xE1\x9A\x80".to_vec(), //   (Space, 90) - 91 => b"\xE1\x9A\x81".to_vec(), // ᚁ (Beith, birch, 91) - 92 => b"\xE1\x9A\x82".to_vec(), // ᚂ (Luis, rowan, 92) - 93 => b"\xE1\x9A\x83".to_vec(), // ᚃ (Fearn, alder, 93) - 94 => b"\xE1\x9A\x84".to_vec(), // ᚄ (Sail, willow, 94) - 95 => b"\xE1\x9A\x85".to_vec(), // ᚅ (Nion, ash, 95) - 96 => b"\xE1\x9A\x9B".to_vec(), // ᚛ (Forfeda, 96) - - // Georgian Alphabet (Mkhedruli) - 97 => b"\xE1\x83\x90".to_vec(), // ა (Ani, 97) - 98 => b"\xE1\x83\x91".to_vec(), // ბ (Bani, 98) - 99 => b"\xE1\x83\x92".to_vec(), // გ (Gani, 99) - 100 => b"\xE1\x83\x93".to_vec(), // დ (Doni, 100) - 101 => b"\xE1\x83\x94".to_vec(), // ე (Eni, 101) - 102 => b"\xE1\x83\x95".to_vec(), // ვ (Vini, 102) - - // Armenian Alphabet - 103 => b"\xD4\xB1".to_vec(), // Ա (Ayp, 103) - 104 => b"\xD4\xB2".to_vec(), // Բ (Ben, 104) - 105 => b"\xD4\xB3".to_vec(), // Գ (Gim, 105) - 106 => b"\xD4\xB4".to_vec(), // Դ (Da, 106) - 107 => b"\xD4\xB5".to_vec(), // Ե (Ech, 107) - 108 => b"\xD4\xB6".to_vec(), // Զ (Za, 108) - 109 => b"\xD5\x9E".to_vec(), // ՞ (Question mark, 109) - - // Cyrillic Alphabet - 110 => b"\xD0\x80".to_vec(), // Ѐ (Ie with grave, 110) - 111 => b"\xD0\x81".to_vec(), // Ё (Io, 111) - 112 => b"\xD0\x82".to_vec(), // Ђ (Dje, 112) - 113 => b"\xD0\x83".to_vec(), // Ѓ (Gje, 113) - 114 => b"\xD0\x84".to_vec(), // Є (Ukrainian Ie, 114) - 115 => b"\xD0\x85".to_vec(), // Ѕ (Dze, 115) - 116 => b"\xD1\x8A".to_vec(), // Ъ (Hard sign, 116) - - // Coptic Alphabet - 117 => b"\xE2\xB2\x80".to_vec(), // Ⲁ (Alfa, 117) - 118 => b"\xE2\xB2\x81".to_vec(), // ⲁ (Small Alfa, 118) - 119 => b"\xE2\xB2\x82".to_vec(), // Ⲃ (Vida, 119) - 120 => b"\xE2\xB2\x83".to_vec(), // ⲃ (Small Vida, 120) - 121 => b"\xE2\xB2\x84".to_vec(), // Ⲅ (Gamma, 121) - 122 => b"\xE2\xB2\x85".to_vec(), // ⲅ (Small Gamma, 122) - - // Brahmi Script - 123 => b"\xF0\x91\x80\x80".to_vec(), // 𑀀 (A, 123) - 124 => b"\xF0\x91\x80\x81".to_vec(), // 𑀁 (Aa, 124) - 125 => b"\xF0\x91\x80\x82".to_vec(), // 𑀂 (I, 125) - 126 => b"\xF0\x91\x80\x83".to_vec(), // 𑀃 (Ii, 126) - 127 => b"\xF0\x91\x80\x85".to_vec(), // 𑀅 (U, 127) - - // End of Sinhala Alphabet - 128 => b"\xE0\xB6\xB1".to_vec(), // ඲ (La, 128) - 129 => b"\xE0\xB6\xB2".to_vec(), // ඳ (Va, 129) - 130 => b"\xE0\xB6\xB3".to_vec(), // ප (Sha, 130) - 131 => b"\xE0\xB6\xB4".to_vec(), // ඵ (Ssa, 131) - 132 => b"\xE0\xB6\xB5".to_vec(), // බ (Sa, 132) - 133 => b"\xE0\xB6\xB6".to_vec(), // භ (Ha, 133) - - // Glagolitic Alphabet - 134 => b"\xE2\xB0\x80".to_vec(), // Ⰰ (Az, 134) - 135 => b"\xE2\xB0\x81".to_vec(), // Ⰱ (Buky, 135) - 136 => b"\xE2\xB0\x82".to_vec(), // Ⰲ (Vede, 136) - 137 => b"\xE2\xB0\x83".to_vec(), // Ⰳ (Glagoli, 137) - 138 => b"\xE2\xB0\x84".to_vec(), // Ⰴ (Dobro, 138) - 139 => b"\xE2\xB0\x85".to_vec(), // Ⰵ (Yest, 139) - 140 => b"\xE2\xB0\x86".to_vec(), // Ⰶ (Zhivete, 140) - 141 => b"\xE2\xB0\x87".to_vec(), // Ⰷ (Zemlja, 141) - 142 => b"\xE2\xB0\x88".to_vec(), // Ⰸ (Izhe, 142) - 143 => b"\xE2\xB0\x89".to_vec(), // Ⰹ (Initial Izhe, 143) - 144 => b"\xE2\xB0\x8A".to_vec(), // Ⰺ (I, 144) - 145 => b"\xE2\xB0\x8B".to_vec(), // Ⰻ (Djerv, 145) - 146 => b"\xE2\xB0\x8C".to_vec(), // Ⰼ (Kako, 146) - 147 => b"\xE2\xB0\x8D".to_vec(), // Ⰽ (Ljudije, 147) - 148 => b"\xE2\xB0\x8E".to_vec(), // Ⰾ (Myse, 148) - 149 => b"\xE2\xB0\x8F".to_vec(), // Ⰿ (Nash, 149) - 150 => b"\xE2\xB0\x90".to_vec(), // Ⱀ (On, 150) - 151 => b"\xE2\xB0\x91".to_vec(), // Ⱁ (Pokoj, 151) - 152 => b"\xE2\xB0\x92".to_vec(), // Ⱂ (Rtsy, 152) - 153 => b"\xE2\xB0\x93".to_vec(), // Ⱃ (Slovo, 153) - 154 => b"\xE2\xB0\x94".to_vec(), // Ⱄ (Tvrido, 154) - 155 => b"\xE2\xB0\x95".to_vec(), // Ⱅ (Uku, 155) - 156 => b"\xE2\xB0\x96".to_vec(), // Ⱆ (Fert, 156) - 157 => b"\xE2\xB0\x97".to_vec(), // Ⱇ (Xrivi, 157) - 158 => b"\xE2\xB0\x98".to_vec(), // Ⱈ (Ot, 158) - 159 => b"\xE2\xB0\x99".to_vec(), // Ⱉ (Cy, 159) - 160 => b"\xE2\xB0\x9A".to_vec(), // Ⱊ (Shcha, 160) - 161 => b"\xE2\xB0\x9B".to_vec(), // Ⱋ (Er, 161) - 162 => b"\xE2\xB0\x9C".to_vec(), // Ⱌ (Yeru, 162) - 163 => b"\xE2\xB0\x9D".to_vec(), // Ⱍ (Small Yer, 163) - 164 => b"\xE2\xB0\x9E".to_vec(), // Ⱎ (Yo, 164) - 165 => b"\xE2\xB0\x9F".to_vec(), // Ⱏ (Yu, 165) - 166 => b"\xE2\xB0\xA0".to_vec(), // Ⱐ (Ja, 166) - - // Thai Alphabet - 167 => b"\xE0\xB8\x81".to_vec(), // ก (Ko Kai, 167) - 168 => b"\xE0\xB8\x82".to_vec(), // ข (Kho Khai, 168) - 169 => b"\xE0\xB8\x83".to_vec(), // ฃ (Kho Khuat, 169) - 170 => b"\xE0\xB8\x84".to_vec(), // ค (Kho Khon, 170) - 171 => b"\xE0\xB8\x85".to_vec(), // ฅ (Kho Rakhang, 171) - 172 => b"\xE0\xB8\x86".to_vec(), // ฆ (Kho Khwai, 172) - 173 => b"\xE0\xB8\x87".to_vec(), // ง (Ngo Ngu, 173) - 174 => b"\xE0\xB8\x88".to_vec(), // จ (Cho Chan, 174) - 175 => b"\xE0\xB8\x89".to_vec(), // ฉ (Cho Ching, 175) - 176 => b"\xE0\xB8\x8A".to_vec(), // ช (Cho Chang, 176) - 177 => b"\xE0\xB8\x8B".to_vec(), // ซ (So So, 177) - 178 => b"\xE0\xB8\x8C".to_vec(), // ฌ (Cho Choe, 178) - 179 => b"\xE0\xB8\x8D".to_vec(), // ญ (Yo Ying, 179) - 180 => b"\xE0\xB8\x8E".to_vec(), // ฎ (Do Chada, 180) - 181 => b"\xE0\xB8\x8F".to_vec(), // ฏ (To Patak, 181) - 182 => b"\xE0\xB8\x90".to_vec(), // ฐ (Tho Than, 182) - 183 => b"\xE0\xB8\x91".to_vec(), // ฑ (Tho Nangmontho, 183) - 184 => b"\xE0\xB8\x92".to_vec(), // ฒ (Tho Phuthao, 184) - 185 => b"\xE0\xB8\x93".to_vec(), // ณ (No Nen, 185) - 186 => b"\xE0\xB8\x94".to_vec(), // ด (Do Dek, 186) - 187 => b"\xE0\xB8\x95".to_vec(), // ต (To Tao, 187) - 188 => b"\xE0\xB8\x96".to_vec(), // ถ (Tho Thung, 188) - 189 => b"\xE0\xB8\x97".to_vec(), // ท (Tho Thahan, 189) - 190 => b"\xE0\xB8\x98".to_vec(), // ธ (Tho Thong, 190) - 191 => b"\xE0\xB8\x99".to_vec(), // น (No Nu, 191) - 192 => b"\xE0\xB8\x9A".to_vec(), // บ (Bo Baimai, 192) - 193 => b"\xE0\xB8\x9B".to_vec(), // ป (Po Pla, 193) - 194 => b"\xE0\xB8\x9C".to_vec(), // ผ (Pho Phung, 194) - 195 => b"\xE0\xB8\x9D".to_vec(), // ฝ (Fo Fa, 195) - 196 => b"\xE0\xB8\x9E".to_vec(), // พ (Pho Phan, 196) - 197 => b"\xE0\xB8\x9F".to_vec(), // ฟ (Fo Fan, 197) - 198 => b"\xE0\xB8\xA0".to_vec(), // ภ (Pho Samphao, 198) - 199 => b"\xE0\xB8\xA1".to_vec(), // ม (Mo Ma, 199) - 200 => b"\xE0\xB8\xA2".to_vec(), // ย (Yo Yak, 200) - 201 => b"\xE0\xB8\xA3".to_vec(), // ร (Ro Rua, 201) - 202 => b"\xE0\xB8\xA5".to_vec(), // ล (Lo Ling, 202) - 203 => b"\xE0\xB8\xA7".to_vec(), // ว (Wo Waen, 203) - 204 => b"\xE0\xB8\xA8".to_vec(), // ศ (So Sala, 204) - 205 => b"\xE0\xB8\xA9".to_vec(), // ษ (So Rusi, 205) - 206 => b"\xE0\xB8\xAA".to_vec(), // ส (So Sua, 206) - 207 => b"\xE0\xB8\xAB".to_vec(), // ห (Ho Hip, 207) - 208 => b"\xE0\xB8\xAC".to_vec(), // ฬ (Lo Chula, 208) - 209 => b"\xE0\xB8\xAD".to_vec(), // อ (O Ang, 209) - 210 => b"\xE0\xB8\xAE".to_vec(), // ฮ (Ho Nokhuk, 210) - - // Hangul Alphabet (Korean) - 211 => b"\xE1\x84\x80".to_vec(), // ㄱ (Giyeok, 211) - 212 => b"\xE1\x84\x81".to_vec(), // ㄴ (Nieun, 212) - 213 => b"\xE1\x84\x82".to_vec(), // ㄷ (Digeut, 213) - 214 => b"\xE1\x84\x83".to_vec(), // ㄹ (Rieul, 214) - 215 => b"\xE1\x84\x84".to_vec(), // ㅁ (Mieum, 215) - 216 => b"\xE1\x84\x85".to_vec(), // ㅂ (Bieup, 216) - 217 => b"\xE1\x84\x86".to_vec(), // ㅅ (Siot, 217) - 218 => b"\xE1\x84\x87".to_vec(), // ㅇ (Ieung, 218) - 219 => b"\xE1\x84\x88".to_vec(), // ㅈ (Jieut, 219) - 220 => b"\xE1\x84\x89".to_vec(), // ㅊ (Chieut, 220) - 221 => b"\xE1\x84\x8A".to_vec(), // ㅋ (Kieuk, 221) - 222 => b"\xE1\x84\x8B".to_vec(), // ㅌ (Tieut, 222) - 223 => b"\xE1\x84\x8C".to_vec(), // ㅍ (Pieup, 223) - 224 => b"\xE1\x84\x8D".to_vec(), // ㅎ (Hieut, 224) - - // Hangul Vowels - 225 => b"\xE1\x85\xA1".to_vec(), // ㅏ (A, 225) - 226 => b"\xE1\x85\xA2".to_vec(), // ㅐ (Ae, 226) - 227 => b"\xE1\x85\xA3".to_vec(), // ㅑ (Ya, 227) - 228 => b"\xE1\x85\xA4".to_vec(), // ㅒ (Yae, 228) - 229 => b"\xE1\x85\xA5".to_vec(), // ㅓ (Eo, 229) - 230 => b"\xE1\x85\xA6".to_vec(), // ㅔ (E, 230) - 231 => b"\xE1\x85\xA7".to_vec(), // ㅕ (Yeo, 231) - 232 => b"\xE1\x85\xA8".to_vec(), // ㅖ (Ye, 232) - 233 => b"\xE1\x85\xA9".to_vec(), // ㅗ (O, 233) - 234 => b"\xE1\x85\xAA".to_vec(), // ㅘ (Wa, 234) - 235 => b"\xE1\x85\xAB".to_vec(), // ㅙ (Wae, 235) - 236 => b"\xE1\x85\xAC".to_vec(), // ㅚ (Oe, 236) - 237 => b"\xE1\x85\xAD".to_vec(), // ㅛ (Yo, 237) - 238 => b"\xE1\x85\xAE".to_vec(), // ㅜ (U, 238) - 239 => b"\xE1\x85\xAF".to_vec(), // ㅝ (Weo, 239) - 240 => b"\xE1\x85\xB0".to_vec(), // ㅞ (We, 240) - 241 => b"\xE1\x85\xB1".to_vec(), // ㅟ (Wi, 241) - 242 => b"\xE1\x85\xB2".to_vec(), // ㅠ (Yu, 242) - 243 => b"\xE1\x85\xB3".to_vec(), // ㅡ (Eu, 243) - 244 => b"\xE1\x85\xB4".to_vec(), // ㅢ (Ui, 244) - 245 => b"\xE1\x85\xB5".to_vec(), // ㅣ (I, 245) - - // Ethiopic Alphabet - 246 => b"\xE1\x8A\xA0".to_vec(), // አ (Glottal A, 246) - 247 => b"\xE1\x8A\xA1".to_vec(), // ኡ (Glottal U, 247) - 248 => b"\xE1\x8A\xA2".to_vec(), // ኢ (Glottal I, 248) - 249 => b"\xE1\x8A\xA3".to_vec(), // ኣ (Glottal Aa, 249) - 250 => b"\xE1\x8A\xA4".to_vec(), // ኤ (Glottal E, 250) - 251 => b"\xE1\x8A\xA5".to_vec(), // እ (Glottal Ie, 251) - 252 => b"\xE1\x8A\xA6".to_vec(), // ኦ (Glottal O, 252) - 253 => b"\xE1\x8A\xA7".to_vec(), // ኧ (Glottal Wa, 253) - 254 => b"\xE1\x8B\x88".to_vec(), // ወ (Wa, 254) - 255 => b"\xE1\x8B\x89".to_vec(), // ዉ (Wu, 255) - 256 => b"\xE1\x8B\x8A".to_vec(), // ዊ (Wi, 256) - 257 => b"\xE1\x8B\x8B".to_vec(), // ዋ (Waa, 257) - 258 => b"\xE1\x8B\x8C".to_vec(), // ዌ (We, 258) - 259 => b"\xE1\x8B\x8D".to_vec(), // ው (Wye, 259) - 260 => b"\xE1\x8B\x8E".to_vec(), // ዎ (Wo, 260) - 261 => b"\xE1\x8A\xB0".to_vec(), // ኰ (Ko, 261) - 262 => b"\xE1\x8A\xB1".to_vec(), // ኱ (Ku, 262) - 263 => b"\xE1\x8A\xB2".to_vec(), // ኲ (Ki, 263) - 264 => b"\xE1\x8A\xB3".to_vec(), // ኳ (Kua, 264) - 265 => b"\xE1\x8A\xB4".to_vec(), // ኴ (Ke, 265) - 266 => b"\xE1\x8A\xB5".to_vec(), // ኵ (Kwe, 266) - 267 => b"\xE1\x8A\xB6".to_vec(), // ኶ (Ko, 267) - 268 => b"\xE1\x8A\x90".to_vec(), // ጐ (Go, 268) - 269 => b"\xE1\x8A\x91".to_vec(), // ጑ (Gu, 269) - 270 => b"\xE1\x8A\x92".to_vec(), // ጒ (Gi, 270) - 271 => b"\xE1\x8A\x93".to_vec(), // መ (Gua, 271) - 272 => b"\xE1\x8A\x94".to_vec(), // ጔ (Ge, 272) - 273 => b"\xE1\x8A\x95".to_vec(), // ጕ (Gwe, 273) - 274 => b"\xE1\x8A\x96".to_vec(), // ጖ (Go, 274) - - // Devanagari Alphabet - 275 => b"\xE0\xA4\x85".to_vec(), // अ (A, 275) - 276 => b"\xE0\xA4\x86".to_vec(), // आ (Aa, 276) - 277 => b"\xE0\xA4\x87".to_vec(), // इ (I, 277) - 278 => b"\xE0\xA4\x88".to_vec(), // ई (Ii, 278) - 279 => b"\xE0\xA4\x89".to_vec(), // उ (U, 279) - 280 => b"\xE0\xA4\x8A".to_vec(), // ऊ (Uu, 280) - 281 => b"\xE0\xA4\x8B".to_vec(), // ऋ (R, 281) - 282 => b"\xE0\xA4\x8F".to_vec(), // ए (E, 282) - 283 => b"\xE0\xA4\x90".to_vec(), // ऐ (Ai, 283) - 284 => b"\xE0\xA4\x93".to_vec(), // ओ (O, 284) - 285 => b"\xE0\xA4\x94".to_vec(), // औ (Au, 285) - 286 => b"\xE0\xA4\x95".to_vec(), // क (Ka, 286) - 287 => b"\xE0\xA4\x96".to_vec(), // ख (Kha, 287) - 288 => b"\xE0\xA4\x97".to_vec(), // ग (Ga, 288) - 289 => b"\xE0\xA4\x98".to_vec(), // घ (Gha, 289) - 290 => b"\xE0\xA4\x99".to_vec(), // ङ (Nga, 290) - 291 => b"\xE0\xA4\x9A".to_vec(), // च (Cha, 291) - 292 => b"\xE0\xA4\x9B".to_vec(), // छ (Chha, 292) - 293 => b"\xE0\xA4\x9C".to_vec(), // ज (Ja, 293) - 294 => b"\xE0\xA4\x9D".to_vec(), // झ (Jha, 294) - 295 => b"\xE0\xA4\x9E".to_vec(), // ञ (Nya, 295) - 296 => b"\xE0\xA4\x9F".to_vec(), // ट (Ta, 296) - 297 => b"\xE0\xA4\xA0".to_vec(), // ठ (Tha, 297) - 298 => b"\xE0\xA4\xA1".to_vec(), // ड (Da, 298) - 299 => b"\xE0\xA4\xA2".to_vec(), // ढ (Dha, 299) - 300 => b"\xE0\xA4\xA3".to_vec(), // ण (Na, 300) - 301 => b"\xE0\xA4\xA4".to_vec(), // त (Ta, 301) - 302 => b"\xE0\xA4\xA5".to_vec(), // थ (Tha, 302) - 303 => b"\xE0\xA4\xA6".to_vec(), // द (Da, 303) - 304 => b"\xE0\xA4\xA7".to_vec(), // ध (Dha, 304) - 305 => b"\xE0\xA4\xA8".to_vec(), // न (Na, 305) - 306 => b"\xE0\xA4\xAA".to_vec(), // प (Pa, 306) - 307 => b"\xE0\xA4\xAB".to_vec(), // फ (Pha, 307) - 308 => b"\xE0\xA4\xAC".to_vec(), // ब (Ba, 308) - 309 => b"\xE0\xA4\xAD".to_vec(), // भ (Bha, 309) - 310 => b"\xE0\xA4\xAE".to_vec(), // म (Ma, 310) - 311 => b"\xE0\xA4\xAF".to_vec(), // य (Ya, 311) - 312 => b"\xE0\xA4\xB0".to_vec(), // र (Ra, 312) - 313 => b"\xE0\xA4\xB2".to_vec(), // ल (La, 313) - 314 => b"\xE0\xA4\xB5".to_vec(), // व (Va, 314) - 315 => b"\xE0\xA4\xB6".to_vec(), // श (Sha, 315) - 316 => b"\xE0\xA4\xB7".to_vec(), // ष (Ssa, 316) - 317 => b"\xE0\xA4\xB8".to_vec(), // स (Sa, 317) - 318 => b"\xE0\xA4\xB9".to_vec(), // ह (Ha, 318) + SYMBOLS + .get(u16::from(netuid) as usize) + .unwrap_or(&DEFAULT_SYMBOL) + .to_vec() + } - // Katakana Alphabet - 319 => b"\xE3\x82\xA2".to_vec(), // ア (A, 319) - 320 => b"\xE3\x82\xA4".to_vec(), // イ (I, 320) - 321 => b"\xE3\x82\xA6".to_vec(), // ウ (U, 321) - 322 => b"\xE3\x82\xA8".to_vec(), // エ (E, 322) - 323 => b"\xE3\x82\xAA".to_vec(), // オ (O, 323) - 324 => b"\xE3\x82\xAB".to_vec(), // カ (Ka, 324) - 325 => b"\xE3\x82\xAD".to_vec(), // キ (Ki, 325) - 326 => b"\xE3\x82\xAF".to_vec(), // ク (Ku, 326) - 327 => b"\xE3\x82\xB1".to_vec(), // ケ (Ke, 327) - 328 => b"\xE3\x82\xB3".to_vec(), // コ (Ko, 328) - 329 => b"\xE3\x82\xB5".to_vec(), // サ (Sa, 329) - 330 => b"\xE3\x82\xB7".to_vec(), // シ (Shi, 330) - 331 => b"\xE3\x82\xB9".to_vec(), // ス (Su, 331) - 332 => b"\xE3\x82\xBB".to_vec(), // セ (Se, 332) - 333 => b"\xE3\x82\xBD".to_vec(), // ソ (So, 333) - 334 => b"\xE3\x82\xBF".to_vec(), // タ (Ta, 334) - 335 => b"\xE3\x83\x81".to_vec(), // チ (Chi, 335) - 336 => b"\xE3\x83\x84".to_vec(), // ツ (Tsu, 336) - 337 => b"\xE3\x83\x86".to_vec(), // テ (Te, 337) - 338 => b"\xE3\x83\x88".to_vec(), // ト (To, 338) - 339 => b"\xE3\x83\x8A".to_vec(), // ナ (Na, 339) - 340 => b"\xE3\x83\x8B".to_vec(), // ニ (Ni, 340) - 341 => b"\xE3\x83\x8C".to_vec(), // ヌ (Nu, 341) - 342 => b"\xE3\x83\x8D".to_vec(), // ネ (Ne, 342) - 343 => b"\xE3\x83\x8E".to_vec(), // ノ (No, 343) - 344 => b"\xE3\x83\x8F".to_vec(), // ハ (Ha, 344) - 345 => b"\xE3\x83\x92".to_vec(), // ヒ (Hi, 345) - 346 => b"\xE3\x83\x95".to_vec(), // フ (Fu, 346) - 347 => b"\xE3\x83\x98".to_vec(), // ヘ (He, 347) - 348 => b"\xE3\x83\x9B".to_vec(), // ホ (Ho, 348) - 349 => b"\xE3\x83\x9E".to_vec(), // マ (Ma, 349) - 350 => b"\xE3\x83\x9F".to_vec(), // ミ (Mi, 350) - 351 => b"\xE3\x83\xA0".to_vec(), // ム (Mu, 351) - 352 => b"\xE3\x83\xA1".to_vec(), // メ (Me, 352) - 353 => b"\xE3\x83\xA2".to_vec(), // モ (Mo, 353) - 354 => b"\xE3\x83\xA4".to_vec(), // ヤ (Ya, 354) - 355 => b"\xE3\x83\xA6".to_vec(), // ユ (Yu, 355) - 356 => b"\xE3\x83\xA8".to_vec(), // ヨ (Yo, 356) - 357 => b"\xE3\x83\xA9".to_vec(), // ラ (Ra, 357) - 358 => b"\xE3\x83\xAA".to_vec(), // リ (Ri, 358) - 359 => b"\xE3\x83\xAB".to_vec(), // ル (Ru, 359) - 360 => b"\xE3\x83\xAC".to_vec(), // レ (Re, 360) - 361 => b"\xE3\x83\xAD".to_vec(), // ロ (Ro, 361) - 362 => b"\xE3\x83\xAF".to_vec(), // ワ (Wa, 362) - 363 => b"\xE3\x83\xB2".to_vec(), // ヲ (Wo, 363) - 364 => b"\xE3\x83\xB3".to_vec(), // ン (N, 364) + pub fn get_next_available_symbol(netuid: NetUid) -> Vec { + let used_symbols: BTreeSet> = TokenSymbol::::iter_values().collect(); - // Tifinagh Alphabet - 365 => b"\xE2\xB4\xB0".to_vec(), // ⴰ (Ya, 365) - 366 => b"\xE2\xB4\xB1".to_vec(), // ⴱ (Yab, 366) - 367 => b"\xE2\xB4\xB2".to_vec(), // ⴲ (Yabh, 367) - 368 => b"\xE2\xB4\xB3".to_vec(), // ⴳ (Yag, 368) - 369 => b"\xE2\xB4\xB4".to_vec(), // ⴴ (Yagh, 369) - 370 => b"\xE2\xB4\xB5".to_vec(), // ⴵ (Yaj, 370) - 371 => b"\xE2\xB4\xB6".to_vec(), // ⴶ (Yach, 371) - 372 => b"\xE2\xB4\xB7".to_vec(), // ⴷ (Yad, 372) - 373 => b"\xE2\xB4\xB8".to_vec(), // ⴸ (Yadh, 373) - 374 => b"\xE2\xB4\xB9".to_vec(), // ⴹ (Yadh, emphatic, 374) - 375 => b"\xE2\xB4\xBA".to_vec(), // ⴺ (Yaz, 375) - 376 => b"\xE2\xB4\xBB".to_vec(), // ⴻ (Yazh, 376) - 377 => b"\xE2\xB4\xBC".to_vec(), // ⴼ (Yaf, 377) - 378 => b"\xE2\xB4\xBD".to_vec(), // ⴽ (Yak, 378) - 379 => b"\xE2\xB4\xBE".to_vec(), // ⴾ (Yak, variant, 379) - 380 => b"\xE2\xB4\xBF".to_vec(), // ⴿ (Yaq, 380) - 381 => b"\xE2\xB5\x80".to_vec(), // ⵀ (Yah, 381) - 382 => b"\xE2\xB5\x81".to_vec(), // ⵁ (Yahh, 382) - 383 => b"\xE2\xB5\x82".to_vec(), // ⵂ (Yahl, 383) - 384 => b"\xE2\xB5\x83".to_vec(), // ⵃ (Yahm, 384) - 385 => b"\xE2\xB5\x84".to_vec(), // ⵄ (Yayn, 385) - 386 => b"\xE2\xB5\x85".to_vec(), // ⵅ (Yakh, 386) - 387 => b"\xE2\xB5\x86".to_vec(), // ⵆ (Yakl, 387) - 388 => b"\xE2\xB5\x87".to_vec(), // ⵇ (Yahq, 388) - 389 => b"\xE2\xB5\x88".to_vec(), // ⵈ (Yash, 389) - 390 => b"\xE2\xB5\x89".to_vec(), // ⵉ (Yi, 390) - 391 => b"\xE2\xB5\x8A".to_vec(), // ⵊ (Yij, 391) - 392 => b"\xE2\xB5\x8B".to_vec(), // ⵋ (Yizh, 392) - 393 => b"\xE2\xB5\x8C".to_vec(), // ⵌ (Yink, 393) - 394 => b"\xE2\xB5\x8D".to_vec(), // ⵍ (Yal, 394) - 395 => b"\xE2\xB5\x8E".to_vec(), // ⵎ (Yam, 395) - 396 => b"\xE2\xB5\x8F".to_vec(), // ⵏ (Yan, 396) - 397 => b"\xE2\xB5\x90".to_vec(), // ⵐ (Yang, 397) - 398 => b"\xE2\xB5\x91".to_vec(), // ⵑ (Yany, 398) - 399 => b"\xE2\xB5\x92".to_vec(), // ⵒ (Yap, 399) - 400 => b"\xE2\xB5\x93".to_vec(), // ⵓ (Yu, 400) + // We first try the default strategy of using the subnet id to get the symbol. + let symbol = Self::get_symbol_for_subnet(netuid); + if !used_symbols.contains(&symbol) { + return symbol; + } - // Sinhala Alphabet - 401 => b"\xE0\xB6\x85".to_vec(), // අ (A, 401) - 402 => b"\xE0\xB6\x86".to_vec(), // ආ (Aa, 402) - 403 => b"\xE0\xB6\x87".to_vec(), // ඉ (I, 403) - 404 => b"\xE0\xB6\x88".to_vec(), // ඊ (Ii, 404) - 405 => b"\xE0\xB6\x89".to_vec(), // උ (U, 405) - 406 => b"\xE0\xB6\x8A".to_vec(), // ඌ (Uu, 406) - 407 => b"\xE0\xB6\x8B".to_vec(), // ඍ (R, 407) - 408 => b"\xE0\xB6\x8C".to_vec(), // ඎ (Rr, 408) - 409 => b"\xE0\xB6\x8F".to_vec(), // ඏ (L, 409) - 410 => b"\xE0\xB6\x90".to_vec(), // ඐ (Ll, 410) - 411 => b"\xE0\xB6\x91".to_vec(), // එ (E, 411) - 412 => b"\xE0\xB6\x92".to_vec(), // ඒ (Ee, 412) - 413 => b"\xE0\xB6\x93".to_vec(), // ඓ (Ai, 413) - 414 => b"\xE0\xB6\x94".to_vec(), // ඔ (O, 414) - 415 => b"\xE0\xB6\x95".to_vec(), // ඕ (Oo, 415) - 416 => b"\xE0\xB6\x96".to_vec(), // ඖ (Au, 416) - 417 => b"\xE0\xB6\x9A".to_vec(), // ක (Ka, 417) - 418 => b"\xE0\xB6\x9B".to_vec(), // ඛ (Kha, 418) - 419 => b"\xE0\xB6\x9C".to_vec(), // ග (Ga, 419) - 420 => b"\xE0\xB6\x9D".to_vec(), // ඝ (Gha, 420) - 421 => b"\xE0\xB6\x9E".to_vec(), // ඞ (Nga, 421) - 422 => b"\xE0\xB6\x9F".to_vec(), // ච (Cha, 422) - 423 => b"\xE0\xB6\xA0".to_vec(), // ඡ (Chha, 423) - 424 => b"\xE0\xB6\xA1".to_vec(), // ජ (Ja, 424) - 425 => b"\xE0\xB6\xA2".to_vec(), // ඣ (Jha, 425) - 426 => b"\xE0\xB6\xA3".to_vec(), // ඤ (Nya, 426) - 427 => b"\xE0\xB6\xA4".to_vec(), // ට (Ta, 427) - 428 => b"\xE0\xB6\xA5".to_vec(), // ඥ (Tha, 428) - 429 => b"\xE0\xB6\xA6".to_vec(), // ඦ (Da, 429) - 430 => b"\xE0\xB6\xA7".to_vec(), // ට (Dha, 430) - 431 => b"\xE0\xB6\xA8".to_vec(), // ඨ (Na, 431) - 432 => b"\xE0\xB6\xAA".to_vec(), // ඪ (Pa, 432) - 433 => b"\xE0\xB6\xAB".to_vec(), // ණ (Pha, 433) - 434 => b"\xE0\xB6\xAC".to_vec(), // ඬ (Ba, 434) - 435 => b"\xE0\xB6\xAD".to_vec(), // ත (Bha, 435) - 436 => b"\xE0\xB6\xAE".to_vec(), // ථ (Ma, 436) - 437 => b"\xE0\xB6\xAF".to_vec(), // ද (Ya, 437) - 438 => b"\xE0\xB6\xB0".to_vec(), // ධ (Ra, 438) + // If it is already taken, we try to get the next available symbol. + let available_symbol = SYMBOLS + .iter() + .skip(1) // Skip the root symbol + .find(|s| !used_symbols.contains(&s[..])) + .map(|s| s.to_vec()); - // Default case - _ => b"\xCE\xA4".to_vec(), // Default to TAO uppercase symbol. + if available_symbol.is_none() { + log::warn!( + "All available symbols have been exhausted for netuid: {:?}. Using default symbol.", + netuid + ); } + + // If we have exhausted all symbols, we use the default symbol. + available_symbol.unwrap_or(DEFAULT_SYMBOL.to_vec()) } } diff --git a/pallets/subtensor/src/tests/mock.rs b/pallets/subtensor/src/tests/mock.rs index d47fbc1ea..e9db6df6e 100644 --- a/pallets/subtensor/src/tests/mock.rs +++ b/pallets/subtensor/src/tests/mock.rs @@ -974,3 +974,12 @@ pub(crate) fn swap_alpha_to_tao(netuid: NetUid, alpha: u64) -> (u64, u64) { (result.amount_paid_out, result.fee_paid) } + +#[allow(dead_code)] +pub(crate) fn last_event() -> RuntimeEvent { + System::events().pop().expect("RuntimeEvent expected").event +} + +pub fn assert_last_event(generic_event: ::RuntimeEvent) { + frame_system::Pallet::::assert_last_event(generic_event.into()); +} diff --git a/pallets/subtensor/src/tests/subnet.rs b/pallets/subtensor/src/tests/subnet.rs index ebac3e786..69a5242d3 100644 --- a/pallets/subtensor/src/tests/subnet.rs +++ b/pallets/subtensor/src/tests/subnet.rs @@ -1,10 +1,12 @@ -use frame_support::{assert_noop, assert_ok}; +#![allow(clippy::unwrap_used)] +use super::mock::*; +use crate::subnets::symbols::{DEFAULT_SYMBOL, SYMBOLS}; +use crate::*; +use frame_support::{assert_err, assert_noop, assert_ok}; use frame_system::Config; use sp_core::U256; use super::mock; -use super::mock::*; -use crate::*; /*************************** pub fn do_start_call() tests @@ -202,27 +204,17 @@ fn test_register_network_min_burn_at_default() { let cost = SubtensorModule::get_network_lock_cost(); // Give coldkey enough for lock - SubtensorModule::add_balance_to_coldkey_account(&sn_owner_coldkey, cost + 10_000_000_000); + SubtensorModule::add_balance_to_coldkey_account(&sn_owner_coldkey, cost); // Register network assert_ok!(SubtensorModule::register_network( <::RuntimeOrigin>::signed(sn_owner_coldkey), sn_owner_hotkey )); - // Get last events - let events = System::events(); - let min_burn_event = events - .iter() - .filter(|event| { - matches!( - event.event, - RuntimeEvent::SubtensorModule(Event::::NetworkAdded(..)) - ) - }) - .next_back(); - - let netuid = match min_burn_event.map(|event| event.event.clone()) { - Some(RuntimeEvent::SubtensorModule(Event::::NetworkAdded(netuid, _))) => netuid, + + // Get netuid of the new network + let netuid = match last_event() { + RuntimeEvent::SubtensorModule(Event::::NetworkAdded(netuid, _)) => netuid, _ => panic!("Expected NetworkAdded event"), }; @@ -231,26 +223,122 @@ fn test_register_network_min_burn_at_default() { }); } -// cargo test --package pallet-subtensor --lib -- tests::subnet::test_no_duplicates_in_get_symbol_for_subnet --exact --show-output #[test] -fn test_no_duplicates_in_get_symbol_for_subnet() { - use std::collections::HashSet; +fn test_register_network_use_symbol_for_subnet_if_available() { + new_test_ext(1).execute_with(|| { + for i in 0..(SYMBOLS.len() - 1) { + let coldkey = U256::from(1_000_000 + i); + let hotkey = U256::from(2_000_000 + i); + let cost = SubtensorModule::get_network_lock_cost(); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, cost); + + assert_ok!(SubtensorModule::register_network( + <::RuntimeOrigin>::signed(coldkey), + hotkey + )); + + let netuid = match last_event() { + RuntimeEvent::SubtensorModule(Event::::NetworkAdded(netuid, _)) => netuid, + _ => panic!("Expected NetworkAdded event"), + }; + + // Ensure the symbol correspond to the netuid has been set + let expected_symbol = SYMBOLS.get(usize::from(u16::from(netuid))).unwrap(); + assert_eq!(TokenSymbol::::get(netuid), *expected_symbol); + } + }); +} - let mut seen = HashSet::new(); - for netuid in 0u16..=438 { - let netuid = NetUid::from(netuid); - let symbol = Pallet::::get_symbol_for_subnet(netuid); - assert!( - seen.insert(symbol.clone()), - "Duplicate symbol found for netuid {}: {:?}", - netuid, - symbol - ); - } +#[test] +fn test_register_network_use_next_available_symbol_if_symbol_for_subnet_is_taken() { + new_test_ext(1).execute_with(|| { + // Register 50 networks (additionnaly to the root network) + for i in 0..50 { + let coldkey = U256::from(1_000_000 + i); + let hotkey = U256::from(2_000_000 + i); + let cost = SubtensorModule::get_network_lock_cost(); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, cost); + + assert_ok!(SubtensorModule::register_network( + <::RuntimeOrigin>::signed(coldkey), + hotkey + )); + + let netuid = match last_event() { + RuntimeEvent::SubtensorModule(Event::::NetworkAdded(netuid, _)) => netuid, + _ => panic!("Expected NetworkAdded event"), + }; + + // Ensure the symbol correspond to the netuid has been set + let expected_symbol = SYMBOLS.get(usize::from(u16::from(netuid))).unwrap(); + assert_eq!(TokenSymbol::::get(netuid), *expected_symbol); + } + + // Swap some of the network symbol for the network 25 to network 51 symbol (not registered yet) + TokenSymbol::::insert(NetUid::from(25), SYMBOLS.get(51).unwrap().to_vec()); + + // Register a new network + let coldkey = U256::from(1_000_000 + 50); + let hotkey = U256::from(2_000_000 + 50); + let cost = SubtensorModule::get_network_lock_cost(); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, cost); + + assert_ok!(SubtensorModule::register_network( + <::RuntimeOrigin>::signed(coldkey), + hotkey + )); + + // Get netuid of the new network + let netuid = match last_event() { + RuntimeEvent::SubtensorModule(Event::::NetworkAdded(netuid, _)) => netuid, + _ => panic!("Expected NetworkAdded event"), + }; + + // We expect the symbol to be the one that was previously taken by network 25, before it was swapped + let expected_symbol = SYMBOLS.get(25).unwrap(); + assert_eq!(TokenSymbol::::get(netuid), *expected_symbol); + }); } -// cargo test --package pallet-subtensor --lib -- tests::subnet::test_subtoken_enable --exact --show-output +#[test] +fn test_register_network_use_default_symbol_if_all_symbols_are_taken() { + new_test_ext(1).execute_with(|| { + // Register networks until we have exhausted all symbols + for i in 0..(SYMBOLS.len() - 1) { + let coldkey = U256::from(1_000_000 + i); + let hotkey = U256::from(2_000_000 + i); + let cost = SubtensorModule::get_network_lock_cost(); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, cost); + + assert_ok!(SubtensorModule::register_network( + <::RuntimeOrigin>::signed(coldkey), + hotkey + )); + } + + // Register a new network + let coldkey = U256::from(1_000_000 + 50); + let hotkey = U256::from(2_000_000 + 50); + let cost = SubtensorModule::get_network_lock_cost(); + SubtensorModule::add_balance_to_coldkey_account(&coldkey, cost); + + assert_ok!(SubtensorModule::register_network( + <::RuntimeOrigin>::signed(coldkey), + hotkey + )); + + // Get netuid of the new network + let netuid = match last_event() { + RuntimeEvent::SubtensorModule(Event::::NetworkAdded(netuid, _)) => netuid, + _ => panic!("Expected NetworkAdded event"), + }; + assert_eq!(netuid, NetUid::from(SYMBOLS.len() as u16)); + // We expect the symbol to be the default symbol + assert_eq!(TokenSymbol::::get(netuid), *DEFAULT_SYMBOL); + }); +} +// cargo test --package pallet-subtensor --lib -- tests::subnet::test_subtoken_enable --exact --show-output #[test] fn test_subtoken_enable() { // ensure_subtoken_enabled @@ -661,3 +749,123 @@ fn test_user_liquidity_access_control() { )); }); } + +// cargo test --package pallet-subtensor --lib -- tests::subnet::test_no_duplicates_in_symbol_static --exact --show-output +#[test] +fn test_no_duplicates_in_symbol_static() { + use std::collections::HashSet; + + let mut seen = HashSet::new(); + for netuid in 0..(SYMBOLS.len() as u16) { + let symbol = SYMBOLS.get(usize::from(netuid)).unwrap(); + assert!( + seen.insert(symbol.to_vec()), + "Duplicate symbol found for netuid {}: {:?}", + netuid, + symbol + ); + } +} + +#[test] +fn test_get_symbol_for_subnet_returns_default_symbol_if_netuid_is_out_of_bounds() { + new_test_ext(1).execute_with(|| { + let netuid = NetUid::from(SYMBOLS.len() as u16 + 1); + let symbol = Pallet::::get_symbol_for_subnet(netuid); + assert_eq!(symbol, DEFAULT_SYMBOL); + }); +} + +#[test] +fn test_update_symbol_works_as_root_if_symbol_exists_and_available() { + new_test_ext(1).execute_with(|| { + let netuid = NetUid::from(1); + add_network(netuid, 10, 0); + + // only one network so we can set any symbol, except the root symbol + for i in 1..SYMBOLS.len() { + let symbol = SYMBOLS.get(i).unwrap().to_vec(); + assert_ok!(SubtensorModule::update_symbol( + ::RuntimeOrigin::root(), + netuid, + symbol.clone() + )); + + assert_eq!(TokenSymbol::::get(netuid), symbol); + assert_last_event::(Event::SymbolUpdated { netuid, symbol }.into()); + } + }); +} + +#[test] +fn test_update_symbol_works_as_subnet_owner_if_symbol_exists_and_available() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let netuid = NetUid::from(1); + add_network(netuid, 10, 0); + SubnetOwner::::insert(netuid, coldkey); + + // only one network so we can set any symbol, except the root symbol + for i in 1..SYMBOLS.len() { + let symbol = SYMBOLS.get(i).unwrap().to_vec(); + + assert_ok!(SubtensorModule::update_symbol( + ::RuntimeOrigin::signed(coldkey), + netuid, + symbol.clone() + )); + + assert_eq!(TokenSymbol::::get(netuid), symbol); + assert_last_event::(Event::SymbolUpdated { netuid, symbol }.into()); + } + }); +} + +#[test] +fn test_update_symbol_fails_if_symbol_doesnt_exist() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let netuid = NetUid::from(1); + add_network(netuid, 10, 0); + SubnetOwner::::insert(netuid, coldkey); + + assert_err!( + SubtensorModule::update_symbol( + ::RuntimeOrigin::signed(coldkey), + netuid, + b"TEST".to_vec() + ), + Error::::SymbolDoesNotExist + ); + }); +} + +#[test] +fn test_update_symbol_fails_if_symbol_already_in_use() { + new_test_ext(1).execute_with(|| { + let coldkey = U256::from(1); + let netuid = NetUid::from(1); + add_network(netuid, 10, 0); + SubnetOwner::::insert(netuid, coldkey); + + let coldkey2 = U256::from(2); + let netuid2 = NetUid::from(2); + add_network(netuid2, 10, 0); + SubnetOwner::::insert(netuid2, coldkey2); + + assert_ok!(SubtensorModule::update_symbol( + ::RuntimeOrigin::signed(coldkey), + netuid, + SYMBOLS.get(42).unwrap().to_vec() + )); + + assert_err!( + SubtensorModule::update_symbol( + ::RuntimeOrigin::signed(coldkey2), + netuid2, + SYMBOLS.get(42).unwrap().to_vec() + ), + Error::::SymbolAlreadyInUse + ); + }); +}