Skip to content
Merged
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
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")
// })

});
Loading