Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subnet hyperparameter #1089

Open
wants to merge 13 commits into
base: devnet-ready
Choose a base branch
from
103 changes: 101 additions & 2 deletions runtime/src/precompiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,37 @@ use sp_core::{hashing::keccak_256, H160};
use sp_runtime::AccountId32;

use pallet_evm::{
ExitError, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle,
AddressMapping, BalanceConverter, ExitError, ExitSucceed, HashedAddressMapping,
IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput,
PrecompileResult, PrecompileSet,
};
use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};

use frame_system::RawOrigin;

use sp_core::crypto::Ss58Codec;
use sp_core::U256;
use sp_runtime::traits::Dispatchable;
use sp_runtime::traits::{BlakeTwo256, UniqueSaturatedInto};

use sp_std::vec;

use crate::{Runtime, RuntimeCall};

// Include custom precompiles
mod balance_transfer;
mod ed25519;
mod metagraph;
mod staking;
mod subnet;

use balance_transfer::*;
use ed25519::*;
use metagraph::*;
use staking::*;
use subnet::*;

pub struct FrontierPrecompiles<R>(PhantomData<R>);

Expand All @@ -39,7 +53,7 @@ where
pub fn new() -> Self {
Self(Default::default())
}
pub fn used_addresses() -> [H160; 11] {
pub fn used_addresses() -> [H160; 12] {
[
hash(1),
hash(2),
Expand All @@ -51,6 +65,7 @@ where
hash(EDVERIFY_PRECOMPILE_INDEX),
hash(BALANCE_TRANSFER_INDEX),
hash(STAKING_PRECOMPILE_INDEX),
hash(SUBNET_PRECOMPILE_INDEX),
hash(METAGRAPH_PRECOMPILE_INDEX),
]
}
Expand All @@ -76,6 +91,7 @@ where
Some(BalanceTransferPrecompile::execute(handle))
}
a if a == hash(STAKING_PRECOMPILE_INDEX) => Some(StakingPrecompile::execute(handle)),
a if a == hash(SUBNET_PRECOMPILE_INDEX) => Some(SubnetPrecompile::execute(handle)),
a if a == hash(METAGRAPH_PRECOMPILE_INDEX) => {
Some(MetagraphPrecompile::execute(handle))
}
Expand Down Expand Up @@ -125,8 +141,91 @@ pub fn get_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], Precompil
if let Some(slice) = maybe_slice {
Ok(slice)
} else {
log::error!(
"fail to get slice from data, {:?}, from {}, to {}",
&data,
from,
to
);
Err(PrecompileFailure::Error {
exit_status: ExitError::InvalidRange,
})
}
}

/// The function return the token to smart contract
fn transfer_back_to_caller(
smart_contract_address: &str,
account_id: &AccountId32,
amount: U256,
) -> Result<(), PrecompileFailure> {
let smart_contract_account_id = match AccountId32::from_ss58check(smart_contract_address) {
// match AccountId32::from_ss58check("5CwnBK9Ack1mhznmCnwiibCNQc174pYQVktYW3ayRpLm4K2X") {
Ok(addr) => addr,
Err(_) => {
return Err(PrecompileFailure::Error {
exit_status: ExitError::Other("Invalid SS58 address".into()),
});
}
};
let amount_sub =
<Runtime as pallet_evm::Config>::BalanceConverter::into_substrate_balance(amount)
.ok_or(ExitError::OutOfFund)?;

// Create a transfer call from the smart contract to the caller
let transfer_call =
RuntimeCall::Balances(pallet_balances::Call::<Runtime>::transfer_allow_death {
dest: account_id.clone().into(),
value: amount_sub.unique_saturated_into(),
});

// Execute the transfer
let transfer_result =
transfer_call.dispatch(RawOrigin::Signed(smart_contract_account_id).into());

if let Err(dispatch_error) = transfer_result {
log::error!(
"Transfer back to caller failed. Error: {:?}",
dispatch_error
);
return Err(PrecompileFailure::Error {
exit_status: ExitError::Other("Transfer back to caller failed".into()),
});
}

Ok(())
}

fn dispatch(
handle: &mut impl PrecompileHandle,
call: RuntimeCall,
smart_contract_address: &str,
) -> PrecompileResult {
let account_id =
<HashedAddressMapping<BlakeTwo256> as AddressMapping<AccountId32>>::into_account_id(
handle.context().caller,
);

// Transfer the amount back to the caller before executing the staking operation
// let caller = handle.context().caller;
let amount = handle.context().apparent_value;

if !amount.is_zero() {
transfer_back_to_caller(smart_contract_address, &account_id, amount)?;
}

let result = call.dispatch(RawOrigin::Signed(account_id.clone()).into());
match &result {
Ok(post_info) => log::info!("Dispatch succeeded. Post info: {:?}", post_info),
Err(dispatch_error) => log::error!("Dispatch failed. Error: {:?}", dispatch_error),
}
match result {
Ok(_) => Ok(PrecompileOutput {
exit_status: ExitSucceed::Returned,
output: vec![],
}),
Err(_) => Err(PrecompileFailure::Error {
exit_status: ExitError::Other("Subtensor call failed".into()),
}),
}
}
Loading
Loading