Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ pub mod pallet {
AddressMapping,
/// Voting power precompile
VotingPower,
/// Neuron registration cost precompile
NeuronRegistrationCost,
}

#[pallet::type_value]
Expand Down
11 changes: 10 additions & 1 deletion precompiles/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::extensions::*;
use crate::leasing::*;
use crate::metagraph::*;
use crate::neuron::*;
use crate::neuron_registration_cost::*;
use crate::proxy::*;
use crate::sr25519::*;
use crate::staking::*;
Expand All @@ -52,6 +53,7 @@ mod extensions;
mod leasing;
mod metagraph;
mod neuron;
mod neuron_registration_cost;
mod proxy;
mod sr25519;
mod staking;
Expand Down Expand Up @@ -135,7 +137,7 @@ where
Self(Default::default())
}

pub fn used_addresses() -> [H160; 27] {
pub fn used_addresses() -> [H160; 28] {
[
hash(1),
hash(2),
Expand Down Expand Up @@ -164,6 +166,7 @@ where
hash(VotingPowerPrecompile::<R>::INDEX),
hash(ProxyPrecompile::<R>::INDEX),
hash(AddressMappingPrecompile::<R>::INDEX),
hash(NeuronRegistrationCostPrecompile::<R>::INDEX),
]
}
}
Expand Down Expand Up @@ -272,6 +275,12 @@ where
PrecompileEnum::AddressMapping,
)
}
a if a == hash(NeuronRegistrationCostPrecompile::<R>::INDEX) => {
NeuronRegistrationCostPrecompile::<R>::try_execute::<R>(
handle,
PrecompileEnum::NeuronRegistrationCost,
)
}
_ => None,
}
}
Expand Down
88 changes: 88 additions & 0 deletions precompiles/src/neuron_registration_cost.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use core::marker::PhantomData;

use fp_evm::PrecompileHandle;
use precompile_utils::EvmResult;
use sp_core::U256;
use subtensor_runtime_common::{Currency, NetUid};

use crate::PrecompileExt;

/// NeuronRegistrationCost precompile for smart contract access to neuron registration cost.
///
/// This precompile allows smart contracts to query the current burn cost
/// required to register a neuron on a subnet.
pub struct NeuronRegistrationCostPrecompile<R>(PhantomData<R>);

impl<R> PrecompileExt<R::AccountId> for NeuronRegistrationCostPrecompile<R>
where
R: frame_system::Config + pallet_subtensor::Config,
R::AccountId: From<[u8; 32]>,
{
// Using 2062 as the next available index after VotingPower (2061)
const INDEX: u64 = 2062;
}

#[precompile_utils::precompile]
impl<R> NeuronRegistrationCostPrecompile<R>
where
R: frame_system::Config + pallet_subtensor::Config,
R::AccountId: From<[u8; 32]>,
{
/// Get the current burn cost to register a neuron on a subnet.
///
/// This is the amount of TAO (in RAO) that will be burned when registering.
/// The cost can change dynamically based on network activity.
///
/// # Arguments
/// * `netuid` - The subnet identifier (u16)
///
/// # Returns
/// * `u256` - The burn cost in RAO (1 TAO = 10^9 RAO)
#[precompile::public("getBurn(uint16)")]
#[precompile::view]
fn get_burn(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<U256> {
let burn = pallet_subtensor::Pallet::<R>::get_burn(NetUid::from(netuid));
Ok(U256::from(burn.to_u64()))
}

/// Get the minimum burn cost for a subnet.
///
/// # Arguments
/// * `netuid` - The subnet identifier (u16)
///
/// # Returns
/// * `u256` - The minimum burn cost in RAO
#[precompile::public("getMinBurn(uint16)")]
#[precompile::view]
fn get_min_burn(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<U256> {
let min_burn = pallet_subtensor::Pallet::<R>::get_min_burn(NetUid::from(netuid));
Ok(U256::from(min_burn.to_u64()))
}

/// Get the maximum burn cost for a subnet.
///
/// # Arguments
/// * `netuid` - The subnet identifier (u16)
///
/// # Returns
/// * `u256` - The maximum burn cost in RAO
#[precompile::public("getMaxBurn(uint16)")]
#[precompile::view]
fn get_max_burn(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<U256> {
let max_burn = pallet_subtensor::Pallet::<R>::get_max_burn(NetUid::from(netuid));
Ok(U256::from(max_burn.to_u64()))
}

/// Check if registration is allowed on a subnet.
///
/// # Arguments
/// * `netuid` - The subnet identifier (u16)
///
/// # Returns
/// * `bool` - True if registration is allowed
#[precompile::public("isRegistrationAllowed(uint16)")]
#[precompile::view]
fn is_registration_allowed(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<bool> {
Ok(pallet_subtensor::Pallet::<R>::get_network_registration_allowed(NetUid::from(netuid)))
}
}
28 changes: 28 additions & 0 deletions precompiles/src/solidity/neuronRegistrationCost.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.8.0;

/// @title INeuronRegistrationCost
/// @notice Interface for querying neuron registration costs on Bittensor subnets
/// @dev Accessible at address 0x0000000000000000000000000000000000000806
interface INeuronRegistrationCost {
/// @notice Get the current burn cost to register a neuron on a subnet
/// @dev The cost can change dynamically based on network activity
/// @param netuid The subnet identifier
/// @return The burn cost in RAO (1 TAO = 10^9 RAO)
function getBurn(uint16 netuid) external view returns (uint256);

/// @notice Get the minimum burn cost for a subnet
/// @param netuid The subnet identifier
/// @return The minimum burn cost in RAO
function getMinBurn(uint16 netuid) external view returns (uint256);

/// @notice Get the maximum burn cost for a subnet
/// @param netuid The subnet identifier
/// @return The maximum burn cost in RAO
function getMaxBurn(uint16 netuid) external view returns (uint256);

/// @notice Check if registration is allowed on a subnet
/// @param netuid The subnet identifier
/// @return True if registration is allowed
function isRegistrationAllowed(uint16 netuid) external view returns (bool);
}