Skip to content

Commit c771436

Browse files
authored
Merge pull request #1374 from opentensor/feat/evm-typed-test
add types e2e test for evm
2 parents b8cbd8d + cff4153 commit c771436

36 files changed

+5762
-7
lines changed

Cargo.lock

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

evm-tests/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.papi
3+
.env

evm-tests/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# type-test
2+
3+
test with ts
4+
5+
## polkadot api
6+
7+
```bash
8+
npx papi add devnet -w ws://10.0.0.11:9944
9+
```
10+
11+
## get the new metadata
12+
13+
```bash
14+
sh get-metadata.sh
15+
```
16+
17+
## run all tests
18+
19+
```bash
20+
yarn run test
21+
```
22+
23+
## To run a particular test case, you can pass an argument with the name or part of the name. For example:
24+
25+
```bash
26+
yarn run test -- -g "Can set subnet parameter"
27+
```

evm-tests/get-metadata.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
rm -rf .papi
2+
npx papi add devnet -w ws://localhost:9944
3+

evm-tests/local.test.ts

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import * as assert from "assert";
2+
import { getAliceSigner, getClient, getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
3+
import { SUB_LOCAL_URL, } from "../src/config";
4+
import { devnet } from "@polkadot-api/descriptors"
5+
import { PolkadotSigner, TypedApi } from "polkadot-api";
6+
import { convertPublicKeyToSs58, convertH160ToSS58 } from "../src/address-utils"
7+
import { ethers } from "ethers"
8+
import { INEURON_ADDRESS, INeuronABI } from "../src/contracts/neuron"
9+
import { generateRandomEthersWallet } from "../src/utils"
10+
import { forceSetBalanceToEthAddress, forceSetBalanceToSs58Address, addNewSubnetwork, burnedRegister } from "../src/subtensor"
11+
12+
describe("Test neuron precompile Serve Axon Prometheus", () => {
13+
// init eth part
14+
// const wallet1 = generateRandomEthersWallet();
15+
// const wallet2 = generateRandomEthersWallet();
16+
// const wallet3 = generateRandomEthersWallet();
17+
18+
// init substrate part
19+
20+
// const coldkey = getRandomSubstrateKeypair();
21+
22+
let api: TypedApi<typeof devnet>
23+
24+
// sudo account alice as signer
25+
let alice: PolkadotSigner;
26+
before(async () => {
27+
// init variables got from await and async
28+
const subClient = await getClient(SUB_LOCAL_URL)
29+
api = await getDevnetApi()
30+
// alice = await getAliceSigner();
31+
32+
// await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
33+
// await forceSetBalanceToEthAddress(api, wallet1.address)
34+
// await forceSetBalanceToEthAddress(api, wallet2.address)
35+
// await forceSetBalanceToEthAddress(api, wallet3.address)
36+
37+
38+
let index = 0;
39+
while (index < 30) {
40+
const hotkey = getRandomSubstrateKeypair();
41+
const coldkey = getRandomSubstrateKeypair();
42+
await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
43+
await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
44+
let netuid = await addNewSubnetwork(api, hotkey, coldkey)
45+
}
46+
47+
48+
})
49+
50+
it("Serve Axon", async () => {
51+
52+
});
53+
});

evm-tests/package.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"scripts": {
3+
"test": "mocha --timeout 999999 --require ts-node/register test/*test.ts"
4+
},
5+
"keywords": [],
6+
"author": "",
7+
"license": "ISC",
8+
"dependencies": {
9+
"@polkadot-api/descriptors": "file:.papi/descriptors",
10+
"@polkadot-labs/hdkd": "^0.0.10",
11+
"@polkadot-labs/hdkd-helpers": "^0.0.11",
12+
"@polkadot/api": "15.1.1",
13+
"crypto": "^1.0.1",
14+
"dotenv": "16.4.7",
15+
"ethers": "^6.13.5",
16+
"polkadot-api": "^1.9.5",
17+
"viem": "2.23.4"
18+
},
19+
"devDependencies": {
20+
"@types/bun": "^1.1.13",
21+
"@types/chai": "^5.0.1",
22+
"@types/mocha": "^10.0.10",
23+
"assert": "^2.1.0",
24+
"chai": "^5.2.0",
25+
"mocha": "^11.1.0",
26+
"prettier": "^3.3.3",
27+
"ts-node": "^10.9.2",
28+
"typescript": "^5.7.2",
29+
"vite": "^5.4.8"
30+
}
31+
}

evm-tests/src/address-utils.ts

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { Address } from "viem"
2+
import { encodeAddress } from "@polkadot/util-crypto";
3+
import { ss58Address } from "@polkadot-labs/hdkd-helpers";
4+
import { hexToU8a } from "@polkadot/util";
5+
import { blake2AsU8a, decodeAddress } from "@polkadot/util-crypto";
6+
import { Binary } from "polkadot-api";
7+
import { SS58_PREFIX } from "./config"
8+
9+
export function toViemAddress(address: string): Address {
10+
let addressNoPrefix = address.replace("0x", "")
11+
return `0x${addressNoPrefix}`
12+
}
13+
14+
export function convertH160ToSS58(ethAddress: string) {
15+
// get the public key
16+
const hash = convertH160ToPublicKey(ethAddress);
17+
18+
// Convert the hash to SS58 format
19+
const ss58Address = encodeAddress(hash, SS58_PREFIX);
20+
return ss58Address;
21+
}
22+
23+
export function convertPublicKeyToSs58(publickey: Uint8Array) {
24+
return ss58Address(publickey, SS58_PREFIX);
25+
}
26+
27+
export function convertH160ToPublicKey(ethAddress: string) {
28+
const prefix = "evm:";
29+
const prefixBytes = new TextEncoder().encode(prefix);
30+
const addressBytes = hexToU8a(
31+
ethAddress.startsWith("0x") ? ethAddress : `0x${ethAddress}`
32+
);
33+
const combined = new Uint8Array(prefixBytes.length + addressBytes.length);
34+
35+
// Concatenate prefix and Ethereum address
36+
combined.set(prefixBytes);
37+
combined.set(addressBytes, prefixBytes.length);
38+
39+
// Hash the combined data (the public key)
40+
const hash = blake2AsU8a(combined);
41+
return hash;
42+
}
43+
44+
export function ss58ToEthAddress(ss58Address: string) {
45+
// Decode the SS58 address to a Uint8Array public key
46+
const publicKey = decodeAddress(ss58Address);
47+
48+
// Take the first 20 bytes of the hashed public key for the Ethereum address
49+
const ethereumAddressBytes = publicKey.slice(0, 20);
50+
51+
// Convert the 20 bytes into an Ethereum H160 address format (Hex string)
52+
const ethereumAddress = '0x' + Buffer.from(ethereumAddressBytes).toString('hex');
53+
54+
return ethereumAddress;
55+
}
56+
57+
export function ss58ToH160(ss58Address: string): Binary {
58+
// Decode the SS58 address to a Uint8Array public key
59+
const publicKey = decodeAddress(ss58Address);
60+
61+
// Take the first 20 bytes of the hashed public key for the Ethereum address
62+
const ethereumAddressBytes = publicKey.slice(0, 20);
63+
64+
65+
return new Binary(ethereumAddressBytes);
66+
}
67+
68+
export function ethAddressToH160(ethAddress: string): Binary {
69+
// Decode the SS58 address to a Uint8Array public key
70+
const publicKey = hexToU8a(ethAddress);
71+
72+
// Take the first 20 bytes of the hashed public key for the Ethereum address
73+
// const ethereumAddressBytes = publicKey.slice(0, 20);
74+
75+
76+
return new Binary(publicKey);
77+
}

evm-tests/src/balance-math.ts

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import assert from "assert"
2+
3+
export const TAO = BigInt(1000000000) // 10^9
4+
export const ETH_PER_RAO = BigInt(1000000000) // 10^9
5+
export const GWEI = BigInt(1000000000) // 10^9
6+
export const MAX_TX_FEE = BigInt(21000000) * GWEI // 100 times EVM to EVM transfer fee
7+
8+
export function bigintToRao(value: bigint) {
9+
return TAO * value
10+
}
11+
12+
export function tao(value: number) {
13+
return TAO * BigInt(value)
14+
}
15+
16+
export function raoToEth(value: bigint) {
17+
return ETH_PER_RAO * value
18+
}
19+
20+
export function compareEthBalanceWithTxFee(balance1: bigint, balance2: bigint) {
21+
if (balance1 > balance2) {
22+
assert((balance1 - balance2) < MAX_TX_FEE)
23+
} else {
24+
assert((balance2 - balance1) < MAX_TX_FEE)
25+
}
26+
}

evm-tests/src/config.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
export const ETH_LOCAL_URL = 'http://localhost:9944'
2+
export const SUB_LOCAL_URL = 'ws://localhost:9944'
3+
export const SS58_PREFIX = 42;
4+
// set the tx timeout as 2 second when eable the fast-blocks feature.
5+
export const TX_TIMEOUT = 2000;
6+
7+
export const IED25519VERIFY_ADDRESS = "0x0000000000000000000000000000000000000402";
8+
export const IEd25519VerifyABI = [
9+
{
10+
inputs: [
11+
{ internalType: "bytes32", name: "message", type: "bytes32" },
12+
{ internalType: "bytes32", name: "publicKey", type: "bytes32" },
13+
{ internalType: "bytes32", name: "r", type: "bytes32" },
14+
{ internalType: "bytes32", name: "s", type: "bytes32" },
15+
],
16+
name: "verify",
17+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
18+
stateMutability: "pure",
19+
type: "function",
20+
},
21+
];
22+
23+
export const IBALANCETRANSFER_ADDRESS = "0x0000000000000000000000000000000000000800";
24+
export const IBalanceTransferABI = [
25+
{
26+
inputs: [
27+
{
28+
internalType: "bytes32",
29+
name: "data",
30+
type: "bytes32",
31+
},
32+
],
33+
name: "transfer",
34+
outputs: [],
35+
stateMutability: "payable",
36+
type: "function",
37+
},
38+
];

0 commit comments

Comments
 (0)