From 04300f545cea1d28eb68c4251b32666f15155008 Mon Sep 17 00:00:00 2001 From: open-junius Date: Sun, 1 Dec 2024 15:36:54 +0800 Subject: [PATCH 1/9] init solution --- runtime/src/precompiles/metagraph.rs | 190 ++++++++++++++++++ runtime/src/precompiles/mod.rs | 6 + .../src/precompiles/solidity/metagraph.abi | 21 ++ .../src/precompiles/solidity/metagraph.sol | 14 ++ 4 files changed, 231 insertions(+) create mode 100644 runtime/src/precompiles/metagraph.rs create mode 100644 runtime/src/precompiles/solidity/metagraph.abi create mode 100644 runtime/src/precompiles/solidity/metagraph.sol diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs new file mode 100644 index 0000000000..85a1e060ec --- /dev/null +++ b/runtime/src/precompiles/metagraph.rs @@ -0,0 +1,190 @@ +extern crate alloc; + +use alloc::vec::Vec; + +use crate::precompiles::{get_method_id, get_slice}; +use crate::{Runtime, RuntimeCall}; +use ed25519_dalek::{Signature, Verifier, VerifyingKey}; +use fp_evm::{ + ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure, PrecompileHandle, + PrecompileOutput, PrecompileResult, +}; +use sp_core::U256; +use sp_std::vec; +pub const METAGRAPH_PRECOMPILE_INDEX: u64 = 2050; +pub struct MetagraphPrecompile; + +/* +get_uid_count SubnetworkN +get_stake Total stake of the neuron in Tao +get_rank Rank score of the neuron +get_trust Trust score assigned to the neuron by other neurons +get_consensus Consensus score of the neuron +get_incentive Incentive score representing the neuron's incentive alignment +get_dividends Dividends earned by the neuron +get_emission Emission received by the neuron (with 18 decimals) +get_vtrust Validator trust score indicating the network's trust in the neuron as a validator +get_validator_status Validator status of the neuron +get_last_updated Number of blocks since the neuron's last update +get_is_active Activity status of the neuron +get_axon Network endpoint information of the neuron +get_hotkey Hotkey (public key as bytes32) of the neuron +get_coldkey Coldkey (public key as bytes32) of the neuron + */ + +impl MetagraphPrecompile { + pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { + log::error!("++++++ execute metagraph"); + let txdata = handle.input(); + let method_id = get_slice(txdata, 0, 4)?; + let method_input = txdata + .get(4..) + .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts + + match method_id { + id if id == get_method_id("getUidCount(uint16)") => Self::get_uid_count(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_stake(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_rank(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_trust(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_consensus(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_emission(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_vtrust(&method_input), + id if id == get_method_id("getUidCount(uint16)") => { + Self::get_validator_status(&method_input) + } + id if id == get_method_id("getUidCount(uint16)") => { + Self::get_last_updated(&method_input) + } + id if id == get_method_id("getUidCount(uint16)") => Self::get_is_active(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_axon(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_hotkey(&method_input), + id if id == get_method_id("getUidCount(uint16)") => Self::get_coldkey(&method_input), + + _ => Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }), + } + } + + fn get_uid_count(data: &[u8]) -> PrecompileResult { + if data.len() < 2 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid = [0u8; 2]; + netuid.copy_from_slice(get_slice(data, 0, 2)?); + let netuid = u16::from_be_bytes(netuid); + + log::error!("++++++ netuid is {:?}", netuid); + + let uid_count = pallet_subtensor::SubnetworkN::::get(netuid); + + let uid_count_u256 = U256::from(uid_count); + let mut result = [0_u8; 32]; + U256::to_big_endian(&uid_count_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + + fn get_stake(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_rank(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_trust(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_consensus(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_incentive(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_dividends(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_emission(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_vtrust(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_validator_status(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_last_updated(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_is_active(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_axon(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_hotkey(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } + + fn get_coldkey(data: &[u8]) -> PrecompileResult { + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: [].into(), + }) + } +} diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 22f2a4881c..33d5902024 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -13,10 +13,12 @@ use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripe // Include custom precompiles mod balance_transfer; mod ed25519; +mod metagraph; mod staking; use balance_transfer::*; use ed25519::*; +use metagraph::*; use staking::*; pub struct FrontierPrecompiles(PhantomData); @@ -73,6 +75,10 @@ where Some(BalanceTransferPrecompile::execute(handle)) } a if a == hash(STAKING_PRECOMPILE_INDEX) => Some(StakingPrecompile::execute(handle)), + a if a == hash(METAGRAPH_PRECOMPILE_INDEX) => { + Some(MetagraphPrecompile::execute(handle)) + } + _ => None, } } diff --git a/runtime/src/precompiles/solidity/metagraph.abi b/runtime/src/precompiles/solidity/metagraph.abi new file mode 100644 index 0000000000..4846598b2d --- /dev/null +++ b/runtime/src/precompiles/solidity/metagraph.abi @@ -0,0 +1,21 @@ +[ + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getUidCount", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/metagraph.sol b/runtime/src/precompiles/solidity/metagraph.sol new file mode 100644 index 0000000000..50440fe101 --- /dev/null +++ b/runtime/src/precompiles/solidity/metagraph.sol @@ -0,0 +1,14 @@ +pragma solidity ^0.8.0; + +address constant IMetagraph_ADDRESS = 0x0000000000000000000000000000000000000802; + +interface IMetagraph { + + /** + * @dev Returns the count of unique identifiers (UIDs) associated with a given network identifier (netuid). + * @param netuid The network identifier for which to retrieve the UID count. + * @return The count of UIDs associated with the specified netuid. + */ + function getUidCount(uint16 netuid) external view returns (uint16); + +} From 1bf273027afb9019e2a36182b2b60cc30d8aa39a Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 2 Dec 2024 23:36:06 +0800 Subject: [PATCH 2/9] more method definition --- runtime/src/precompiles/metagraph.rs | 274 +++++++++++++++++++++------ 1 file changed, 221 insertions(+), 53 deletions(-) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index 85a1e060ec..f53922a3ff 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -9,29 +9,12 @@ use fp_evm::{ ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; -use sp_core::U256; +use sp_core::{ByteArray, U256}; use sp_std::vec; pub const METAGRAPH_PRECOMPILE_INDEX: u64 = 2050; +use sp_runtime::AccountId32; pub struct MetagraphPrecompile; -/* -get_uid_count SubnetworkN -get_stake Total stake of the neuron in Tao -get_rank Rank score of the neuron -get_trust Trust score assigned to the neuron by other neurons -get_consensus Consensus score of the neuron -get_incentive Incentive score representing the neuron's incentive alignment -get_dividends Dividends earned by the neuron -get_emission Emission received by the neuron (with 18 decimals) -get_vtrust Validator trust score indicating the network's trust in the neuron as a validator -get_validator_status Validator status of the neuron -get_last_updated Number of blocks since the neuron's last update -get_is_active Activity status of the neuron -get_axon Network endpoint information of the neuron -get_hotkey Hotkey (public key as bytes32) of the neuron -get_coldkey Coldkey (public key as bytes32) of the neuron - */ - impl MetagraphPrecompile { pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { log::error!("++++++ execute metagraph"); @@ -43,22 +26,40 @@ impl MetagraphPrecompile { match method_id { id if id == get_method_id("getUidCount(uint16)") => Self::get_uid_count(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_stake(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_rank(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_trust(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_consensus(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_emission(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_vtrust(&method_input), - id if id == get_method_id("getUidCount(uint16)") => { + id if id == get_method_id("getStake(uint16,uint16)") => Self::get_stake(&method_input), + id if id == get_method_id("getRank(uint16,uint16)") => Self::get_rank(&method_input), + id if id == get_method_id("getTrust(uint16,uint16)") => Self::get_trust(&method_input), + id if id == get_method_id("getConsensus(uint16,uint16)") => { + Self::get_consensus(&method_input) + } + id if id == get_method_id("getIncentive(uint16,uint16)") => { + Self::get_incentive(&method_input) + } + id if id == get_method_id("getDividends(uint16,uint16)") => { + Self::get_dividends(&method_input) + } + id if id == get_method_id("getEmission(uint16,uint16)") => { + Self::get_emission(&method_input) + } + id if id == get_method_id("getVtrust(uint16,uint16)") => { + Self::get_vtrust(&method_input) + } + id if id == get_method_id("getValidatorStatus(uint16,uint16)") => { Self::get_validator_status(&method_input) } - id if id == get_method_id("getUidCount(uint16)") => { - Self::get_last_updated(&method_input) + id if id == get_method_id("getLastUpdate(uint16,uint16)") => { + Self::get_last_update(&method_input) + } + id if id == get_method_id("getIsActive(uint16,uint16)") => { + Self::get_is_active(&method_input) + } + id if id == get_method_id("getAxon(uint16,uint16)") => Self::get_axon(&method_input), + id if id == get_method_id("getHotkey(uint16,uint16)") => { + Self::get_hotkey(&method_input) + } + id if id == get_method_id("getColdkey(uint16,uint16)") => { + Self::get_coldkey(&method_input) } - id if id == get_method_id("getUidCount(uint16)") => Self::get_is_active(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_axon(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_hotkey(&method_input), - id if id == get_method_id("getUidCount(uint16)") => Self::get_coldkey(&method_input), _ => Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, @@ -67,14 +68,9 @@ impl MetagraphPrecompile { } fn get_uid_count(data: &[u8]) -> PrecompileResult { - if data.len() < 2 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let mut netuid = [0u8; 2]; - netuid.copy_from_slice(get_slice(data, 0, 2)?); - let netuid = u16::from_be_bytes(netuid); + log::error!("++++++ data len is {:?}", data.len()); + + let netuid = Self::parse_netuid(data)?; log::error!("++++++ netuid is {:?}", netuid); @@ -91,6 +87,20 @@ impl MetagraphPrecompile { } fn get_stake(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + .map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + })?; + + let stake = pallet_subtensor::TotalHotkeyStake::::get(&hotkey); + + let result_u256 = U256::from(stake); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: [].into(), @@ -98,93 +108,251 @@ impl MetagraphPrecompile { } fn get_rank(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let rank = pallet_subtensor::Pallet::::get_rank_for_uid(netuid, uid); + + let result_u256 = U256::from(rank); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_trust(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let trust = pallet_subtensor::Pallet::::get_trust_for_uid(netuid, uid); + + let result_u256 = U256::from(trust); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_consensus(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let consensus = pallet_subtensor::Pallet::::get_consensus_for_uid(netuid, uid); + + let result_u256 = U256::from(consensus); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_incentive(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let incentive = pallet_subtensor::Pallet::::get_incentive_for_uid(netuid, uid); + + let result_u256 = U256::from(incentive); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_dividends(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let dividends = pallet_subtensor::Pallet::::get_dividends_for_uid(netuid, uid); + + let result_u256 = U256::from(dividends); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_emission(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let emission = pallet_subtensor::Pallet::::get_emission_for_uid(netuid, uid); + + let result_u256 = U256::from(emission); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_vtrust(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let vtrust = pallet_subtensor::Pallet::::get_validator_trust_for_uid(netuid, uid); + + let result_u256 = U256::from(vtrust); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_validator_status(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let validator_permit = + pallet_subtensor::Pallet::::get_validator_permit_for_uid(netuid, uid); + + // let result_u256 = U256::from(validator_status); + // let mut result = [0_u8; 32]; + // U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: [].into(), }) } - fn get_last_updated(data: &[u8]) -> PrecompileResult { + fn get_last_update(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let last_update = pallet_subtensor::Pallet::::get_last_update_for_uid(netuid, uid); + + let result_u256 = U256::from(last_update); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_is_active(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let rank = pallet_subtensor::Pallet::::get_rank_for_uid(netuid, uid); + + let result_u256 = U256::from(rank); + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_axon(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + .map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + })?; + + let axon = pallet_subtensor::Pallet::::get_axon_info(netuid, &hotkey); + + // let result_u256 = U256::from(rank); + // let mut result = [0_u8; 32]; + // U256::to_big_endian(&result_u256, &mut result); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: axon.decode().into(), }) } fn get_hotkey(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + .map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + })?; + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: hotkey.as_slice().into(), }) } fn get_coldkey(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let uid = Self::parse_uid(&data[32..])?; + + let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + .map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + })?; + + let coldkey = pallet_subtensor::Owner::::get(&hotkey); + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: coldkey.as_slice().into(), }) } + + fn parse_netuid(data: &[u8]) -> Result { + if data.len() < 32 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid = [0u8; 2]; + netuid.copy_from_slice(get_slice(data, 30, 32)?); + let result = u16::from_be_bytes(netuid); + Ok(result) + } + + fn parse_uid(data: &[u8]) -> Result { + if data.len() < 32 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut uid = [0u8; 2]; + uid.copy_from_slice(get_slice(data, 30, 32)?); + let result = u16::from_be_bytes(uid); + Ok(result) + } + + fn parse_hotkey(data: &[u8]) -> Result<[u8; 32], PrecompileFailure> { + if data.len() < 32 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut hotkey = [0u8; 32]; + hotkey.copy_from_slice(get_slice(data, 0, 32)?); + Ok(hotkey) + } } From 50b9b8bc5e254692cb3721d2ea82386621f7f8b6 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 3 Dec 2024 13:32:03 +0800 Subject: [PATCH 3/9] axon data support --- runtime/src/precompiles/metagraph.rs | 34 ++++++++++++++++--- .../src/precompiles/solidity/metagraph.sol | 11 ++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index f53922a3ff..f5a1c4c491 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -15,6 +15,8 @@ pub const METAGRAPH_PRECOMPILE_INDEX: u64 = 2050; use sp_runtime::AccountId32; pub struct MetagraphPrecompile; +const NO_HOTKEY: &str = "no hotkey"; + impl MetagraphPrecompile { pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { log::error!("++++++ execute metagraph"); @@ -274,18 +276,40 @@ impl MetagraphPrecompile { let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, + exit_status: ExitError::Other(sp_version::Cow::Borrowed(NO_HOTKEY)), })?; let axon = pallet_subtensor::Pallet::::get_axon_info(netuid, &hotkey); - // let result_u256 = U256::from(rank); - // let mut result = [0_u8; 32]; - // U256::to_big_endian(&result_u256, &mut result); + let mut block_result = [0_u8; 32]; + U256::to_big_endian(&U256::from(axon.block), &mut block_result); + + let mut version_result = [0_u8; 32]; + U256::to_big_endian(&U256::from(axon.version), &mut version_result); + + let mut ip_result = [0_u8; 32]; + U256::to_big_endian(&U256::from(axon.ip), &mut ip_result); + + let mut port_result = [0_u8; 32]; + U256::to_big_endian(&U256::from(axon.port), &mut port_result); + + let mut ip_type_result = [0_u8; 32]; + U256::to_big_endian(&U256::from(axon.ip_type), &mut ip_type_result); + + let mut protocol_result = [0_u8; 32]; + U256::to_big_endian(&U256::from(axon.protocol), &mut protocol_result); + + let mut result = [0_u8; 192]; + result[..32].copy_from_slice(&block_result); + result[32..64].copy_from_slice(&version_result); + result[64..96].copy_from_slice(&ip_result); + result[96..128].copy_from_slice(&port_result); + result[128..160].copy_from_slice(&ip_type_result); + result[160..].copy_from_slice(&protocol_result); Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: axon.decode().into(), + output: result.into(), }) } diff --git a/runtime/src/precompiles/solidity/metagraph.sol b/runtime/src/precompiles/solidity/metagraph.sol index 50440fe101..adc8f5a78d 100644 --- a/runtime/src/precompiles/solidity/metagraph.sol +++ b/runtime/src/precompiles/solidity/metagraph.sol @@ -2,6 +2,15 @@ pragma solidity ^0.8.0; address constant IMetagraph_ADDRESS = 0x0000000000000000000000000000000000000802; +struct AxonInfo { + uint64 block; + uint32 version; + uint128 ip; + uint16 port; + uint8 ip_type; + uint8 protocol; +} + interface IMetagraph { /** @@ -11,4 +20,6 @@ interface IMetagraph { */ function getUidCount(uint16 netuid) external view returns (uint16); + function getAxon(uint16 netuid, uint16 uid) external view returns (AxonInfo memory); + } From 12d90d4f8bc365c3e61d4bbb6cfdaaf269ef5bba Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 3 Dec 2024 14:42:51 +0800 Subject: [PATCH 4/9] implement done --- runtime/src/precompiles/metagraph.rs | 14 +- .../src/precompiles/solidity/metagraph.abi | 368 ++++++++++++++++++ .../src/precompiles/solidity/metagraph.sol | 16 +- 3 files changed, 392 insertions(+), 6 deletions(-) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index f5a1c4c491..67fb3fd800 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -228,9 +228,13 @@ impl MetagraphPrecompile { let validator_permit = pallet_subtensor::Pallet::::get_validator_permit_for_uid(netuid, uid); - // let result_u256 = U256::from(validator_status); - // let mut result = [0_u8; 32]; - // U256::to_big_endian(&result_u256, &mut result); + let result_u256 = if validator_permit { + U256::from(1) + } else { + U256::from(0) + }; + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, @@ -258,9 +262,9 @@ impl MetagraphPrecompile { let netuid = Self::parse_netuid(data)?; let uid = Self::parse_uid(&data[32..])?; - let rank = pallet_subtensor::Pallet::::get_rank_for_uid(netuid, uid); + let active = pallet_subtensor::Pallet::::get_active_for_uid(netuid, uid); - let result_u256 = U256::from(rank); + let result_u256 = if active { U256::from(1) } else { U256::from(0) }; let mut result = [0_u8; 32]; U256::to_big_endian(&result_u256, &mut result); diff --git a/runtime/src/precompiles/solidity/metagraph.abi b/runtime/src/precompiles/solidity/metagraph.abi index 4846598b2d..eb4b9be6ab 100644 --- a/runtime/src/precompiles/solidity/metagraph.abi +++ b/runtime/src/precompiles/solidity/metagraph.abi @@ -1,4 +1,324 @@ [ + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getAxon", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "block", + "type": "uint64" + }, + { + "internalType": "uint32", + "name": "version", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ip", + "type": "uint128" + }, + { + "internalType": "uint16", + "name": "port", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "ip_type", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "protocol", + "type": "uint8" + } + ], + "internalType": "struct AxonInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getColdkey", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getConsensus", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getDividends", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getEmission", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getHotkey", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getIncentive", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getIsActive", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getLastUpdate", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getRank", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getStake", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getTrust", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -17,5 +337,53 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getValidatorStatus", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "uid", + "type": "uint16" + } + ], + "name": "getVtrust", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" } ] \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/metagraph.sol b/runtime/src/precompiles/solidity/metagraph.sol index adc8f5a78d..bf96775594 100644 --- a/runtime/src/precompiles/solidity/metagraph.sol +++ b/runtime/src/precompiles/solidity/metagraph.sol @@ -20,6 +20,20 @@ interface IMetagraph { */ function getUidCount(uint16 netuid) external view returns (uint16); - function getAxon(uint16 netuid, uint16 uid) external view returns (AxonInfo memory); + function getStake(uint16 netuid, uint16 uid) external view returns (uint64); + + function getRank(uint16 netuid, uint16 uid) external view returns (uint16); + function getTrust(uint16 netuid, uint16 uid) external view returns (uint16); + function getConsensus(uint16 netuid, uint16 uid) external view returns (uint16); + function getIncentive(uint16 netuid, uint16 uid) external view returns (uint16); + function getDividends(uint16 netuid, uint16 uid) external view returns (uint16); + function getEmission(uint16 netuid, uint16 uid) external view returns (uint64); + function getVtrust(uint16 netuid, uint16 uid) external view returns (uint16); + function getValidatorStatus(uint16 netuid, uint16 uid) external view returns (bool); + function getLastUpdate(uint16 netuid, uint16 uid) external view returns (uint64); + function getIsActive(uint16 netuid, uint16 uid) external view returns (bool); + function getAxon(uint16 netuid, uint16 uid) external view returns (AxonInfo memory); + function getHotkey(uint16 netuid, uint16 uid) external view returns (bytes32); + function getColdkey(uint16 netuid, uint16 uid) external view returns (bytes32); } From 2d76d849aacda9d40128437db743902a1de3f6b1 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 3 Dec 2024 20:20:00 +0800 Subject: [PATCH 5/9] fix clippy --- runtime/src/precompiles/metagraph.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index 67fb3fd800..888d0a7369 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -372,15 +372,4 @@ impl MetagraphPrecompile { let result = u16::from_be_bytes(uid); Ok(result) } - - fn parse_hotkey(data: &[u8]) -> Result<[u8; 32], PrecompileFailure> { - if data.len() < 32 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let mut hotkey = [0u8; 32]; - hotkey.copy_from_slice(get_slice(data, 0, 32)?); - Ok(hotkey) - } } From 95764b6863d0f53f6b3d673711d08b911e352968 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 4 Dec 2024 19:27:04 +0800 Subject: [PATCH 6/9] fix clippy --- runtime/src/precompiles/metagraph.rs | 51 ++++++++++------------------ 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index 888d0a7369..28bf664b88 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -1,25 +1,18 @@ extern crate alloc; - -use alloc::vec::Vec; - use crate::precompiles::{get_method_id, get_slice}; -use crate::{Runtime, RuntimeCall}; -use ed25519_dalek::{Signature, Verifier, VerifyingKey}; +use crate::Runtime; use fp_evm::{ - ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure, PrecompileHandle, - PrecompileOutput, PrecompileResult, + ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; use sp_core::{ByteArray, U256}; use sp_std::vec; pub const METAGRAPH_PRECOMPILE_INDEX: u64 = 2050; -use sp_runtime::AccountId32; pub struct MetagraphPrecompile; const NO_HOTKEY: &str = "no hotkey"; impl MetagraphPrecompile { pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - log::error!("++++++ execute metagraph"); let txdata = handle.input(); let method_id = get_slice(txdata, 0, 4)?; let method_input = txdata @@ -70,12 +63,7 @@ impl MetagraphPrecompile { } fn get_uid_count(data: &[u8]) -> PrecompileResult { - log::error!("++++++ data len is {:?}", data.len()); - let netuid = Self::parse_netuid(data)?; - - log::error!("++++++ netuid is {:?}", netuid); - let uid_count = pallet_subtensor::SubnetworkN::::get(netuid); let uid_count_u256 = U256::from(uid_count); @@ -90,29 +78,26 @@ impl MetagraphPrecompile { fn get_stake(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; - + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::InvalidRange, })?; let stake = pallet_subtensor::TotalHotkeyStake::::get(&hotkey); - let result_u256 = U256::from(stake); let mut result = [0_u8; 32]; U256::to_big_endian(&result_u256, &mut result); Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_rank(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; - + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let rank = pallet_subtensor::Pallet::::get_rank_for_uid(netuid, uid); let result_u256 = U256::from(rank); @@ -127,7 +112,7 @@ impl MetagraphPrecompile { fn get_trust(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let trust = pallet_subtensor::Pallet::::get_trust_for_uid(netuid, uid); @@ -143,7 +128,7 @@ impl MetagraphPrecompile { fn get_consensus(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let consensus = pallet_subtensor::Pallet::::get_consensus_for_uid(netuid, uid); @@ -159,7 +144,7 @@ impl MetagraphPrecompile { fn get_incentive(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let incentive = pallet_subtensor::Pallet::::get_incentive_for_uid(netuid, uid); @@ -175,7 +160,7 @@ impl MetagraphPrecompile { fn get_dividends(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let dividends = pallet_subtensor::Pallet::::get_dividends_for_uid(netuid, uid); @@ -191,7 +176,7 @@ impl MetagraphPrecompile { fn get_emission(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let emission = pallet_subtensor::Pallet::::get_emission_for_uid(netuid, uid); @@ -207,7 +192,7 @@ impl MetagraphPrecompile { fn get_vtrust(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let vtrust = pallet_subtensor::Pallet::::get_validator_trust_for_uid(netuid, uid); @@ -223,7 +208,7 @@ impl MetagraphPrecompile { fn get_validator_status(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let validator_permit = pallet_subtensor::Pallet::::get_validator_permit_for_uid(netuid, uid); @@ -238,13 +223,13 @@ impl MetagraphPrecompile { Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, - output: [].into(), + output: result.into(), }) } fn get_last_update(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let last_update = pallet_subtensor::Pallet::::get_last_update_for_uid(netuid, uid); @@ -260,7 +245,7 @@ impl MetagraphPrecompile { fn get_is_active(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let active = pallet_subtensor::Pallet::::get_active_for_uid(netuid, uid); @@ -276,7 +261,7 @@ impl MetagraphPrecompile { fn get_axon(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { @@ -319,7 +304,7 @@ impl MetagraphPrecompile { fn get_hotkey(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { @@ -334,7 +319,7 @@ impl MetagraphPrecompile { fn get_coldkey(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(&data[32..])?; + let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { From 4bfae6b0bc49de394ea1012e9fc9103c8e1d5fa2 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 4 Dec 2024 19:34:25 +0800 Subject: [PATCH 7/9] update version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index fcaeb56d19..b8e9fa0d2d 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -160,7 +160,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 211, + spec_version: 212, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 13983531f15be79c451934f5ff0d6afed8077bbd Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 5 Dec 2024 19:21:20 +0800 Subject: [PATCH 8/9] add get subnet register interface --- runtime/src/precompiles/metagraph.rs | 21 ++++ .../src/precompiles/solidity/metagraph.abi | 19 ++++ .../src/precompiles/solidity/metagraph.sol | 102 ++++++++++++++++++ 3 files changed, 142 insertions(+) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index 28bf664b88..c2b31f40d2 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -21,6 +21,9 @@ impl MetagraphPrecompile { match method_id { id if id == get_method_id("getUidCount(uint16)") => Self::get_uid_count(&method_input), + id if id == get_method_id("getIsSubnetRegistered(uint16)") => { + Self::get_is_subnet_registered(&method_input) + } id if id == get_method_id("getStake(uint16,uint16)") => Self::get_stake(&method_input), id if id == get_method_id("getRank(uint16,uint16)") => Self::get_rank(&method_input), id if id == get_method_id("getTrust(uint16,uint16)") => Self::get_trust(&method_input), @@ -76,6 +79,24 @@ impl MetagraphPrecompile { }) } + fn get_is_subnet_registered(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + let is_registered = pallet_subtensor::Pallet::::if_subnet_exist(netuid); + + let result_u256 = if is_registered { + U256::from(1) + } else { + U256::from(0) + }; + let mut result = [0_u8; 32]; + U256::to_big_endian(&result_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn get_stake(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; diff --git a/runtime/src/precompiles/solidity/metagraph.abi b/runtime/src/precompiles/solidity/metagraph.abi index eb4b9be6ab..2f9862d86c 100644 --- a/runtime/src/precompiles/solidity/metagraph.abi +++ b/runtime/src/precompiles/solidity/metagraph.abi @@ -338,6 +338,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getIsSubnetRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { diff --git a/runtime/src/precompiles/solidity/metagraph.sol b/runtime/src/precompiles/solidity/metagraph.sol index bf96775594..5a87b64b78 100644 --- a/runtime/src/precompiles/solidity/metagraph.sol +++ b/runtime/src/precompiles/solidity/metagraph.sol @@ -19,21 +19,123 @@ interface IMetagraph { * @return The count of UIDs associated with the specified netuid. */ function getUidCount(uint16 netuid) external view returns (uint16); + + /** + * @dev Checks if a subnet with the given network identifier (netuid) is registered. + * @param netuid The network identifier of the subnet to check. + * @return Returns true if the subnet is registered, false otherwise. + */ + function getIsSubnetRegistered(uint16 netuid) external view returns (bool); + /** + * @dev Retrieves the stake amount associated with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the stake. + * @param uid The unique identifier for which to retrieve the stake. + * @return The stake amount associated with the specified netuid and uid. + */ function getStake(uint16 netuid, uint16 uid) external view returns (uint64); + /** + * @dev Retrieves the rank of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the rank. + * @param uid The unique identifier for which to retrieve the rank. + * @return The rank of the node with the specified netuid and uid. + */ function getRank(uint16 netuid, uint16 uid) external view returns (uint16); + /** + * @dev Retrieves the trust value of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the trust value. + * @param uid The unique identifier for which to retrieve the trust value. + * @return The trust value of the node with the specified netuid and uid. + */ function getTrust(uint16 netuid, uint16 uid) external view returns (uint16); + + /** + * @dev Retrieves the consensus value of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the consensus value. + * @param uid The unique identifier for which to retrieve the consensus value. + * @return The consensus value of the node with the specified netuid and uid. + */ function getConsensus(uint16 netuid, uint16 uid) external view returns (uint16); + + /** + * @dev Retrieves the incentive value of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the incentive value. + * @param uid The unique identifier for which to retrieve the incentive value. + * @return The incentive value of the node with the specified netuid and uid. + */ function getIncentive(uint16 netuid, uint16 uid) external view returns (uint16); + + /** + * @dev Retrieves the dividend value of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the dividend value. + * @param uid The unique identifier for which to retrieve the dividend value. + * @return The dividend value of the node with the specified netuid and uid. + */ function getDividends(uint16 netuid, uint16 uid) external view returns (uint16); + + /** + * @dev Retrieves the emission value of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the emission value. + * @param uid The unique identifier for which to retrieve the emission value. + * @return The emission value of the node with the specified netuid and uid. + */ function getEmission(uint16 netuid, uint16 uid) external view returns (uint64); + + /** + * @dev Retrieves the v-trust value of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the v-trust value. + * @param uid The unique identifier for which to retrieve the v-trust value. + * @return The v-trust value of the node with the specified netuid and uid. + */ function getVtrust(uint16 netuid, uint16 uid) external view returns (uint16); + + /** + * @dev Checks the validator status of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to check the validator status. + * @param uid The unique identifier for which to check the validator status. + * @return Returns true if the node is a validator, false otherwise. + */ function getValidatorStatus(uint16 netuid, uint16 uid) external view returns (bool); + + /** + * @dev Retrieves the last update timestamp of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the last update timestamp. + * @param uid The unique identifier for which to retrieve the last update timestamp. + * @return The last update timestamp of the node with the specified netuid and uid. + */ function getLastUpdate(uint16 netuid, uint16 uid) external view returns (uint64); + + /** + * @dev Checks if a node with a given network identifier (netuid) and unique identifier (uid) is active. + * @param netuid The network identifier for which to check the node's activity. + * @param uid The unique identifier for which to check the node's activity. + * @return Returns true if the node is active, false otherwise. + */ function getIsActive(uint16 netuid, uint16 uid) external view returns (bool); + + /** + * @dev Retrieves the axon information of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the axon information. + * @param uid The unique identifier for which to retrieve the axon information. + * @return The axon information of the node with the specified netuid and uid. + */ function getAxon(uint16 netuid, uint16 uid) external view returns (AxonInfo memory); + + /** + * @dev Retrieves the hotkey of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the hotkey. + * @param uid The unique identifier for which to retrieve the hotkey. + * @return The hotkey of the node with the specified netuid and uid. + */ function getHotkey(uint16 netuid, uint16 uid) external view returns (bytes32); + + /** + * @dev Retrieves the coldkey of a node with a given network identifier (netuid) and unique identifier (uid). + * @param netuid The network identifier for which to retrieve the coldkey. + * @param uid The unique identifier for which to retrieve the coldkey. + * @return The coldkey of the node with the specified netuid and uid. + */ function getColdkey(uint16 netuid, uint16 uid) external view returns (bytes32); } From c2106ecb5428ca7f16122d6e85705ad11d4686e8 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 6 Dec 2024 22:01:40 +0800 Subject: [PATCH 9/9] fix according comments --- runtime/src/precompiles/metagraph.rs | 21 ------------------- runtime/src/precompiles/mod.rs | 3 ++- .../src/precompiles/solidity/metagraph.abi | 19 ----------------- .../src/precompiles/solidity/metagraph.sol | 7 ------- 4 files changed, 2 insertions(+), 48 deletions(-) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index c2b31f40d2..28bf664b88 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -21,9 +21,6 @@ impl MetagraphPrecompile { match method_id { id if id == get_method_id("getUidCount(uint16)") => Self::get_uid_count(&method_input), - id if id == get_method_id("getIsSubnetRegistered(uint16)") => { - Self::get_is_subnet_registered(&method_input) - } id if id == get_method_id("getStake(uint16,uint16)") => Self::get_stake(&method_input), id if id == get_method_id("getRank(uint16,uint16)") => Self::get_rank(&method_input), id if id == get_method_id("getTrust(uint16,uint16)") => Self::get_trust(&method_input), @@ -79,24 +76,6 @@ impl MetagraphPrecompile { }) } - fn get_is_subnet_registered(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let is_registered = pallet_subtensor::Pallet::::if_subnet_exist(netuid); - - let result_u256 = if is_registered { - U256::from(1) - } else { - U256::from(0) - }; - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) - } - fn get_stake(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 33d5902024..e13516e958 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -39,7 +39,7 @@ where pub fn new() -> Self { Self(Default::default()) } - pub fn used_addresses() -> [H160; 10] { + pub fn used_addresses() -> [H160; 11] { [ hash(1), hash(2), @@ -51,6 +51,7 @@ where hash(EDVERIFY_PRECOMPILE_INDEX), hash(BALANCE_TRANSFER_INDEX), hash(STAKING_PRECOMPILE_INDEX), + hash(METAGRAPH_PRECOMPILE_INDEX), ] } } diff --git a/runtime/src/precompiles/solidity/metagraph.abi b/runtime/src/precompiles/solidity/metagraph.abi index 2f9862d86c..eb4b9be6ab 100644 --- a/runtime/src/precompiles/solidity/metagraph.abi +++ b/runtime/src/precompiles/solidity/metagraph.abi @@ -338,25 +338,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "netuid", - "type": "uint16" - } - ], - "name": "getIsSubnetRegistered", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { diff --git a/runtime/src/precompiles/solidity/metagraph.sol b/runtime/src/precompiles/solidity/metagraph.sol index 5a87b64b78..3a19281a57 100644 --- a/runtime/src/precompiles/solidity/metagraph.sol +++ b/runtime/src/precompiles/solidity/metagraph.sol @@ -19,13 +19,6 @@ interface IMetagraph { * @return The count of UIDs associated with the specified netuid. */ function getUidCount(uint16 netuid) external view returns (uint16); - - /** - * @dev Checks if a subnet with the given network identifier (netuid) is registered. - * @param netuid The network identifier of the subnet to check. - * @return Returns true if the subnet is registered, false otherwise. - */ - function getIsSubnetRegistered(uint16 netuid) external view returns (bool); /** * @dev Retrieves the stake amount associated with a given network identifier (netuid) and unique identifier (uid).