Skip to content

Commit 3fb3061

Browse files
authored
Merge pull request #1174 from opentensor/serve-axon-promethoeus
update neuron precompile
2 parents fc49aca + 925dd85 commit 3fb3061

File tree

4 files changed

+436
-2
lines changed

4 files changed

+436
-2
lines changed

runtime/src/precompiles/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,22 @@ fn try_dispatch_runtime_call(
236236
}
237237
}
238238
}
239+
240+
/// Retrieves a single u8 value from the given data slice at the specified index.
241+
///
242+
/// # Args
243+
/// * `data`: The slice of bytes from which to retrieve the u8 value.
244+
/// * `index`: The index within the `data` slice where the u8 value is located.
245+
///
246+
/// # Returns
247+
/// A `Result` containing the u8 value at the specified index if successful, or a `PrecompileFailure` if the index is out of range.
248+
pub fn get_single_u8(data: &[u8], index: usize) -> Result<u8, PrecompileFailure> {
249+
if let Some(result) = data.get(index) {
250+
Ok(*result)
251+
} else {
252+
log::error!("fail to get data from data, {:?}, at {}", &data, index);
253+
Err(PrecompileFailure::Error {
254+
exit_status: ExitError::InvalidRange,
255+
})
256+
}
257+
}

runtime/src/precompiles/neuron.rs

Lines changed: 215 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use pallet_evm::{
44
};
55

66
use crate::precompiles::{
7-
get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call,
7+
get_method_id, get_pubkey, get_single_u8, get_slice, parse_netuid, try_dispatch_runtime_call,
88
};
99
use crate::{Runtime, RuntimeCall};
1010
use frame_system::RawOrigin;
@@ -60,6 +60,23 @@ impl NeuronPrecompile {
6060
id if id == get_method_id("burnedRegister(uint16,bytes32)") => {
6161
Self::burned_register(handle, &method_input)
6262
}
63+
id if id
64+
== get_method_id(
65+
"serveAxon(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8)",
66+
) =>
67+
{
68+
Self::serve_axon(handle, &method_input)
69+
}
70+
id if id
71+
== get_method_id(
72+
"serveAxonTls(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8,bytes)",
73+
) =>
74+
{
75+
Self::serve_axon_tls(handle, &method_input)
76+
}
77+
id if id == get_method_id("servePrometheus(uint16,uint32,uint128,uint16,uint8)") => {
78+
Self::serve_prometheus(handle, &method_input)
79+
}
6380

6481
_ => Err(PrecompileFailure::Error {
6582
exit_status: ExitError::InvalidRange,
@@ -123,11 +140,74 @@ impl NeuronPrecompile {
123140
netuid,
124141
hotkey,
125142
});
143+
let account_id =
144+
<HashedAddressMapping<BlakeTwo256> as AddressMapping<AccountId32>>::into_account_id(
145+
handle.context().caller,
146+
);
147+
148+
try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))
149+
}
126150

151+
pub fn serve_axon(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult {
152+
let (netuid, version, ip, port, ip_type, protocol, placeholder1, placeholder2) =
153+
Self::parse_serve_axon_parameters(data)?;
154+
let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::<Runtime>::serve_axon {
155+
netuid,
156+
version,
157+
ip,
158+
port,
159+
ip_type,
160+
protocol,
161+
placeholder1,
162+
placeholder2,
163+
});
127164
let account_id =
128165
<HashedAddressMapping<BlakeTwo256> as AddressMapping<AccountId32>>::into_account_id(
129166
handle.context().caller,
130167
);
168+
169+
try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))
170+
}
171+
172+
pub fn serve_axon_tls(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult {
173+
let (netuid, version, ip, port, ip_type, protocol, placeholder1, placeholder2, certificate) =
174+
Self::parse_serve_axon_tls_parameters(data)?;
175+
let call =
176+
RuntimeCall::SubtensorModule(pallet_subtensor::Call::<Runtime>::serve_axon_tls {
177+
netuid,
178+
version,
179+
ip,
180+
port,
181+
ip_type,
182+
protocol,
183+
placeholder1,
184+
placeholder2,
185+
certificate,
186+
});
187+
let account_id =
188+
<HashedAddressMapping<BlakeTwo256> as AddressMapping<AccountId32>>::into_account_id(
189+
handle.context().caller,
190+
);
191+
192+
try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))
193+
}
194+
195+
pub fn serve_prometheus(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult {
196+
let (netuid, version, ip, port, ip_type) = Self::parse_serve_prometheus_parameters(data)?;
197+
let call =
198+
RuntimeCall::SubtensorModule(pallet_subtensor::Call::<Runtime>::serve_prometheus {
199+
netuid,
200+
version,
201+
ip,
202+
port,
203+
ip_type,
204+
});
205+
let account_id =
206+
<HashedAddressMapping<BlakeTwo256> as AddressMapping<AccountId32>>::into_account_id(
207+
handle.context().caller,
208+
);
209+
210+
// Dispatch the register_network call
131211
try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))
132212
}
133213

@@ -412,4 +492,138 @@ impl NeuronPrecompile {
412492

413493
Ok((netuid, uids, values, salt, version_key))
414494
}
495+
496+
fn parse_serve_axon_parameters(
497+
data: &[u8],
498+
) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8), PrecompileFailure> {
499+
if data.len() < 256 {
500+
return Err(PrecompileFailure::Error {
501+
exit_status: ExitError::InvalidRange,
502+
});
503+
}
504+
505+
let netuid = parse_netuid(data, 30)?;
506+
507+
let mut version_vec = [0u8; 4];
508+
version_vec.copy_from_slice(get_slice(data, 60, 64)?);
509+
let version = u32::from_be_bytes(version_vec);
510+
511+
let mut ip_vec = [0u8; 16];
512+
ip_vec.copy_from_slice(get_slice(data, 80, 96)?);
513+
let ip = u128::from_be_bytes(ip_vec);
514+
515+
let mut port_vec = [0u8; 2];
516+
port_vec.copy_from_slice(get_slice(data, 126, 128)?);
517+
let port = u16::from_be_bytes(port_vec);
518+
519+
let ip_type = get_single_u8(data, 159)?;
520+
let protocol = get_single_u8(data, 191)?;
521+
let placeholder1 = get_single_u8(data, 223)?;
522+
let placeholder2 = get_single_u8(data, 255)?;
523+
Ok((
524+
netuid,
525+
version,
526+
ip,
527+
port,
528+
ip_type,
529+
protocol,
530+
placeholder1,
531+
placeholder2,
532+
))
533+
}
534+
535+
fn parse_serve_axon_tls_parameters(
536+
data: &[u8],
537+
) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8, vec::Vec<u8>), PrecompileFailure> {
538+
let data_len = data.len();
539+
if data_len < 288 {
540+
return Err(PrecompileFailure::Error {
541+
exit_status: ExitError::InvalidRange,
542+
});
543+
}
544+
545+
let netuid = parse_netuid(data, 30)?;
546+
547+
let mut version_vec = [0u8; 4];
548+
version_vec.copy_from_slice(get_slice(data, 60, 64)?);
549+
let version = u32::from_be_bytes(version_vec);
550+
551+
let mut ip_vec = [0u8; 16];
552+
ip_vec.copy_from_slice(get_slice(data, 80, 96)?);
553+
let ip = u128::from_be_bytes(ip_vec);
554+
555+
let mut port_vec = [0u8; 2];
556+
port_vec.copy_from_slice(get_slice(data, 126, 128)?);
557+
let port = u16::from_be_bytes(port_vec);
558+
559+
let ip_type = get_single_u8(data, 159)?;
560+
let protocol = get_single_u8(data, 191)?;
561+
let placeholder1 = get_single_u8(data, 223)?;
562+
let placeholder2 = get_single_u8(data, 255)?;
563+
564+
let mut len_position_vec = [0u8; 2];
565+
len_position_vec.copy_from_slice(get_slice(data, 286, 288)?);
566+
let len_position = u16::from_be_bytes(len_position_vec) as usize;
567+
568+
if len_position > data_len {
569+
log::error!(
570+
"the start position of certificate as {} is bigger than whole data len {}",
571+
len_position,
572+
data_len
573+
);
574+
return Err(PrecompileFailure::Error {
575+
exit_status: ExitError::InvalidRange,
576+
});
577+
}
578+
579+
let mut len_vec = [0u8; 2];
580+
len_vec.copy_from_slice(get_slice(data, len_position + 30, len_position + 32)?);
581+
let vec_len = u16::from_be_bytes(len_vec) as usize;
582+
583+
let vec_result = get_slice(
584+
data,
585+
len_position + 32,
586+
len_position.saturating_add(32).saturating_add(vec_len),
587+
)?
588+
.to_vec();
589+
590+
Ok((
591+
netuid,
592+
version,
593+
ip,
594+
port,
595+
ip_type,
596+
protocol,
597+
placeholder1,
598+
placeholder2,
599+
vec_result,
600+
))
601+
}
602+
603+
fn parse_serve_prometheus_parameters(
604+
data: &[u8],
605+
) -> Result<(u16, u32, u128, u16, u8), PrecompileFailure> {
606+
if data.len() < 160 {
607+
return Err(PrecompileFailure::Error {
608+
exit_status: ExitError::InvalidRange,
609+
});
610+
}
611+
612+
let netuid = parse_netuid(data, 30)?;
613+
614+
let mut version_vec = [0u8; 4];
615+
version_vec.copy_from_slice(get_slice(data, 60, 64)?);
616+
let version = u32::from_be_bytes(version_vec);
617+
618+
let mut ip_vec = [0u8; 16];
619+
ip_vec.copy_from_slice(get_slice(data, 80, 96)?);
620+
let ip = u128::from_be_bytes(ip_vec);
621+
622+
let mut port_vec = [0u8; 2];
623+
port_vec.copy_from_slice(get_slice(data, 126, 128)?);
624+
let port = u16::from_be_bytes(port_vec);
625+
626+
let ip_type = get_single_u8(data, 159)?;
627+
Ok((netuid, version, ip, port, ip_type))
628+
}
415629
}

0 commit comments

Comments
 (0)