From 8144ed0bc77c1da70aa6a1daf8462bd7a0b811ab Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 21 Jan 2025 23:55:50 +0800 Subject: [PATCH 1/8] update neuron precompile --- runtime/src/precompiles/neuron.rs | 173 ++++++++++++++++++++ runtime/src/precompiles/solidity/neuron.abi | 134 +++++++++++++++ runtime/src/precompiles/solidity/neuron.sol | 68 ++++++++ 3 files changed, 375 insertions(+) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 341683cb36..135911a823 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -23,6 +23,23 @@ impl NeuronPrecompile { id if id == get_method_id("burnedRegister(uint16,bytes32)") => { Self::burned_register(handle, &method_input) } + id if id + == get_method_id( + "serveAxon(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8)", + ) => + { + Self::serve_axon(handle, &method_input) + } + id if id + == get_method_id( + "serveAxonTls(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8,bytes)", + ) => + { + Self::serve_axon_tls(handle, &method_input) + } + id if id == get_method_id("servePrometheus(uint16,uint32,uint128,uint16,uint8)") => { + Self::serve_prometheus(handle, &method_input) + } _ => Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, @@ -40,6 +57,53 @@ impl NeuronPrecompile { dispatch(handle, call, NEURON_CONTRACT_ADDRESS) } + pub fn serve_axon(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, version, ip, port, ip_type, protocol, placeholder1, placeholder2) = + Self::parse_serve_axon_parameters(data)?; + let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::serve_axon { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + }); + dispatch(handle, call, NEURON_CONTRACT_ADDRESS) + } + + pub fn serve_axon_tls(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, version, ip, port, ip_type, protocol, placeholder1, placeholder2, certificate) = + Self::parse_serve_axon_tls_parameters(data)?; + let call = + RuntimeCall::SubtensorModule(pallet_subtensor::Call::::serve_axon_tls { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + certificate, + }); + dispatch(handle, call, NEURON_CONTRACT_ADDRESS) + } + + pub fn serve_prometheus(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, version, ip, port, ip_type) = Self::parse_serve_prometheus_parameters(data)?; + let call = + RuntimeCall::SubtensorModule(pallet_subtensor::Call::::serve_prometheus { + netuid, + version, + ip, + port, + ip_type, + }); + dispatch(handle, call, NEURON_CONTRACT_ADDRESS) + } + fn parse_netuid_hotkey_parameter(data: &[u8]) -> Result<(u16, [u8; 32]), PrecompileFailure> { if data.len() < 64 { return Err(PrecompileFailure::Error { @@ -55,4 +119,113 @@ impl NeuronPrecompile { Ok((netuid, parameter)) } + + fn parse_serve_axon_parameters( + data: &[u8], + ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8), PrecompileFailure> { + if data.len() < 256 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut version_vec = [0u8; 4]; + version_vec.copy_from_slice(get_slice(data, 60, 64)?); + let version = u32::from_be_bytes(version_vec); + + let mut ip_vec = [0u8; 16]; + ip_vec.copy_from_slice(get_slice(data, 80, 96)?); + let ip = u128::from_be_bytes(ip_vec); + + let mut port_vec = [0u8; 2]; + port_vec.copy_from_slice(get_slice(data, 126, 128)?); + let port = u16::from_be_bytes(port_vec); + + let ip_type = data[160]; + let protocol = data[192]; + let placeholder1 = data[224]; + let placeholder2 = data[256]; + Ok(( + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + )) + } + + fn parse_serve_axon_tls_parameters( + data: &[u8], + ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8, vec::Vec), PrecompileFailure> { + if data.len() < 256 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut version_vec = [0u8; 4]; + version_vec.copy_from_slice(get_slice(data, 60, 64)?); + let version = u32::from_be_bytes(version_vec); + + let mut ip_vec = [0u8; 16]; + ip_vec.copy_from_slice(get_slice(data, 80, 96)?); + let ip = u128::from_be_bytes(ip_vec); + + let mut port_vec = [0u8; 2]; + port_vec.copy_from_slice(get_slice(data, 126, 128)?); + let port = u16::from_be_bytes(port_vec); + + let ip_type = data[160]; + let protocol = data[192]; + let placeholder1 = data[224]; + let placeholder2 = data[256]; + Ok(( + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + vec![], + )) + } + + fn parse_serve_prometheus_parameters( + data: &[u8], + ) -> Result<(u16, u32, u128, u16, u8), PrecompileFailure> { + if data.len() < 160 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut version_vec = [0u8; 4]; + version_vec.copy_from_slice(get_slice(data, 60, 64)?); + let version = u32::from_be_bytes(version_vec); + + let mut ip_vec = [0u8; 16]; + ip_vec.copy_from_slice(get_slice(data, 80, 96)?); + let ip = u128::from_be_bytes(ip_vec); + + let mut port_vec = [0u8; 2]; + port_vec.copy_from_slice(get_slice(data, 126, 128)?); + let port = u16::from_be_bytes(port_vec); + + let ip_type = data[160]; + Ok((netuid, version, ip, port, ip_type)) + } } diff --git a/runtime/src/precompiles/solidity/neuron.abi b/runtime/src/precompiles/solidity/neuron.abi index 09a14eb2db..52e371fdbe 100644 --- a/runtime/src/precompiles/solidity/neuron.abi +++ b/runtime/src/precompiles/solidity/neuron.abi @@ -16,5 +16,139 @@ "outputs": [], "stateMutability": "payable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "version", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ip", + "type": "uint128" + }, + { + "internalType": "uint16", + "name": "port", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "ipType", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "protocol", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder1", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder2", + "type": "uint8" + } + ], + "name": "serveAxon", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "version", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ip", + "type": "uint128" + }, + { + "internalType": "uint16", + "name": "port", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "ipType", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "protocol", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder1", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder2", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "certificate", + "type": "bytes" + } + ], + "name": "serveAxonTls", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "version", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ip", + "type": "uint128" + }, + { + "internalType": "uint16", + "name": "port", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "ipType", + "type": "uint8" + } + ], + "name": "servePrometheus", + "outputs": [], + "stateMutability": "payable", + "type": "function" } ] diff --git a/runtime/src/precompiles/solidity/neuron.sol b/runtime/src/precompiles/solidity/neuron.sol index a768423398..c4d9e5b61e 100644 --- a/runtime/src/precompiles/solidity/neuron.sol +++ b/runtime/src/precompiles/solidity/neuron.sol @@ -11,4 +11,72 @@ interface INeuron { * @param hotkey The hotkey public key (32 bytes). */ function burnedRegister(uint16 netuid, bytes32 hotkey) external payable; + + /** + * @dev Registers axon information for a neuron. + * This function is used to serve axon information, including the subnet to register to, version, IP address, port, IP type, protocol, and placeholders for future use. + * + * @param netuid The subnet to register the axon to (uint16). + * @param version The version of the axon (uint32). + * @param ip The IP address of the axon (uint128). + * @param port The port number of the axon (uint16). + * @param ipType The type of IP address (uint8). + * @param protocol The protocol used by the axon (uint8). + * @param placeholder1 Placeholder for future use (uint8). + * @param placeholder2 Placeholder for future use (uint8). + */ + function serveAxon( + uint16 netuid, + uint32 version, + uint128 ip, + uint16 port, + uint8 ipType, + uint8 protocol, + uint8 placeholder1, + uint8 placeholder2 + ) external payable; + + /** + * @dev Serves axon information for a neuron over TLS. + * This function is used to serve axon information, including the subnet to register to, version, IP address, port, IP type, protocol, and placeholders for future use. + * + * @param netuid The subnet to register the axon to (uint16). + * @param version The version of the axon (uint32). + * @param ip The IP address of the axon (uint128). + * @param port The port number of the axon (uint16). + * @param ipType The type of IP address (uint8). + * @param protocol The protocol used by the axon (uint8). + * @param placeholder1 Placeholder for future use (uint8). + * @param placeholder2 Placeholder for future use (uint8). + * @param certificate The TLS certificate for the axon (bytes). + */ + function serveAxonTls( + uint16 netuid, + uint32 version, + uint128 ip, + uint16 port, + uint8 ipType, + uint8 protocol, + uint8 placeholder1, + uint8 placeholder2, + bytes memory certificate + ) external payable; + + /** + * @dev Serves Prometheus information for a neuron. + * This function is used to serve Prometheus information, including the subnet to register to, version, IP address, port, and IP type. + * + * @param netuid The subnet to register the Prometheus information to (uint16). + * @param version The version of the Prometheus information (uint32). + * @param ip The IP address of the Prometheus information (uint128). + * @param port The port number of the Prometheus information (uint16). + * @param ipType The type of IP address (uint8). + */ + function servePrometheus( + uint16 netuid, + uint32 version, + uint128 ip, + uint16 port, + uint8 ipType + ) external payable; } From cc03f1a971043e7be8e36a0275da551c31aa3373 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 10:43:14 +0800 Subject: [PATCH 2/8] fix bug --- runtime/src/precompiles/neuron.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 135911a823..d7b4833b6e 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -144,10 +144,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[160]; - let protocol = data[192]; - let placeholder1 = data[224]; - let placeholder2 = data[256]; + let ip_type = data[159]; + let protocol = data[191]; + let placeholder1 = data[223]; + let placeholder2 = data[255]; Ok(( netuid, version, @@ -184,10 +184,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[160]; - let protocol = data[192]; - let placeholder1 = data[224]; - let placeholder2 = data[256]; + let ip_type = data[159]; + let protocol = data[191]; + let placeholder1 = data[223]; + let placeholder2 = data[255]; Ok(( netuid, version, @@ -225,7 +225,7 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[160]; + let ip_type = data[159]; Ok((netuid, version, ip, port, ip_type)) } } From 3fd2c8314e229c0602ad350e7d30b5f8dd27ec41 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 20:07:28 +0800 Subject: [PATCH 3/8] commit Cargo.lock --- runtime/src/precompiles/neuron.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index d7b4833b6e..f8a006e285 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -163,7 +163,7 @@ impl NeuronPrecompile { fn parse_serve_axon_tls_parameters( data: &[u8], ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8, vec::Vec), PrecompileFailure> { - if data.len() < 256 { + if data.len() < 288 { return Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, }); @@ -188,6 +188,17 @@ impl NeuronPrecompile { let protocol = data[191]; let placeholder1 = data[223]; let placeholder2 = data[255]; + + let mut len_position_vec = [0u8; 2]; + len_position_vec.copy_from_slice(get_slice(data, 286, 288)?); + let len_position = u16::from_be_bytes(len_position_vec) as usize; + + let mut len_vec = [0u8; 2]; + len_vec.copy_from_slice(get_slice(data, len_position + 30, len_position + 32)?); + let vec_len = u16::from_be_bytes(len_vec) as usize; + + let vec_result = get_slice(data, len_position + 32, len_position + 32 + vec_len)?.to_vec(); + Ok(( netuid, version, @@ -197,7 +208,7 @@ impl NeuronPrecompile { protocol, placeholder1, placeholder2, - vec![], + vec_result, )) } From ef3af14a0b22779dc2ae9891b8b308fb8d6393bf Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 20:14:20 +0800 Subject: [PATCH 4/8] commit Cargo.lock --- runtime/src/precompiles/mod.rs | 11 +++++++++++ runtime/src/precompiles/neuron.rs | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 3d2c19ae9d..cefa3a1653 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -232,3 +232,14 @@ fn dispatch( }), } } + +pub fn get_single_u8(data: &[u8], index: usize) -> Result { + if let Some(result) = data.get(index) { + Ok(*result) + } else { + log::error!("fail to get data from data, {:?}, at {}", &data, index); + Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }) + } +} diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index f8a006e285..cb6295c241 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -1,6 +1,6 @@ use pallet_evm::{ExitError, PrecompileFailure, PrecompileHandle, PrecompileResult}; -use crate::precompiles::{dispatch, get_method_id, get_slice}; +use crate::precompiles::{dispatch, get_method_id, get_single_u8, get_slice}; use sp_std::vec; use crate::{Runtime, RuntimeCall}; @@ -144,10 +144,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[159]; - let protocol = data[191]; - let placeholder1 = data[223]; - let placeholder2 = data[255]; + let ip_type = get_single_u8(data, 159)?; + let protocol = get_single_u8(data, 191)?; + let placeholder1 = get_single_u8(data, 223)?; + let placeholder2 = get_single_u8(data, 255)?; Ok(( netuid, version, @@ -184,10 +184,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[159]; - let protocol = data[191]; - let placeholder1 = data[223]; - let placeholder2 = data[255]; + let ip_type = get_single_u8(data, 159)?; + let protocol = get_single_u8(data, 191)?; + let placeholder1 = get_single_u8(data, 223)?; + let placeholder2 = get_single_u8(data, 255)?; let mut len_position_vec = [0u8; 2]; len_position_vec.copy_from_slice(get_slice(data, 286, 288)?); @@ -236,7 +236,7 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[159]; + let ip_type = get_single_u8(data, 159)?; Ok((netuid, version, ip, port, ip_type)) } } From 959d981c3d5cae9fe0482554dcc35a3b78ca2613 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 20:16:30 +0800 Subject: [PATCH 5/8] add document for function --- runtime/src/precompiles/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index cefa3a1653..4e9c93e5a7 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -233,6 +233,14 @@ fn dispatch( } } +/// Retrieves a single u8 value from the given data slice at the specified index. +/// +/// # Args +/// * `data`: The slice of bytes from which to retrieve the u8 value. +/// * `index`: The index within the `data` slice where the u8 value is located. +/// +/// # Returns +/// A `Result` containing the u8 value at the specified index if successful, or a `PrecompileFailure` if the index is out of range. pub fn get_single_u8(data: &[u8], index: usize) -> Result { if let Some(result) = data.get(index) { Ok(*result) From 79e121baed964956db62f6bdbd10f2c1f54779b3 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 31 Jan 2025 20:44:00 +0800 Subject: [PATCH 6/8] add length check --- runtime/src/precompiles/neuron.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 6a1e40b15d..52c4ca7a7d 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -194,14 +194,14 @@ impl NeuronPrecompile { fn parse_serve_axon_tls_parameters( data: &[u8], ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8, vec::Vec), PrecompileFailure> { - if data.len() < 288 { + let data_len = data.len(); + if data_len < 288 { return Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + + let netuid = parse_netuid(data, 30)?; let mut version_vec = [0u8; 4]; version_vec.copy_from_slice(get_slice(data, 60, 64)?); @@ -224,6 +224,17 @@ impl NeuronPrecompile { len_position_vec.copy_from_slice(get_slice(data, 286, 288)?); let len_position = u16::from_be_bytes(len_position_vec) as usize; + if len_position > data_len { + log::error!( + "the start position of certificate as {} is bigger than whole data len {}", + subnet_contact_start, + data_len + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut len_vec = [0u8; 2]; len_vec.copy_from_slice(get_slice(data, len_position + 30, len_position + 32)?); let vec_len = u16::from_be_bytes(len_vec) as usize; From c7366eb64e80258d4169eca4a0fb3c7b1f60d490 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 31 Jan 2025 20:56:09 +0800 Subject: [PATCH 7/8] fix compile --- runtime/src/precompiles/neuron.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 52c4ca7a7d..9c8d6dced3 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -227,7 +227,7 @@ impl NeuronPrecompile { if len_position > data_len { log::error!( "the start position of certificate as {} is bigger than whole data len {}", - subnet_contact_start, + len_position, data_len ); return Err(PrecompileFailure::Error { From d3b97d31d21e8884a90718687c7abf1e0eb0fda0 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 4 Feb 2025 08:26:17 +0800 Subject: [PATCH 8/8] safe math --- runtime/src/precompiles/neuron.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 01d5cefee7..38fb701fbe 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -145,7 +145,6 @@ impl NeuronPrecompile { handle.context().caller, ); - // Dispatch the register_network call try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } @@ -167,7 +166,6 @@ impl NeuronPrecompile { handle.context().caller, ); - // Dispatch the register_network call try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } @@ -191,7 +189,6 @@ impl NeuronPrecompile { handle.context().caller, ); - // Dispatch the register_network call try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } @@ -504,9 +501,8 @@ impl NeuronPrecompile { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + + let netuid = parse_netuid(data, 30)?; let mut version_vec = [0u8; 4]; version_vec.copy_from_slice(get_slice(data, 60, 64)?); @@ -584,7 +580,12 @@ impl NeuronPrecompile { len_vec.copy_from_slice(get_slice(data, len_position + 30, len_position + 32)?); let vec_len = u16::from_be_bytes(len_vec) as usize; - let vec_result = get_slice(data, len_position + 32, len_position + 32 + vec_len)?.to_vec(); + let vec_result = get_slice( + data, + len_position + 32, + len_position.saturating_add(32).saturating_add(vec_len), + )? + .to_vec(); Ok(( netuid, @@ -607,9 +608,8 @@ impl NeuronPrecompile { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + + let netuid = parse_netuid(data, 30)?; let mut version_vec = [0u8; 4]; version_vec.copy_from_slice(get_slice(data, 60, 64)?);