Skip to content

Commit c28baff

Browse files
authored
Merge pull request #2272 from opentensor/alpha-price-ink
get alpha price in Ink
2 parents e58b165 + 1576fdd commit c28baff

File tree

9 files changed

+115
-13
lines changed

9 files changed

+115
-13
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chain-extensions/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pallet-subtensor-proxy.workspace = true
3434
pallet-drand.workspace = true
3535
subtensor-swap-interface.workspace = true
3636
num_enum.workspace = true
37+
substrate-fixed.workspace = true
3738

3839
[lints]
3940
workspace = true
@@ -64,4 +65,5 @@ std = [
6465
"pallet-drand/std",
6566
"subtensor-swap-interface/std",
6667
"num_enum/std",
68+
"substrate-fixed/std",
6769
]

chain-extensions/src/lib.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ use pallet_subtensor_proxy as pallet_proxy;
1818
use pallet_subtensor_proxy::WeightInfo;
1919
use sp_runtime::{DispatchError, Weight, traits::StaticLookup};
2020
use sp_std::marker::PhantomData;
21+
use substrate_fixed::types::U96F32;
2122
use subtensor_runtime_common::{AlphaCurrency, NetUid, ProxyType, TaoCurrency};
23+
use subtensor_swap_interface::SwapHandler;
2224

2325
#[derive(DebugNoBound)]
2426
pub struct SubtensorChainExtension<T>(PhantomData<T>);
@@ -33,7 +35,8 @@ impl<T> ChainExtension<T> for SubtensorChainExtension<T>
3335
where
3436
T: pallet_subtensor::Config
3537
+ pallet_contracts::Config
36-
+ pallet_proxy::Config<ProxyType = ProxyType>,
38+
+ pallet_proxy::Config<ProxyType = ProxyType>
39+
+ pallet_subtensor_swap::Config,
3740
T::AccountId: Clone,
3841
<<T as SysConfig>::Lookup as StaticLookup>::Source: From<<T as SysConfig>::AccountId>,
3942
{
@@ -54,7 +57,8 @@ impl<T> SubtensorChainExtension<T>
5457
where
5558
T: pallet_subtensor::Config
5659
+ pallet_contracts::Config
57-
+ pallet_proxy::Config<ProxyType = ProxyType>,
60+
+ pallet_proxy::Config<ProxyType = ProxyType>
61+
+ pallet_subtensor_swap::Config,
5862
T::AccountId: Clone,
5963
{
6064
fn dispatch<Env>(env: &mut Env) -> Result<RetVal, DispatchError>
@@ -506,6 +510,26 @@ where
506510
}
507511
}
508512
}
513+
FunctionId::GetAlphaPriceV1 => {
514+
let netuid: NetUid = env
515+
.read_as()
516+
.map_err(|_| DispatchError::Other("Failed to decode input parameters"))?;
517+
518+
let current_alpha_price =
519+
<pallet_subtensor_swap::Pallet<T> as SwapHandler>::current_alpha_price(
520+
netuid.into(),
521+
);
522+
523+
let price = current_alpha_price.saturating_mul(U96F32::from_num(1_000_000_000));
524+
let price: u64 = price.saturating_to_num();
525+
526+
let encoded_result = price.encode();
527+
528+
env.write_output(&encoded_result)
529+
.map_err(|_| DispatchError::Other("Failed to write output"))?;
530+
531+
Ok(RetVal::Converging(Output::Success as u32))
532+
}
509533
}
510534
}
511535
}

chain-extensions/src/tests.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
use super::{SubtensorChainExtension, SubtensorExtensionEnv, mock};
44
use crate::types::{FunctionId, Output};
5-
use codec::Encode;
5+
use codec::{Decode, Encode};
66
use frame_support::{assert_ok, weights::Weight};
77
use frame_system::RawOrigin;
88
use pallet_contracts::chain_extension::RetVal;
99
use pallet_subtensor::DefaultMinStake;
1010
use sp_core::Get;
1111
use sp_core::U256;
1212
use sp_runtime::DispatchError;
13+
use substrate_fixed::types::U96F32;
1314
use subtensor_runtime_common::{AlphaCurrency, Currency as CurrencyTrait, NetUid, TaoCurrency};
1415
use subtensor_swap_interface::SwapHandler;
1516

@@ -964,3 +965,41 @@ fn unstake_all_success_unstakes_balance() {
964965
assert!(post_balance > pre_balance);
965966
});
966967
}
968+
969+
#[test]
970+
fn get_alpha_price_returns_encoded_price() {
971+
mock::new_test_ext(1).execute_with(|| {
972+
let owner_hotkey = U256::from(8001);
973+
let owner_coldkey = U256::from(8002);
974+
let caller = U256::from(8003);
975+
976+
let netuid = mock::add_dynamic_network(&owner_hotkey, &owner_coldkey);
977+
978+
// Set up reserves to establish a price
979+
let tao_reserve = TaoCurrency::from(150_000_000_000u64);
980+
let alpha_reserve = AlphaCurrency::from(100_000_000_000u64);
981+
mock::setup_reserves(netuid, tao_reserve, alpha_reserve);
982+
983+
// Get expected price from swap handler
984+
let expected_price =
985+
<pallet_subtensor_swap::Pallet<mock::Test> as SwapHandler>::current_alpha_price(
986+
netuid.into(),
987+
);
988+
let expected_price_scaled = expected_price.saturating_mul(U96F32::from_num(1_000_000_000));
989+
let expected_price_u64: u64 = expected_price_scaled.saturating_to_num();
990+
991+
let mut env = MockEnv::new(FunctionId::GetAlphaPriceV1, caller, netuid.encode());
992+
993+
let ret = SubtensorChainExtension::<mock::Test>::dispatch(&mut env).unwrap();
994+
assert_success(ret);
995+
assert!(env.charged_weight().is_none());
996+
997+
// Decode the output
998+
let output_price: u64 = Decode::decode(&mut &env.output()[..]).unwrap();
999+
1000+
assert_eq!(
1001+
output_price, expected_price_u64,
1002+
"Price should match expected value"
1003+
);
1004+
});
1005+
}

chain-extensions/src/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub enum FunctionId {
2020
SetColdkeyAutoStakeHotkeyV1 = 12,
2121
AddProxyV1 = 13,
2222
RemoveProxyV1 = 14,
23+
GetAlphaPriceV1 = 15,
2324
}
2425

2526
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Debug)]

contract-tests/bittensor/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub enum FunctionId {
2222
SetColdkeyAutoStakeHotkeyV1 = 12,
2323
AddProxyV1 = 13,
2424
RemoveProxyV1 = 14,
25+
GetAlphaPriceV1 = 15,
2526
}
2627

2728
#[ink::chain_extension(extension = 0x1000)]
@@ -127,6 +128,9 @@ pub trait RuntimeReadWrite {
127128

128129
#[ink(function = 14)]
129130
fn remove_proxy(delegate: <CustomEnvironment as ink::env::Environment>::AccountId);
131+
132+
#[ink(function = 15)]
133+
fn get_alpha_price(netuid: NetUid) -> u64;
130134
}
131135

132136
#[ink::scale_derive(Encode, Decode, TypeInfo)]
@@ -412,5 +416,13 @@ mod bittensor {
412416
.remove_proxy(delegate.into())
413417
.map_err(|_e| ReadWriteErrorCode::WriteFailed)
414418
}
419+
420+
#[ink(message)]
421+
pub fn get_alpha_price(&self, netuid: u16) -> Result<u64, ReadWriteErrorCode> {
422+
self.env()
423+
.extension()
424+
.get_alpha_price(netuid.into())
425+
.map_err(|_e| ReadWriteErrorCode::ReadFailed)
426+
}
415427
}
416428
}

contract-tests/run-ci.sh

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
echo "start run-ci.sh"
44

5+
cd contract-tests
6+
7+
cd bittensor
8+
9+
rustup component add rust-src
10+
cargo install cargo-contract
11+
cargo contract build --release
12+
13+
cd ../..
14+
515
scripts/localnet.sh &>/dev/null &
616

717
i=1
@@ -15,7 +25,7 @@ while [ $i -le 2000 ]; do
1525
done
1626

1727
# port not available exit with error
18-
if [ "$i" -eq 1000 ]; then
28+
if [ "$i" -eq 2000 ]; then
1929
exit 1
2030
fi
2131

@@ -28,14 +38,6 @@ fi
2838

2939
cd contract-tests
3040

31-
cd bittensor
32-
33-
rustup component add rust-src
34-
cargo install cargo-contract
35-
cargo contract build --release
36-
37-
cd ..
38-
3941
# required for papi in get-metadata.sh, but we cannot run yarn before papi as it adds the descriptors to the package.json which won't resolve
4042
npm i -g polkadot-api
4143

contract-tests/test/wasm.contract.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,4 +563,25 @@ describe("Test wasm contract", () => {
563563
assert.ok(proxiesAfterRemove !== undefined)
564564
assert.ok(proxiesAfterRemove[0].length === 0)
565565
})
566+
567+
it("Can get alpha price", async () => {
568+
const message = inkClient.message("get_alpha_price")
569+
const data = message.encode({
570+
netuid: netuid,
571+
})
572+
573+
const response = await api.apis.ContractsApi.call(
574+
convertPublicKeyToSs58(hotkey.publicKey),
575+
contractAddress,
576+
BigInt(0),
577+
undefined,
578+
undefined,
579+
Binary.fromBytes(data.asBytes()),
580+
)
581+
582+
assert.ok(response.result.success)
583+
const result = message.decode(response.result.value).value.value
584+
585+
assert.ok(result !== undefined)
586+
})
566587
});

runtime/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
237237
// `spec_version`, and `authoring_version` are the same between Wasm and native.
238238
// This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use
239239
// the compatible custom types.
240-
spec_version: 362,
240+
spec_version: 363,
241241
impl_version: 1,
242242
apis: RUNTIME_API_VERSIONS,
243243
transaction_version: 1,

0 commit comments

Comments
 (0)