Skip to content

Commit f991965

Browse files
authored
Merge pull request #690 from opentensor/remove_registry
Add Chain IDS
2 parents a1e2287 + dd938c2 commit f991965

File tree

13 files changed

+1015
-1
lines changed

13 files changed

+1015
-1
lines changed

.rustfmt.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
##
77
# rustup run nightly -- rustfmt node/src/main.rs
88

9-
# max_width = 100
9+
# max_width = 180
1010
# hard_tabs = false
1111
# tab_spaces = 4
1212
# newline_style = "Auto"

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/delegate-info.json

Lines changed: 394 additions & 0 deletions
Large diffs are not rendered by default.

pallets/subtensor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ frame-support = { workspace = true }
2828
frame-system = { workspace = true }
2929
sp-io = { workspace = true }
3030
serde = { workspace = true, features = ["derive"] }
31+
serde_json = { workspace = true }
3132
serde-tuple-vec-map = { workspace = true }
3233
serde_bytes = { workspace = true, features = ["alloc"] }
3334
serde_with = { workspace = true, features = ["macros"] }

pallets/subtensor/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,25 @@ pub mod pallet {
133133
pub ip_type: u8,
134134
}
135135

136+
/// Struct for Prometheus.
137+
pub type ChainIdentityOf = ChainIdentity;
138+
/// Data structure for Prometheus information.
139+
#[derive(Encode, Decode, Default, TypeInfo, Clone, PartialEq, Eq, Debug)]
140+
pub struct ChainIdentity {
141+
/// The name of the chain identity
142+
pub name: Vec<u8>,
143+
/// The URL associated with the chain identity
144+
pub url: Vec<u8>,
145+
/// The image representation of the chain identity
146+
pub image: Vec<u8>,
147+
/// The Discord information for the chain identity
148+
pub discord: Vec<u8>,
149+
/// A description of the chain identity
150+
pub description: Vec<u8>,
151+
/// Additional information about the chain identity
152+
pub additional: Vec<u8>,
153+
}
154+
136155
/// ============================
137156
/// ==== Staking + Accounts ====
138157
/// ============================
@@ -1057,6 +1076,9 @@ pub mod pallet {
10571076
PrometheusInfoOf,
10581077
OptionQuery,
10591078
>;
1079+
#[pallet::storage] // --- MAP ( coldkey ) --> identity
1080+
pub type Identities<T: Config> =
1081+
StorageMap<_, Blake2_128Concat, T::AccountId, ChainIdentityOf, OptionQuery>;
10601082

10611083
/// =================================
10621084
/// ==== Axon / Promo Endpoints =====

pallets/subtensor/src/macros/dispatches.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,5 +901,41 @@ mod dispatches {
901901
Self::do_set_children(origin, hotkey, netuid, children)?;
902902
Ok(().into())
903903
}
904+
905+
/// ---- Set prometheus information for the neuron.
906+
/// # Args:
907+
/// * 'origin': (<T as frame_system::Config>Origin):
908+
/// - The signature of the calling hotkey.
909+
///
910+
/// * 'netuid' (u16):
911+
/// - The u16 network identifier.
912+
///
913+
/// * 'version' (u16):
914+
/// - The bittensor version identifier.
915+
///
916+
/// * 'ip' (u128):
917+
/// - The prometheus ip information as a u128 encoded integer.
918+
///
919+
/// * 'port' (u16):
920+
/// - The prometheus port information as a u16 encoded integer.
921+
///
922+
/// * 'ip_type' (u8):
923+
/// - The ip type v4 or v6.
924+
///
925+
#[pallet::call_index(68)]
926+
#[pallet::weight((Weight::from_parts(45_000_000, 0)
927+
.saturating_add(T::DbWeight::get().reads(4))
928+
.saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::Yes))]
929+
pub fn set_identity(
930+
origin: OriginFor<T>,
931+
name: Vec<u8>,
932+
url: Vec<u8>,
933+
image: Vec<u8>,
934+
discord: Vec<u8>,
935+
description: Vec<u8>,
936+
additional: Vec<u8>,
937+
) -> DispatchResult {
938+
Self::do_set_identity(origin, name, url, image, discord, description, additional)
939+
}
904940
}
905941
}

pallets/subtensor/src/macros/errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,5 +168,7 @@ mod errors {
168168
TooManyChildren,
169169
/// Default transaction rate limit exceeded.
170170
TxRateLimitExceeded,
171+
/// Invalid identity.
172+
InvalidIdentity,
171173
}
172174
}

pallets/subtensor/src/macros/events.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,5 +177,7 @@ mod events {
177177
HotkeyEmissionTempoSet(u64),
178178
/// The network maximum stake has been set
179179
NetworkMaxStakeSet(u16, u64),
180+
/// The identity of a coldkey has been set
181+
ChainIdentitySet(T::AccountId),
180182
}
181183
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
use crate::alloc::borrow::ToOwned;
2+
use codec::Decode;
3+
use scale_info::prelude::{string::String, vec::Vec};
4+
use serde::Deserialize;
5+
use sp_core::{crypto::Ss58Codec, ConstU32};
6+
use sp_runtime::{AccountId32, BoundedVec};
7+
8+
use super::*;
9+
use frame_support::{traits::Get, weights::Weight};
10+
use log;
11+
12+
#[derive(Deserialize, Debug)]
13+
struct RegistrationRecordJSON {
14+
address: String,
15+
name: String,
16+
url: String,
17+
description: String,
18+
}
19+
20+
fn string_to_bounded_vec(input: &str) -> Result<BoundedVec<u8, ConstU32<1024>>, &'static str> {
21+
let vec_u8: Vec<u8> = input.to_owned().into_bytes();
22+
23+
// Check if the length is within bounds
24+
if vec_u8.len() > 64 {
25+
return Err("Input string is too long");
26+
}
27+
28+
// Convert to BoundedVec
29+
BoundedVec::<u8, ConstU32<1024>>::try_from(vec_u8)
30+
.map_err(|_| "Failed to convert to BoundedVec")
31+
}
32+
33+
pub fn migrate_set_hotkey_identities<T: Config>() -> Weight {
34+
let migration_name = b"fix_total_coldkey_stake_v7".to_vec();
35+
36+
// Initialize the weight with one read operation.
37+
let mut weight = T::DbWeight::get().reads(1);
38+
39+
// Check if the migration has already run
40+
if HasMigrationRun::<T>::get(&migration_name) {
41+
log::info!(
42+
"Migration '{:?}' has already run. Skipping.",
43+
migration_name
44+
);
45+
return weight;
46+
}
47+
log::info!(
48+
"Running migration '{}'",
49+
String::from_utf8_lossy(&migration_name)
50+
);
51+
52+
// Include the JSON file with delegate info
53+
let data = include_str!("../../../../docs/delegate-info.json");
54+
55+
// Iterate over all the delegate records
56+
if let Ok(delegates) = serde_json::from_str::<Vec<RegistrationRecordJSON>>(data) {
57+
// Iterate through the delegates
58+
for delegate in delegates.iter() {
59+
// Convert fields to bounded vecs
60+
let name_result = string_to_bounded_vec(&delegate.name);
61+
let desc_result = string_to_bounded_vec(&delegate.description);
62+
let url_result = string_to_bounded_vec(&delegate.url);
63+
let hotkey: AccountId32 = match AccountId32::from_ss58check(&delegate.address) {
64+
Ok(account) => account,
65+
Err(_) => {
66+
log::warn!(
67+
"Invalid SS58 address: {:?}. Skipping this delegate.",
68+
delegate.address
69+
);
70+
continue;
71+
}
72+
};
73+
let decoded_hotkey: T::AccountId = match T::AccountId::decode(&mut hotkey.as_ref()) {
74+
Ok(decoded) => decoded,
75+
Err(e) => {
76+
log::warn!("Failed to decode hotkey: {:?}. Skipping this delegate.", e);
77+
continue;
78+
}
79+
};
80+
log::info!("Hotkey unwrapped: {:?}", decoded_hotkey);
81+
82+
// If we should continue with real values.
83+
let mut name: BoundedVec<u8, ConstU32<1024>> = BoundedVec::default();
84+
let mut description: BoundedVec<u8, ConstU32<1024>> = BoundedVec::default();
85+
let mut url: BoundedVec<u8, ConstU32<1024>> = BoundedVec::default();
86+
if let Ok(n) = name_result {
87+
name = n;
88+
}
89+
if let Ok(d) = desc_result {
90+
description = d;
91+
}
92+
if let Ok(u) = url_result {
93+
url = u;
94+
}
95+
96+
// Unwrap the real values.
97+
let image: BoundedVec<u8, ConstU32<1024>> = BoundedVec::default();
98+
let discord: BoundedVec<u8, ConstU32<1024>> = BoundedVec::default();
99+
let additional: BoundedVec<u8, ConstU32<1024>> = BoundedVec::default();
100+
101+
// Create the chain identity.
102+
let identity = ChainIdentityOf {
103+
name: name.into(),
104+
url: url.into(),
105+
image: image.into(),
106+
discord: discord.into(),
107+
description: description.into(),
108+
additional: additional.into(),
109+
};
110+
111+
// Log the identity details
112+
log::info!("Setting identity for hotkey: {:?}", hotkey);
113+
log::info!("Name: {:?}", String::from_utf8_lossy(&identity.name));
114+
log::info!("URL: {:?}", String::from_utf8_lossy(&identity.url));
115+
log::info!("Image: {:?}", String::from_utf8_lossy(&identity.image));
116+
log::info!("Discord: {:?}", String::from_utf8_lossy(&identity.discord));
117+
log::info!(
118+
"Description: {:?}",
119+
String::from_utf8_lossy(&identity.description)
120+
);
121+
log::info!(
122+
"Additional: {:?}",
123+
String::from_utf8_lossy(&identity.additional)
124+
);
125+
126+
// Check validation.
127+
let total_length = identity
128+
.name
129+
.len()
130+
.saturating_add(identity.url.len())
131+
.saturating_add(identity.image.len())
132+
.saturating_add(identity.discord.len())
133+
.saturating_add(identity.description.len())
134+
.saturating_add(identity.additional.len());
135+
let is_valid: bool = total_length <= 256 + 256 + 1024 + 256 + 1024 + 1024
136+
&& identity.name.len() <= 256
137+
&& identity.url.len() <= 256
138+
&& identity.image.len() <= 1024
139+
&& identity.discord.len() <= 256
140+
&& identity.description.len() <= 1024
141+
&& identity.additional.len() <= 1024;
142+
if !is_valid {
143+
continue;
144+
}
145+
146+
// Get the owning coldkey.
147+
let coldkey = Owner::<T>::get(decoded_hotkey.clone());
148+
weight = weight.saturating_add(T::DbWeight::get().reads(1));
149+
150+
// Sink into the map.
151+
Identities::<T>::insert(coldkey.clone(), identity.clone());
152+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
153+
}
154+
}
155+
// Mark the migration as completed
156+
HasMigrationRun::<T>::insert(&migration_name, true);
157+
weight = weight.saturating_add(T::DbWeight::get().writes(1));
158+
159+
log::info!(
160+
"Migration '{:?}' completed. Storage version set to 7.",
161+
String::from_utf8_lossy(&migration_name)
162+
);
163+
164+
// Return the migration weight.
165+
weight
166+
}

pallets/subtensor/src/migrations/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::*;
2+
pub mod migrate_chain_identity;
23
pub mod migrate_create_root_network;
34
pub mod migrate_delete_subnet_21;
45
pub mod migrate_delete_subnet_3;

0 commit comments

Comments
 (0)