Skip to content
176 changes: 176 additions & 0 deletions chain-extensions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ pub mod types;

use crate::types::{FunctionId, Output};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::storage::{TransactionOutcome, transactional};
use frame_support::{DebugNoBound, traits::Get};
use frame_system::RawOrigin;
use pallet_contracts::chain_extension::{
BufInBufOutState, ChainExtension, Environment, Ext, InitState, RetVal, SysConfig,
};
use pallet_subtensor::weights::WeightInfo as SubtensorWeightInfo;
use pallet_subtensor_proxy as pallet_proxy;
use pallet_subtensor_proxy::WeightInfo;
use sp_runtime::{DispatchError, Weight, traits::StaticLookup};
Expand Down Expand Up @@ -523,6 +525,180 @@ where

Ok(RetVal::Converging(Output::Success as u32))
}
FunctionId::RecycleAlphaV1 => {
let weight =
<<T as pallet_subtensor::Config>::WeightInfo as SubtensorWeightInfo>::recycle_alpha();

env.charge_weight(weight)?;

let (hotkey, amount, netuid): (T::AccountId, AlphaBalance, NetUid) =
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make arguments order consistent with AddStakeRecycleV1?

env.read_as()?;

let caller = env.caller();

let call_result = pallet_subtensor::Pallet::<T>::do_recycle_alpha(
RawOrigin::Signed(caller).into(),
hotkey,
amount,
netuid,
);

match call_result {
Ok(real_amount) => {
env.write_output(&real_amount.encode())
.map_err(|_| DispatchError::Other("Failed to write output"))?;
Ok(RetVal::Converging(Output::Success as u32))
}
Err(e) => {
let error_code = Output::from(e) as u32;
Ok(RetVal::Converging(error_code))
}
}
}
FunctionId::BurnAlphaV1 => {
let weight =
<<T as pallet_subtensor::Config>::WeightInfo as SubtensorWeightInfo>::burn_alpha();

env.charge_weight(weight)?;

let (hotkey, amount, netuid): (T::AccountId, AlphaBalance, NetUid) =
env.read_as()?;

let caller = env.caller();

let call_result = pallet_subtensor::Pallet::<T>::do_burn_alpha(
RawOrigin::Signed(caller).into(),
hotkey,
amount,
netuid,
);

match call_result {
Ok(real_amount) => {
env.write_output(&real_amount.encode())
.map_err(|_| DispatchError::Other("Failed to write output"))?;
Ok(RetVal::Converging(Output::Success as u32))
}
Err(e) => {
let error_code = Output::from(e) as u32;
Ok(RetVal::Converging(error_code))
}
}
}
FunctionId::AddStakeRecycleV1 => {
let add_stake_weight =
<<T as pallet_subtensor::Config>::WeightInfo as SubtensorWeightInfo>::add_stake(
);
let recycle_weight =
<<T as pallet_subtensor::Config>::WeightInfo as SubtensorWeightInfo>::recycle_alpha();

env.charge_weight(add_stake_weight)?;

let (hotkey, netuid, tao_amount): (T::AccountId, NetUid, TaoBalance) =
env.read_as()?;

let caller = env.caller();

let mut recycle_attempted = false;

let result: Result<AlphaBalance, DispatchError> =
transactional::with_transaction(|| {
let alpha = match pallet_subtensor::Pallet::<T>::do_add_stake(
RawOrigin::Signed(caller.clone()).into(),
hotkey.clone(),
netuid,
tao_amount,
) {
Ok(a) => a,
Err(e) => return TransactionOutcome::Rollback(Err(e)),
};

recycle_attempted = true;

match pallet_subtensor::Pallet::<T>::do_recycle_alpha(
RawOrigin::Signed(caller).into(),
hotkey,
alpha,
netuid,
) {
Ok(real_alpha) => TransactionOutcome::Commit(Ok(real_alpha)),
Err(e) => TransactionOutcome::Rollback(Err(e)),
}
});

if recycle_attempted {
env.charge_weight(recycle_weight)?;
}

match result {
Ok(alpha) => {
env.write_output(&alpha.encode())
.map_err(|_| DispatchError::Other("Failed to write output"))?;
Ok(RetVal::Converging(Output::Success as u32))
}
Err(e) => {
let error_code = Output::from(e) as u32;
Ok(RetVal::Converging(error_code))
}
}
}
FunctionId::AddStakeBurnV1 => {
let add_stake_weight =
<<T as pallet_subtensor::Config>::WeightInfo as SubtensorWeightInfo>::add_stake(
);
let burn_weight =
<<T as pallet_subtensor::Config>::WeightInfo as SubtensorWeightInfo>::burn_alpha();

env.charge_weight(add_stake_weight)?;

let (hotkey, netuid, tao_amount): (T::AccountId, NetUid, TaoBalance) =
env.read_as()?;

let caller = env.caller();

let mut burn_attempted = false;

let result: Result<AlphaBalance, DispatchError> =
transactional::with_transaction(|| {
let alpha = match pallet_subtensor::Pallet::<T>::do_add_stake(
RawOrigin::Signed(caller.clone()).into(),
hotkey.clone(),
netuid,
tao_amount,
) {
Ok(a) => a,
Err(e) => return TransactionOutcome::Rollback(Err(e)),
};

burn_attempted = true;

match pallet_subtensor::Pallet::<T>::do_burn_alpha(
RawOrigin::Signed(caller).into(),
hotkey,
alpha,
netuid,
) {
Ok(real_alpha) => TransactionOutcome::Commit(Ok(real_alpha)),
Err(e) => TransactionOutcome::Rollback(Err(e)),
}
});

if burn_attempted {
env.charge_weight(burn_weight)?;
}

match result {
Ok(alpha) => {
env.write_output(&alpha.encode())
.map_err(|_| DispatchError::Other("Failed to write output"))?;
Ok(RetVal::Converging(Output::Success as u32))
}
Err(e) => {
let error_code = Output::from(e) as u32;
Ok(RetVal::Converging(error_code))
}
}
}
}
}
}
Expand Down
Loading
Loading