Skip to content
260 changes: 140 additions & 120 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ scale-info = { workspace = true }
serde = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
substrate-fixed = { workspace = true }
subtensor-macros = { workspace = true }

approx = {workspace = true, optional = true}

[lints]
workspace = true

[features]
default = ["std"]
approx = ["dep:approx"]
fast-blocks = []
std = [
"codec/std",
Expand All @@ -32,4 +36,5 @@ std = [
"serde/std",
"sp-core/std",
"sp-runtime/std",
"substrate-fixed/std",
]
231 changes: 231 additions & 0 deletions common/src/currency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
use core::fmt::{self, Display, Formatter};
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};

#[cfg(feature = "approx")]
use approx::AbsDiffEq;
use codec::{Compact, CompactAs, Decode, Encode, Error as CodecError, MaxEncodedLen};
use frame_support::pallet_prelude::*;
use scale_info::TypeInfo;
use serde::{Deserialize, Serialize};
use substrate_fixed::traits::{Fixed, ToFixed};
use subtensor_macros::freeze_struct;

#[freeze_struct("b21dcd0434b67c67")]
#[repr(transparent)]
#[derive(
Deserialize,
Serialize,
Clone,
Copy,
Decode,
Default,
Encode,
Eq,
Hash,
MaxEncodedLen,
Ord,
PartialEq,
PartialOrd,
RuntimeDebug,
)]
pub struct AlphaCurrency(u64);

impl TypeInfo for AlphaCurrency {
type Identity = <u64 as TypeInfo>::Identity;
fn type_info() -> scale_info::Type {
<u64 as TypeInfo>::type_info()
}
}

impl Display for AlphaCurrency {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}

impl CompactAs for AlphaCurrency {
type As = u64;

fn encode_as(&self) -> &Self::As {
&self.0
}

fn decode_from(v: Self::As) -> Result<Self, CodecError> {
Ok(Self(v))
}
}

impl From<Compact<AlphaCurrency>> for AlphaCurrency {
fn from(c: Compact<AlphaCurrency>) -> Self {
c.0
}
}

impl From<AlphaCurrency> for u64 {
fn from(val: AlphaCurrency) -> Self {
val.0
}
}

impl From<u64> for AlphaCurrency {
fn from(value: u64) -> Self {
Self(value)
}
}

impl ToFixed for AlphaCurrency {
fn to_fixed<F: Fixed>(self) -> F {
self.0.to_fixed()
}

fn checked_to_fixed<F: Fixed>(self) -> Option<F> {
self.0.checked_to_fixed()
}

fn saturating_to_fixed<F: Fixed>(self) -> F {
self.0.saturating_to_fixed()
}
fn wrapping_to_fixed<F: Fixed>(self) -> F {
self.0.wrapping_to_fixed()
}

fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool) {
self.0.overflowing_to_fixed()
}
}

impl Currency for AlphaCurrency {
const MAX: Self = Self(u64::MAX);
const ZERO: Self = Self(0);
}

pub trait Currency: ToFixed + Into<u64> + From<u64> + Clone + Copy {
const MAX: Self;
const ZERO: Self;

fn is_zero(&self) -> bool {
Into::<u64>::into(*self) == 0
}

fn to_u64(&self) -> u64 {
(*self).into()
}

fn saturating_add(&self, rhv: Self) -> Self {
Into::<u64>::into(*self).saturating_add(rhv.into()).into()
}

#[allow(clippy::arithmetic_side_effects)]
fn saturating_div(&self, rhv: Self) -> Self {
Into::<u64>::into(*self).saturating_div(rhv.into()).into()
}

fn saturating_sub(&self, rhv: Self) -> Self {
Into::<u64>::into(*self).saturating_sub(rhv.into()).into()
}

fn saturating_mul(&self, rhv: Self) -> Self {
Into::<u64>::into(*self).saturating_mul(rhv.into()).into()
}
}

macro_rules! impl_arithmetic_operators {
($currency_type:ident) => {
impl Add for $currency_type {
type Output = Self;

#[allow(clippy::arithmetic_side_effects)]
fn add(self, rhs: Self) -> Self::Output {
let lhs_u64: u64 = self.into();
let rhs_u64: u64 = rhs.into();
(lhs_u64 + rhs_u64).into()
}
}

impl Sub for $currency_type {
type Output = Self;

#[allow(clippy::arithmetic_side_effects)]
fn sub(self, rhs: Self) -> Self::Output {
let lhs_u64: u64 = self.into();
let rhs_u64: u64 = rhs.into();
(lhs_u64 - rhs_u64).into()
}
}

impl Mul for $currency_type {
type Output = Self;

#[allow(clippy::arithmetic_side_effects)]
fn mul(self, rhs: Self) -> Self::Output {
let lhs_u64: u64 = self.into();
let rhs_u64: u64 = rhs.into();
(lhs_u64 * rhs_u64).into()
}
}

impl Div for $currency_type {
type Output = Self;

#[allow(clippy::arithmetic_side_effects)]
fn div(self, rhs: Self) -> Self::Output {
let lhs_u64: u64 = self.into();
let rhs_u64: u64 = rhs.into();
(lhs_u64 / rhs_u64).into()
}
}

impl AddAssign for $currency_type {
#[allow(clippy::arithmetic_side_effects)]
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}

impl SubAssign for $currency_type {
#[allow(clippy::arithmetic_side_effects)]
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}

impl MulAssign for $currency_type {
#[allow(clippy::arithmetic_side_effects)]
fn mul_assign(&mut self, rhs: Self) {
*self = *self * rhs;
}
}

impl DivAssign for $currency_type {
#[allow(clippy::arithmetic_side_effects)]
fn div_assign(&mut self, rhs: Self) {
*self = *self / rhs;
}
}
};
}

impl_arithmetic_operators!(AlphaCurrency);

macro_rules! impl_approx {
($currency_type:ident) => {
#[cfg(feature = "approx")]
impl AbsDiffEq<Self> for $currency_type {
type Epsilon = Self;

fn default_epsilon() -> Self::Epsilon {
u64::default_epsilon().into()
}

fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
u64::abs_diff_eq(&u64::from(*self), &u64::from(*other), epsilon.into())
}

fn abs_diff_ne(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
u64::abs_diff_ne(&u64::from(*self), &u64::from(*other), epsilon.into())
}
}
};
}

impl_approx!(AlphaCurrency);
18 changes: 11 additions & 7 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ use sp_runtime::{
};
use subtensor_macros::freeze_struct;

pub use currency::*;

mod currency;

/// Balance of an account.
pub type Balance = u64;

Expand Down Expand Up @@ -151,33 +155,33 @@ impl Default for ProxyType {

pub trait SubnetInfo<AccountId> {
fn tao_reserve(netuid: NetUid) -> u64;
fn alpha_reserve(netuid: NetUid) -> u64;
fn alpha_reserve(netuid: NetUid) -> AlphaCurrency;
fn exists(netuid: NetUid) -> bool;
fn mechanism(netuid: NetUid) -> u16;
fn is_owner(account_id: &AccountId, netuid: NetUid) -> bool;
}

pub trait BalanceOps<AccountId> {
fn tao_balance(account_id: &AccountId) -> u64;
fn alpha_balance(netuid: NetUid, coldkey: &AccountId, hotkey: &AccountId) -> u64;
fn alpha_balance(netuid: NetUid, coldkey: &AccountId, hotkey: &AccountId) -> AlphaCurrency;
fn increase_balance(coldkey: &AccountId, tao: u64);
fn decrease_balance(coldkey: &AccountId, tao: u64) -> Result<u64, DispatchError>;
fn increase_stake(
coldkey: &AccountId,
hotkey: &AccountId,
netuid: NetUid,
alpha: u64,
alpha: AlphaCurrency,
) -> Result<(), DispatchError>;
fn decrease_stake(
coldkey: &AccountId,
hotkey: &AccountId,
netuid: NetUid,
alpha: u64,
) -> Result<u64, DispatchError>;
alpha: AlphaCurrency,
) -> Result<AlphaCurrency, DispatchError>;
fn increase_provided_tao_reserve(netuid: NetUid, tao: u64);
fn decrease_provided_tao_reserve(netuid: NetUid, tao: u64);
fn increase_provided_alpha_reserve(netuid: NetUid, alpha: u64);
fn decrease_provided_alpha_reserve(netuid: NetUid, alpha: u64);
fn increase_provided_alpha_reserve(netuid: NetUid, alpha: AlphaCurrency);
fn decrease_provided_alpha_reserve(netuid: NetUid, alpha: AlphaCurrency);
}

pub mod time {
Expand Down
Loading
Loading