//! Gamma reads for `GammaRuntimeApi`. use frame_support::pallet_prelude::{Decode, Encode}; use frame_support::storage::{TransactionOutcome, with_transaction}; use subtensor_runtime_common::{AlphaBalance, GammaBalance, NetUid, TaoBalance}; use subtensor_swap_interface::SwapHandler; use super::*; /// A gamma deposit and what its spender can spend from it now. #[freeze_struct("1fbec154e8c48c46")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct GammaDepositInfo { pub netuid: NetUid, pub hotkey: AccountId, pub deposit: GammaDeposit, /// The deposit's balance within what its daily spend cap allows now. pub spendable: GammaBalance, } impl Pallet { fn gamma_deposit_info( netuid: NetUid, hotkey: T::AccountId, deposit: GammaDeposit, ) -> GammaDepositInfo { let spendable = Self::gamma_allowance(&deposit, Self::get_current_block_as_u64()) .map_or(deposit.balance, |allowance| allowance.min(deposit.balance)); GammaDepositInfo { netuid, hotkey, deposit, spendable, } } /// The deposit at `hotkey` on `netuid`. pub fn get_gamma_deposit( netuid: NetUid, hotkey: T::AccountId, ) -> Option> { let deposit = GammaDeposits::::get(netuid, &hotkey)?; Some(Self::gamma_deposit_info(netuid, hotkey, deposit)) } /// Every deposit `coldkey` owns, on every subnet. pub fn get_gamma_deposits_for_coldkey( coldkey: &T::AccountId, ) -> Vec> { Self::get_all_subnet_netuids() .into_iter() .flat_map(|netuid| { ColdkeyGammaHotkeys::::get(netuid, coldkey) .into_iter() .filter_map(move |hotkey| Self::get_gamma_deposit(netuid, hotkey)) }) .collect() } /// The alpha burned, TAO value and gamma `mint_gamma` would mint for `amount` now, or the /// error that stops it. pub fn sim_mint_gamma( netuid: NetUid, amount: TaoBalance, ) -> Result<(AlphaBalance, TaoBalance, GammaBalance), DispatchError> { with_transaction(|| { TransactionOutcome::Rollback((|| { Self::ensure_gamma_mintable(netuid)?; Self::ensure_add_stake_input_within_swap_limit(netuid, amount)?; let mark = Self::gamma_mark(netuid); let swap = Self::swap_tao_for_alpha(netuid, amount, T::SwapInterface::max_price(), false)?; let alpha = swap.amount_paid_out; let (value, gamma) = Self::gamma_for_alpha(alpha, mark)?; Ok::<_, DispatchError>((alpha, value, gamma)) })()) }) } /// `alpha_amount` and the TAO value and gamma of burning it now, or the error that stops /// it; it reads no stake. pub fn sim_mint_gamma_with_stake( netuid: NetUid, alpha_amount: AlphaBalance, ) -> Result<(AlphaBalance, TaoBalance, GammaBalance), DispatchError> { Self::ensure_gamma_mintable(netuid)?; let mark = Self::gamma_mark(netuid); let (value, gamma) = Self::gamma_for_alpha(alpha_amount, mark)?; Ok((alpha_amount, value, gamma)) } }