Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion evm-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"dotenv": "16.4.7",
"ethers": "^6.13.5",
"mocha": "^11.1.0",
"polkadot-api": "^1.9.5",
"polkadot-api": "^1.11.0",
"scale-ts": "^1.6.1",
"viem": "2.23.4",
"ws": "^8.18.2"
Expand Down
100 changes: 80 additions & 20 deletions evm-tests/test/runtime.call.precompile.test.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
import * as assert from "assert";
import { getAliceSigner, getDevnetApi } from "../src/substrate"
import { getAliceSigner, getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
import { generateRandomEthersWallet, getPublicClient } from "../src/utils";
import { IDISPATCH_ADDRESS, ISTORAGE_QUERY_ADDRESS, ETH_LOCAL_URL } from "../src/config";
import { devnet, MultiAddress } from "@polkadot-api/descriptors"
import { hexToNumber, PublicClient } from "viem";
import { PolkadotSigner, TypedApi } from "polkadot-api";
import { PublicClient } from "viem";
import { PolkadotSigner, TypedApi, getTypedCodecs } from "polkadot-api";
import { convertPublicKeyToSs58 } from "../src/address-utils"
import { forceSetBalanceToEthAddress, setMaxChildkeyTake } from "../src/subtensor";
import { xxhashAsU8a } from '@polkadot/util-crypto';
import { u8aToHex } from '@polkadot/util';
import { forceSetBalanceToEthAddress, setMaxChildkeyTake, burnedRegister, forceSetBalanceToSs58Address, addStake, setTxRateLimit, addNewSubnetwork, startCall, setTempo } from "../src/subtensor";

describe("Test the dispatch precompile", () => {
let publicClient: PublicClient;
const wallet1 = generateRandomEthersWallet();
let api: TypedApi<typeof devnet>
let alice: PolkadotSigner;
const hotkey = getRandomSubstrateKeypair();
const coldkey = getRandomSubstrateKeypair();
let netuid: number;

before(async () => {
publicClient = await getPublicClient(ETH_LOCAL_URL)
api = await getDevnetApi()
alice = await getAliceSigner()
await forceSetBalanceToEthAddress(api, wallet1.address)

await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))


netuid = await addNewSubnetwork(api, hotkey, coldkey)
// set tempo big enough to avoid stake value updated with fast block feature
await setTempo(api, netuid, 10000)
await startCall(api, netuid, coldkey)
await setTxRateLimit(api, BigInt(0))

await burnedRegister(api, netuid, convertPublicKeyToSs58(hotkey.publicKey), coldkey)
await addStake(api, netuid, convertPublicKeyToSs58(hotkey.publicKey), BigInt(1_000_000_000), coldkey)
})

it("Dispatch transfer call via precompile contract works correctly", async () => {
Expand Down Expand Up @@ -49,27 +63,73 @@ describe("Test the dispatch precompile", () => {
})


it("Storage query call via precompile contract works correctly", async () => {
const palletPrefixBytes = xxhashAsU8a("SubtensorModule", 128);
const storageItemPrefixBytes = xxhashAsU8a("MaxChildkeyTake", 128);
const fullStorageKeyBytes = new Uint8Array([...palletPrefixBytes, ...storageItemPrefixBytes]);
// 0x658faa385070e074c85bf6b568cf0555dba018859cab7e989f77669457b394be
// key for max child key take
const fullStorageKeyHex = u8aToHex(fullStorageKeyBytes);
it("Value type storage query call via precompile contract works correctly", async () => {
const key = await api.query.SubtensorModule.MaxChildkeyTake.getKey();

let maxChildkeyTake = 257;
await setMaxChildkeyTake(api, maxChildkeyTake)

api.query.SubtensorModule.MaxChildkeyTake.getValue();
const rawCallResponse = await publicClient.call({
to: ISTORAGE_QUERY_ADDRESS,
data: fullStorageKeyHex,
data: key.toString() as `0x${string}`,
})
const rawResultData = rawCallResponse.data ?? "";

const codec = await getTypedCodecs(devnet);
const maxChildkeyTakeCodec = codec.query.SubtensorModule.MaxChildkeyTake.value;
const maxChildkeyTakeFromContract = maxChildkeyTakeCodec.dec(rawResultData);
assert.equal(maxChildkeyTakeFromContract, maxChildkeyTake, "value should be 257")
})

it("Map type storage query call via precompile contract works correctly", async () => {

const key = await api.query.SubtensorModule.Tempo.getKey(netuid);

const tempoOnChain = await api.query.SubtensorModule.Tempo.getValue(netuid);
const rawCallResponse = await publicClient.call({
to: ISTORAGE_QUERY_ADDRESS,
data: key.toString() as `0x${string}`,
})
const rawResultData = rawCallResponse.data;
if (rawResultData === undefined) {
throw new Error("rawResultData is undefined");
}
let value = hexToNumber(rawResultData);
assert.equal(value, maxChildkeyTake, "value should be 257")
const rawResultData = rawCallResponse.data ?? "";

const codec = await getTypedCodecs(devnet);
const maxChildkeyTakeValueCodec = codec.query.SubtensorModule.Tempo.value;
const decodedValue = maxChildkeyTakeValueCodec.dec(rawResultData);
assert.equal(tempoOnChain, decodedValue, "value should be the same as on chain")
})

it("Double map type storage query call via precompile contract works correctly", async () => {
const key = await api.query.SubtensorModule.TotalHotkeyAlpha.getKey(convertPublicKeyToSs58(hotkey.publicKey), netuid);
const totalHotkeyAlphaOnChain = await api.query.SubtensorModule.TotalHotkeyAlpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), netuid);

const rawCallResponse = await publicClient.call({
to: ISTORAGE_QUERY_ADDRESS,
data: key.toString() as `0x${string}`,
})
const rawResultData = rawCallResponse.data ?? "";
const codec = await getTypedCodecs(devnet);
const totalHotkeyAlphaValueCodec = codec.query.SubtensorModule.TotalHotkeyAlpha.value;
const decodedValue = totalHotkeyAlphaValueCodec.dec(rawResultData);
assert.equal(totalHotkeyAlphaOnChain, decodedValue, "value should be the same as on chain")

})

// Polkadot api can't decode the boolean type for now.
// it("Double map type storage query call via precompile contract works correctly", async () => {
// const key = await api.query.SubtensorModule.IsNetworkMember.getKey(convertPublicKeyToSs58(alice.publicKey), netuid);

// const isNetworkMemberOnChain = await api.query.SubtensorModule.IsNetworkMember.getValue(convertPublicKeyToSs58(alice.publicKey), netuid);
// const rawCallResponse = await publicClient.call({
// to: ISTORAGE_QUERY_ADDRESS,
// data: key.toString() as `0x${string}`,
// })

// const rawResultData = rawCallResponse.data ?? "";
// const codec = await getTypedCodecs(devnet);
// const isNetworkMemberValueCodec = codec.query.SubtensorModule.IsNetworkMember.value;
// const decodedValue = isNetworkMemberValueCodec.dec(rawResultData);
// assert.equal(isNetworkMemberOnChain, decodedValue, "value should be the same as on chain")
// })

});
8 changes: 4 additions & 4 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ mod dispatches {
/// - On failure for each failed item in the batch.
///
#[pallet::call_index(80)]
#[pallet::weight((Weight::from_parts(95_160_000, 0)
.saturating_add(T::DbWeight::get().reads(14))
.saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))]
#[pallet::weight((Weight::from_parts(18_930_000, 0)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(0_u64)), DispatchClass::Normal, Pays::No))]
pub fn batch_set_weights(
origin: OriginFor<T>,
netuids: Vec<Compact<NetUid>>,
Expand Down Expand Up @@ -2201,7 +2201,7 @@ mod dispatches {
/// * commit_reveal_version (`u16`):
/// - The client (bittensor-drand) version
#[pallet::call_index(113)]
#[pallet::weight((Weight::from_parts(64_530_000, 0)
#[pallet::weight((Weight::from_parts(80_110_000, 0)
.saturating_add(T::DbWeight::get().reads(7_u64))
.saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))]
pub fn commit_timelocked_weights(
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// `spec_version`, and `authoring_version` are the same between Wasm and native.
// This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use
// the compatible custom types.
spec_version: 307,
spec_version: 308,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
Expand Down