diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 530c7cd8df..904027bde2 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -9,7 +9,6 @@ on:
description: "Branch or tag to use for the Docker image tag and ref to checkout (optional)"
required: false
default: ""
-
push:
branches:
- devnet-ready
@@ -35,6 +34,13 @@ jobs:
echo "tag=$branch_or_tag" >> $GITHUB_ENV
echo "ref=$branch_or_tag" >> $GITHUB_ENV
+ # Check if this is a tagged release (not devnet-ready/devnet/testnet)
+ if [[ "${{ github.event_name }}" == "release" && "$branch_or_tag" != "devnet-ready" && "$branch_or_tag" != "devnet" && "$branch_or_tag" != "testnet" ]]; then
+ echo "latest_tag=true" >> $GITHUB_ENV
+ else
+ echo "latest_tag=false" >> $GITHUB_ENV
+ fi
+
- name: Checkout code
uses: actions/checkout@v4
with:
@@ -58,5 +64,7 @@ jobs:
with:
context: .
push: true
+ platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/${{ github.repository }}:${{ env.tag }}
+ ${{ env.latest_tag == 'true' && format('ghcr.io/{0}:latest', github.repository) || '' }}
diff --git a/Cargo.lock b/Cargo.lock
index 70dcd3d377..6fe43451ed 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -23,11 +23,11 @@ dependencies = [
[[package]]
name = "addr2line"
-version = "0.24.1"
+version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
- "gimli 0.31.0",
+ "gimli 0.31.1",
]
[[package]]
@@ -77,7 +77,7 @@ version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
"once_cell",
"version_check",
]
@@ -89,7 +89,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
dependencies = [
"cfg-if",
- "getrandom",
+ "getrandom 0.2.15",
"once_cell",
"version_check",
"zerocopy",
@@ -106,9 +106,9 @@ dependencies = [
[[package]]
name = "allocator-api2"
-version = "0.2.18"
+version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
+checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "android-tzdata"
@@ -127,9 +127,9 @@ dependencies = [
[[package]]
name = "anstream"
-version = "0.6.15"
+version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -142,43 +142,44 @@ dependencies = [
[[package]]
name = "anstyle"
-version = "1.0.8"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
+checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.1.1"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
+checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.4"
+version = "3.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
+checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
- "windows-sys 0.52.0",
+ "once_cell",
+ "windows-sys 0.59.0",
]
[[package]]
name = "anyhow"
-version = "1.0.89"
+version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
+checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
[[package]]
name = "approx"
@@ -200,7 +201,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -567,7 +568,7 @@ dependencies = [
"nom",
"num-traits",
"rusticata-macros",
- "thiserror",
+ "thiserror 1.0.69",
"time",
]
@@ -583,7 +584,7 @@ dependencies = [
"nom",
"num-traits",
"rusticata-macros",
- "thiserror",
+ "thiserror 1.0.69",
"time",
]
@@ -607,7 +608,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
"synstructure 0.13.1",
]
@@ -630,7 +631,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -652,9 +653,9 @@ dependencies = [
[[package]]
name = "async-io"
-version = "2.3.4"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8"
+checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059"
dependencies = [
"async-lock",
"cfg-if",
@@ -663,7 +664,7 @@ dependencies = [
"futures-lite",
"parking",
"polling",
- "rustix 0.38.37",
+ "rustix 0.38.44",
"slab",
"tracing",
"windows-sys 0.59.0",
@@ -675,20 +676,20 @@ version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
dependencies = [
- "event-listener 5.3.1",
+ "event-listener 5.4.0",
"event-listener-strategy",
"pin-project-lite",
]
[[package]]
name = "async-trait"
-version = "0.1.83"
+version = "0.1.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
+checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -732,13 +733,13 @@ dependencies = [
[[package]]
name = "auto_impl"
-version = "1.2.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
+checksum = "e12882f59de5360c748c4cbf569a042d5fb0eb515f7bea9c1f470b47f6ffbd73"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -753,11 +754,11 @@ version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
- "addr2line 0.24.1",
+ "addr2line 0.24.2",
"cfg-if",
"libc",
"miniz_oxide",
- "object 0.36.4",
+ "object 0.36.7",
"rustc-demangle",
"windows-targets 0.52.6",
]
@@ -819,13 +820,13 @@ dependencies = [
"lazy_static",
"lazycell",
"peeking_take_while",
- "prettyplease 0.2.22",
+ "prettyplease 0.2.29",
"proc-macro2",
"quote",
"regex",
"rustc-hash 1.1.0",
"shlex",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -852,9 +853,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "2.6.0"
+version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "bitvec"
@@ -913,9 +914,9 @@ dependencies = [
[[package]]
name = "blake3"
-version = "1.5.4"
+version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7"
+checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e"
dependencies = [
"arrayref",
"arrayvec",
@@ -944,9 +945,9 @@ dependencies = [
[[package]]
name = "bounded-collections"
-version = "0.2.0"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32385ecb91a31bddaf908e8dcf4a15aef1bcd3913cc03ebfad02ff6d568abc1"
+checksum = "3d077619e9c237a5d1875166f5e8033e8f6bff0c96f8caf81e1c2d7738c431bf"
dependencies = [
"log",
"parity-scale-codec",
@@ -980,9 +981,9 @@ dependencies = [
[[package]]
name = "bumpalo"
-version = "3.16.0"
+version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "byte-slice-cast"
@@ -998,9 +999,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "bytemuck"
-version = "1.18.0"
+version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae"
+checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "byteorder"
@@ -1010,9 +1011,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.7.2"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
+checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
[[package]]
name = "bzip2-sys"
@@ -1046,9 +1047,9 @@ dependencies = [
[[package]]
name = "cargo-platform"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
+checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
dependencies = [
"serde",
]
@@ -1061,10 +1062,10 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a"
dependencies = [
"camino",
"cargo-platform",
- "semver 1.0.23",
+ "semver 1.0.25",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -1075,9 +1076,9 @@ checksum = "fd6c0e7b807d60291f42f33f58480c0bfafe28ed08286446f45e463728cf9c1c"
[[package]]
name = "cc"
-version = "1.1.24"
+version = "1.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
+checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229"
dependencies = [
"jobserver",
"libc",
@@ -1150,9 +1151,9 @@ dependencies = [
[[package]]
name = "chrono"
-version = "0.4.38"
+version = "0.4.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
+checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
dependencies = [
"android-tzdata",
"iana-time-zone",
@@ -1222,9 +1223,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.19"
+version = "4.5.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615"
+checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
dependencies = [
"clap_builder",
"clap_derive",
@@ -1232,9 +1233,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.19"
+version = "4.5.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b"
+checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
dependencies = [
"anstream",
"anstyle",
@@ -1245,21 +1246,21 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.5.18"
+version = "4.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "clap_lex"
-version = "0.7.2"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "codespan-reporting"
@@ -1268,14 +1269,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [
"termcolor",
- "unicode-width",
+ "unicode-width 0.1.14",
]
[[package]]
name = "colorchoice"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
+checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "combine"
@@ -1289,13 +1290,13 @@ dependencies = [
[[package]]
name = "comfy-table"
-version = "7.1.1"
+version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7"
+checksum = "24f165e7b643266ea80cb858aed492ad9280e3e05ce24d4a99d7d7b889b6a4d9"
dependencies = [
"strum 0.26.3",
"strum_macros 0.26.4",
- "unicode-width",
+ "unicode-width 0.2.0",
]
[[package]]
@@ -1315,15 +1316,15 @@ dependencies = [
[[package]]
name = "console"
-version = "0.15.8"
+version = "0.15.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
+checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b"
dependencies = [
"encode_unicode",
- "lazy_static",
"libc",
- "unicode-width",
- "windows-sys 0.52.0",
+ "once_cell",
+ "unicode-width 0.2.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -1347,7 +1348,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
"once_cell",
"tiny-keccak",
]
@@ -1406,9 +1407,9 @@ dependencies = [
[[package]]
name = "cpufeatures"
-version = "0.2.14"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
@@ -1537,9 +1538,9 @@ dependencies = [
[[package]]
name = "crossbeam-deque"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
+checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
@@ -1565,15 +1566,15 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.20"
+version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crunchy"
-version = "0.2.2"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
[[package]]
name = "crypto-bigint"
@@ -1651,51 +1652,66 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "cxx"
-version = "1.0.128"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54ccead7d199d584d139148b04b4a368d1ec7556a1d9ea2548febb1b9d49f9a4"
+checksum = "0fc894913dccfed0f84106062c284fa021c3ba70cb1d78797d6f5165d4492e45"
dependencies = [
"cc",
+ "cxxbridge-cmd",
"cxxbridge-flags",
"cxxbridge-macro",
+ "foldhash",
"link-cplusplus",
]
[[package]]
name = "cxx-build"
-version = "1.0.128"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c77953e99f01508f89f55c494bfa867171ef3a6c8cea03d26975368f2121a5c1"
+checksum = "503b2bfb6b3e8ce7f95d865a67419451832083d3186958290cee6c53e39dfcfe"
dependencies = [
"cc",
"codespan-reporting",
- "once_cell",
"proc-macro2",
"quote",
"scratch",
- "syn 2.0.90",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "cxxbridge-cmd"
+version = "1.0.137"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0d2cb64a95b4b5a381971482235c4db2e0208302a962acdbe314db03cbbe2fb"
+dependencies = [
+ "clap",
+ "codespan-reporting",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
]
[[package]]
name = "cxxbridge-flags"
-version = "1.0.128"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65777e06cc48f0cb0152024c77d6cf9e4bdb4408e7b48bea993d42fa0f5b02b6"
+checksum = "5f797b0206463c9c2a68ed605ab28892cca784f1ef066050f4942e3de26ad885"
[[package]]
name = "cxxbridge-macro"
-version = "1.0.128"
+version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98532a60dedaebc4848cb2cba5023337cc9ea3af16a5b062633fabfd9f18fb60"
+checksum = "e79010a2093848e65a3e0f7062d3f02fb2ef27f866416dfe436fccfa73d3bb59"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "rustversion",
+ "syn 2.0.96",
]
[[package]]
@@ -1719,7 +1735,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -1730,7 +1746,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [
"darling_core",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -1748,15 +1764,15 @@ dependencies = [
[[package]]
name = "data-encoding"
-version = "2.6.0"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
+checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f"
[[package]]
name = "data-encoding-macro"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639"
+checksum = "5b16d9d0d88a5273d830dac8b78ceb217ffc9b1d5404e5597a3542515329405b"
dependencies = [
"data-encoding",
"data-encoding-macro-internal",
@@ -1764,9 +1780,9 @@ dependencies = [
[[package]]
name = "data-encoding-macro-internal"
-version = "0.1.13"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f"
+checksum = "1145d32e826a7748b69ee8fc62d3e6355ff7f1051df53141e7048162fc90481b"
dependencies = [
"data-encoding",
"syn 1.0.109",
@@ -1839,7 +1855,7 @@ checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -1852,7 +1868,27 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version 0.4.1",
- "syn 2.0.90",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "derive_more"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
+dependencies = [
+ "derive_more-impl",
+]
+
+[[package]]
+name = "derive_more-impl"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
]
[[package]]
@@ -1941,23 +1977,23 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "docify"
-version = "0.2.8"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a2f138ad521dc4a2ced1a4576148a6a610b4c5923933b062a263130a6802ce"
+checksum = "a772b62b1837c8f060432ddcc10b17aae1453ef17617a99bc07789252d2a5896"
dependencies = [
"docify_macros",
]
[[package]]
name = "docify_macros"
-version = "0.2.8"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a081e51fb188742f5a7a1164ad752121abcb22874b21e2c3b0dd040c515fdad"
+checksum = "60e6be249b0a462a14784a99b19bf35a667bb5e09de611738bb7362fa4c95ff7"
dependencies = [
"common-path",
"derive-syn-parse",
@@ -1965,7 +2001,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
- "syn 2.0.90",
+ "syn 2.0.96",
"termcolor",
"toml 0.8.19",
"walkdir",
@@ -1991,9 +2027,9 @@ checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653"
[[package]]
name = "dyn-clonable"
-version = "0.9.0"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4"
+checksum = "a36efbb9bfd58e1723780aa04b61aba95ace6a05d9ffabfdb0b43672552f0805"
dependencies = [
"dyn-clonable-impl",
"dyn-clone",
@@ -2001,13 +2037,13 @@ dependencies = [
[[package]]
name = "dyn-clonable-impl"
-version = "0.9.0"
+version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5"
+checksum = "7e8671d54058979a37a26f3511fbf8d198ba1aa35ffb202c42587d918d77213a"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.96",
]
[[package]]
@@ -2102,9 +2138,9 @@ dependencies = [
[[package]]
name = "encode_unicode"
-version = "0.3.6"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
+checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "enum-as-inner"
@@ -2127,27 +2163,27 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "enumflags2"
-version = "0.7.10"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d"
+checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147"
dependencies = [
"enumflags2_derive",
]
[[package]]
name = "enumflags2_derive"
-version = "0.7.10"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
+checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -2177,12 +2213,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
-version = "0.3.9"
+version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -2193,9 +2229,9 @@ checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60"
dependencies = [
"crunchy",
"fixed-hash",
- "impl-codec",
+ "impl-codec 0.6.0",
"impl-rlp",
- "impl-serde",
+ "impl-serde 0.4.0",
"scale-info",
"tiny-keccak",
]
@@ -2226,12 +2262,12 @@ checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee"
dependencies = [
"ethbloom",
"fixed-hash",
- "impl-codec",
+ "impl-codec 0.6.0",
"impl-rlp",
- "impl-serde",
- "primitive-types",
+ "impl-serde 0.4.0",
+ "primitive-types 0.12.2",
"scale-info",
- "uint",
+ "uint 0.9.5",
]
[[package]]
@@ -2242,9 +2278,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "event-listener"
-version = "5.3.1"
+version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
+checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
dependencies = [
"concurrent-queue",
"parking",
@@ -2253,11 +2289,11 @@ dependencies = [
[[package]]
name = "event-listener-strategy"
-version = "0.5.2"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1"
+checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2"
dependencies = [
- "event-listener 5.3.1",
+ "event-listener 5.4.0",
"pin-project-lite",
]
@@ -2275,7 +2311,7 @@ dependencies = [
"evm-runtime",
"log",
"parity-scale-codec",
- "primitive-types",
+ "primitive-types 0.12.2",
"rlp",
"scale-info",
"serde",
@@ -2289,7 +2325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1da6cedc5cedb4208e59467106db0d1f50db01b920920589f8e672c02fdc04f"
dependencies = [
"parity-scale-codec",
- "primitive-types",
+ "primitive-types 0.12.2",
"scale-info",
"serde",
]
@@ -2303,7 +2339,7 @@ dependencies = [
"environmental",
"evm-core",
"evm-runtime",
- "primitive-types",
+ "primitive-types 0.12.2",
]
[[package]]
@@ -2315,7 +2351,7 @@ dependencies = [
"auto_impl",
"environmental",
"evm-core",
- "primitive-types",
+ "primitive-types 0.12.2",
"sha3",
]
@@ -2337,10 +2373,10 @@ dependencies = [
"blake2 0.10.6",
"file-guard",
"fs-err",
- "prettyplease 0.2.22",
+ "prettyplease 0.2.29",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -2357,9 +2393,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "fastrand"
-version = "2.1.1"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
+checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fc-api"
@@ -2386,7 +2422,7 @@ dependencies = [
"sp-block-builder",
"sp-consensus",
"sp-runtime",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -2492,7 +2528,7 @@ dependencies = [
"sp-storage 21.0.0",
"sp-timestamp",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
]
@@ -2535,7 +2571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5"
dependencies = [
"libc",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -2648,9 +2684,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
-version = "0.1.3"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2"
+checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
[[package]]
name = "foreign-types"
@@ -2691,7 +2727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9"
dependencies = [
"nonempty",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -2700,7 +2736,7 @@ version = "1.0.0-dev"
source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac882333afed827053f31ef56ab739f7a2e"
dependencies = [
"hex",
- "impl-serde",
+ "impl-serde 0.4.0",
"libsecp256k1",
"log",
"parity-scale-codec",
@@ -2864,7 +2900,7 @@ dependencies = [
"sp-storage 21.0.0",
"sp-trie",
"sp-wasm-interface 21.0.1",
- "thiserror",
+ "thiserror 1.0.69",
"thousands",
]
@@ -2971,7 +3007,7 @@ dependencies = [
"proc-macro2",
"quote",
"sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -2984,7 +3020,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -2996,7 +3032,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -3007,7 +3043,7 @@ checksum = "68672b9ec6fe72d259d3879dc212c5e42e977588cdac830c76f54d9f492aeb58"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -3017,7 +3053,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -3172,9 +3208,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-lite"
-version = "2.3.0"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5"
+checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -3188,7 +3224,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -3284,7 +3320,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi 0.13.3+wasi-0.2.2",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -3330,15 +3378,15 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.31.0"
+version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "glob"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "governor"
@@ -3383,7 +3431,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http 0.2.12",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"slab",
"tokio",
"tokio-util",
@@ -3392,17 +3440,17 @@ dependencies = [
[[package]]
name = "h2"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205"
+checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e"
dependencies = [
"atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
- "http 1.1.0",
- "indexmap 2.6.0",
+ "http 1.2.0",
+ "indexmap 2.7.1",
"slab",
"tokio",
"tokio-util",
@@ -3426,7 +3474,7 @@ dependencies = [
"pest_derive",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -3494,11 +3542,11 @@ dependencies = [
[[package]]
name = "hashlink"
-version = "0.9.1"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
+checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
dependencies = [
- "hashbrown 0.14.5",
+ "hashbrown 0.15.2",
]
[[package]]
@@ -3587,11 +3635,11 @@ dependencies = [
[[package]]
name = "home"
-version = "0.5.9"
+version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
+checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -3618,9 +3666,9 @@ dependencies = [
[[package]]
name = "http"
-version = "1.1.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
+checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
dependencies = [
"bytes",
"fnv",
@@ -3645,7 +3693,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
- "http 1.1.0",
+ "http 1.2.0",
]
[[package]]
@@ -3656,16 +3704,16 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
- "http 1.1.0",
+ "http 1.2.0",
"http-body 1.0.1",
"pin-project-lite",
]
[[package]]
name = "httparse"
-version = "1.9.5"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
+checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a"
[[package]]
name = "httpdate"
@@ -3681,9 +3729,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
-version = "0.14.30"
+version = "0.14.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
+checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7"
dependencies = [
"bytes",
"futures-channel",
@@ -3696,7 +3744,7 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite",
- "socket2 0.5.7",
+ "socket2 0.5.8",
"tokio",
"tower-service",
"tracing",
@@ -3705,15 +3753,15 @@ dependencies = [
[[package]]
name = "hyper"
-version = "1.5.0"
+version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a"
+checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
- "h2 0.4.6",
- "http 1.1.0",
+ "h2 0.4.7",
+ "http 1.2.0",
"http-body 1.0.1",
"httparse",
"httpdate",
@@ -3731,7 +3779,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
"futures-util",
"http 0.2.12",
- "hyper 0.14.30",
+ "hyper 0.14.32",
"log",
"rustls 0.21.12",
"rustls-native-certs",
@@ -3747,9 +3795,9 @@ checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
dependencies = [
"bytes",
"futures-util",
- "http 1.1.0",
+ "http 1.2.0",
"http-body 1.0.1",
- "hyper 1.5.0",
+ "hyper 1.6.0",
"pin-project-lite",
"tokio",
"tower-service",
@@ -3778,6 +3826,124 @@ dependencies = [
"cc",
]
+[[package]]
+name = "icu_collections"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_locid_transform_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
+
+[[package]]
+name = "icu_normalizer"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "utf16_iter",
+ "utf8_iter",
+ "write16",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+
+[[package]]
+name = "icu_properties"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_locid_transform",
+ "icu_properties_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+
+[[package]]
+name = "icu_provider"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider_macros",
+ "stable_deref_trait",
+ "tinystr",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_macros"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+]
+
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -3807,12 +3973,23 @@ dependencies = [
[[package]]
name = "idna"
-version = "0.5.0"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
+checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
dependencies = [
- "unicode-bidi",
- "unicode-normalization",
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
]
[[package]]
@@ -3827,9 +4004,9 @@ dependencies = [
[[package]]
name = "if-watch"
-version = "3.2.0"
+version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e"
+checksum = "cdf9d64cfcf380606e64f9a0bcf493616b65331199f984151a6fa11a7b3cde38"
dependencies = [
"async-io",
"core-foundation",
@@ -3838,6 +4015,10 @@ dependencies = [
"if-addrs",
"ipnet",
"log",
+ "netlink-packet-core",
+ "netlink-packet-route",
+ "netlink-proto",
+ "netlink-sys",
"rtnetlink",
"system-configuration",
"tokio",
@@ -3855,7 +4036,7 @@ dependencies = [
"bytes",
"futures",
"http 0.2.12",
- "hyper 0.14.30",
+ "hyper 0.14.32",
"log",
"rand",
"tokio",
@@ -3872,6 +4053,26 @@ dependencies = [
"parity-scale-codec",
]
+[[package]]
+name = "impl-codec"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67aa010c1e3da95bf151bd8b4c059b2ed7e75387cdb969b4f8f2723a43f9941"
+dependencies = [
+ "parity-scale-codec",
+]
+
+[[package]]
+name = "impl-num-traits"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "803d15461ab0dcc56706adf266158acbc44ccf719bf7d0af30705f58b90a4b8c"
+dependencies = [
+ "integer-sqrt",
+ "num-traits",
+ "uint 0.10.0",
+]
+
[[package]]
name = "impl-rlp"
version = "0.3.0"
@@ -3890,15 +4091,24 @@ dependencies = [
"serde",
]
+[[package]]
+name = "impl-serde"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a143eada6a1ec4aefa5049037a26a6d597bfd64f8c026d07b77133e02b7dd0b"
+dependencies = [
+ "serde",
+]
+
[[package]]
name = "impl-trait-for-tuples"
-version = "0.2.2"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb"
+checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9"
dependencies = [
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.96",
]
[[package]]
@@ -3933,9 +4143,9 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.6.0"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
+checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
@@ -3991,7 +4201,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
dependencies = [
- "socket2 0.5.7",
+ "socket2 0.5.8",
"widestring",
"windows-sys 0.48.0",
"winreg",
@@ -3999,19 +4209,19 @@ dependencies = [
[[package]]
name = "ipnet"
-version = "2.10.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4"
+checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]]
name = "is-terminal"
-version = "0.4.13"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b"
+checksum = "e19b23d53f35ce9f56aebc7d1bb4e6ac1e9c0db7ac85c8d1760c04379edced37"
dependencies = [
"hermit-abi 0.4.0",
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -4049,9 +4259,9 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.11"
+version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "jobserver"
@@ -4064,18 +4274,19 @@ dependencies = [
[[package]]
name = "js-sys"
-version = "0.3.70"
+version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
+checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
+ "once_cell",
"wasm-bindgen",
]
[[package]]
name = "jsonrpsee"
-version = "0.24.7"
+version = "0.24.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5c71d8c1a731cc4227c2f698d377e7848ca12c8a48866fc5e6951c43a4db843"
+checksum = "834af00800e962dee8f7bfc0f60601de215e73e78e5497d733a2919da837d3c8"
dependencies = [
"jsonrpsee-core",
"jsonrpsee-proc-macros",
@@ -4087,51 +4298,51 @@ dependencies = [
[[package]]
name = "jsonrpsee-core"
-version = "0.24.7"
+version = "0.24.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2882f6f8acb9fdaec7cefc4fd607119a9bd709831df7d7672a1d3b644628280"
+checksum = "76637f6294b04e747d68e69336ef839a3493ca62b35bf488ead525f7da75c5bb"
dependencies = [
"async-trait",
"bytes",
"futures-util",
- "http 1.1.0",
+ "http 1.2.0",
"http-body 1.0.1",
"http-body-util",
"jsonrpsee-types",
"parking_lot 0.12.3",
"rand",
- "rustc-hash 2.0.0",
+ "rustc-hash 2.1.0",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tracing",
]
[[package]]
name = "jsonrpsee-proc-macros"
-version = "0.24.7"
+version = "0.24.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06c01ae0007548e73412c08e2285ffe5d723195bf268bce67b1b77c3bb2a14d"
+checksum = "6fcae0c6c159e11541080f1f829873d8f374f81eda0abc67695a13fc8dc1a580"
dependencies = [
"heck 0.5.0",
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "jsonrpsee-server"
-version = "0.24.7"
+version = "0.24.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82ad8ddc14be1d4290cd68046e7d1d37acd408efed6d3ca08aefcc3ad6da069c"
+checksum = "66b7a3df90a1a60c3ed68e7ca63916b53e9afa928e33531e87f61a9c8e9ae87b"
dependencies = [
"futures-util",
- "http 1.1.0",
+ "http 1.2.0",
"http-body 1.0.1",
"http-body-util",
- "hyper 1.5.0",
+ "hyper 1.6.0",
"hyper-util",
"jsonrpsee-core",
"jsonrpsee-types",
@@ -4140,7 +4351,7 @@ dependencies = [
"serde",
"serde_json",
"soketto",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tokio-stream",
"tokio-util",
@@ -4150,14 +4361,14 @@ dependencies = [
[[package]]
name = "jsonrpsee-types"
-version = "0.24.7"
+version = "0.24.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a178c60086f24cc35bb82f57c651d0d25d99c4742b4d335de04e97fa1f08a8a1"
+checksum = "ddb81adb1a5ae9182df379e374a79e24e992334e7346af4d065ae5b2acb8d4c6"
dependencies = [
- "http 1.1.0",
+ "http 1.2.0",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -4236,25 +4447,25 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
-version = "0.2.159"
+version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libloading"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
+checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
- "windows-targets 0.52.6",
+ "windows-targets 0.48.5",
]
[[package]]
name = "libm"
-version = "0.2.8"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
+checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
[[package]]
name = "libp2p"
@@ -4266,7 +4477,7 @@ dependencies = [
"either",
"futures",
"futures-timer",
- "getrandom",
+ "getrandom 0.2.15",
"instant",
"libp2p-allow-block-list",
"libp2p-connection-limits",
@@ -4290,7 +4501,7 @@ dependencies = [
"multiaddr 0.18.2",
"pin-project",
"rw-stream-sink",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -4331,7 +4542,7 @@ dependencies = [
"libp2p-identity",
"log",
"multiaddr 0.18.2",
- "multihash 0.19.2",
+ "multihash 0.19.3",
"multistream-select",
"once_cell",
"parking_lot 0.12.3",
@@ -4340,7 +4551,7 @@ dependencies = [
"rand",
"rw-stream-sink",
"smallvec",
- "thiserror",
+ "thiserror 1.0.69",
"unsigned-varint 0.7.2",
"void",
]
@@ -4380,24 +4591,24 @@ dependencies = [
"quick-protobuf",
"quick-protobuf-codec",
"smallvec",
- "thiserror",
+ "thiserror 1.0.69",
"void",
]
[[package]]
name = "libp2p-identity"
-version = "0.2.9"
+version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8"
+checksum = "257b5621d159b32282eac446bed6670c39c7dc68a200a992d8f056afa0066f6d"
dependencies = [
"bs58 0.5.1",
"ed25519-dalek",
"hkdf",
- "multihash 0.19.2",
+ "multihash 0.19.3",
"quick-protobuf",
"rand",
"sha2 0.10.8",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
"zeroize",
]
@@ -4425,8 +4636,8 @@ dependencies = [
"rand",
"sha2 0.10.8",
"smallvec",
- "thiserror",
- "uint",
+ "thiserror 1.0.69",
+ "uint 0.9.5",
"unsigned-varint 0.7.2",
"void",
]
@@ -4446,7 +4657,7 @@ dependencies = [
"log",
"rand",
"smallvec",
- "socket2 0.5.7",
+ "socket2 0.5.8",
"tokio",
"trust-dns-proto 0.22.0",
"void",
@@ -4482,14 +4693,14 @@ dependencies = [
"libp2p-identity",
"log",
"multiaddr 0.18.2",
- "multihash 0.19.2",
+ "multihash 0.19.3",
"once_cell",
"quick-protobuf",
"rand",
"sha2 0.10.8",
"snow",
"static_assertions",
- "thiserror",
+ "thiserror 1.0.69",
"x25519-dalek",
"zeroize",
]
@@ -4531,8 +4742,8 @@ dependencies = [
"rand",
"ring 0.16.20",
"rustls 0.21.12",
- "socket2 0.5.7",
- "thiserror",
+ "socket2 0.5.8",
+ "thiserror 1.0.69",
"tokio",
]
@@ -4587,7 +4798,7 @@ dependencies = [
"proc-macro-warning 0.4.2",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -4603,7 +4814,7 @@ dependencies = [
"libp2p-core",
"libp2p-identity",
"log",
- "socket2 0.5.7",
+ "socket2 0.5.8",
"tokio",
]
@@ -4621,7 +4832,7 @@ dependencies = [
"ring 0.16.20",
"rustls 0.21.12",
"rustls-webpki",
- "thiserror",
+ "thiserror 1.0.69",
"x509-parser 0.15.1",
"yasna",
]
@@ -4672,7 +4883,7 @@ dependencies = [
"pin-project-lite",
"rw-stream-sink",
"soketto",
- "thiserror",
+ "thiserror 1.0.69",
"url",
"webpki-roots",
]
@@ -4686,7 +4897,7 @@ dependencies = [
"futures",
"libp2p-core",
"log",
- "thiserror",
+ "thiserror 1.0.69",
"yamux",
]
@@ -4696,9 +4907,9 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
"libc",
- "redox_syscall 0.5.7",
+ "redox_syscall 0.5.8",
]
[[package]]
@@ -4777,9 +4988,9 @@ dependencies = [
[[package]]
name = "libz-sys"
-version = "1.1.20"
+version = "1.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472"
+checksum = "df9b68e50e6e0b26f672573834882eb57759f6db9b3be2ea3c35c91188bb4eaa"
dependencies = [
"cc",
"pkg-config",
@@ -4803,18 +5014,18 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linked_hash_set"
-version = "0.1.4"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588"
+checksum = "bae85b5be22d9843c80e5fc80e9b64c8a3b1f98f867c709956eca3efff4e92e2"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "linregress"
-version = "0.5.3"
+version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4de04dcecc58d366391f9920245b85ffa684558a5ef6e7736e754347c3aea9c2"
+checksum = "a9eda9dcf4f2a99787827661f312ac3219292549c2ee992bf9a6248ffb066bf7"
dependencies = [
"nalgebra",
]
@@ -4827,9 +5038,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "lioness"
@@ -4843,6 +5054,12 @@ dependencies = [
"keystream",
]
+[[package]]
+name = "litemap"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
+
[[package]]
name = "litep2p"
version = "0.6.2"
@@ -4857,7 +5074,7 @@ dependencies = [
"futures",
"futures-timer",
"hex-literal",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"libc",
"mockall 0.12.1",
"multiaddr 0.17.1",
@@ -4878,17 +5095,17 @@ dependencies = [
"simple-dns",
"smallvec",
"snow",
- "socket2 0.5.7",
+ "socket2 0.5.8",
"static_assertions",
"str0m",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tokio-stream",
"tokio-tungstenite",
"tokio-util",
"tracing",
"trust-dns-resolver",
- "uint",
+ "uint 0.9.5",
"unsigned-varint 0.8.0",
"url",
"webpki",
@@ -4910,9 +5127,9 @@ dependencies = [
[[package]]
name = "log"
-version = "0.4.22"
+version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
name = "lru"
@@ -4943,9 +5160,9 @@ dependencies = [
[[package]]
name = "lz4"
-version = "1.28.0"
+version = "1.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d1febb2b4a79ddd1980eede06a8f7902197960aa0383ffcfdd62fe723036725"
+checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4"
dependencies = [
"lz4-sys",
]
@@ -4978,7 +5195,7 @@ dependencies = [
"macro_magic_core",
"macro_magic_macros",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -4992,7 +5209,7 @@ dependencies = [
"macro_magic_core_macros",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -5003,7 +5220,7 @@ checksum = "b02abfe41815b5bd98dbd4260173db2c116dda171dc0fe7838cb206333b83308"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -5014,7 +5231,7 @@ checksum = "73ea28ee64b88876bf45277ed9a5817c1817df061a74f2b988971a12570e5869"
dependencies = [
"macro_magic_core",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -5060,7 +5277,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64"
dependencies = [
- "rustix 0.38.37",
+ "rustix 0.38.44",
]
[[package]]
@@ -5133,22 +5350,21 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
-version = "0.8.0"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
+checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
dependencies = [
"adler2",
]
[[package]]
name = "mio"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [
- "hermit-abi 0.3.9",
"libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0",
]
@@ -5173,7 +5389,7 @@ dependencies = [
"rand_chacha",
"rand_distr",
"subtle 2.6.1",
- "thiserror",
+ "thiserror 1.0.69",
"zeroize",
]
@@ -5203,7 +5419,7 @@ dependencies = [
"fragile",
"lazy_static",
"mockall_derive 0.12.1",
- "predicates 3.1.2",
+ "predicates 3.1.3",
"predicates-tree",
]
@@ -5228,7 +5444,7 @@ dependencies = [
"cfg-if",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -5261,7 +5477,7 @@ dependencies = [
"data-encoding",
"libp2p-identity",
"multibase",
- "multihash 0.19.2",
+ "multihash 0.19.3",
"percent-encoding",
"serde",
"static_assertions",
@@ -5316,9 +5532,9 @@ dependencies = [
[[package]]
name = "multihash"
-version = "0.19.2"
+version = "0.19.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2"
+checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d"
dependencies = [
"core2",
"unsigned-varint 0.8.0",
@@ -5344,6 +5560,12 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
+[[package]]
+name = "multimap"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
+
[[package]]
name = "multistream-select"
version = "0.13.0"
@@ -5360,13 +5582,12 @@ dependencies = [
[[package]]
name = "nalgebra"
-version = "0.32.6"
+version = "0.33.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4"
+checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b"
dependencies = [
"approx",
"matrixmultiply",
- "nalgebra-macros",
"num-complex",
"num-rational",
"num-traits",
@@ -5374,17 +5595,6 @@ dependencies = [
"typenum 1.17.0",
]
-[[package]]
-name = "nalgebra-macros"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.90",
-]
-
[[package]]
name = "names"
version = "0.14.0"
@@ -5396,9 +5606,9 @@ dependencies = [
[[package]]
name = "native-tls"
-version = "0.2.12"
+version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
+checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c"
dependencies = [
"libc",
"log",
@@ -5426,21 +5636,20 @@ dependencies = [
[[package]]
name = "netlink-packet-core"
-version = "0.4.2"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297"
+checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4"
dependencies = [
"anyhow",
"byteorder",
- "libc",
"netlink-packet-utils",
]
[[package]]
name = "netlink-packet-route"
-version = "0.12.0"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab"
+checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66"
dependencies = [
"anyhow",
"bitflags 1.3.2",
@@ -5459,29 +5668,28 @@ dependencies = [
"anyhow",
"byteorder",
"paste",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
name = "netlink-proto"
-version = "0.10.0"
+version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6"
+checksum = "72452e012c2f8d612410d89eea01e2d9b56205274abb35d53f60200b2ec41d60"
dependencies = [
"bytes",
"futures",
"log",
"netlink-packet-core",
"netlink-sys",
- "thiserror",
- "tokio",
+ "thiserror 2.0.11",
]
[[package]]
name = "netlink-sys"
-version = "0.8.6"
+version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307"
+checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23"
dependencies = [
"bytes",
"futures",
@@ -5498,15 +5706,15 @@ checksum = "a4a43439bf756eed340bdf8feba761e2d50c7d47175d87545cd5cbe4a137c4d1"
dependencies = [
"cc",
"libc",
- "thiserror",
+ "thiserror 1.0.69",
"winapi",
]
[[package]]
name = "nix"
-version = "0.24.3"
+version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
+checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
@@ -5597,7 +5805,8 @@ dependencies = [
"substrate-prometheus-endpoint",
"subtensor-custom-rpc",
"subtensor-custom-rpc-runtime-api",
- "thiserror",
+ "subtensor-runtime-common",
+ "thiserror 1.0.69",
]
[[package]]
@@ -5605,7 +5814,6 @@ name = "node-subtensor-runtime"
version = "4.0.0-dev"
dependencies = [
"ark-serialize",
- "ed25519-dalek",
"fp-account",
"fp-evm",
"fp-rpc",
@@ -5619,7 +5827,7 @@ dependencies = [
"frame-system-benchmarking",
"frame-system-rpc-runtime-api",
"frame-try-runtime",
- "getrandom",
+ "getrandom 0.2.15",
"hex",
"log",
"pallet-admin-utils",
@@ -5641,7 +5849,7 @@ dependencies = [
"pallet-membership",
"pallet-multisig",
"pallet-preimage",
- "pallet-proxy",
+ "pallet-proxy 38.0.0",
"pallet-registry",
"pallet-safe-mode",
"pallet-scheduler",
@@ -5650,7 +5858,7 @@ dependencies = [
"pallet-timestamp",
"pallet-transaction-payment",
"pallet-transaction-payment-rpc-runtime-api",
- "pallet-utility",
+ "pallet-utility 38.0.0",
"parity-scale-codec",
"precompile-utils",
"rand_chacha",
@@ -5676,6 +5884,8 @@ dependencies = [
"substrate-wasm-builder",
"subtensor-custom-rpc-runtime-api",
"subtensor-macros",
+ "subtensor-precompiles",
+ "subtensor-runtime-common",
"tle",
"w3f-bls",
]
@@ -5842,7 +6052,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -5868,9 +6078,9 @@ dependencies = [
[[package]]
name = "object"
-version = "0.36.4"
+version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"memchr",
]
@@ -5895,12 +6105,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.20.1"
+version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
-dependencies = [
- "portable-atomic",
-]
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "opaque-debug"
@@ -5920,7 +6127,7 @@ version = "0.10.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
"cfg-if",
"foreign-types",
"libc",
@@ -5937,20 +6144,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "openssl-probe"
-version = "0.1.5"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-src"
-version = "300.4.0+3.4.0"
+version = "300.4.1+3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a709e02f2b4aca747929cca5ed248880847c650233cf8b8cdc48f40aaf4898a6"
+checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c"
dependencies = [
"cc",
]
@@ -6315,6 +6522,23 @@ dependencies = [
"sp-runtime",
]
+[[package]]
+name = "pallet-proxy"
+version = "38.0.0"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "pallet-balances",
+ "pallet-utility 38.0.0",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "subtensor-macros",
+]
+
[[package]]
name = "pallet-proxy"
version = "38.0.0"
@@ -6346,6 +6570,20 @@ dependencies = [
"subtensor-macros",
]
+[[package]]
+name = "pallet-root-testing"
+version = "14.0.0"
+source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409#87971b3e92721bdf10bf40b410eaae779d494ca0"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+]
+
[[package]]
name = "pallet-safe-mode"
version = "19.0.0"
@@ -6356,8 +6594,8 @@ dependencies = [
"frame-support",
"frame-system",
"pallet-balances",
- "pallet-proxy",
- "pallet-utility",
+ "pallet-proxy 38.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
+ "pallet-utility 38.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
"parity-scale-codec",
"scale-info",
"sp-arithmetic",
@@ -6424,7 +6662,7 @@ dependencies = [
"pallet-preimage",
"pallet-scheduler",
"pallet-transaction-payment",
- "pallet-utility",
+ "pallet-utility 38.0.0",
"parity-scale-codec",
"parity-util-mem",
"rand",
@@ -6527,6 +6765,25 @@ dependencies = [
"sp-weights",
]
+[[package]]
+name = "pallet-utility"
+version = "38.0.0"
+dependencies = [
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "pallet-balances",
+ "pallet-collective",
+ "pallet-root-testing",
+ "pallet-timestamp",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-io",
+ "sp-runtime",
+ "subtensor-macros",
+]
+
[[package]]
name = "pallet-utility"
version = "38.0.0"
@@ -6616,7 +6873,7 @@ dependencies = [
"lru 0.8.1",
"parity-util-mem-derive",
"parking_lot 0.12.3",
- "primitive-types",
+ "primitive-types 0.12.2",
"smallvec",
"winapi",
]
@@ -6687,7 +6944,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.5.7",
+ "redox_syscall 0.5.8",
"smallvec",
"windows-targets 0.52.6",
]
@@ -6748,20 +7005,20 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
-version = "2.7.13"
+version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9"
+checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
dependencies = [
"memchr",
- "thiserror",
+ "thiserror 2.0.11",
"ucd-trie",
]
[[package]]
name = "pest_derive"
-version = "2.7.13"
+version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0"
+checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e"
dependencies = [
"pest",
"pest_generator",
@@ -6769,22 +7026,22 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.7.13"
+version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e"
+checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "pest_meta"
-version = "2.7.13"
+version = "2.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f"
+checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea"
dependencies = [
"once_cell",
"pest",
@@ -6798,34 +7055,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
]
[[package]]
name = "pin-project"
-version = "1.1.5"
+version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
+checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.1.5"
+version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
+checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "pin-project-lite"
-version = "0.2.14"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
@@ -6858,7 +7115,7 @@ dependencies = [
"libc",
"log",
"polkavm-assembler",
- "polkavm-common",
+ "polkavm-common 0.9.0",
"polkavm-linux-raw",
]
@@ -6880,25 +7137,52 @@ dependencies = [
"log",
]
+[[package]]
+name = "polkavm-common"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31ff33982a807d8567645d4784b9b5d7ab87bcb494f534a57cadd9012688e102"
+
[[package]]
name = "polkavm-derive"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae8c4bea6f3e11cd89bb18bcdddac10bd9a24015399bd1c485ad68a985a19606"
dependencies = [
- "polkavm-derive-impl-macro",
+ "polkavm-derive-impl-macro 0.9.0",
+]
+
+[[package]]
+name = "polkavm-derive"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2eb703f3b6404c13228402e98a5eae063fd16b8f58afe334073ec105ee4117e"
+dependencies = [
+ "polkavm-derive-impl-macro 0.18.0",
+]
+
+[[package]]
+name = "polkavm-derive-impl"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c"
+dependencies = [
+ "polkavm-common 0.9.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
]
[[package]]
name = "polkavm-derive-impl"
-version = "0.9.0"
+version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c"
+checksum = "2f2116a92e6e96220a398930f4c8a6cda1264206f3e2034fc9982bfd93f261f7"
dependencies = [
- "polkavm-common",
+ "polkavm-common 0.18.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -6907,8 +7191,18 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429"
dependencies = [
- "polkavm-derive-impl",
- "syn 2.0.90",
+ "polkavm-derive-impl 0.9.0",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "polkavm-derive-impl-macro"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c16669ddc7433e34c1007d31080b80901e3e8e523cb9d4b441c3910cf9294b"
+dependencies = [
+ "polkavm-derive-impl 0.18.1",
+ "syn 2.0.96",
]
[[package]]
@@ -6921,7 +7215,7 @@ dependencies = [
"hashbrown 0.14.5",
"log",
"object 0.32.2",
- "polkavm-common",
+ "polkavm-common 0.9.0",
"regalloc2 0.9.3",
"rustc-demangle",
]
@@ -6934,15 +7228,15 @@ checksum = "26e85d3456948e650dff0cfc85603915847faf893ed1e66b020bb82ef4557120"
[[package]]
name = "polling"
-version = "3.7.3"
+version = "3.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511"
+checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi 0.4.0",
"pin-project-lite",
- "rustix 0.38.37",
+ "rustix 0.38.44",
"tracing",
"windows-sys 0.59.0",
]
@@ -6972,9 +7266,9 @@ dependencies = [
[[package]]
name = "portable-atomic"
-version = "1.9.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
+checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
[[package]]
name = "powerfmt"
@@ -7022,7 +7316,7 @@ source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac88233
dependencies = [
"case",
"num_enum",
- "prettyplease 0.2.22",
+ "prettyplease 0.2.29",
"proc-macro2",
"quote",
"sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
@@ -7045,9 +7339,9 @@ dependencies = [
[[package]]
name = "predicates"
-version = "3.1.2"
+version = "3.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97"
+checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"
dependencies = [
"anstyle",
"predicates-core",
@@ -7055,15 +7349,15 @@ dependencies = [
[[package]]
name = "predicates-core"
-version = "1.0.8"
+version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931"
+checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"
[[package]]
name = "predicates-tree"
-version = "1.0.11"
+version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13"
+checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"
dependencies = [
"predicates-core",
"termtree",
@@ -7081,12 +7375,12 @@ dependencies = [
[[package]]
name = "prettyplease"
-version = "0.2.22"
+version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
+checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
dependencies = [
"proc-macro2",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -7096,11 +7390,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2"
dependencies = [
"fixed-hash",
- "impl-codec",
+ "impl-codec 0.6.0",
"impl-rlp",
- "impl-serde",
+ "impl-serde 0.4.0",
"scale-info",
- "uint",
+ "uint 0.9.5",
+]
+
+[[package]]
+name = "primitive-types"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5"
+dependencies = [
+ "fixed-hash",
+ "impl-codec 0.7.0",
+ "impl-num-traits",
+ "uint 0.10.0",
]
[[package]]
@@ -7109,7 +7415,7 @@ version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
dependencies = [
- "thiserror",
+ "thiserror 1.0.69",
"toml 0.5.11",
]
@@ -7154,7 +7460,7 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -7165,14 +7471,14 @@ checksum = "834da187cfe638ae8abb0203f0b33e5ccdb02a28e7199f2f47b3e2754f50edca"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
dependencies = [
"unicode-ident",
]
@@ -7193,7 +7499,7 @@ dependencies = [
"quote",
"regex",
"sp-crypto-hashing 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -7207,7 +7513,7 @@ dependencies = [
"lazy_static",
"memchr",
"parking_lot 0.12.3",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -7230,7 +7536,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -7264,7 +7570,7 @@ dependencies = [
"itertools 0.10.5",
"lazy_static",
"log",
- "multimap",
+ "multimap 0.8.3",
"petgraph",
"prettyplease 0.1.25",
"prost 0.11.9",
@@ -7285,14 +7591,14 @@ dependencies = [
"heck 0.5.0",
"itertools 0.12.1",
"log",
- "multimap",
+ "multimap 0.10.0",
"once_cell",
"petgraph",
- "prettyplease 0.2.22",
+ "prettyplease 0.2.29",
"prost 0.12.6",
"prost-types 0.12.6",
"regex",
- "syn 2.0.90",
+ "syn 2.0.96",
"tempfile",
]
@@ -7319,7 +7625,7 @@ dependencies = [
"itertools 0.12.1",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -7342,24 +7648,24 @@ dependencies = [
[[package]]
name = "psm"
-version = "0.1.23"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa37f80ca58604976033fae9515a8a2989fc13797d953f7c04fb8fa36a11f205"
+checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810"
dependencies = [
"cc",
]
[[package]]
name = "quanta"
-version = "0.12.3"
+version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5"
+checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e"
dependencies = [
"crossbeam-utils",
"libc",
"once_cell",
"raw-cpuid",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
"web-sys",
"winapi",
]
@@ -7388,7 +7694,7 @@ dependencies = [
"asynchronous-codec",
"bytes",
"quick-protobuf",
- "thiserror",
+ "thiserror 1.0.69",
"unsigned-varint 0.7.2",
]
@@ -7404,7 +7710,7 @@ dependencies = [
"quinn-udp 0.3.2",
"rustc-hash 1.1.0",
"rustls 0.20.9",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tracing",
"webpki",
@@ -7423,7 +7729,7 @@ dependencies = [
"quinn-udp 0.4.1",
"rustc-hash 1.1.0",
"rustls 0.21.12",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tracing",
]
@@ -7440,7 +7746,7 @@ dependencies = [
"rustc-hash 1.1.0",
"rustls 0.20.9",
"slab",
- "thiserror",
+ "thiserror 1.0.69",
"tinyvec",
"tracing",
"webpki",
@@ -7458,7 +7764,7 @@ dependencies = [
"rustc-hash 1.1.0",
"rustls 0.21.12",
"slab",
- "thiserror",
+ "thiserror 1.0.69",
"tinyvec",
"tracing",
]
@@ -7484,16 +7790,16 @@ checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7"
dependencies = [
"bytes",
"libc",
- "socket2 0.5.7",
+ "socket2 0.5.8",
"tracing",
"windows-sys 0.48.0",
]
[[package]]
name = "quote"
-version = "1.0.37"
+version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
@@ -7531,7 +7837,7 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
]
[[package]]
@@ -7555,11 +7861,11 @@ dependencies = [
[[package]]
name = "raw-cpuid"
-version = "11.2.0"
+version = "11.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0"
+checksum = "c6928fa44c097620b706542d428957635951bade7143269085389d42c8a4927e"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
]
[[package]]
@@ -7611,11 +7917,11 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.5.7"
+version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
+checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
]
[[package]]
@@ -7624,9 +7930,9 @@ version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
- "getrandom",
+ "getrandom 0.2.15",
"libredox",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -7646,7 +7952,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -7676,13 +7982,13 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.11.0"
+version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
- "regex-automata 0.4.8",
+ "regex-automata 0.4.9",
"regex-syntax 0.8.5",
]
@@ -7697,9 +8003,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.8"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@@ -7755,15 +8061,14 @@ dependencies = [
[[package]]
name = "ring"
-version = "0.17.8"
+version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
+checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
dependencies = [
"cc",
"cfg-if",
- "getrandom",
+ "getrandom 0.2.15",
"libc",
- "spin 0.9.8",
"untrusted 0.9.0",
"windows-sys 0.52.0",
]
@@ -7828,16 +8133,19 @@ dependencies = [
[[package]]
name = "rtnetlink"
-version = "0.10.1"
+version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0"
+checksum = "7a552eb82d19f38c3beed3f786bd23aa434ceb9ac43ab44419ca6d67a7e186c0"
dependencies = [
"futures",
"log",
+ "netlink-packet-core",
"netlink-packet-route",
+ "netlink-packet-utils",
"netlink-proto",
+ "netlink-sys",
"nix",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
]
@@ -7865,9 +8173,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc-hash"
-version = "2.0.0"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
+checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
[[package]]
name = "rustc-hex"
@@ -7890,7 +8198,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
- "semver 1.0.23",
+ "semver 1.0.25",
]
[[package]]
@@ -7918,15 +8226,15 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.37"
+version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
"errno",
"libc",
- "linux-raw-sys 0.4.14",
- "windows-sys 0.52.0",
+ "linux-raw-sys 0.4.15",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -7947,7 +8255,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
dependencies = [
"log",
- "ring 0.17.8",
+ "ring 0.17.13",
"rustls-webpki",
"sct",
]
@@ -7979,15 +8287,15 @@ version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
- "ring 0.17.8",
+ "ring 0.17.13",
"untrusted 0.9.0",
]
[[package]]
name = "rustversion"
-version = "1.0.17"
+version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
+checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]]
name = "rw-stream-sink"
@@ -8002,9 +8310,9 @@ dependencies = [
[[package]]
name = "ryu"
-version = "1.0.18"
+version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
[[package]]
name = "safe-math"
@@ -8026,9 +8334,9 @@ dependencies = [
[[package]]
name = "safe_arch"
-version = "0.7.2"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3460605018fdc9612bce72735cba0d27efbcd9904780d44c7e3a9948f96148a"
+checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
dependencies = [
"bytemuck",
]
@@ -8050,7 +8358,7 @@ dependencies = [
"log",
"sp-core",
"sp-wasm-interface 21.0.1",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8125,7 +8433,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -8165,7 +8473,7 @@ dependencies = [
"sp-panic-handler",
"sp-runtime",
"sp-version",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
]
@@ -8243,7 +8551,7 @@ dependencies = [
"sp-runtime",
"sp-state-machine",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8272,7 +8580,7 @@ dependencies = [
"sp-keystore",
"sp-runtime",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8308,7 +8616,7 @@ dependencies = [
"sp-keystore",
"sp-runtime",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8365,7 +8673,7 @@ dependencies = [
"sp-keystore",
"sp-runtime",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8385,7 +8693,7 @@ dependencies = [
"sp-blockchain",
"sp-core",
"sp-runtime",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8420,7 +8728,7 @@ dependencies = [
"sp-runtime",
"sp-timestamp",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8478,7 +8786,7 @@ dependencies = [
"sc-allocator",
"sp-maybe-compressed-blob",
"sp-wasm-interface 21.0.1",
- "thiserror",
+ "thiserror 1.0.69",
"wasm-instrument",
]
@@ -8539,7 +8847,7 @@ dependencies = [
"sp-application-crypto",
"sp-core",
"sp-keystore",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8568,7 +8876,7 @@ dependencies = [
"sp-keystore",
"sp-mixnet",
"sp-runtime",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8613,7 +8921,7 @@ dependencies = [
"sp-core",
"sp-runtime",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tokio-stream",
"unsigned-varint 0.7.2",
@@ -8677,7 +8985,7 @@ dependencies = [
"sp-blockchain",
"sp-core",
"sp-runtime",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8712,7 +9020,7 @@ dependencies = [
"sp-core",
"sp-runtime",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tokio-stream",
]
@@ -8747,9 +9055,9 @@ dependencies = [
"litep2p",
"log",
"multiaddr 0.18.2",
- "multihash 0.19.2",
+ "multihash 0.19.3",
"rand",
- "thiserror",
+ "thiserror 1.0.69",
"zeroize",
]
@@ -8763,7 +9071,7 @@ dependencies = [
"fnv",
"futures",
"futures-timer",
- "hyper 0.14.30",
+ "hyper 0.14.32",
"hyper-rustls",
"log",
"num_cpus",
@@ -8845,7 +9153,7 @@ dependencies = [
"sp-rpc",
"sp-runtime",
"sp-version",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -8857,9 +9165,9 @@ dependencies = [
"forwarded-header-value",
"futures",
"governor",
- "http 1.1.0",
+ "http 1.2.0",
"http-body-util",
- "hyper 1.5.0",
+ "hyper 1.6.0",
"ip_network",
"jsonrpsee",
"log",
@@ -8899,7 +9207,7 @@ dependencies = [
"sp-rpc",
"sp-runtime",
"sp-version",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tokio-stream",
]
@@ -8962,7 +9270,7 @@ dependencies = [
"static_init",
"substrate-prometheus-endpoint",
"tempfile",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tracing",
"tracing-futures",
@@ -8984,7 +9292,7 @@ name = "sc-sysinfo"
version = "38.0.0"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409#87971b3e92721bdf10bf40b410eaae779d494ca0"
dependencies = [
- "derive_more",
+ "derive_more 0.99.18",
"futures",
"libc",
"log",
@@ -9016,7 +9324,7 @@ dependencies = [
"sc-utils",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 1.0.69",
"wasm-timer",
]
@@ -9043,10 +9351,10 @@ dependencies = [
"sp-rpc",
"sp-runtime",
"sp-tracing 17.0.1",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
"tracing-log",
- "tracing-subscriber 0.3.18",
+ "tracing-subscriber 0.3.19",
]
[[package]]
@@ -9057,7 +9365,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -9084,7 +9392,7 @@ dependencies = [
"sp-tracing 17.0.1",
"sp-transaction-pool",
"substrate-prometheus-endpoint",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -9100,7 +9408,7 @@ dependencies = [
"sp-blockchain",
"sp-core",
"sp-runtime",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -9134,7 +9442,7 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e98f3262c250d90e700bb802eb704e1f841e03331c2eb815e46516c4edbf5b27"
dependencies = [
- "derive_more",
+ "derive_more 0.99.18",
"parity-scale-codec",
"scale-bits",
"scale-type-resolver",
@@ -9143,13 +9451,13 @@ dependencies = [
[[package]]
name = "scale-info"
-version = "2.11.3"
+version = "2.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024"
+checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b"
dependencies = [
"bitvec",
"cfg-if",
- "derive_more",
+ "derive_more 1.0.0",
"parity-scale-codec",
"scale-info-derive",
"serde",
@@ -9157,14 +9465,14 @@ dependencies = [
[[package]]
name = "scale-info-derive"
-version = "2.11.3"
+version = "2.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62"
+checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 1.0.109",
+ "syn 2.0.96",
]
[[package]]
@@ -9175,18 +9483,18 @@ checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb"
[[package]]
name = "schannel"
-version = "0.1.24"
+version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b"
+checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "schnellru"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367"
+checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649"
dependencies = [
"ahash 0.8.11",
"cfg-if",
@@ -9230,7 +9538,7 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
- "ring 0.17.8",
+ "ring 0.17.13",
"untrusted 0.9.0",
]
@@ -9246,7 +9554,7 @@ dependencies = [
"log",
"rand",
"slab",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -9297,7 +9605,7 @@ version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -9306,9 +9614,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
-version = "2.12.0"
+version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6"
+checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
@@ -9334,9 +9642,9 @@ dependencies = [
[[package]]
name = "semver"
-version = "1.0.23"
+version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
+checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
dependencies = [
"serde",
]
@@ -9355,9 +9663,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
[[package]]
name = "serde"
-version = "1.0.216"
+version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
+checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
@@ -9392,20 +9700,20 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.216"
+version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
+checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "serde_json"
-version = "1.0.128"
+version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
+checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
dependencies = [
"itoa",
"memchr",
@@ -9459,7 +9767,7 @@ dependencies = [
"darling",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -9583,9 +9891,9 @@ dependencies = [
[[package]]
name = "simba"
-version = "0.8.1"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae"
+checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
dependencies = [
"approx",
"num-complex",
@@ -9600,7 +9908,7 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cae9a3fcdadafb6d97f4c0e007e4247b114ee0f119f650c3cbf3a8b3a1479694"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
]
[[package]]
@@ -9653,7 +9961,7 @@ dependencies = [
"chacha20poly1305",
"curve25519-dalek",
"rand_core",
- "ring 0.17.8",
+ "ring 0.17.13",
"rustc_version 0.4.1",
"sha2 0.10.8",
"subtle 2.6.1",
@@ -9671,9 +9979,9 @@ dependencies = [
[[package]]
name = "socket2"
-version = "0.5.7"
+version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
+checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -9681,14 +9989,14 @@ dependencies = [
[[package]]
name = "soketto"
-version = "0.8.0"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53"
+checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721"
dependencies = [
"base64 0.22.1",
"bytes",
"futures",
- "http 1.1.0",
+ "http 1.2.0",
"httparse",
"log",
"rand",
@@ -9714,7 +10022,7 @@ dependencies = [
"sp-state-machine",
"sp-trie",
"sp-version",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -9728,7 +10036,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -9791,7 +10099,7 @@ dependencies = [
"sp-database",
"sp-runtime",
"sp-state-machine",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
]
@@ -9807,7 +10115,7 @@ dependencies = [
"sp-inherents",
"sp-runtime",
"sp-state-machine",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -9887,7 +10195,7 @@ dependencies = [
"futures",
"hash-db",
"hash256-std-hasher",
- "impl-serde",
+ "impl-serde 0.4.0",
"itertools 0.11.0",
"k256",
"libsecp256k1",
@@ -9897,7 +10205,7 @@ dependencies = [
"parity-scale-codec",
"parking_lot 0.12.3",
"paste",
- "primitive-types",
+ "primitive-types 0.12.2",
"rand",
"scale-info",
"schnorrkel",
@@ -9912,7 +10220,7 @@ dependencies = [
"sp-storage 21.0.0",
"ss58-registry",
"substrate-bip39",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
"w3f-bls",
"zeroize",
@@ -9921,7 +10229,7 @@ dependencies = [
[[package]]
name = "sp-crypto-ec-utils"
version = "0.10.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
"ark-bls12-377",
"ark-bls12-377-ext",
@@ -9992,7 +10300,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable
dependencies = [
"quote",
"sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -10011,23 +10319,23 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "sp-debug-derive"
version = "14.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "sp-externalities"
version = "0.25.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
"environmental",
"parity-scale-codec",
@@ -10066,7 +10374,7 @@ dependencies = [
"parity-scale-codec",
"scale-info",
"sp-runtime",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -10080,7 +10388,7 @@ dependencies = [
"libsecp256k1",
"log",
"parity-scale-codec",
- "polkavm-derive",
+ "polkavm-derive 0.9.1",
"rustversion",
"secp256k1",
"sp-core",
@@ -10121,7 +10429,7 @@ name = "sp-maybe-compressed-blob"
version = "11.0.0"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409#87971b3e92721bdf10bf40b410eaae779d494ca0"
dependencies = [
- "thiserror",
+ "thiserror 1.0.69",
"zstd 0.12.4",
]
@@ -10205,13 +10513,13 @@ dependencies = [
[[package]]
name = "sp-runtime-interface"
version = "24.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
"bytes",
"impl-trait-for-tuples",
"parity-scale-codec",
- "polkavm-derive",
- "primitive-types",
+ "polkavm-derive 0.18.0",
+ "primitive-types 0.13.1",
"sp-externalities 0.25.0",
"sp-runtime-interface-proc-macro 17.0.0",
"sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk)",
@@ -10229,8 +10537,8 @@ dependencies = [
"bytes",
"impl-trait-for-tuples",
"parity-scale-codec",
- "polkavm-derive",
- "primitive-types",
+ "polkavm-derive 0.9.1",
+ "primitive-types 0.12.2",
"sp-externalities 0.29.0",
"sp-runtime-interface-proc-macro 18.0.0",
"sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
@@ -10243,14 +10551,14 @@ dependencies = [
[[package]]
name = "sp-runtime-interface-proc-macro"
version = "17.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
"Inflector",
"expander",
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -10263,7 +10571,7 @@ dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -10308,7 +10616,7 @@ dependencies = [
"sp-externalities 0.29.0",
"sp-panic-handler",
"sp-trie",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
"trie-db",
]
@@ -10333,7 +10641,7 @@ dependencies = [
"sp-externalities 0.29.0",
"sp-runtime",
"sp-runtime-interface 28.0.0",
- "thiserror",
+ "thiserror 1.0.69",
"x25519-dalek",
]
@@ -10345,14 +10653,14 @@ source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable
[[package]]
name = "sp-std"
version = "14.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
[[package]]
name = "sp-storage"
version = "19.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
- "impl-serde",
+ "impl-serde 0.5.0",
"parity-scale-codec",
"ref-cast",
"serde",
@@ -10364,7 +10672,7 @@ name = "sp-storage"
version = "21.0.0"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409#87971b3e92721bdf10bf40b410eaae779d494ca0"
dependencies = [
- "impl-serde",
+ "impl-serde 0.4.0",
"parity-scale-codec",
"ref-cast",
"serde",
@@ -10380,18 +10688,18 @@ dependencies = [
"parity-scale-codec",
"sp-inherents",
"sp-runtime",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
name = "sp-tracing"
version = "16.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
"parity-scale-codec",
"tracing",
"tracing-core",
- "tracing-subscriber 0.3.18",
+ "tracing-subscriber 0.3.19",
]
[[package]]
@@ -10402,7 +10710,7 @@ dependencies = [
"parity-scale-codec",
"tracing",
"tracing-core",
- "tracing-subscriber 0.3.18",
+ "tracing-subscriber 0.3.19",
]
[[package]]
@@ -10445,7 +10753,7 @@ dependencies = [
"schnellru",
"sp-core",
"sp-externalities 0.29.0",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
"trie-db",
"trie-root",
@@ -10456,7 +10764,7 @@ name = "sp-version"
version = "37.0.0"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409#87971b3e92721bdf10bf40b410eaae779d494ca0"
dependencies = [
- "impl-serde",
+ "impl-serde 0.4.0",
"parity-scale-codec",
"parity-wasm",
"scale-info",
@@ -10465,7 +10773,7 @@ dependencies = [
"sp-runtime",
"sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
"sp-version-proc-macro",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -10476,13 +10784,13 @@ dependencies = [
"parity-scale-codec",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "sp-wasm-interface"
version = "20.0.0"
-source = "git+https://github.com/paritytech/polkadot-sdk#8614dc0e055d06de4a3774ac1da0a422b33f34e2"
+source = "git+https://github.com/paritytech/polkadot-sdk#80e30ec3cdccae8e9099bd67840ff8737b043496"
dependencies = [
"anyhow",
"impl-trait-for-tuples",
@@ -10550,21 +10858,11 @@ dependencies = [
"der",
]
-[[package]]
-name = "sqlformat"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790"
-dependencies = [
- "nom",
- "unicode_categories",
-]
-
[[package]]
name = "sqlx"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e"
+checksum = "4410e73b3c0d8442c5f99b425d7a435b5ee0ae4167b3196771dd3f7a01be745f"
dependencies = [
"sqlx-core",
"sqlx-macros",
@@ -10573,37 +10871,31 @@ dependencies = [
[[package]]
name = "sqlx-core"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e"
+checksum = "6a007b6936676aa9ab40207cde35daab0a04b823be8ae004368c0793b96a61e0"
dependencies = [
- "atoi",
- "byteorder",
"bytes",
"crc",
"crossbeam-queue",
"either",
- "event-listener 5.3.1",
- "futures-channel",
+ "event-listener 5.4.0",
"futures-core",
"futures-intrusive",
"futures-io",
"futures-util",
- "hashbrown 0.14.5",
- "hashlink 0.9.1",
- "hex",
- "indexmap 2.6.0",
+ "hashbrown 0.15.2",
+ "hashlink 0.10.0",
+ "indexmap 2.7.1",
"log",
"memchr",
"native-tls",
"once_cell",
- "paste",
"percent-encoding",
"serde",
"sha2 0.10.8",
"smallvec",
- "sqlformat",
- "thiserror",
+ "thiserror 2.0.11",
"tokio",
"tokio-stream",
"tracing",
@@ -10612,22 +10904,22 @@ dependencies = [
[[package]]
name = "sqlx-macros"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657"
+checksum = "3112e2ad78643fef903618d78cf0aec1cb3134b019730edb039b69eaf531f310"
dependencies = [
"proc-macro2",
"quote",
"sqlx-core",
"sqlx-macros-core",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "sqlx-macros-core"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5"
+checksum = "4e9f90acc5ab146a99bf5061a7eb4976b573f560bc898ef3bf8435448dd5e7ad"
dependencies = [
"dotenvy",
"either",
@@ -10641,7 +10933,7 @@ dependencies = [
"sha2 0.10.8",
"sqlx-core",
"sqlx-sqlite",
- "syn 2.0.90",
+ "syn 2.0.96",
"tempfile",
"tokio",
"url",
@@ -10649,9 +10941,9 @@ dependencies = [
[[package]]
name = "sqlx-sqlite"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680"
+checksum = "f85ca71d3a5b24e64e1d08dd8fe36c6c95c339a896cc33068148906784620540"
dependencies = [
"atoi",
"flume",
@@ -10672,9 +10964,9 @@ dependencies = [
[[package]]
name = "ss58-registry"
-version = "1.50.0"
+version = "1.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43fce22ed1df64d04b262351c8f9d5c6da4f76f79f25ad15529792f893fad25d"
+checksum = "19409f13998e55816d1c728395af0b52ec066206341d939e22e7766df9b494b8"
dependencies = [
"Inflector",
"num-format",
@@ -10733,9 +11025,9 @@ dependencies = [
[[package]]
name = "static_init_macro"
-version = "1.0.2"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf"
+checksum = "1389c88ddd739ec6d3f8f83343764a0e944cd23cfbf126a9796a714b0b6edd6f"
dependencies = [
"cfg_aliases",
"memchr",
@@ -10760,7 +11052,7 @@ dependencies = [
"sctp-proto",
"serde",
"sha-1",
- "thiserror",
+ "thiserror 1.0.69",
"tracing",
]
@@ -10808,7 +11100,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -10865,11 +11157,11 @@ version = "0.17.0"
source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409#87971b3e92721bdf10bf40b410eaae779d494ca0"
dependencies = [
"http-body-util",
- "hyper 1.5.0",
+ "hyper 1.6.0",
"hyper-util",
"log",
"prometheus",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
]
@@ -10912,7 +11204,7 @@ dependencies = [
"quote",
"rayon",
"subtensor-linting",
- "syn 2.0.90",
+ "syn 2.0.96",
"walkdir",
]
@@ -10950,7 +11242,7 @@ dependencies = [
"proc-macro2",
"procedural-fork",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -10960,7 +11252,42 @@ dependencies = [
"ahash 0.8.11",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "subtensor-precompiles"
+version = "0.1.0"
+dependencies = [
+ "ed25519-dalek",
+ "fp-evm",
+ "frame-support",
+ "frame-system",
+ "log",
+ "pallet-admin-utils",
+ "pallet-balances",
+ "pallet-evm",
+ "pallet-evm-precompile-modexp",
+ "pallet-evm-precompile-sha3fips",
+ "pallet-evm-precompile-simple",
+ "pallet-proxy 38.0.0",
+ "pallet-subtensor",
+ "precompile-utils",
+ "sp-core",
+ "sp-runtime",
+ "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)",
+ "subtensor-runtime-common",
+]
+
+[[package]]
+name = "subtensor-runtime-common"
+version = "0.1.0"
+dependencies = [
+ "frame-support",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-core",
+ "sp-runtime",
]
[[package]]
@@ -10969,7 +11296,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"clap",
- "semver 1.0.23",
+ "semver 1.0.25",
"toml_edit",
]
@@ -10998,9 +11325,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.90"
+version = "2.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
+checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
dependencies = [
"proc-macro2",
"quote",
@@ -11027,25 +11354,25 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "system-configuration"
-version = "0.5.1"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
+checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.8.0",
"core-foundation",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
-version = "0.5.0"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
dependencies = [
"core-foundation-sys",
"libc",
@@ -11065,14 +11392,15 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tempfile"
-version = "3.13.0"
+version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
+checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
dependencies = [
"cfg-if",
"fastrand",
+ "getrandom 0.3.1",
"once_cell",
- "rustix 0.38.37",
+ "rustix 0.38.44",
"windows-sys 0.59.0",
]
@@ -11087,38 +11415,58 @@ dependencies = [
[[package]]
name = "terminal_size"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef"
+checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9"
dependencies = [
- "rustix 0.38.37",
+ "rustix 0.38.44",
"windows-sys 0.59.0",
]
[[package]]
name = "termtree"
-version = "0.4.1"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
+checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
[[package]]
name = "thiserror"
-version = "1.0.64"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
- "thiserror-impl",
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
+dependencies = [
+ "thiserror-impl 2.0.11",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.64"
+version = "2.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
+checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -11158,9 +11506,9 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.36"
+version = "0.3.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
+checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
dependencies = [
"deranged",
"itoa",
@@ -11179,9 +11527,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
-version = "0.2.18"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
+checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
dependencies = [
"num-conv",
"time-core",
@@ -11196,11 +11544,21 @@ dependencies = [
"crunchy",
]
+[[package]]
+name = "tinystr"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
[[package]]
name = "tinyvec"
-version = "1.8.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
+checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
dependencies = [
"tinyvec_macros",
]
@@ -11241,9 +11599,9 @@ dependencies = [
[[package]]
name = "tokio"
-version = "1.40.0"
+version = "1.43.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
+checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
dependencies = [
"backtrace",
"bytes",
@@ -11252,20 +11610,20 @@ dependencies = [
"parking_lot 0.12.3",
"pin-project-lite",
"signal-hook-registry",
- "socket2 0.5.7",
+ "socket2 0.5.8",
"tokio-macros",
"windows-sys 0.52.0",
]
[[package]]
name = "tokio-macros"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
+checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
@@ -11280,9 +11638,9 @@ dependencies = [
[[package]]
name = "tokio-stream"
-version = "0.1.16"
+version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1"
+checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -11307,9 +11665,9 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.12"
+version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
+checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
dependencies = [
"bytes",
"futures-core",
@@ -11355,7 +11713,7 @@ version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
- "indexmap 2.6.0",
+ "indexmap 2.7.1",
"serde",
"serde_spanned",
"toml_datetime",
@@ -11383,9 +11741,9 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
dependencies = [
- "bitflags 2.6.0",
+ "bitflags 2.8.0",
"bytes",
- "http 1.1.0",
+ "http 1.2.0",
"http-body 1.0.1",
"http-body-util",
"pin-project-lite",
@@ -11407,9 +11765,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
-version = "0.1.40"
+version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"log",
"pin-project-lite",
@@ -11419,20 +11777,20 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.27"
+version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
+checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "tracing-core"
-version = "0.1.32"
+version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
+checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
dependencies = [
"once_cell",
"valuable",
@@ -11470,9 +11828,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
-version = "0.3.18"
+version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
+checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
dependencies = [
"matchers",
"nu-ansi-term",
@@ -11528,7 +11886,7 @@ dependencies = [
"rand",
"smallvec",
"socket2 0.4.10",
- "thiserror",
+ "thiserror 1.0.69",
"tinyvec",
"tokio",
"tracing",
@@ -11553,7 +11911,7 @@ dependencies = [
"once_cell",
"rand",
"smallvec",
- "thiserror",
+ "thiserror 1.0.69",
"tinyvec",
"tokio",
"tracing",
@@ -11575,7 +11933,7 @@ dependencies = [
"rand",
"resolv-conf",
"smallvec",
- "thiserror",
+ "thiserror 1.0.69",
"tokio",
"tracing",
"trust-dns-proto 0.23.2",
@@ -11608,7 +11966,7 @@ dependencies = [
"rand",
"rustls 0.21.12",
"sha1",
- "thiserror",
+ "thiserror 1.0.69",
"url",
"utf-8",
]
@@ -11658,17 +12016,29 @@ dependencies = [
"static_assertions",
]
+[[package]]
+name = "uint"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e"
+dependencies = [
+ "byteorder",
+ "crunchy",
+ "hex",
+ "static_assertions",
+]
+
[[package]]
name = "unicode-bidi"
-version = "0.3.17"
+version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
+checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
[[package]]
name = "unicode-ident"
-version = "1.0.13"
+version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]]
name = "unicode-normalization"
@@ -11686,16 +12056,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
-name = "unicode-xid"
-version = "0.2.6"
+name = "unicode-width"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
[[package]]
-name = "unicode_categories"
-version = "0.1.1"
+name = "unicode-xid"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "universal-hash"
@@ -11743,12 +12113,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
-version = "2.5.2"
+version = "2.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
+checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
dependencies = [
"form_urlencoded",
- "idna 0.5.0",
+ "idna 1.0.3",
"percent-encoding",
]
@@ -11758,6 +12128,18 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+[[package]]
+name = "utf16_iter"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
[[package]]
name = "utf8parse"
version = "0.2.2"
@@ -11766,9 +12148,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
name = "vcpkg"
@@ -11808,7 +12190,7 @@ dependencies = [
"rand_core",
"sha2 0.10.8",
"sha3",
- "thiserror",
+ "thiserror 1.0.69",
"zeroize",
]
@@ -11837,49 +12219,59 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+[[package]]
+name = "wasi"
+version = "0.13.3+wasi-0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
+dependencies = [
+ "wit-bindgen-rt",
+]
+
[[package]]
name = "wasm-bindgen"
-version = "0.2.93"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
+checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
+ "rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.93"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
+checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
- "once_cell",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.43"
+version = "0.4.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed"
+checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
dependencies = [
"cfg-if",
"js-sys",
+ "once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.93"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
+checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -11887,22 +12279,25 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.93"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
+checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.93"
+version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
+checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+dependencies = [
+ "unicode-ident",
+]
[[package]]
name = "wasm-instrument"
@@ -11924,7 +12319,7 @@ dependencies = [
"strum 0.24.1",
"strum_macros 0.24.3",
"tempfile",
- "thiserror",
+ "thiserror 1.0.69",
"wasm-opt-cxx-sys",
"wasm-opt-sys",
]
@@ -12051,7 +12446,7 @@ dependencies = [
"log",
"object 0.30.4",
"target-lexicon",
- "thiserror",
+ "thiserror 1.0.69",
"wasmparser",
"wasmtime-cranelift-shared",
"wasmtime-environ",
@@ -12086,7 +12481,7 @@ dependencies = [
"object 0.30.4",
"serde",
"target-lexicon",
- "thiserror",
+ "thiserror 1.0.69",
"wasmparser",
"wasmtime-types",
]
@@ -12169,15 +12564,15 @@ checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f"
dependencies = [
"cranelift-entity",
"serde",
- "thiserror",
+ "thiserror 1.0.69",
"wasmparser",
]
[[package]]
name = "web-sys"
-version = "0.3.70"
+version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0"
+checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -12189,7 +12584,7 @@ version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53"
dependencies = [
- "ring 0.17.8",
+ "ring 0.17.13",
"untrusted 0.9.0",
]
@@ -12208,14 +12603,14 @@ dependencies = [
"either",
"home",
"once_cell",
- "rustix 0.38.37",
+ "rustix 0.38.44",
]
[[package]]
name = "wide"
-version = "0.7.28"
+version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b828f995bf1e9622031f8009f8481a85406ce1f4d4588ff746d872043e855690"
+checksum = "41b5576b9a81633f3e8df296ce0063042a73507636cbe956c61133dd7034ab22"
dependencies = [
"bytemuck",
"safe_arch",
@@ -12260,28 +12655,38 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
-version = "0.51.1"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9"
+checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538"
dependencies = [
- "windows-core 0.51.1",
- "windows-targets 0.48.5",
+ "windows-core 0.53.0",
+ "windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
-version = "0.51.1"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
- "windows-targets 0.48.5",
+ "windows-targets 0.52.6",
]
[[package]]
name = "windows-core"
-version = "0.52.0"
+version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd"
+dependencies = [
+ "windows-result",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
dependencies = [
"windows-targets 0.52.6",
]
@@ -12517,9 +12922,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
-version = "0.6.20"
+version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
+checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310"
dependencies = [
"memchr",
]
@@ -12534,6 +12939,27 @@ dependencies = [
"windows-sys 0.48.0",
]
+[[package]]
+name = "wit-bindgen-rt"
+version = "0.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
+dependencies = [
+ "bitflags 2.8.0",
+]
+
+[[package]]
+name = "write16"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
+
+[[package]]
+name = "writeable"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+
[[package]]
name = "wyz"
version = "0.5.1"
@@ -12568,7 +12994,7 @@ dependencies = [
"nom",
"oid-registry 0.6.1",
"rusticata-macros",
- "thiserror",
+ "thiserror 1.0.69",
"time",
]
@@ -12585,7 +13011,7 @@ dependencies = [
"nom",
"oid-registry 0.7.1",
"rusticata-macros",
- "thiserror",
+ "thiserror 1.0.69",
"time",
]
@@ -12597,14 +13023,14 @@ dependencies = [
"Inflector",
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
]
[[package]]
name = "xml-rs"
-version = "0.8.22"
+version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26"
+checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
[[package]]
name = "xmltree"
@@ -12639,6 +13065,30 @@ dependencies = [
"time",
]
+[[package]]
+name = "yoke"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+ "synstructure 0.13.1",
+]
+
[[package]]
name = "zerocopy"
version = "0.7.35"
@@ -12657,7 +13107,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
+ "synstructure 0.13.1",
]
[[package]]
@@ -12677,7 +13148,29 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.90",
+ "syn 2.0.96",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.96",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index ef5d64b0d6..15dd760a57 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,21 +23,14 @@ rayon = "1.10"
[workspace]
members = [
- "node",
- "pallets/commitments",
- "pallets/subtensor",
- "pallets/admin-utils",
- "pallets/collective",
- "pallets/registry",
- "primitives/*",
- "runtime",
- "support/tools",
- "support/macros",
- "support/linting",
- "support/procedural-fork",
- "pallets/drand",
+ "common",
+ "node",
+ "pallets/*",
+ "precompiles",
+ "primitives/*",
+ "runtime",
+ "support/*",
]
-exclude = ["support/procedural-fork"]
resolver = "2"
[workspace.lints.clippy]
@@ -46,14 +39,29 @@ arithmetic-side-effects = "deny"
type_complexity = "allow"
unwrap-used = "deny"
manual_inspect = "allow"
-useless_conversion = "allow" # until polkadot is patched
+useless_conversion = "allow" # until polkadot is patched
[workspace.dependencies]
+pallet-admin-utils = { default-features = false, path = "pallets/admin-utils" }
+pallet-collective = { default-features = false, path = "pallets/collective" }
+pallet-commitments = { default-features = false, path = "pallets/commitments" }
+pallet-registry = { default-features = false, path = "pallets/registry" }
+pallet-subtensor = { default-features = false, path = "pallets/subtensor" }
+subtensor-custom-rpc = { default-features = false, path = "pallets/subtensor/rpc" }
+subtensor-custom-rpc-runtime-api = { default-features = false, path = "pallets/subtensor/runtime-api" }
+subtensor-precompiles = { default-features = false, path = "precompiles" }
+subtensor-runtime-common = { default-features = false, path = "common" }
+node-subtensor-runtime = { default-features = false, path = "runtime" }
+
async-trait = "0.1"
cargo-husky = { version = "1", default-features = false }
clap = "4.5.4"
-codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] }
-ed25519-dalek = { version = "2.1.0", default-features = false, features = ["alloc"] }
+codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [
+ "derive",
+] }
+ed25519-dalek = { version = "2.1.0", default-features = false, features = [
+ "alloc",
+] }
enumflags2 = "0.7.9"
futures = "0.3.30"
hex = { version = "0.4", default-features = false }
@@ -64,7 +72,9 @@ memmap2 = "0.9.4"
ndarray = { version = "0.15.6", default-features = false }
parity-util-mem = "0.12.0"
rand = "0.8.5"
-scale-codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false, features = ["derive"] }
+scale-codec = { package = "parity-scale-codec", version = "3.6.12", default-features = false, features = [
+ "derive",
+] }
scale-info = { version = "2.11.2", default-features = false }
serde = { version = "1.0.214", default-features = false }
serde-tuple-vec-map = { version = "1.0.1", default-features = false }
@@ -74,11 +84,11 @@ serde_with = { version = "=2.0.0", default-features = false }
smallvec = "1.13.2"
litep2p = { git = "https://github.com/paritytech/litep2p", tag = "v0.7.0" }
syn = { version = "2.0.87", features = [
- "full",
- "visit-mut",
- "visit",
- "extra-traits",
- "parsing",
+ "full",
+ "visit-mut",
+ "visit",
+ "extra-traits",
+ "parsing",
] }
quote = "1"
proc-macro2 = { version = "1", features = ["span-locations"] }
@@ -105,7 +115,7 @@ pallet-insecure-randomness-collective-flip = { git = "https://github.com/parityt
pallet-membership = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
pallet-multisig = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
pallet-preimage = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
-pallet-proxy = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
+pallet-proxy = { path = "pallets/proxy", default-features = false }
pallet-safe-mode = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
pallet-scheduler = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
@@ -113,7 +123,8 @@ pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk.git", tag
pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409" }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
-pallet-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
+pallet-utility = { path = "pallets/utility", default-features = false }
+pallet-root-testing = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
sc-basic-authorship = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409" }
sc-cli = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409" }
@@ -181,7 +192,9 @@ fc-consensus = { git = "https://github.com/opentensor/frontier", rev = "635bdac8
fp-consensus = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false }
fp-dynamic-fee = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false }
fc-api = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false }
-fc-rpc = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false, features = ["rpc-binary-search-estimate"]}
+fc-rpc = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false, features = [
+ "rpc-binary-search-estimate",
+] }
fc-rpc-core = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false }
fc-mapping-sync = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false }
precompile-utils = { git = "https://github.com/opentensor/frontier", rev = "635bdac882", default-features = false }
@@ -199,21 +212,34 @@ pallet-hotfix-sufficients = { git = "https://github.com/opentensor/frontier", re
#DRAND
pallet-drand = { path = "pallets/drand", default-features = false }
-sp-crypto-ec-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", features = ["bls12-381"] }
-getrandom = { version = "0.2.15", features = ["custom"], default-features = false }
-sp-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
+sp-crypto-ec-utils = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", features = [
+ "bls12-381",
+] }
+getrandom = { version = "0.2.15", features = [
+ "custom",
+], default-features = false }
+sp-keystore = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2409", default-features = false }
w3f-bls = { version = "=0.1.3", default-features = false }
-ark-crypto-primitives = { version = "0.4.0", default-features = false, features = [ "r1cs", "snark" ] }
-ark-scale = { version = "0.0.11", default-features = false, features = ["hazmat"] }
+ark-crypto-primitives = { version = "0.4.0", default-features = false, features = [
+ "r1cs",
+ "snark",
+] }
+ark-scale = { version = "0.0.11", default-features = false, features = [
+ "hazmat",
+] }
sp-ark-bls12-381 = { git = "https://github.com/paritytech/substrate-curves", default-features = false }
-ark-bls12-381 = { version = "0.4.0", features = ["curve"], default-features = false }
-ark-serialize = { version = "0.4.0", features = [ "derive" ], default-features = false }
+ark-bls12-381 = { version = "0.4.0", features = [
+ "curve",
+], default-features = false }
+ark-serialize = { version = "0.4.0", features = [
+ "derive",
+], default-features = false }
ark-ff = { version = "0.4.0", default-features = false }
ark-ec = { version = "0.4.0", default-features = false }
ark-std = { version = "0.4.0", default-features = false }
anyhow = "1.0.81"
sha2 = { version = "0.10.8", default-features = false }
-rand_chacha = { version = "0.3.1", default-features = false }
+rand_chacha = { version = "0.3.1", default-features = false }
tle = { git = "https://github.com/ideal-lab5/timelock", rev = "5416406cfd32799e31e1795393d4916894de4468", default-features = false }
frame-metadata = "16"
@@ -232,11 +258,11 @@ codegen-units = 1
[features]
default = []
try-runtime = [
- "node-subtensor/try-runtime",
- "node-subtensor-runtime/try-runtime",
+ "node-subtensor/try-runtime",
+ "node-subtensor-runtime/try-runtime",
]
runtime-benchmarks = [
- "node-subtensor/runtime-benchmarks",
- "node-subtensor-runtime/runtime-benchmarks",
+ "node-subtensor/runtime-benchmarks",
+ "node-subtensor-runtime/runtime-benchmarks",
]
metadata-hash = ["node-subtensor-runtime/metadata-hash"]
diff --git a/Dockerfile b/Dockerfile
index edceab0e8c..2439d5b2a2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-ARG BASE_IMAGE=ubuntu:24.04
+ARG BASE_IMAGE=ubuntu:latest
FROM $BASE_IMAGE AS builder
SHELL ["/bin/bash", "-c"]
@@ -18,18 +18,22 @@ RUN apt-get update && \
apt-get install -y curl build-essential protobuf-compiler clang git pkg-config libssl-dev && \
rm -rf /var/lib/apt/lists/*
-RUN set -o pipefail && curl https://sh.rustup.rs -sSf | sh -s -- -y
-ENV PATH="/root/.cargo/bin:${PATH}"
-RUN rustup update stable
-RUN rustup target add wasm32-unknown-unknown --toolchain stable
-
# Copy entire repository
COPY . /build
WORKDIR /build
+# Install Rust
+RUN set -o pipefail && curl https://sh.rustup.rs -sSf | sh -s -- -y
+ENV PATH="/root/.cargo/bin:${PATH}"
+RUN rustup toolchain install
+RUN rustup target add wasm32-unknown-unknown
+
# Build the project
RUN cargo build -p node-subtensor --profile production --features="metadata-hash" --locked
+# Slim down image
+RUN rm -rf /root/.cargo
+
# Verify the binary was produced
RUN test -e /build/target/production/node-subtensor
diff --git a/build.rs b/build.rs
index 1abd7456b4..854778873e 100644
--- a/build.rs
+++ b/build.rs
@@ -31,6 +31,7 @@ fn main() {
// Parse each rust file with syn and run the linting suite on it in parallel
rust_files.par_iter().for_each_with(tx.clone(), |tx, file| {
+ let is_test = file.display().to_string().contains("test");
let Ok(content) = fs::read_to_string(file) else {
return;
};
@@ -63,6 +64,10 @@ fn main() {
track_lint(ForbidKeysRemoveCall::lint(&parsed_file));
track_lint(RequireFreezeStruct::lint(&parsed_file));
track_lint(RequireExplicitPalletIndex::lint(&parsed_file));
+
+ if is_test {
+ track_lint(ForbidSaturatingMath::lint(&parsed_file));
+ }
});
// Collect and print all errors after the parallel processing is done
diff --git a/common/Cargo.toml b/common/Cargo.toml
new file mode 100644
index 0000000000..d0b43cdc1b
--- /dev/null
+++ b/common/Cargo.toml
@@ -0,0 +1,32 @@
+[package]
+name = "subtensor-runtime-common"
+version = "0.1.0"
+edition = "2024"
+authors = ["Opentensor Foundation "]
+homepage = "https://opentensor.ai/"
+publish = false
+repository = "https://github.com/opentensor/subtensor/"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+codec = { workspace = true }
+frame-support = { workspace = true }
+scale-info = { workspace = true }
+sp-runtime = { workspace = true }
+sp-core = { workspace = true }
+
+[lints]
+workspace = true
+
+[features]
+default = ["std"]
+fast-blocks = []
+std = [
+ "codec/std",
+ "frame-support/std",
+ "scale-info/std",
+ "sp-core/std",
+ "sp-runtime/std",
+]
diff --git a/common/src/lib.rs b/common/src/lib.rs
new file mode 100644
index 0000000000..75b18e3b14
--- /dev/null
+++ b/common/src/lib.rs
@@ -0,0 +1,86 @@
+#![cfg_attr(not(feature = "std"), no_std)]
+
+use codec::{Decode, Encode, MaxEncodedLen};
+use scale_info::TypeInfo;
+use sp_runtime::{
+ MultiSignature,
+ traits::{IdentifyAccount, Verify},
+};
+
+/// Balance of an account.
+pub type Balance = u64;
+
+/// An index to a block.
+pub type BlockNumber = u32;
+
+/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
+pub type Signature = MultiSignature;
+
+/// Some way of identifying an account on the chain. We intentionally make it equivalent to the
+/// public key of our transaction signing scheme.
+pub type AccountId = <::Signer as IdentifyAccount>::AccountId;
+
+/// Index of a transaction in the chain.
+pub type Index = u32;
+
+/// A hash of some data used by the chain.
+pub type Hash = sp_core::H256;
+
+pub type Nonce = u32;
+
+/// Transfers below SMALL_TRANSFER_LIMIT are considered small transfers
+pub const SMALL_TRANSFER_LIMIT: Balance = 500_000_000; // 0.5 TAO
+
+#[derive(
+ Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug, MaxEncodedLen, TypeInfo,
+)]
+pub enum ProxyType {
+ Any,
+ Owner, // Subnet owner Calls
+ NonCritical,
+ NonTransfer,
+ Senate,
+ NonFungibile, // Nothing involving moving TAO
+ Triumvirate,
+ Governance, // Both above governance
+ Staking,
+ Registration,
+ Transfer,
+ SmallTransfer,
+ RootWeights,
+ ChildKeys,
+ SudoUncheckedSetCode,
+}
+
+impl Default for ProxyType {
+ // allow all Calls; required to be most permissive
+ fn default() -> Self {
+ Self::Any
+ }
+}
+
+pub mod time {
+ use super::*;
+
+ /// This determines the average expected block time that we are targeting. Blocks will be
+ /// produced at a minimum duration defined by `SLOT_DURATION`. `SLOT_DURATION` is picked up by
+ /// `pallet_timestamp` which is in turn picked up by `pallet_aura` to implement `fn
+ /// slot_duration()`.
+ ///
+ /// Change this to adjust the block time.
+ #[cfg(not(feature = "fast-blocks"))]
+ pub const MILLISECS_PER_BLOCK: u64 = 12000;
+
+ /// Fast blocks for development
+ #[cfg(feature = "fast-blocks")]
+ pub const MILLISECS_PER_BLOCK: u64 = 250;
+
+ // NOTE: Currently it is not possible to change the slot duration after the chain has started.
+ // Attempting to do so will brick block production.
+ pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
+
+ // Time is measured by number of blocks.
+ pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
+ pub const HOURS: BlockNumber = MINUTES * 60;
+ pub const DAYS: BlockNumber = HOURS * 24;
+}
diff --git a/evm-tests/.gitignore b/evm-tests/.gitignore
new file mode 100644
index 0000000000..661f94a6e0
--- /dev/null
+++ b/evm-tests/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+.papi
+.env
diff --git a/evm-tests/README.md b/evm-tests/README.md
new file mode 100644
index 0000000000..7d01034bd8
--- /dev/null
+++ b/evm-tests/README.md
@@ -0,0 +1,27 @@
+# type-test
+
+test with ts
+
+## polkadot api
+
+```bash
+npx papi add devnet -w ws://10.0.0.11:9944
+```
+
+## get the new metadata
+
+```bash
+sh get-metadata.sh
+```
+
+## run all tests
+
+```bash
+yarn run test
+```
+
+## To run a particular test case, you can pass an argument with the name or part of the name. For example:
+
+```bash
+yarn run test -- -g "Can set subnet parameter"
+```
diff --git a/evm-tests/get-metadata.sh b/evm-tests/get-metadata.sh
new file mode 100644
index 0000000000..6d7727009d
--- /dev/null
+++ b/evm-tests/get-metadata.sh
@@ -0,0 +1,3 @@
+rm -rf .papi
+npx papi add devnet -w ws://localhost:9944
+
diff --git a/evm-tests/local.test.ts b/evm-tests/local.test.ts
new file mode 100644
index 0000000000..9eb24d4327
--- /dev/null
+++ b/evm-tests/local.test.ts
@@ -0,0 +1,53 @@
+import * as assert from "assert";
+import { getAliceSigner, getClient, getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { SUB_LOCAL_URL, } from "../src/config";
+import { devnet } from "@polkadot-api/descriptors"
+import { PolkadotSigner, TypedApi } from "polkadot-api";
+import { convertPublicKeyToSs58, convertH160ToSS58 } from "../src/address-utils"
+import { ethers } from "ethers"
+import { INEURON_ADDRESS, INeuronABI } from "../src/contracts/neuron"
+import { generateRandomEthersWallet } from "../src/utils"
+import { forceSetBalanceToEthAddress, forceSetBalanceToSs58Address, addNewSubnetwork, burnedRegister } from "../src/subtensor"
+
+describe("Test neuron precompile Serve Axon Prometheus", () => {
+ // init eth part
+ // const wallet1 = generateRandomEthersWallet();
+ // const wallet2 = generateRandomEthersWallet();
+ // const wallet3 = generateRandomEthersWallet();
+
+ // init substrate part
+
+ // const coldkey = getRandomSubstrateKeypair();
+
+ let api: TypedApi
+
+ // sudo account alice as signer
+ let alice: PolkadotSigner;
+ before(async () => {
+ // init variables got from await and async
+ const subClient = await getClient(SUB_LOCAL_URL)
+ api = await getDevnetApi()
+ // alice = await getAliceSigner();
+
+ // await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ // await forceSetBalanceToEthAddress(api, wallet1.address)
+ // await forceSetBalanceToEthAddress(api, wallet2.address)
+ // await forceSetBalanceToEthAddress(api, wallet3.address)
+
+
+ let index = 0;
+ while (index < 30) {
+ const hotkey = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ let netuid = await addNewSubnetwork(api, hotkey, coldkey)
+ }
+
+
+ })
+
+ it("Serve Axon", async () => {
+
+ });
+});
\ No newline at end of file
diff --git a/evm-tests/package.json b/evm-tests/package.json
new file mode 100644
index 0000000000..a96a2c4a0c
--- /dev/null
+++ b/evm-tests/package.json
@@ -0,0 +1,31 @@
+{
+ "scripts": {
+ "test": "mocha --timeout 999999 --require ts-node/register test/*test.ts"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "@polkadot-api/descriptors": "file:.papi/descriptors",
+ "@polkadot-labs/hdkd": "^0.0.10",
+ "@polkadot-labs/hdkd-helpers": "^0.0.11",
+ "@polkadot/api": "15.1.1",
+ "crypto": "^1.0.1",
+ "dotenv": "16.4.7",
+ "ethers": "^6.13.5",
+ "polkadot-api": "^1.9.5",
+ "viem": "2.23.4"
+ },
+ "devDependencies": {
+ "@types/bun": "^1.1.13",
+ "@types/chai": "^5.0.1",
+ "@types/mocha": "^10.0.10",
+ "assert": "^2.1.0",
+ "chai": "^5.2.0",
+ "mocha": "^11.1.0",
+ "prettier": "^3.3.3",
+ "ts-node": "^10.9.2",
+ "typescript": "^5.7.2",
+ "vite": "^5.4.8"
+ }
+}
diff --git a/evm-tests/src/address-utils.ts b/evm-tests/src/address-utils.ts
new file mode 100644
index 0000000000..ed3abc5008
--- /dev/null
+++ b/evm-tests/src/address-utils.ts
@@ -0,0 +1,77 @@
+import { Address } from "viem"
+import { encodeAddress } from "@polkadot/util-crypto";
+import { ss58Address } from "@polkadot-labs/hdkd-helpers";
+import { hexToU8a } from "@polkadot/util";
+import { blake2AsU8a, decodeAddress } from "@polkadot/util-crypto";
+import { Binary } from "polkadot-api";
+import { SS58_PREFIX } from "./config"
+
+export function toViemAddress(address: string): Address {
+ let addressNoPrefix = address.replace("0x", "")
+ return `0x${addressNoPrefix}`
+}
+
+export function convertH160ToSS58(ethAddress: string) {
+ // get the public key
+ const hash = convertH160ToPublicKey(ethAddress);
+
+ // Convert the hash to SS58 format
+ const ss58Address = encodeAddress(hash, SS58_PREFIX);
+ return ss58Address;
+}
+
+export function convertPublicKeyToSs58(publickey: Uint8Array) {
+ return ss58Address(publickey, SS58_PREFIX);
+}
+
+export function convertH160ToPublicKey(ethAddress: string) {
+ const prefix = "evm:";
+ const prefixBytes = new TextEncoder().encode(prefix);
+ const addressBytes = hexToU8a(
+ ethAddress.startsWith("0x") ? ethAddress : `0x${ethAddress}`
+ );
+ const combined = new Uint8Array(prefixBytes.length + addressBytes.length);
+
+ // Concatenate prefix and Ethereum address
+ combined.set(prefixBytes);
+ combined.set(addressBytes, prefixBytes.length);
+
+ // Hash the combined data (the public key)
+ const hash = blake2AsU8a(combined);
+ return hash;
+}
+
+export function ss58ToEthAddress(ss58Address: string) {
+ // Decode the SS58 address to a Uint8Array public key
+ const publicKey = decodeAddress(ss58Address);
+
+ // Take the first 20 bytes of the hashed public key for the Ethereum address
+ const ethereumAddressBytes = publicKey.slice(0, 20);
+
+ // Convert the 20 bytes into an Ethereum H160 address format (Hex string)
+ const ethereumAddress = '0x' + Buffer.from(ethereumAddressBytes).toString('hex');
+
+ return ethereumAddress;
+}
+
+export function ss58ToH160(ss58Address: string): Binary {
+ // Decode the SS58 address to a Uint8Array public key
+ const publicKey = decodeAddress(ss58Address);
+
+ // Take the first 20 bytes of the hashed public key for the Ethereum address
+ const ethereumAddressBytes = publicKey.slice(0, 20);
+
+
+ return new Binary(ethereumAddressBytes);
+}
+
+export function ethAddressToH160(ethAddress: string): Binary {
+ // Decode the SS58 address to a Uint8Array public key
+ const publicKey = hexToU8a(ethAddress);
+
+ // Take the first 20 bytes of the hashed public key for the Ethereum address
+ // const ethereumAddressBytes = publicKey.slice(0, 20);
+
+
+ return new Binary(publicKey);
+}
\ No newline at end of file
diff --git a/evm-tests/src/balance-math.ts b/evm-tests/src/balance-math.ts
new file mode 100644
index 0000000000..8d6e86bd5a
--- /dev/null
+++ b/evm-tests/src/balance-math.ts
@@ -0,0 +1,26 @@
+import assert from "assert"
+
+export const TAO = BigInt(1000000000) // 10^9
+export const ETH_PER_RAO = BigInt(1000000000) // 10^9
+export const GWEI = BigInt(1000000000) // 10^9
+export const MAX_TX_FEE = BigInt(21000000) * GWEI // 100 times EVM to EVM transfer fee
+
+export function bigintToRao(value: bigint) {
+ return TAO * value
+}
+
+export function tao(value: number) {
+ return TAO * BigInt(value)
+}
+
+export function raoToEth(value: bigint) {
+ return ETH_PER_RAO * value
+}
+
+export function compareEthBalanceWithTxFee(balance1: bigint, balance2: bigint) {
+ if (balance1 > balance2) {
+ assert((balance1 - balance2) < MAX_TX_FEE)
+ } else {
+ assert((balance2 - balance1) < MAX_TX_FEE)
+ }
+}
diff --git a/evm-tests/src/config.ts b/evm-tests/src/config.ts
new file mode 100644
index 0000000000..601c89c8c1
--- /dev/null
+++ b/evm-tests/src/config.ts
@@ -0,0 +1,38 @@
+export const ETH_LOCAL_URL = 'http://localhost:9944'
+export const SUB_LOCAL_URL = 'ws://localhost:9944'
+export const SS58_PREFIX = 42;
+// set the tx timeout as 2 second when eable the fast-blocks feature.
+export const TX_TIMEOUT = 2000;
+
+export const IED25519VERIFY_ADDRESS = "0x0000000000000000000000000000000000000402";
+export const IEd25519VerifyABI = [
+ {
+ inputs: [
+ { internalType: "bytes32", name: "message", type: "bytes32" },
+ { internalType: "bytes32", name: "publicKey", type: "bytes32" },
+ { internalType: "bytes32", name: "r", type: "bytes32" },
+ { internalType: "bytes32", name: "s", type: "bytes32" },
+ ],
+ name: "verify",
+ outputs: [{ internalType: "bool", name: "", type: "bool" }],
+ stateMutability: "pure",
+ type: "function",
+ },
+];
+
+export const IBALANCETRANSFER_ADDRESS = "0x0000000000000000000000000000000000000800";
+export const IBalanceTransferABI = [
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "data",
+ type: "bytes32",
+ },
+ ],
+ name: "transfer",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+];
\ No newline at end of file
diff --git a/evm-tests/src/contracts/bridgeToken.ts b/evm-tests/src/contracts/bridgeToken.ts
new file mode 100644
index 0000000000..f8b3ea4d03
--- /dev/null
+++ b/evm-tests/src/contracts/bridgeToken.ts
@@ -0,0 +1,631 @@
+export const BRIDGE_TOKEN_CONTRACT_ABI = [
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "name_",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "symbol_",
+ "type": "string"
+ },
+ {
+ "internalType": "address",
+ "name": "admin",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [],
+ "name": "AccessControlBadConfirmation",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "neededRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "AccessControlUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "allowance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientAllowance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "balance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientBalance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "approver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidApprover",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidReceiver",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSender",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSpender",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UnauthorizedHandler",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "previousAdminRole",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "newAdminRole",
+ "type": "bytes32"
+ }
+ ],
+ "name": "RoleAdminChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleGranted",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "RoleRevoked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "DEFAULT_ADMIN_ROLE",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "burnFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getRoleAdmin",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "grantRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "hasRole",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isAdmin",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "callerConfirmation",
+ "type": "address"
+ }
+ ],
+ "name": "renounceRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "role",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "revokeRole",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes4",
+ "name": "interfaceId",
+ "type": "bytes4"
+ }
+ ],
+ "name": "supportsInterface",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+];
+
+export const BRIDGE_TOKEN_CONTRACT_BYTECODE = "0x60806040523480156200001157600080fd5b5060405162000fac38038062000fac8339810160408190526200003491620001ea565b8282600362000044838262000308565b50600462000053828262000308565b5062000065915060009050826200006f565b50505050620003d4565b60008281526005602090815260408083206001600160a01b038516845290915281205460ff16620001185760008381526005602090815260408083206001600160a01b03861684529091529020805460ff19166001179055620000cf3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45060016200011c565b5060005b92915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014a57600080fd5b81516001600160401b038082111562000167576200016762000122565b604051601f8301601f19908116603f0116810190828211818310171562000192576200019262000122565b8160405283815260209250866020858801011115620001b057600080fd5b600091505b83821015620001d45785820183015181830184015290820190620001b5565b6000602085830101528094505050505092915050565b6000806000606084860312156200020057600080fd5b83516001600160401b03808211156200021857600080fd5b620002268783880162000138565b945060208601519150808211156200023d57600080fd5b506200024c8682870162000138565b604086015190935090506001600160a01b03811681146200026c57600080fd5b809150509250925092565b600181811c908216806200028c57607f821691505b602082108103620002ad57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111562000303576000816000526020600020601f850160051c81016020861015620002de5750805b601f850160051c820191505b81811015620002ff57828155600101620002ea565b5050505b505050565b81516001600160401b0381111562000324576200032462000122565b6200033c8162000335845462000277565b84620002b3565b602080601f8311600181146200037457600084156200035b5750858301515b600019600386901b1c1916600185901b178555620002ff565b600085815260208120601f198616915b82811015620003a55788860151825594840194600190910190840162000384565b5085821015620003c45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610bc880620003e46000396000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c806340c10f19116100ad57806395d89b411161007157806395d89b4114610288578063a217fddf14610290578063a9059cbb14610298578063d547741f146102ab578063dd62ed3e146102be57600080fd5b806340c10f191461021357806342966c681461022657806370a082311461023957806379cc67901461026257806391d148541461027557600080fd5b8063248a9ca3116100f4578063248a9ca3146101a657806324d7806c146101c95780632f2ff15d146101dc578063313ce567146101f157806336568abe1461020057600080fd5b806301ffc9a71461013157806306fdde0314610159578063095ea7b31461016e57806318160ddd1461018157806323b872dd14610193575b600080fd5b61014461013f3660046109ab565b6102f7565b60405190151581526020015b60405180910390f35b61016161032e565b60405161015091906109dc565b61014461017c366004610a47565b6103c0565b6002545b604051908152602001610150565b6101446101a1366004610a71565b6103d8565b6101856101b4366004610aad565b60009081526005602052604090206001015490565b6101446101d7366004610ac6565b6103fc565b6101ef6101ea366004610ae1565b610408565b005b60405160128152602001610150565b6101ef61020e366004610ae1565b610433565b6101ef610221366004610a47565b61046b565b6101ef610234366004610aad565b610480565b610185610247366004610ac6565b6001600160a01b031660009081526020819052604090205490565b6101ef610270366004610a47565b61048d565b610144610283366004610ae1565b6104a2565b6101616104cd565b610185600081565b6101446102a6366004610a47565b6104dc565b6101ef6102b9366004610ae1565b6104ea565b6101856102cc366004610b0d565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60006001600160e01b03198216637965db0b60e01b148061032857506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606003805461033d90610b37565b80601f016020809104026020016040519081016040528092919081815260200182805461036990610b37565b80156103b65780601f1061038b576101008083540402835291602001916103b6565b820191906000526020600020905b81548152906001019060200180831161039957829003601f168201915b5050505050905090565b6000336103ce81858561050f565b5060019392505050565b6000336103e685828561051c565b6103f1858585610599565b506001949350505050565b600061032881836104a2565b600082815260056020526040902060010154610423816105f8565b61042d8383610602565b50505050565b6001600160a01b038116331461045c5760405163334bd91960e11b815260040160405180910390fd5b6104668282610696565b505050565b6000610476816105f8565b6104668383610703565b61048a338261073d565b50565b6000610498816105f8565b610466838361073d565b60009182526005602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60606004805461033d90610b37565b6000336103ce818585610599565b600082815260056020526040902060010154610505816105f8565b61042d8383610696565b6104668383836001610773565b6001600160a01b03838116600090815260016020908152604080832093861683529290522054600019811461042d578181101561058a57604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b61042d84848484036000610773565b6001600160a01b0383166105c357604051634b637e8f60e11b815260006004820152602401610581565b6001600160a01b0382166105ed5760405163ec442f0560e01b815260006004820152602401610581565b610466838383610848565b61048a8133610972565b600061060e83836104a2565b61068e5760008381526005602090815260408083206001600160a01b03861684529091529020805460ff191660011790556106463390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610328565b506000610328565b60006106a283836104a2565b1561068e5760008381526005602090815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610328565b6001600160a01b03821661072d5760405163ec442f0560e01b815260006004820152602401610581565b61073960008383610848565b5050565b6001600160a01b03821661076757604051634b637e8f60e11b815260006004820152602401610581565b61073982600083610848565b6001600160a01b03841661079d5760405163e602df0560e01b815260006004820152602401610581565b6001600160a01b0383166107c757604051634a1406b160e11b815260006004820152602401610581565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561042d57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161083a91815260200190565b60405180910390a350505050565b6001600160a01b0383166108735780600260008282546108689190610b71565b909155506108e59050565b6001600160a01b038316600090815260208190526040902054818110156108c65760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610581565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661090157600280548290039055610920565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161096591815260200190565b60405180910390a3505050565b61097c82826104a2565b6107395760405163e2517d3f60e01b81526001600160a01b038216600482015260248101839052604401610581565b6000602082840312156109bd57600080fd5b81356001600160e01b0319811681146109d557600080fd5b9392505050565b60006020808352835180602085015260005b81811015610a0a578581018301518582016040015282016109ee565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b0381168114610a4257600080fd5b919050565b60008060408385031215610a5a57600080fd5b610a6383610a2b565b946020939093013593505050565b600080600060608486031215610a8657600080fd5b610a8f84610a2b565b9250610a9d60208501610a2b565b9150604084013590509250925092565b600060208284031215610abf57600080fd5b5035919050565b600060208284031215610ad857600080fd5b6109d582610a2b565b60008060408385031215610af457600080fd5b82359150610b0460208401610a2b565b90509250929050565b60008060408385031215610b2057600080fd5b610b2983610a2b565b9150610b0460208401610a2b565b600181811c90821680610b4b57607f821691505b602082108103610b6b57634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561032857634e487b7160e01b600052601160045260246000fdfea2646970667358221220e179fc58c926e64cb6e87416f8ca64c117044e3195b184afe45038857606c15364736f6c63430008160033"
diff --git a/evm-tests/src/contracts/incremental.sol b/evm-tests/src/contracts/incremental.sol
new file mode 100644
index 0000000000..2b3bc2fd49
--- /dev/null
+++ b/evm-tests/src/contracts/incremental.sol
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity >=0.8.2 <0.9.0;
+
+contract Storage {
+ uint256 number;
+
+ /**
+ * @dev Store value in variable
+ * @param num value to store
+ */
+ function store(uint256 num) public {
+ number = num;
+ }
+
+ /**
+ * @dev Return value
+ * @return value of 'number'
+ */
+ function retrieve() public view returns (uint256) {
+ return number;
+ }
+}
diff --git a/evm-tests/src/contracts/incremental.ts b/evm-tests/src/contracts/incremental.ts
new file mode 100644
index 0000000000..b19909e491
--- /dev/null
+++ b/evm-tests/src/contracts/incremental.ts
@@ -0,0 +1,39 @@
+export const INCREMENTAL_CONTRACT_ABI = [
+ {
+ "inputs": [],
+ "name": "retrieve",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "num",
+ "type": "uint256"
+ }
+ ],
+ "name": "store",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+];
+
+/*
+"compiler": {
+ "version": "0.8.26+commit.8a97fa7a"
+ },
+*/
+
+export const INCREMENTAL_CONTRACT_BYTECODE = "6080604052348015600e575f80fd5b506101438061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c80632e64cec1146100385780636057361d14610056575b5f80fd5b610040610072565b60405161004d919061009b565b60405180910390f35b610070600480360381019061006b91906100e2565b61007a565b005b5f8054905090565b805f8190555050565b5f819050919050565b61009581610083565b82525050565b5f6020820190506100ae5f83018461008c565b92915050565b5f80fd5b6100c181610083565b81146100cb575f80fd5b50565b5f813590506100dc816100b8565b92915050565b5f602082840312156100f7576100f66100b4565b5b5f610104848285016100ce565b9150509291505056fea26469706673582212209a0dd35336aff1eb3eeb11db76aa60a1427a12c1b92f945ea8c8d1dfa337cf2264736f6c634300081a0033"
+
+
+
diff --git a/evm-tests/src/contracts/metagraph.ts b/evm-tests/src/contracts/metagraph.ts
new file mode 100644
index 0000000000..d0c3bf5154
--- /dev/null
+++ b/evm-tests/src/contracts/metagraph.ts
@@ -0,0 +1,391 @@
+export const IMETAGRAPH_ADDRESS = "0x0000000000000000000000000000000000000802";
+
+export const IMetagraphABI = [
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getAxon",
+ outputs: [
+ {
+ components: [
+ {
+ internalType: "uint64",
+ name: "block",
+ type: "uint64",
+ },
+ {
+ internalType: "uint32",
+ name: "version",
+ type: "uint32",
+ },
+ {
+ internalType: "uint128",
+ name: "ip",
+ type: "uint128",
+ },
+ {
+ internalType: "uint16",
+ name: "port",
+ type: "uint16",
+ },
+ {
+ internalType: "uint8",
+ name: "ip_type",
+ type: "uint8",
+ },
+ {
+ internalType: "uint8",
+ name: "protocol",
+ type: "uint8",
+ },
+ ],
+ internalType: "struct AxonInfo",
+ name: "",
+ type: "tuple",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getColdkey",
+ outputs: [
+ {
+ internalType: "bytes32",
+ name: "",
+ type: "bytes32",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getConsensus",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getDividends",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getEmission",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getHotkey",
+ outputs: [
+ {
+ internalType: "bytes32",
+ name: "",
+ type: "bytes32",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getIncentive",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getIsActive",
+ outputs: [
+ {
+ internalType: "bool",
+ name: "",
+ type: "bool",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getLastUpdate",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getRank",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getStake",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getTrust",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getUidCount",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getValidatorStatus",
+ outputs: [
+ {
+ internalType: "bool",
+ name: "",
+ type: "bool",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "uid",
+ type: "uint16",
+ },
+ ],
+ name: "getVtrust",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+];
\ No newline at end of file
diff --git a/evm-tests/src/contracts/neuron.ts b/evm-tests/src/contracts/neuron.ts
new file mode 100644
index 0000000000..4a8fb47e4c
--- /dev/null
+++ b/evm-tests/src/contracts/neuron.ts
@@ -0,0 +1,235 @@
+export const INEURON_ADDRESS = "0x0000000000000000000000000000000000000804";
+
+export const INeuronABI = [
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "bytes32",
+ name: "commitHash",
+ type: "bytes32",
+ },
+ ],
+ name: "commitWeights",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16[]",
+ name: "uids",
+ type: "uint16[]",
+ },
+ {
+ internalType: "uint16[]",
+ name: "values",
+ type: "uint16[]",
+ },
+ {
+ internalType: "uint16[]",
+ name: "salt",
+ type: "uint16[]",
+ },
+ {
+ internalType: "uint64",
+ name: "versionKey",
+ type: "uint64",
+ },
+ ],
+ name: "revealWeights",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16[]",
+ name: "dests",
+ type: "uint16[]",
+ },
+ {
+ internalType: "uint16[]",
+ name: "weights",
+ type: "uint16[]",
+ },
+ {
+ internalType: "uint64",
+ name: "versionKey",
+ type: "uint64",
+ },
+ ],
+ name: "setWeights",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint32",
+ name: "version",
+ type: "uint32",
+ },
+ {
+ internalType: "uint128",
+ name: "ip",
+ type: "uint128",
+ },
+ {
+ internalType: "uint16",
+ name: "port",
+ type: "uint16",
+ },
+ {
+ internalType: "uint8",
+ name: "ipType",
+ type: "uint8",
+ },
+ {
+ internalType: "uint8",
+ name: "protocol",
+ type: "uint8",
+ },
+ {
+ internalType: "uint8",
+ name: "placeholder1",
+ type: "uint8",
+ },
+ {
+ internalType: "uint8",
+ name: "placeholder2",
+ type: "uint8",
+ },
+ ],
+ name: "serveAxon",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint32",
+ name: "version",
+ type: "uint32",
+ },
+ {
+ internalType: "uint128",
+ name: "ip",
+ type: "uint128",
+ },
+ {
+ internalType: "uint16",
+ name: "port",
+ type: "uint16",
+ },
+ {
+ internalType: "uint8",
+ name: "ipType",
+ type: "uint8",
+ },
+ {
+ internalType: "uint8",
+ name: "protocol",
+ type: "uint8",
+ },
+ {
+ internalType: "uint8",
+ name: "placeholder1",
+ type: "uint8",
+ },
+ {
+ internalType: "uint8",
+ name: "placeholder2",
+ type: "uint8",
+ },
+ {
+ internalType: "bytes",
+ name: "certificate",
+ type: "bytes",
+ },
+ ],
+ name: "serveAxonTls",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint32",
+ name: "version",
+ type: "uint32",
+ },
+ {
+ internalType: "uint128",
+ name: "ip",
+ type: "uint128",
+ },
+ {
+ internalType: "uint16",
+ name: "port",
+ type: "uint16",
+ },
+ {
+ internalType: "uint8",
+ name: "ipType",
+ type: "uint8",
+ },
+ ],
+ name: "servePrometheus",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "bytes32",
+ name: "hotkey",
+ type: "bytes32",
+ },
+ ],
+ name: "burnedRegister",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+];
\ No newline at end of file
diff --git a/evm-tests/src/contracts/staking.ts b/evm-tests/src/contracts/staking.ts
new file mode 100644
index 0000000000..9a30d307ba
--- /dev/null
+++ b/evm-tests/src/contracts/staking.ts
@@ -0,0 +1,243 @@
+export const ISTAKING_ADDRESS = "0x0000000000000000000000000000000000000801";
+export const ISTAKING_V2_ADDRESS = "0x0000000000000000000000000000000000000805";
+
+export const IStakingABI = [
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "delegate",
+ type: "bytes32",
+ },
+ ],
+ name: "addProxy",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "hotkey",
+ type: "bytes32",
+ },
+ {
+ internalType: "uint256",
+ name: "netuid",
+ type: "uint256",
+ },
+ ],
+ name: "addStake",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "delegate",
+ type: "bytes32",
+ },
+ ],
+ name: "removeProxy",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "hotkey",
+ type: "bytes32",
+ },
+ {
+ internalType: "bytes32",
+ name: "coldkey",
+ type: "bytes32",
+ },
+ {
+ internalType: "uint256",
+ name: "netuid",
+ type: "uint256",
+ },
+ ],
+ name: "getStake",
+ outputs: [
+ {
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "hotkey",
+ type: "bytes32",
+ },
+ {
+ internalType: "uint256",
+ name: "amount",
+ type: "uint256",
+ },
+ {
+ internalType: "uint256",
+ name: "netuid",
+ type: "uint256",
+ },
+ ],
+ name: "removeStake",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
+ },
+];
+
+export const IStakingV2ABI = [
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "delegate",
+ "type": "bytes32"
+ }
+ ],
+ "name": "addProxy",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "hotkey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "netuid",
+ "type": "uint256"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "hotkey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "coldkey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "netuid",
+ "type": "uint256"
+ }
+ ],
+ "name": "getStake",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "coldkey",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTotalColdkeyStake",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "hotkey",
+ "type": "bytes32"
+ }
+ ],
+ "name": "getTotalHotkeyStake",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "delegate",
+ "type": "bytes32"
+ }
+ ],
+ "name": "removeProxy",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "hotkey",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "netuid",
+ "type": "uint256"
+ }
+ ],
+ "name": "removeStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+];
\ No newline at end of file
diff --git a/evm-tests/src/contracts/subnet.ts b/evm-tests/src/contracts/subnet.ts
new file mode 100644
index 0000000000..9b6fe00596
--- /dev/null
+++ b/evm-tests/src/contracts/subnet.ts
@@ -0,0 +1,889 @@
+export const ISUBNET_ADDRESS = "0x0000000000000000000000000000000000000803";
+
+export const ISubnetABI = [
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getAdjustmentAlpha",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getAlphaValues",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getBondsMovingAverage",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getCommitRevealWeightsEnabled",
+ outputs: [
+ {
+ internalType: "bool",
+ name: "",
+ type: "bool",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getDifficulty",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ name: "getImmunityPeriod",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ name: "getKappa",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getMaxBurn",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getMaxDifficulty",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getMaxWeightLimit",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getMinAllowedWeights",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getMinBurn",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getMinDifficulty",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getNetworkRegistrationAllowed",
+ outputs: [
+ {
+ internalType: "bool",
+ name: "",
+ type: "bool",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ name: "getRho",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getServingRateLimit",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getWeightsSetRateLimit",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getWeightsVersionKey",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "activityCutoff",
+ type: "uint16",
+ },
+ ],
+ name: "setActivityCutoff",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getActivityCutoff",
+ outputs: [
+ {
+ internalType: "uint16",
+ name: "",
+ type: "uint16",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "adjustmentAlpha",
+ type: "uint64",
+ },
+ ],
+ name: "setAdjustmentAlpha",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "alphaLow",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "alphaHigh",
+ type: "uint16",
+ },
+ ],
+ name: "setAlphaValues",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "bondsMovingAverage",
+ type: "uint64",
+ },
+ ],
+ name: "setBondsMovingAverage",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "bool",
+ name: "commitRevealWeightsEnabled",
+ type: "bool",
+ },
+ ],
+ name: "setCommitRevealWeightsEnabled",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getCommitRevealWeightsInterval",
+ outputs: [
+ {
+ internalType: "uint64",
+ name: "",
+ type: "uint64",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "commitRevealWeightsInterval",
+ type: "uint64",
+ },
+ ],
+ name: "setCommitRevealWeightsInterval",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "difficulty",
+ type: "uint64",
+ },
+ ],
+ name: "setDifficulty",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "immunityPeriod",
+ type: "uint16",
+ },
+ ],
+ name: "setImmunityPeriod",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "kappa",
+ type: "uint16",
+ },
+ ],
+ name: "setKappa",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getLiquidAlphaEnabled",
+ outputs: [
+ {
+ internalType: "bool",
+ name: "",
+ type: "bool",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "bool",
+ name: "liquidAlphaEnabled",
+ type: "bool",
+ },
+ ],
+ name: "setLiquidAlphaEnabled",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "maxBurn",
+ type: "uint64",
+ },
+ ],
+ name: "setMaxBurn",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "maxDifficulty",
+ type: "uint64",
+ },
+ ],
+ name: "setMaxDifficulty",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "maxWeightLimit",
+ type: "uint16",
+ },
+ ],
+ name: "setMaxWeightLimit",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "minAllowedWeights",
+ type: "uint16",
+ },
+ ],
+ name: "setMinAllowedWeights",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "minBurn",
+ type: "uint64",
+ },
+ ],
+ name: "setMinBurn",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "minDifficulty",
+ type: "uint64",
+ },
+ ],
+ name: "setMinDifficulty",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ ],
+ name: "getNetworkPowRegistrationAllowed",
+ outputs: [
+ {
+ internalType: "bool",
+ name: "",
+ type: "bool",
+ },
+ ],
+ stateMutability: "view",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "bool",
+ name: "networkPowRegistrationAllowed",
+ type: "bool",
+ },
+ ],
+ name: "setNetworkPowRegistrationAllowed",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "bool",
+ name: "networkRegistrationAllowed",
+ type: "bool",
+ },
+ ],
+ name: "setNetworkRegistrationAllowed",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint16",
+ name: "rho",
+ type: "uint16",
+ },
+ ],
+ name: "setRho",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "servingRateLimit",
+ type: "uint64",
+ },
+ ],
+ name: "setServingRateLimit",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "weightsSetRateLimit",
+ type: "uint64",
+ },
+ ],
+ name: "setWeightsSetRateLimit",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "uint16",
+ name: "netuid",
+ type: "uint16",
+ },
+ {
+ internalType: "uint64",
+ name: "weightsVersionKey",
+ type: "uint64",
+ },
+ ],
+ name: "setWeightsVersionKey",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "hotkey",
+ type: "bytes32",
+ },
+ ],
+ name: "registerNetwork",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
+ },
+ {
+ inputs: [
+ {
+ internalType: "bytes32",
+ name: "hotkey",
+ type: "bytes32"
+ },
+ {
+ internalType: "string",
+ name: "subnetName",
+ type: "string"
+ },
+ {
+ internalType: "string",
+ name: "githubRepo",
+ type: "string"
+ },
+ {
+ internalType: "string",
+ name: "subnetContact",
+ type: "string"
+ },
+ {
+ internalType: "string",
+ name: "subnetUrl",
+ type: "string"
+ },
+ {
+ internalType: "string",
+ name: "discord",
+ type: "string"
+ },
+ {
+ internalType: "string",
+ name: "description",
+ type: "string"
+ },
+ {
+ internalType: "string",
+ name: "additional",
+ type: "string"
+ }
+ ],
+ name: "registerNetwork",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function"
+ },
+];
\ No newline at end of file
diff --git a/evm-tests/src/contracts/withdraw.sol b/evm-tests/src/contracts/withdraw.sol
new file mode 100644
index 0000000000..3945661e09
--- /dev/null
+++ b/evm-tests/src/contracts/withdraw.sol
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-3.0
+
+pragma solidity >=0.7.0 <0.9.0;
+
+contract Withdraw {
+ constructor() {}
+
+ function withdraw(uint256 value) public payable {
+ payable(msg.sender).transfer(value);
+ }
+
+ receive() external payable {}
+}
diff --git a/evm-tests/src/contracts/withdraw.ts b/evm-tests/src/contracts/withdraw.ts
new file mode 100644
index 0000000000..46fe66bf24
--- /dev/null
+++ b/evm-tests/src/contracts/withdraw.ts
@@ -0,0 +1,31 @@
+export const WITHDRAW_CONTRACT_ABI = [
+ {
+ "inputs": [],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdraw",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+];
+
+// "compiler": {
+// "version": "0.8.26+commit.8a97fa7a"
+// },
+
+export const WITHDRAW_CONTRACT_BYTECODE = "6080604052348015600e575f80fd5b506101148061001c5f395ff3fe608060405260043610601e575f3560e01c80632e1a7d4d146028576024565b36602457005b5f80fd5b603e6004803603810190603a919060b8565b6040565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f193505050501580156082573d5f803e3d5ffd5b5050565b5f80fd5b5f819050919050565b609a81608a565b811460a3575f80fd5b50565b5f8135905060b2816093565b92915050565b5f6020828403121560ca5760c96086565b5b5f60d58482850160a6565b9150509291505056fea2646970667358221220f43400858bfe4fcc0bf3c1e2e06d3a9e6ced86454a00bd7e4866b3d4d64e46bb64736f6c634300081a0033"
+
diff --git a/evm-tests/src/eth.ts b/evm-tests/src/eth.ts
new file mode 100644
index 0000000000..ea3ebb9976
--- /dev/null
+++ b/evm-tests/src/eth.ts
@@ -0,0 +1,17 @@
+
+import { ethers, Provider, TransactionRequest, Wallet } from "ethers";
+export async function estimateTransactionCost(provider: Provider, tx: TransactionRequest) {
+ const feeData = await provider.getFeeData();
+ const estimatedGas = BigInt(await provider.estimateGas(tx));
+ const gasPrice = feeData.gasPrice || feeData.maxFeePerGas;
+ if (gasPrice === null)
+ return estimatedGas
+ else
+ return estimatedGas * BigInt(gasPrice);
+}
+
+export function getContract(contractAddress: string, abi: {}[], wallet: Wallet) {
+ const contract = new ethers.Contract(contractAddress, abi, wallet);
+ return contract
+
+}
\ No newline at end of file
diff --git a/evm-tests/src/substrate.ts b/evm-tests/src/substrate.ts
new file mode 100644
index 0000000000..ddfdfb626d
--- /dev/null
+++ b/evm-tests/src/substrate.ts
@@ -0,0 +1,274 @@
+import * as assert from "assert";
+import { devnet, MultiAddress } from '@polkadot-api/descriptors';
+import { createClient, TypedApi, Transaction, PolkadotSigner, Binary } from 'polkadot-api';
+import { getWsProvider } from 'polkadot-api/ws-provider/web';
+import { sr25519CreateDerive } from "@polkadot-labs/hdkd"
+import { convertPublicKeyToSs58 } from "../src/address-utils"
+import { DEV_PHRASE, entropyToMiniSecret, mnemonicToEntropy, KeyPair } from "@polkadot-labs/hdkd-helpers"
+import { getPolkadotSigner } from "polkadot-api/signer"
+import { randomBytes } from 'crypto';
+import { Keyring } from '@polkadot/keyring';
+import { SS58_PREFIX, TX_TIMEOUT } from "./config";
+
+let api: TypedApi | undefined = undefined
+
+// define url string as type to extend in the future
+// export type ClientUrlType = 'ws://localhost:9944' | 'wss://test.finney.opentensor.ai:443' | 'wss://dev.chain.opentensor.ai:443' | 'wss://archive.chain.opentensor.ai';
+export type ClientUrlType = 'ws://localhost:9944'
+
+export async function getClient(url: ClientUrlType) {
+ const provider = getWsProvider(url);
+ const client = createClient(provider);
+ return client
+}
+
+export async function getDevnetApi() {
+ if (api === undefined) {
+ let client = await getClient('ws://localhost:9944')
+ api = client.getTypedApi(devnet)
+ }
+ return api
+}
+
+export function getAlice() {
+ const entropy = mnemonicToEntropy(DEV_PHRASE)
+ const miniSecret = entropyToMiniSecret(entropy)
+ const derive = sr25519CreateDerive(miniSecret)
+ const hdkdKeyPair = derive("//Alice")
+
+ return hdkdKeyPair
+}
+
+export function getAliceSigner() {
+ const alice = getAlice()
+ const polkadotSigner = getPolkadotSigner(
+ alice.publicKey,
+ "Sr25519",
+ alice.sign,
+ )
+
+ return polkadotSigner
+}
+
+export function getRandomSubstrateSigner() {
+ const keypair = getRandomSubstrateKeypair();
+ return getSignerFromKeypair(keypair)
+}
+
+export function getSignerFromKeypair(keypair: KeyPair) {
+ const polkadotSigner = getPolkadotSigner(
+ keypair.publicKey,
+ "Sr25519",
+ keypair.sign,
+ )
+ return polkadotSigner
+}
+
+export function getRandomSubstrateKeypair() {
+ const seed = randomBytes(32);
+ const miniSecret = entropyToMiniSecret(seed)
+ const derive = sr25519CreateDerive(miniSecret)
+ const hdkdKeyPair = derive("")
+
+ return hdkdKeyPair
+}
+
+export async function getBalance(api: TypedApi) {
+ const value = await api.query.Balances.Account.getValue("")
+ return value
+}
+
+export async function getNonce(api: TypedApi, ss58Address: string): Promise {
+ const value = await api.query.System.Account.getValue(ss58Address);
+ return value.nonce
+}
+
+export async function getNonceChangePromise(api: TypedApi, ss58Address: string) {
+ // api.query.System.Account.getValue()
+ const initValue = await api.query.System.Account.getValue(ss58Address);
+ return new Promise((resolve, reject) => {
+ const subscription = api.query.System.Account.watchValue(ss58Address).subscribe({
+ next(value) {
+ if (value.nonce > initValue.nonce) {
+ subscription.unsubscribe();
+ // Resolve the promise when the transaction is finalized
+ resolve();
+ }
+ },
+
+ error(err: Error) {
+ console.error("Transaction failed:", err);
+ subscription.unsubscribe();
+ // Reject the promise in case of an error
+ reject(err);
+ },
+ complete() {
+ console.log("Subscription complete");
+ }
+ })
+
+ setTimeout(() => {
+ subscription.unsubscribe();
+ console.log('unsubscribed!');
+ resolve()
+ }, TX_TIMEOUT);
+
+ })
+}
+
+export function convertPublicKeyToMultiAddress(publicKey: Uint8Array, ss58Format: number = SS58_PREFIX): MultiAddress {
+ // Create a keyring instance
+ const keyring = new Keyring({ type: 'sr25519', ss58Format });
+
+ // Add the public key to the keyring
+ const address = keyring.encodeAddress(publicKey);
+
+ return MultiAddress.Id(address);
+}
+
+
+export async function waitForTransactionCompletion(api: TypedApi, tx: Transaction<{}, string, string, void>, signer: PolkadotSigner,) {
+ const transactionPromise = await getTransactionWatchPromise(tx, signer)
+ return transactionPromise
+
+ // If we can't always get the finalized event, then add nonce subscribe as other evidence for tx is finalized.
+ // Don't need it based on current testing.
+ // const ss58Address = convertPublicKeyToSs58(signer.publicKey)
+ // const noncePromise = await getNonceChangePromise(api, ss58Address)
+
+ // return new Promise((resolve, reject) => {
+ // Promise.race([transactionPromise, noncePromise])
+ // .then(resolve)
+ // .catch(reject);
+ // })
+}
+
+export async function getTransactionWatchPromise(tx: Transaction<{}, string, string, void>, signer: PolkadotSigner,) {
+ return new Promise((resolve, reject) => {
+ // store the txHash, then use it in timeout. easier to know which tx is not finalized in time
+ let txHash = ""
+ const subscription = tx.signSubmitAndWatch(signer).subscribe({
+ next(value) {
+ console.log("Event:", value);
+ txHash = value.txHash
+
+ // TODO investigate why finalized not for each extrinsic
+ if (value.type === "finalized") {
+ console.log("Transaction is finalized in block:", value.txHash);
+ subscription.unsubscribe();
+ // Resolve the promise when the transaction is finalized
+ resolve();
+
+ }
+ },
+ error(err) {
+ console.error("Transaction failed:", err);
+ subscription.unsubscribe();
+ // Reject the promise in case of an error
+ reject(err);
+
+ },
+ complete() {
+ console.log("Subscription complete");
+ }
+ });
+
+ setTimeout(() => {
+ subscription.unsubscribe();
+ console.log('unsubscribed because of timeout for tx {}', txHash);
+ reject()
+ }, TX_TIMEOUT);
+ });
+}
+
+export async function waitForFinalizedBlock(api: TypedApi) {
+ const currentBlockNumber = await api.query.System.Number.getValue()
+ return new Promise((resolve, reject) => {
+
+ const subscription = api.query.System.Number.watchValue().subscribe({
+ // TODO check why the block number event just get once
+ next(value: number) {
+ console.log("Event block number is :", value);
+
+ if (value > currentBlockNumber + 6) {
+ console.log("Transaction is finalized in block:", value);
+ subscription.unsubscribe();
+
+ resolve();
+
+ }
+
+ },
+ error(err: Error) {
+ console.error("Transaction failed:", err);
+ subscription.unsubscribe();
+ // Reject the promise in case of an error
+ reject(err);
+
+ },
+ complete() {
+ console.log("Subscription complete");
+ }
+ });
+
+ setTimeout(() => {
+ subscription.unsubscribe();
+ console.log('unsubscribed!');
+ resolve()
+ }, 2000);
+ });
+}
+
+// second solution to wait for transaction finalization. pass the raw data to avoid the complex transaction type definition
+export async function waitForTransactionCompletion2(api: TypedApi, raw: Binary, signer: PolkadotSigner,) {
+ const tx = await api.txFromCallData(raw);
+ return new Promise((resolve, reject) => {
+ const subscription = tx.signSubmitAndWatch(signer).subscribe({
+ next(value) {
+ console.log("Event:", value);
+
+ if (value.type === "txBestBlocksState") {
+ console.log("Transaction is finalized in block:", value.txHash);
+ subscription.unsubscribe();
+ // Resolve the promise when the transaction is finalized
+ resolve();
+
+ }
+ },
+ error(err: Error) {
+ console.error("Transaction failed:", err);
+ subscription.unsubscribe();
+ // Reject the promise in case of an error
+ reject(err);
+
+ },
+ complete() {
+ console.log("Subscription complete");
+ }
+ });
+ });
+}
+
+export async function waitForNonceChange(api: TypedApi, ss58Address: string) {
+ const initNonce = await getNonce(api, ss58Address)
+ while (true) {
+ const currentNonce = await getNonce(api, ss58Address)
+ if (currentNonce > initNonce) {
+ break
+ }
+
+ await new Promise(resolve => setTimeout(resolve, 200));
+ }
+}
+
+
+// other approach to convert public key to ss58
+// export function convertPublicKeyToSs58(publicKey: Uint8Array, ss58Format: number = 42): string {
+// // Create a keyring instance
+// const keyring = new Keyring({ type: 'sr25519', ss58Format });
+
+// // Add the public key to the keyring
+// const address = keyring.encodeAddress(publicKey);
+
+// return address
+// }
\ No newline at end of file
diff --git a/evm-tests/src/subtensor.ts b/evm-tests/src/subtensor.ts
new file mode 100644
index 0000000000..48dc5c83c7
--- /dev/null
+++ b/evm-tests/src/subtensor.ts
@@ -0,0 +1,345 @@
+import * as assert from "assert";
+import { devnet, MultiAddress } from '@polkadot-api/descriptors';
+import { TypedApi, TxCallData } from 'polkadot-api';
+import { KeyPair } from "@polkadot-labs/hdkd-helpers"
+import { getAliceSigner, waitForTransactionCompletion, getSignerFromKeypair } from './substrate'
+import { convertH160ToSS58, convertPublicKeyToSs58 } from './address-utils'
+import { tao } from './balance-math'
+
+// create a new subnet and return netuid
+export async function addNewSubnetwork(api: TypedApi, hotkey: KeyPair, coldkey: KeyPair) {
+ const alice = getAliceSigner()
+ const totalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue()
+
+ const rateLimit = await api.query.SubtensorModule.NetworkRateLimit.getValue()
+ if (rateLimit !== BigInt(0)) {
+ const internalCall = api.tx.AdminUtils.sudo_set_network_rate_limit({ rate_limit: BigInt(0) })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ }
+
+ const signer = getSignerFromKeypair(coldkey)
+ const registerNetworkTx = api.tx.SubtensorModule.register_network({ hotkey: convertPublicKeyToSs58(hotkey.publicKey) })
+ await waitForTransactionCompletion(api, registerNetworkTx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+ assert.equal(totalNetworks + 1, await api.query.SubtensorModule.TotalNetworks.getValue())
+ return totalNetworks
+}
+
+// force set balance for a ss58 address
+export async function forceSetBalanceToSs58Address(api: TypedApi, ss58Address: string) {
+ const alice = getAliceSigner()
+ const balance = tao(1e8)
+ const internalCall = api.tx.Balances.force_set_balance({ who: MultiAddress.Id(ss58Address), new_free: balance })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+ const balanceOnChain = (await api.query.System.Account.getValue(ss58Address)).data.free
+ // check the balance except for sudo account becasue of tx fee
+ if (ss58Address !== convertPublicKeyToSs58(alice.publicKey)) {
+ assert.equal(balance, balanceOnChain)
+ }
+}
+
+// set balance for an eth address
+export async function forceSetBalanceToEthAddress(api: TypedApi, ethAddress: string) {
+ const ss58Address = convertH160ToSS58(ethAddress)
+ await forceSetBalanceToSs58Address(api, ss58Address)
+}
+
+export async function setCommitRevealWeightsEnabled(api: TypedApi, netuid: number, enabled: boolean) {
+ const value = await api.query.SubtensorModule.CommitRevealWeightsEnabled.getValue(netuid)
+ if (value === enabled) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+ const internalCall = api.tx.AdminUtils.sudo_set_commit_reveal_weights_enabled({ netuid: netuid, enabled: enabled })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(enabled, await api.query.SubtensorModule.CommitRevealWeightsEnabled.getValue(netuid))
+}
+
+export async function setWeightsSetRateLimit(api: TypedApi, netuid: number, rateLimit: bigint) {
+ const value = await api.query.SubtensorModule.WeightsSetRateLimit.getValue(netuid)
+ if (value === rateLimit) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+ const internalCall = api.tx.AdminUtils.sudo_set_weights_set_rate_limit({ netuid: netuid, weights_set_rate_limit: rateLimit })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(rateLimit, await api.query.SubtensorModule.WeightsSetRateLimit.getValue(netuid))
+}
+
+// tempo is u16 in rust, but we just number in js. so value should be less than u16::Max
+export async function setTempo(api: TypedApi, netuid: number, tempo: number) {
+ const value = await api.query.SubtensorModule.Tempo.getValue(netuid)
+ console.log("init avlue is ", value)
+ if (value === tempo) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+ const internalCall = api.tx.AdminUtils.sudo_set_tempo({ netuid: netuid, tempo: tempo })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(tempo, await api.query.SubtensorModule.Tempo.getValue(netuid))
+}
+
+export async function setCommitRevealWeightsInterval(api: TypedApi, netuid: number, interval: bigint) {
+ const value = await api.query.SubtensorModule.RevealPeriodEpochs.getValue(netuid)
+ if (value === interval) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+ const internalCall = api.tx.AdminUtils.sudo_set_commit_reveal_weights_interval({ netuid: netuid, interval: interval })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(interval, await api.query.SubtensorModule.RevealPeriodEpochs.getValue(netuid))
+}
+
+
+export async function forceSetChainID(api: TypedApi, chainId: bigint) {
+ const value = await api.query.EVMChainId.ChainId.getValue()
+ if (value === chainId) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+ const internalCall = api.tx.AdminUtils.sudo_set_evm_chain_id({ chain_id: chainId })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(chainId, await api.query.EVMChainId.ChainId.getValue())
+}
+
+export async function disableWhiteListCheck(api: TypedApi, disabled: boolean) {
+ const value = await api.query.EVM.DisableWhitelistCheck.getValue()
+ if (value === disabled) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+ const internalCall = api.tx.EVM.disable_whitelist({ disabled: disabled })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(disabled, await api.query.EVM.DisableWhitelistCheck.getValue())
+}
+
+export async function burnedRegister(api: TypedApi, netuid: number, ss58Address: string, keypair: KeyPair) {
+ const uids = await api.query.SubtensorModule.SubnetworkN.getValue(netuid)
+ const signer = getSignerFromKeypair(keypair)
+ const tx = api.tx.SubtensorModule.burned_register({ hotkey: ss58Address, netuid: netuid })
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(uids + 1, await api.query.SubtensorModule.SubnetworkN.getValue(netuid))
+}
+
+
+export async function sendProxyCall(api: TypedApi, calldata: TxCallData, ss58Address: string, keypair: KeyPair) {
+ const signer = getSignerFromKeypair(keypair)
+ const tx = api.tx.Proxy.proxy({
+ call: calldata,
+ real: MultiAddress.Id(ss58Address),
+ force_proxy_type: undefined
+ });
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+}
+
+
+export async function setTxRateLimit(api: TypedApi, txRateLimit: bigint) {
+ const value = await api.query.SubtensorModule.TxRateLimit.getValue()
+ if (value === txRateLimit) {
+ return;
+ }
+ const alice = getAliceSigner()
+
+ const internalCall = api.tx.AdminUtils.sudo_set_tx_rate_limit({ tx_rate_limit: txRateLimit })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(txRateLimit, await api.query.SubtensorModule.TxRateLimit.getValue())
+}
+
+export async function setMaxAllowedValidators(api: TypedApi, netuid: number, maxAllowedValidators: number) {
+ const value = await api.query.SubtensorModule.MaxAllowedValidators.getValue(netuid)
+ if (value === maxAllowedValidators) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+
+ const internalCall = api.tx.AdminUtils.sudo_set_max_allowed_validators({
+ netuid: netuid,
+ max_allowed_validators: maxAllowedValidators
+ })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(maxAllowedValidators, await api.query.SubtensorModule.MaxAllowedValidators.getValue(netuid))
+}
+
+export async function setSubnetOwnerCut(api: TypedApi, subnetOwnerCut: number) {
+ const value = await api.query.SubtensorModule.SubnetOwnerCut.getValue()
+ if (value === subnetOwnerCut) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+
+ const internalCall = api.tx.AdminUtils.sudo_set_subnet_owner_cut({
+ subnet_owner_cut: subnetOwnerCut
+ })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(subnetOwnerCut, await api.query.SubtensorModule.SubnetOwnerCut.getValue())
+}
+
+export async function setActivityCutoff(api: TypedApi, netuid: number, activityCutoff: number) {
+ const value = await api.query.SubtensorModule.ActivityCutoff.getValue(netuid)
+ if (value === activityCutoff) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+
+ const internalCall = api.tx.AdminUtils.sudo_set_activity_cutoff({
+ netuid: netuid,
+ activity_cutoff: activityCutoff
+ })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(activityCutoff, await api.query.SubtensorModule.ActivityCutoff.getValue(netuid))
+}
+
+export async function setMaxAllowedUids(api: TypedApi, netuid: number, maxAllowedUids: number) {
+ const value = await api.query.SubtensorModule.MaxAllowedUids.getValue(netuid)
+ if (value === maxAllowedUids) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+
+ const internalCall = api.tx.AdminUtils.sudo_set_max_allowed_uids({
+ netuid: netuid,
+ max_allowed_uids: maxAllowedUids
+ })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(maxAllowedUids, await api.query.SubtensorModule.MaxAllowedUids.getValue(netuid))
+}
+
+export async function setMinDelegateTake(api: TypedApi, minDelegateTake: number) {
+ const value = await api.query.SubtensorModule.MinDelegateTake.getValue()
+ if (value === minDelegateTake) {
+ return;
+ }
+
+ const alice = getAliceSigner()
+
+ const internalCall = api.tx.AdminUtils.sudo_set_min_delegate_take({
+ take: minDelegateTake
+ })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ assert.equal(minDelegateTake, await api.query.SubtensorModule.MinDelegateTake.getValue())
+}
+
+export async function becomeDelegate(api: TypedApi, ss58Address: string, keypair: KeyPair) {
+ const singer = getSignerFromKeypair(keypair)
+
+ const tx = api.tx.SubtensorModule.become_delegate({
+ hotkey: ss58Address
+ })
+ await waitForTransactionCompletion(api, tx, singer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+}
+
+export async function addStake(api: TypedApi, netuid: number, ss58Address: string, amount_staked: bigint, keypair: KeyPair) {
+ const singer = getSignerFromKeypair(keypair)
+ let tx = api.tx.SubtensorModule.add_stake({
+ netuid: netuid,
+ hotkey: ss58Address,
+ amount_staked: amount_staked
+ })
+
+ await waitForTransactionCompletion(api, tx, singer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+}
+
+export async function setWeight(api: TypedApi, netuid: number, dests: number[], weights: number[], version_key: bigint, keypair: KeyPair) {
+ const singer = getSignerFromKeypair(keypair)
+ let tx = api.tx.SubtensorModule.set_weights({
+ netuid: netuid,
+ dests: dests,
+ weights: weights,
+ version_key: version_key
+ })
+
+ await waitForTransactionCompletion(api, tx, singer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+}
+
+export async function rootRegister(api: TypedApi, ss58Address: string, keypair: KeyPair) {
+ const singer = getSignerFromKeypair(keypair)
+ let tx = api.tx.SubtensorModule.root_register({
+ hotkey: ss58Address
+ })
+
+ await waitForTransactionCompletion(api, tx, singer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+}
\ No newline at end of file
diff --git a/evm-tests/src/utils.ts b/evm-tests/src/utils.ts
new file mode 100644
index 0000000000..36e922b49e
--- /dev/null
+++ b/evm-tests/src/utils.ts
@@ -0,0 +1,55 @@
+import { defineChain, http, publicActions, createPublicClient } from "viem"
+import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts'
+import { ethers } from "ethers"
+import { ETH_LOCAL_URL } from "./config"
+
+export type ClientUrlType = 'http://localhost:9944';
+
+export const chain = (id: number, url: string) => defineChain({
+ id: id,
+ name: 'bittensor',
+ network: 'bittensor',
+ nativeCurrency: {
+ name: 'tao',
+ symbol: 'TAO',
+ decimals: 9,
+ },
+ rpcUrls: {
+ default: {
+ http: [url],
+ },
+ },
+ testnet: true,
+})
+
+
+export async function getPublicClient(url: ClientUrlType) {
+ const wallet = createPublicClient({
+ chain: chain(42, url),
+ transport: http(),
+
+ })
+
+ return wallet.extend(publicActions)
+}
+
+/**
+ * Generates a random Ethereum wallet
+ * @returns wallet keyring
+ */
+export function generateRandomEthWallet() {
+ let privateKey = generatePrivateKey().toString();
+ privateKey = privateKey.replace('0x', '');
+
+ const account = privateKeyToAccount(`0x${privateKey}`)
+ return account
+}
+
+
+export function generateRandomEthersWallet() {
+ const account = ethers.Wallet.createRandom();
+ const provider = new ethers.JsonRpcProvider(ETH_LOCAL_URL);
+
+ const wallet = new ethers.Wallet(account.privateKey, provider);
+ return wallet;
+}
\ No newline at end of file
diff --git a/evm-tests/test/ed25519.precompile.verify.test.ts b/evm-tests/test/ed25519.precompile.verify.test.ts
new file mode 100644
index 0000000000..fcd79ec9d7
--- /dev/null
+++ b/evm-tests/test/ed25519.precompile.verify.test.ts
@@ -0,0 +1,122 @@
+import { IED25519VERIFY_ADDRESS, IEd25519VerifyABI, ETH_LOCAL_URL } from '../src/config'
+import { getPublicClient } from "../src/utils";
+import { toHex, toBytes, keccak256, PublicClient } from 'viem'
+import { Keyring } from "@polkadot/keyring";
+import * as assert from "assert";
+
+describe("Verfication of ed25519 signature", () => {
+ // init eth part
+ let ethClient: PublicClient;
+
+ before(async () => {
+ ethClient = await getPublicClient(ETH_LOCAL_URL);
+ });
+
+ it("Verification of ed25519 works", async () => {
+ const keyring = new Keyring({ type: "ed25519" });
+ const alice = keyring.addFromUri("//Alice");
+
+ // Use this example: https://github.com/gztensor/evm-demo/blob/main/docs/ed25519verify-precompile.md
+ // const keyring = new Keyring({ type: "ed25519" });
+ // const myAccount = keyring.addFromUri("//Alice");
+
+ //////////////////////////////////////////////////////////////////////
+ // Generate a signature
+
+ // Your message to sign
+ const message = "Sign this message";
+ const messageU8a = new TextEncoder().encode(message);
+ const messageHex = toHex(messageU8a); // Convert message to hex string
+ const messageHash = keccak256(messageHex); // Hash the message to fit into bytes32
+ console.log(`messageHash = ${messageHash}`);
+ const hashedMessageBytes = toBytes(messageHash);
+ console.log(`hashedMessageBytes = ${hashedMessageBytes}`);
+
+ // Sign the message
+ const signature = await alice.sign(hashedMessageBytes);
+ console.log(`Signature: ${toHex(signature)}`);
+
+ // Verify the signature locally
+ const isValid = alice.verify(
+ hashedMessageBytes,
+ signature,
+ alice.publicKey
+ );
+ console.log(`Is the signature valid? ${isValid}`);
+
+ //////////////////////////////////////////////////////////////////////
+ // Verify the signature using the precompile contract
+
+ const publicKeyBytes = toHex(alice.publicKey);
+ console.log(`publicKeyBytes = ${publicKeyBytes}`);
+
+ // Split signture into Commitment (R) and response (s)
+ let r = signature.slice(0, 32); // Commitment, a.k.a. "r" - first 32 bytes
+ let s = signature.slice(32, 64); // Response, a.k.a. "s" - second 32 bytes
+ let rBytes = toHex(r);
+ let sBytes = toHex(s);
+
+ const isPrecompileValid = await ethClient.readContract({
+ address: IED25519VERIFY_ADDRESS,
+ abi: IEd25519VerifyABI,
+ functionName: "verify",
+ args: [messageHash,
+ publicKeyBytes,
+ rBytes,
+ sBytes]
+
+ });
+
+ console.log(
+ `Is the signature valid according to the smart contract? ${isPrecompileValid}`
+ );
+ assert.equal(isPrecompileValid, true)
+
+ //////////////////////////////////////////////////////////////////////
+ // Verify the signature for bad data using the precompile contract
+
+ let brokenHashedMessageBytes = hashedMessageBytes;
+ brokenHashedMessageBytes[0] = (brokenHashedMessageBytes[0] + 1) % 0xff;
+ const brokenMessageHash = toHex(brokenHashedMessageBytes);
+ console.log(`brokenMessageHash = ${brokenMessageHash}`);
+
+ const isPrecompileValidBadData = await ethClient.readContract({
+ address: IED25519VERIFY_ADDRESS,
+ abi: IEd25519VerifyABI,
+ functionName: "verify",
+ args: [brokenMessageHash,
+ publicKeyBytes,
+ rBytes,
+ sBytes]
+
+ });
+
+ console.log(
+ `Is the signature valid according to the smart contract for broken data? ${isPrecompileValidBadData}`
+ );
+ assert.equal(isPrecompileValidBadData, false)
+
+ //////////////////////////////////////////////////////////////////////
+ // Verify the bad signature for good data using the precompile contract
+
+ let brokenR = r;
+ brokenR[0] = (brokenR[0] + 1) % 0xff;
+ rBytes = toHex(r);
+ const isPrecompileValidBadSignature = await ethClient.readContract({
+ address: IED25519VERIFY_ADDRESS,
+ abi: IEd25519VerifyABI,
+ functionName: "verify",
+ args: [messageHash,
+ publicKeyBytes,
+ rBytes,
+ sBytes]
+
+ });
+
+ console.log(
+ `Is the signature valid according to the smart contract for broken signature? ${isPrecompileValidBadSignature}`
+ );
+ assert.equal(isPrecompileValidBadSignature, false)
+
+ });
+});
\ No newline at end of file
diff --git a/evm-tests/test/eth.bridgeToken.deploy.test.ts b/evm-tests/test/eth.bridgeToken.deploy.test.ts
new file mode 100644
index 0000000000..94ebcd1260
--- /dev/null
+++ b/evm-tests/test/eth.bridgeToken.deploy.test.ts
@@ -0,0 +1,69 @@
+import * as assert from "assert";
+import * as chai from "chai";
+
+import { getDevnetApi } from "../src/substrate"
+import { generateRandomEthersWallet, getPublicClient } from "../src/utils";
+import { ETH_LOCAL_URL } from "../src/config";
+import { devnet } from "@polkadot-api/descriptors"
+import { PublicClient } from "viem";
+import { TypedApi } from "polkadot-api";
+import { BRIDGE_TOKEN_CONTRACT_ABI, BRIDGE_TOKEN_CONTRACT_BYTECODE } from "../src/contracts/bridgeToken";
+import { toViemAddress } from "../src/address-utils";
+import { forceSetBalanceToEthAddress, disableWhiteListCheck } from "../src/subtensor";
+import { ethers } from "ethers"
+describe("bridge token contract deployment", () => {
+ // init eth part
+ const wallet = generateRandomEthersWallet();
+ let publicClient: PublicClient;
+
+ // init substrate part
+ let api: TypedApi
+
+ before(async () => {
+ // init variables got from await and async
+ publicClient = await getPublicClient(ETH_LOCAL_URL)
+ api = await getDevnetApi()
+
+ await forceSetBalanceToEthAddress(api, wallet.address)
+ await disableWhiteListCheck(api, true)
+ });
+
+ it("Can deploy bridge token smart contract", async () => {
+ const contractFactory = new ethers.ContractFactory(BRIDGE_TOKEN_CONTRACT_ABI, BRIDGE_TOKEN_CONTRACT_BYTECODE, wallet)
+ const contract = await contractFactory.deploy("name",
+ "symbol", wallet.address)
+ await contract.waitForDeployment()
+ assert.notEqual(contract.target, undefined)
+
+ const contractAddress = contract.target.toString()
+
+ const code = await publicClient.getCode({ address: toViemAddress(contractAddress) })
+ if (code === undefined) {
+ throw new Error("code not available")
+ }
+ assert.ok(code.length > 100)
+ assert.ok(code.includes("0x60806040523480156"))
+ });
+
+ it("Can deploy bridge token contract with gas limit", async () => {
+ const contractFactory = new ethers.ContractFactory(BRIDGE_TOKEN_CONTRACT_ABI, BRIDGE_TOKEN_CONTRACT_BYTECODE, wallet)
+ const successful_gas_limit = "12345678";
+ const contract = await contractFactory.deploy("name",
+ "symbol", wallet.address,
+ {
+ gasLimit: successful_gas_limit,
+ }
+ )
+ await contract.waitForDeployment()
+ assert.notEqual(contract.target, undefined)
+
+ const contractAddress = contract.target.toString()
+
+ const code = await publicClient.getCode({ address: toViemAddress(contractAddress) })
+ if (code === undefined) {
+ throw new Error("code not available")
+ }
+ assert.ok(code.length > 100)
+ assert.ok(code.includes("0x60806040523480156"))
+ });
+});
\ No newline at end of file
diff --git a/evm-tests/test/eth.chain-id.test.ts b/evm-tests/test/eth.chain-id.test.ts
new file mode 100644
index 0000000000..09174c1212
--- /dev/null
+++ b/evm-tests/test/eth.chain-id.test.ts
@@ -0,0 +1,76 @@
+
+import * as assert from "assert";
+import * as chai from "chai";
+
+import { getDevnetApi, waitForTransactionCompletion, getRandomSubstrateKeypair } from "../src/substrate"
+import { generateRandomEthWallet, getPublicClient } from "../src/utils";
+import { convertPublicKeyToSs58 } from "../src/address-utils"
+import { ETH_LOCAL_URL } from "../src/config";
+import { devnet } from "@polkadot-api/descriptors"
+import { getPolkadotSigner } from "polkadot-api/signer";
+import { PublicClient } from "viem";
+import { TypedApi } from "polkadot-api";
+import { forceSetBalanceToSs58Address, forceSetChainID } from "../src/subtensor";
+
+describe("Test the EVM chain ID", () => {
+ // init eth part
+ const wallet = generateRandomEthWallet();
+ let ethClient: PublicClient;
+
+ // init substrate part
+ const keyPair = getRandomSubstrateKeypair();
+ let api: TypedApi;
+
+ // init other variable
+ const initChainId = 42;
+
+ before(async () => {
+ // init variables got from await and async
+ ethClient = await getPublicClient(ETH_LOCAL_URL);
+ api = await getDevnetApi()
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(keyPair.publicKey))
+
+ });
+
+ it("EVM chain id update is ok", async () => {
+ let chainId = await ethClient.getChainId();
+ // init chain id should be 42
+ assert.equal(chainId, initChainId);
+
+ const newChainId = BigInt(100)
+ await forceSetChainID(api, newChainId)
+
+ chainId = await ethClient.getChainId();
+ assert.equal(chainId, newChainId);
+
+ await forceSetChainID(api, BigInt(initChainId))
+
+ chainId = await ethClient.getChainId();
+ // back to original value for other tests. and we can run it repeatedly
+ assert.equal(chainId, initChainId);
+
+ });
+
+ it("EVM chain id is the same, only sudo can change it.", async () => {
+ let chainId = await ethClient.getChainId();
+ // init chain id should be 42
+ assert.equal(chainId, initChainId);
+
+ // invalide signer for set chain ID
+ let signer = getPolkadotSigner(
+ keyPair.publicKey,
+ "Sr25519",
+ keyPair.sign,
+ )
+
+ let tx = api.tx.AdminUtils.sudo_set_evm_chain_id({ chain_id: BigInt(100) })
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+ // extrinsic should be failed and chain ID not updated.
+ chainId = await ethClient.getChainId();
+ assert.equal(chainId, 42);
+
+ });
+});
\ No newline at end of file
diff --git a/evm-tests/test/eth.incremental.deploy.test.ts b/evm-tests/test/eth.incremental.deploy.test.ts
new file mode 100644
index 0000000000..c22187538d
--- /dev/null
+++ b/evm-tests/test/eth.incremental.deploy.test.ts
@@ -0,0 +1,61 @@
+
+
+import * as assert from "assert";
+import * as chai from "chai";
+
+import { getDevnetApi } from "../src/substrate"
+import { generateRandomEthersWallet, getPublicClient } from "../src/utils";
+import { ETH_LOCAL_URL } from "../src/config";
+import { devnet } from "@polkadot-api/descriptors"
+import { PublicClient } from "viem";
+import { TypedApi } from "polkadot-api";
+import { INCREMENTAL_CONTRACT_ABI, INCREMENTAL_CONTRACT_BYTECODE } from "../src/contracts/incremental";
+import { toViemAddress } from "../src/address-utils";
+import { ethers } from "ethers"
+import { disableWhiteListCheck, forceSetBalanceToEthAddress } from "../src/subtensor";
+
+describe("bridge token contract deployment", () => {
+ // init eth part
+ const wallet = generateRandomEthersWallet();
+ let publicClient: PublicClient;
+
+ // init substrate part
+ let api: TypedApi
+
+ before(async () => {
+ publicClient = await getPublicClient(ETH_LOCAL_URL)
+ api = await getDevnetApi()
+
+ await forceSetBalanceToEthAddress(api, wallet.address)
+ await disableWhiteListCheck(api, true)
+ });
+
+ it("Can deploy incremental smart contract", async () => {
+ const contractFactory = new ethers.ContractFactory(INCREMENTAL_CONTRACT_ABI, INCREMENTAL_CONTRACT_BYTECODE, wallet)
+ const contract = await contractFactory.deploy()
+ await contract.waitForDeployment()
+
+ const value = await publicClient.readContract({
+ abi: INCREMENTAL_CONTRACT_ABI,
+ address: toViemAddress(contract.target.toString()),
+ functionName: "retrieve",
+ args: []
+ })
+ assert.equal(value, 0)
+
+ const newValue = 1234
+
+ const deployContract = new ethers.Contract(contract.target.toString(), INCREMENTAL_CONTRACT_ABI, wallet)
+ const storeTx = await deployContract.store(newValue)
+ await storeTx.wait()
+
+ const newValueAfterStore = await publicClient.readContract({
+ abi: INCREMENTAL_CONTRACT_ABI,
+ address: toViemAddress(contract.target.toString()),
+ functionName: "retrieve",
+ args: []
+ })
+
+ assert.equal(newValue, newValueAfterStore)
+ });
+});
diff --git a/evm-tests/test/eth.substrate-transfer.test.ts b/evm-tests/test/eth.substrate-transfer.test.ts
new file mode 100644
index 0000000000..9e3a2b2050
--- /dev/null
+++ b/evm-tests/test/eth.substrate-transfer.test.ts
@@ -0,0 +1,412 @@
+import * as assert from "assert";
+
+import { getDevnetApi, waitForTransactionCompletion, getRandomSubstrateSigner, } from "../src/substrate"
+import { getPublicClient } from "../src/utils";
+import { ETH_LOCAL_URL, IBALANCETRANSFER_ADDRESS, IBalanceTransferABI } from "../src/config";
+import { devnet, MultiAddress } from "@polkadot-api/descriptors"
+import { PublicClient } from "viem";
+import { TypedApi, Binary, FixedSizeBinary } from "polkadot-api";
+import { generateRandomEthersWallet } from "../src/utils";
+import { tao, raoToEth, bigintToRao, compareEthBalanceWithTxFee } from "../src/balance-math";
+import { toViemAddress, convertPublicKeyToSs58, convertH160ToSS58, ss58ToH160, ss58ToEthAddress, ethAddressToH160 } from "../src/address-utils"
+import { ethers } from "ethers"
+import { estimateTransactionCost, getContract } from "../src/eth"
+
+import { WITHDRAW_CONTRACT_ABI, WITHDRAW_CONTRACT_BYTECODE } from "../src/contracts/withdraw"
+
+import { forceSetBalanceToEthAddress, forceSetBalanceToSs58Address, disableWhiteListCheck } from "../src/subtensor";
+
+describe("Balance transfers between substrate and EVM", () => {
+ const gwei = BigInt("1000000000");
+ // init eth part
+ const wallet = generateRandomEthersWallet();
+ const wallet2 = generateRandomEthersWallet();
+ let publicClient: PublicClient;
+ const provider = new ethers.JsonRpcProvider(ETH_LOCAL_URL);
+ // init substrate part
+ const signer = getRandomSubstrateSigner();
+ let api: TypedApi
+
+ before(async () => {
+
+ publicClient = await getPublicClient(ETH_LOCAL_URL)
+ api = await getDevnetApi()
+
+ await forceSetBalanceToEthAddress(api, wallet.address)
+ await forceSetBalanceToEthAddress(api, wallet2.address)
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(signer.publicKey))
+ await disableWhiteListCheck(api, true)
+ });
+
+ it("Can transfer token from EVM to EVM", async () => {
+ const senderBalance = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ const receiverBalance = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+ const transferBalance = raoToEth(tao(1))
+ const tx = {
+ to: wallet2.address,
+ value: transferBalance.toString()
+ }
+ const txFee = await estimateTransactionCost(provider, tx)
+
+ const txResponse = await wallet.sendTransaction(tx)
+ await txResponse.wait();
+
+
+ const senderBalanceAfterTransfer = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ const receiverBalanceAfterTranser = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+
+ assert.equal(senderBalanceAfterTransfer, senderBalance - transferBalance - txFee)
+ assert.equal(receiverBalance, receiverBalanceAfterTranser - transferBalance)
+ });
+
+ it("Can transfer token from Substrate to EVM", async () => {
+ const ss58Address = convertH160ToSS58(wallet.address)
+ const senderBalance = (await api.query.System.Account.getValue(ss58Address)).data.free
+ const receiverBalance = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ const transferBalance = tao(1)
+
+ const tx = api.tx.Balances.transfer_keep_alive({ value: transferBalance, dest: MultiAddress.Id(ss58Address) })
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+
+ const senderBalanceAfterTransfer = (await api.query.System.Account.getValue(ss58Address)).data.free
+ const receiverBalanceAfterTranser = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+
+ assert.equal(senderBalanceAfterTransfer, senderBalance + transferBalance)
+ assert.equal(receiverBalance, receiverBalanceAfterTranser - raoToEth(transferBalance))
+ });
+
+ it("Can transfer token from EVM to Substrate", async () => {
+ const contract = getContract(IBALANCETRANSFER_ADDRESS, IBalanceTransferABI, wallet)
+ const senderBalance = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ const receiverBalance = (await api.query.System.Account.getValue(convertPublicKeyToSs58(signer.publicKey))).data.free
+ const transferBalance = raoToEth(tao(1))
+
+ const tx = await contract.transfer(signer.publicKey, { value: transferBalance.toString() })
+ await tx.wait()
+
+
+ const senderBalanceAfterTransfer = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ const receiverBalanceAfterTranser = (await api.query.System.Account.getValue(convertPublicKeyToSs58(signer.publicKey))).data.free
+
+ compareEthBalanceWithTxFee(senderBalanceAfterTransfer, senderBalance - transferBalance)
+ assert.equal(receiverBalance, receiverBalanceAfterTranser - tao(1))
+ });
+
+ it("Transfer from EVM to substrate using evm::withdraw", async () => {
+ const ss58Address = convertPublicKeyToSs58(signer.publicKey)
+ const senderBalance = (await api.query.System.Account.getValue(ss58Address)).data.free
+ const ethAddresss = ss58ToH160(ss58Address);
+
+ // transfer token to mirror eth address
+ const ethTransfer = {
+ to: ss58ToEthAddress(ss58Address),
+ value: raoToEth(tao(2)).toString()
+ }
+
+ const txResponse = await wallet.sendTransaction(ethTransfer)
+ await txResponse.wait();
+
+ const tx = api.tx.EVM.withdraw({ address: ethAddresss, value: tao(1) })
+ const txFee = (await tx.getPaymentInfo(ss58Address)).partial_fee
+
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+ const senderBalanceAfterWithdraw = (await api.query.System.Account.getValue(ss58Address)).data.free
+
+ assert.equal(senderBalance, senderBalanceAfterWithdraw - tao(1) + txFee)
+ });
+
+ it("Transfer from EVM to substrate using evm::call", async () => {
+ const ss58Address = convertPublicKeyToSs58(signer.publicKey)
+ const ethAddresss = ss58ToH160(ss58Address);
+
+ // transfer token to mirror eth address
+ const ethTransfer = {
+ to: ss58ToEthAddress(ss58Address),
+ value: raoToEth(tao(2)).toString()
+ }
+
+ const txResponse = await wallet.sendTransaction(ethTransfer)
+ await txResponse.wait();
+
+ const source: FixedSizeBinary<20> = ethAddresss;
+ const target = ethAddressToH160(wallet.address)
+ const receiverBalance = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+
+ // all these parameter value are tricky, any change could make the call failed
+ const tx = api.tx.EVM.call({
+ source: source,
+ target: target,
+ // it is U256 in the extrinsic.
+ value: [raoToEth(tao(1)), tao(0), tao(0), tao(0)],
+ gas_limit: BigInt(1000000),
+ // it is U256 in the extrinsic.
+ max_fee_per_gas: [BigInt(10e9), BigInt(0), BigInt(0), BigInt(0)],
+ max_priority_fee_per_gas: undefined,
+ input: Binary.fromText(""),
+ nonce: undefined,
+ access_list: []
+ })
+ // txFee not accurate
+ const txFee = (await tx.getPaymentInfo(ss58Address)).partial_fee
+
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+
+ const receiverBalanceAfterCall = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ assert.equal(receiverBalanceAfterCall, receiverBalance + raoToEth(tao(1)))
+ });
+
+ it("Forward value in smart contract", async () => {
+
+
+ const contractFactory = new ethers.ContractFactory(WITHDRAW_CONTRACT_ABI, WITHDRAW_CONTRACT_BYTECODE, wallet)
+ const contract = await contractFactory.deploy()
+ await contract.waitForDeployment()
+
+ const code = await publicClient.getCode({ address: toViemAddress(contract.target.toString()) })
+ if (code === undefined) {
+ throw new Error("code length is wrong for deployed contract")
+ }
+ assert.ok(code.length > 100)
+
+ // transfer 2 TAO to contract
+ const ethTransfer = {
+ to: contract.target.toString(),
+ value: raoToEth(tao(2)).toString()
+ }
+
+ const txResponse = await wallet.sendTransaction(ethTransfer)
+ await txResponse.wait();
+
+ const contractBalance = await publicClient.getBalance({ address: toViemAddress(contract.target.toString()) })
+ const callerBalance = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+
+ const contractForCall = new ethers.Contract(contract.target.toString(), WITHDRAW_CONTRACT_ABI, wallet)
+
+ const withdrawTx = await contractForCall.withdraw(
+ raoToEth(tao(1)).toString()
+ );
+
+ await withdrawTx.wait();
+
+ const contractBalanceAfterWithdraw = await publicClient.getBalance({ address: toViemAddress(contract.target.toString()) })
+ const callerBalanceAfterWithdraw = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+
+ compareEthBalanceWithTxFee(callerBalanceAfterWithdraw, callerBalance + raoToEth(tao(1)))
+ assert.equal(contractBalance, contractBalanceAfterWithdraw + raoToEth(tao(1)))
+ });
+
+ it("Transfer full balance", async () => {
+ const ethBalance = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ const receiverBalance = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+ const tx = {
+ to: wallet2.address,
+ value: ethBalance.toString(),
+ };
+ const txPrice = await estimateTransactionCost(provider, tx);
+ const finalTx = {
+ to: wallet2.address,
+ value: (ethBalance - txPrice).toString(),
+ };
+ try {
+ // transfer should be failed since substrate requires existial balance to keep account
+ const txResponse = await wallet.sendTransaction(finalTx)
+ await txResponse.wait();
+ } catch (error) {
+ if (error instanceof Error) {
+ assert.equal((error as any).code, "INSUFFICIENT_FUNDS")
+ assert.equal(error.toString().includes("insufficient funds"), true)
+ }
+ }
+
+ const receiverBalanceAfterTransfer = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+ assert.equal(receiverBalance, receiverBalanceAfterTransfer)
+ })
+
+ it("Transfer more than owned balance should fail", async () => {
+ const ethBalance = await publicClient.getBalance({ address: toViemAddress(wallet.address) })
+ const receiverBalance = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+ const tx = {
+ to: wallet2.address,
+ value: (ethBalance + raoToEth(tao(1))).toString(),
+ };
+
+ try {
+ // transfer should be failed since substrate requires existial balance to keep account
+ const txResponse = await wallet.sendTransaction(tx)
+ await txResponse.wait();
+ } catch (error) {
+ if (error instanceof Error) {
+ assert.equal((error as any).code, "INSUFFICIENT_FUNDS")
+ assert.equal(error.toString().includes("insufficient funds"), true)
+ }
+ }
+
+ const receiverBalanceAfterTransfer = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+ assert.equal(receiverBalance, receiverBalanceAfterTransfer)
+ });
+
+ it("Transfer more than u64::max in substrate equivalent should receive error response", async () => {
+ const receiverBalance = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+ try {
+ const tx = {
+ to: wallet2.address,
+ value: raoToEth(BigInt(2) ** BigInt(64)).toString(),
+ };
+ // transfer should be failed since substrate requires existial balance to keep account
+ const txResponse = await wallet.sendTransaction(tx)
+ await txResponse.wait();
+ } catch (error) {
+ if (error instanceof Error) {
+ assert.equal((error as any).code, "INSUFFICIENT_FUNDS")
+ assert.equal(error.toString().includes("insufficient funds"), true)
+ }
+ }
+
+ const contract = getContract(IBALANCETRANSFER_ADDRESS, IBalanceTransferABI, wallet)
+ try {
+ const tx = await contract.transfer(signer.publicKey, { value: raoToEth(BigInt(2) ** BigInt(64)).toString() })
+ await tx.await()
+ } catch (error) {
+ if (error instanceof Error) {
+ console.log(error.toString())
+ assert.equal(error.toString().includes("revert data"), true)
+ }
+ }
+
+ try {
+ const dest = convertH160ToSS58(wallet2.address)
+ const tx = api.tx.Balances.transfer_keep_alive({ value: bigintToRao(BigInt(2) ** BigInt(64)), dest: MultiAddress.Id(dest) })
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ } catch (error) {
+ if (error instanceof Error) {
+ console.log(error.toString())
+ assert.equal(error.toString().includes("Cannot convert"), true)
+ }
+ }
+
+ try {
+ const dest = ethAddressToH160(wallet2.address)
+ const tx = api.tx.EVM.withdraw({ value: bigintToRao(BigInt(2) ** BigInt(64)), address: dest })
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ } catch (error) {
+ if (error instanceof Error) {
+ assert.equal(error.toString().includes("Cannot convert"), true)
+ }
+ }
+
+ try {
+ const source = ethAddressToH160(wallet.address)
+ const target = ethAddressToH160(wallet2.address)
+ const tx = api.tx.EVM.call({
+ source: source,
+ target: target,
+ // it is U256 in the extrinsic, the value is more than u64::MAX
+ value: [raoToEth(tao(1)), tao(0), tao(0), tao(1)],
+ gas_limit: BigInt(1000000),
+ // it is U256 in the extrinsic.
+ max_fee_per_gas: [BigInt(10e9), BigInt(0), BigInt(0), BigInt(0)],
+ max_priority_fee_per_gas: undefined,
+ input: Binary.fromText(""),
+ nonce: undefined,
+ access_list: []
+ })
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ } catch (error) {
+ if (error instanceof Error) {
+ console.log(error.toString())
+ assert.equal((error as any).code, "INSUFFICIENT_FUNDS")
+ assert.equal(error.toString().includes("insufficient funds"), true)
+ }
+ }
+
+ const receiverBalanceAfterTransfer = await publicClient.getBalance({ address: toViemAddress(wallet2.address) })
+ assert.equal(receiverBalance, receiverBalanceAfterTransfer)
+ });
+
+ it("Gas price should be 10 GWei", async () => {
+ const feeData = await provider.getFeeData();
+ assert.equal(feeData.gasPrice, BigInt(10000000000));
+ });
+
+
+ it("max_fee_per_gas and max_priority_fee_per_gas affect transaction fee properly", async () => {
+
+ const testCases = [
+ [10, 0, 21000 * 10 * 1e9],
+ [10, 10, 21000 * 10 * 1e9],
+ [11, 0, 21000 * 10 * 1e9],
+ [11, 1, (21000 * 10 + 21000) * 1e9],
+ [11, 2, (21000 * 10 + 21000) * 1e9],
+ ];
+
+ for (let i in testCases) {
+ const tc = testCases[i];
+ const actualFee = await transferAndGetFee(
+ wallet, wallet2, publicClient,
+ gwei * BigInt(tc[0]),
+ gwei * BigInt(tc[1])
+ );
+ assert.equal(actualFee, BigInt(tc[2]))
+ }
+ });
+
+ it("Low max_fee_per_gas gets transaction rejected", async () => {
+ try {
+ await transferAndGetFee(wallet, wallet2, publicClient, gwei * BigInt(9), BigInt(0))
+ } catch (error) {
+ if (error instanceof Error) {
+ console.log(error.toString())
+ assert.equal(error.toString().includes("gas price less than block base fee"), true)
+ }
+ }
+ });
+
+ it("max_fee_per_gas lower than max_priority_fee_per_gas gets transaction rejected", async () => {
+ try {
+ await transferAndGetFee(wallet, wallet2, publicClient, gwei * BigInt(10), gwei * BigInt(11))
+ } catch (error) {
+ if (error instanceof Error) {
+ assert.equal(error.toString().includes("priorityFee cannot be more than maxFee"), true)
+ }
+ }
+ });
+});
+
+async function transferAndGetFee(wallet: ethers.Wallet, wallet2: ethers.Wallet, client: PublicClient, max_fee_per_gas: BigInt, max_priority_fee_per_gas: BigInt) {
+
+ const ethBalanceBefore = await client.getBalance({ address: toViemAddress(wallet.address) })
+ // Send TAO
+ const tx = {
+ to: wallet2.address,
+ value: raoToEth(tao(1)).toString(),
+ // EIP-1559 transaction parameters
+ maxPriorityFeePerGas: max_priority_fee_per_gas.toString(),
+ maxFeePerGas: max_fee_per_gas.toString(),
+ gasLimit: 21000,
+ };
+
+ // Send the transaction
+ const txResponse = await wallet.sendTransaction(tx);
+ await txResponse.wait()
+
+ // Check balances
+ const ethBalanceAfter = await client.getBalance({ address: toViemAddress(wallet.address) })
+ const fee = ethBalanceBefore - ethBalanceAfter - raoToEth(tao(1))
+
+ return fee;
+}
\ No newline at end of file
diff --git a/evm-tests/test/metagraph.precompile.test.ts b/evm-tests/test/metagraph.precompile.test.ts
new file mode 100644
index 0000000000..94c0df8861
--- /dev/null
+++ b/evm-tests/test/metagraph.precompile.test.ts
@@ -0,0 +1,147 @@
+import * as assert from "assert";
+
+import { getAliceSigner, getClient, getDevnetApi, waitForTransactionCompletion, convertPublicKeyToMultiAddress, getRandomSubstrateKeypair, getSignerFromKeypair } from "../src/substrate"
+import { getPublicClient, } from "../src/utils";
+import { ETH_LOCAL_URL, SUB_LOCAL_URL, } from "../src/config";
+import { devnet } from "@polkadot-api/descriptors"
+import { PublicClient } from "viem";
+import { PolkadotSigner, TypedApi } from "polkadot-api";
+import { toViemAddress, convertPublicKeyToSs58 } from "../src/address-utils"
+import { IMetagraphABI, IMETAGRAPH_ADDRESS } from "../src/contracts/metagraph"
+
+describe("Test the EVM chain ID", () => {
+ // init substrate part
+ const hotkey = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+ let publicClient: PublicClient;
+
+ let api: TypedApi
+
+ // sudo account alice as signer
+ let alice: PolkadotSigner;
+
+ // init other variable
+ let subnetId = 0;
+
+ before(async () => {
+ // init variables got from await and async
+ publicClient = await getPublicClient(ETH_LOCAL_URL)
+ const subClient = await getClient(SUB_LOCAL_URL)
+ api = await getDevnetApi()
+ alice = await getAliceSigner();
+
+ {
+ const multiAddress = convertPublicKeyToMultiAddress(hotkey.publicKey)
+ const internalCall = api.tx.Balances.force_set_balance({ who: multiAddress, new_free: BigInt(1e12) })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ }
+
+ {
+ const multiAddress = convertPublicKeyToMultiAddress(coldkey.publicKey)
+ const internalCall = api.tx.Balances.force_set_balance({ who: multiAddress, new_free: BigInt(1e12) })
+ const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall })
+
+ await waitForTransactionCompletion(api, tx, alice)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ }
+
+ const signer = getSignerFromKeypair(coldkey)
+ const registerNetworkTx = api.tx.SubtensorModule.register_network({ hotkey: convertPublicKeyToSs58(hotkey.publicKey) })
+ await waitForTransactionCompletion(api, registerNetworkTx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+
+ let totalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue()
+ assert.ok(totalNetworks > 1)
+ subnetId = totalNetworks - 1
+
+ let uid_count =
+ await api.query.SubtensorModule.SubnetworkN.getValue(subnetId)
+ if (uid_count === 0) {
+ const tx = api.tx.SubtensorModule.burned_register({ hotkey: convertPublicKeyToSs58(hotkey.publicKey), netuid: subnetId })
+ await waitForTransactionCompletion(api, tx, signer)
+ .then(() => { })
+ .catch((error) => { console.log(`transaction error ${error}`) });
+ }
+ })
+
+ it("Metagraph data access via precompile contract is ok", async () => {
+ const uid = 0
+ const uid_count = await publicClient.readContract({
+ abi: IMetagraphABI,
+ address: toViemAddress(IMETAGRAPH_ADDRESS),
+ functionName: "getUidCount",
+ args: [subnetId]
+ })
+ // back to original value for other tests. and we can run it repeatedly
+ assert.ok(uid_count != undefined);
+
+ // const axon = api.query.SubtensorModule.Axons.getValue()
+
+ const axon = await publicClient.readContract({
+ abi: IMetagraphABI,
+ address: toViemAddress(IMETAGRAPH_ADDRESS),
+ functionName: "getAxon",
+ args: [subnetId, uid]
+ })
+
+ assert.ok(axon != undefined);
+ if (axon instanceof Object) {
+ assert.ok(axon != undefined);
+ if ("block" in axon) {
+ assert.ok(axon.block != undefined);
+ } else {
+ throw new Error("block not included in axon")
+ }
+
+ if ("version" in axon) {
+ assert.ok(axon.version != undefined);
+ } else {
+ throw new Error("version not included in axon")
+ }
+
+ if ("ip" in axon) {
+ assert.ok(axon.ip != undefined);
+ } else {
+ throw new Error("ip not included in axon")
+ }
+
+ if ("port" in axon) {
+ assert.ok(axon.port != undefined);
+ } else {
+ throw new Error("port not included in axon")
+ }
+
+ if ("ip_type" in axon) {
+ assert.ok(axon.ip_type != undefined);
+ } else {
+ throw new Error("ip_type not included in axon")
+ }
+
+ if ("protocol" in axon) {
+ assert.ok(axon.protocol != undefined);
+ } else {
+ throw new Error("protocol not included in axon")
+ }
+ }
+
+ const methodList = ["getEmission", "getVtrust", "getValidatorStatus", "getLastUpdate", "getIsActive",
+ "getHotkey", "getColdkey"
+ ]
+ for (const method of methodList) {
+ const value = await publicClient.readContract({
+ abi: IMetagraphABI,
+ address: toViemAddress(IMETAGRAPH_ADDRESS),
+ functionName: method,
+ args: [subnetId, uid]
+ })
+
+ assert.ok(value != undefined);
+ }
+ });
+});
\ No newline at end of file
diff --git a/evm-tests/test/neuron.precompile.emission-check.test.ts b/evm-tests/test/neuron.precompile.emission-check.test.ts
new file mode 100644
index 0000000000..ac609c1e27
--- /dev/null
+++ b/evm-tests/test/neuron.precompile.emission-check.test.ts
@@ -0,0 +1,72 @@
+import * as assert from "assert";
+
+import { getAliceSigner, getClient, getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { getPublicClient, } from "../src/utils";
+import { ETH_LOCAL_URL, SUB_LOCAL_URL, } from "../src/config";
+import { devnet } from "@polkadot-api/descriptors"
+import { PublicClient } from "viem";
+import { PolkadotSigner, TypedApi } from "polkadot-api";
+import { convertPublicKeyToSs58, } from "../src/address-utils"
+import { ethers } from "ethers"
+import { INEURON_ADDRESS, INeuronABI } from "../src/contracts/neuron"
+import { generateRandomEthersWallet } from "../src/utils"
+import { forceSetBalanceToSs58Address, forceSetBalanceToEthAddress, addNewSubnetwork } from "../src/subtensor"
+
+describe("Test the EVM chain ID", () => {
+ // init eth part
+ const wallet = generateRandomEthersWallet();
+
+ // init substrate part
+ const hotkey = getRandomSubstrateKeypair();
+ const hotkey2 = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+ let publicClient: PublicClient;
+
+ let api: TypedApi
+
+ // sudo account alice as signer
+ let alice: PolkadotSigner;
+
+ before(async () => {
+ // init variables got from await and async
+ publicClient = await getPublicClient(ETH_LOCAL_URL)
+ const subClient = await getClient(SUB_LOCAL_URL)
+ api = await getDevnetApi()
+ alice = await getAliceSigner();
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey2.publicKey))
+
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ await forceSetBalanceToEthAddress(api, wallet.address)
+
+ const netuid = await addNewSubnetwork(api, hotkey2, coldkey)
+ console.log("test on subnet ", netuid)
+ })
+
+ it("Burned register and check emission", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ const uid = await api.query.SubtensorModule.SubnetworkN.getValue(netuid)
+ const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet);
+
+ const tx = await contract.burnedRegister(
+ netuid,
+ hotkey.publicKey
+ );
+ await tx.wait();
+
+ const uidAfterNew = await api.query.SubtensorModule.SubnetworkN.getValue(netuid)
+ assert.equal(uid + 1, uidAfterNew)
+
+ const key = await api.query.SubtensorModule.Keys.getValue(netuid, uid)
+ assert.equal(key, convertPublicKeyToSs58(hotkey.publicKey))
+
+ let i = 0;
+ while (i < 10) {
+ const emission = await api.query.SubtensorModule.PendingEmission.getValue(netuid)
+
+ console.log("emission is ", emission);
+ await new Promise((resolve) => setTimeout(resolve, 2000));
+ i += 1;
+ }
+ })
+});
\ No newline at end of file
diff --git a/evm-tests/test/neuron.precompile.reveal-weights.test.ts b/evm-tests/test/neuron.precompile.reveal-weights.test.ts
new file mode 100644
index 0000000000..85125f0956
--- /dev/null
+++ b/evm-tests/test/neuron.precompile.reveal-weights.test.ts
@@ -0,0 +1,142 @@
+import * as assert from "assert";
+import { getAliceSigner, getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { devnet } from "@polkadot-api/descriptors"
+import { PolkadotSigner, TypedApi } from "polkadot-api";
+import { convertPublicKeyToSs58, convertH160ToSS58 } from "../src/address-utils"
+import { Vec, Tuple, VecFixed, u16, u8, u64 } from "@polkadot/types-codec";
+import { TypeRegistry } from "@polkadot/types";
+import { ethers } from "ethers"
+import { INEURON_ADDRESS, INeuronABI } from "../src/contracts/neuron"
+import { generateRandomEthersWallet } from "../src/utils"
+import { convertH160ToPublicKey } from "../src/address-utils"
+import { blake2AsU8a } from "@polkadot/util-crypto"
+import {
+ forceSetBalanceToEthAddress, forceSetBalanceToSs58Address, addNewSubnetwork, setCommitRevealWeightsEnabled, setWeightsSetRateLimit, burnedRegister,
+ setTempo, setCommitRevealWeightsInterval
+} from "../src/subtensor"
+
+// hardcode some values for reveal hash
+const uids = [1];
+const values = [5];
+const salt = [9];
+const version_key = 0;
+
+function getCommitHash(netuid: number, address: string) {
+ const registry = new TypeRegistry();
+ let publicKey = convertH160ToPublicKey(address);
+
+ const tupleData = new Tuple(
+ registry,
+ [
+ VecFixed.with(u8, 32),
+ u16,
+ Vec.with(u16),
+ Vec.with(u16),
+ Vec.with(u16),
+ u64,
+ ],
+ [publicKey, netuid, uids, values, salt, version_key]
+ );
+
+ const hash = blake2AsU8a(tupleData.toU8a());
+ return hash;
+}
+
+describe("Test neuron precompile reveal weights", () => {
+ // init eth part
+ const wallet = generateRandomEthersWallet();
+
+ // init substrate part
+ const hotkey = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+
+ let api: TypedApi
+
+ // sudo account alice as signer
+ let alice: PolkadotSigner;
+ before(async () => {
+ // init variables got from await and async
+ api = await getDevnetApi()
+ alice = await getAliceSigner();
+
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(alice.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ await forceSetBalanceToEthAddress(api, wallet.address)
+ let netuid = await addNewSubnetwork(api, hotkey, coldkey)
+
+ console.log("test the case on subnet ", netuid)
+
+ // enable commit reveal feature
+ await setCommitRevealWeightsEnabled(api, netuid, true)
+ // set it as 0, we can set the weight anytime
+ await setWeightsSetRateLimit(api, netuid, BigInt(0))
+
+ const ss58Address = convertH160ToSS58(wallet.address)
+ await burnedRegister(api, netuid, ss58Address, coldkey)
+
+ const uid = await api.query.SubtensorModule.Uids.getValue(
+ netuid,
+ ss58Address
+ )
+ // eth wallet account should be the first neuron in the subnet
+ assert.equal(uid, uids[0])
+ })
+
+ it("EVM neuron commit weights via call precompile", async () => {
+ let totalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue()
+ const subnetId = totalNetworks - 1
+ const commitHash = getCommitHash(subnetId, wallet.address)
+ const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet);
+ const tx = await contract.commitWeights(subnetId, commitHash)
+ await tx.wait()
+
+ const ss58Address = convertH160ToSS58(wallet.address)
+
+ const weightsCommit = await api.query.SubtensorModule.WeightCommits.getValue(subnetId, ss58Address)
+ if (weightsCommit === undefined) {
+ throw new Error("submit weights failed")
+ }
+ assert.ok(weightsCommit.length > 0)
+ })
+
+ it("EVM neuron reveal weights via call precompile", async () => {
+ let totalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue()
+ const netuid = totalNetworks - 1
+ const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet);
+ // set tempo or epoch large, then enough time to reveal weight
+ await setTempo(api, netuid, 60000)
+ // set interval epoch as 0, we can reveal at the same epoch
+ await setCommitRevealWeightsInterval(api, netuid, BigInt(0))
+
+ const tx = await contract.revealWeights(
+ netuid,
+ uids,
+ values,
+ salt,
+ version_key
+ );
+ await tx.wait()
+ const ss58Address = convertH160ToSS58(wallet.address)
+
+ // check the weight commit is removed after reveal successfully
+ const weightsCommit = await api.query.SubtensorModule.WeightCommits.getValue(netuid, ss58Address)
+ assert.equal(weightsCommit, undefined)
+
+ // check the weight is set after reveal with correct uid
+ const neuron_uid = await api.query.SubtensorModule.Uids.getValue(
+ netuid,
+ ss58Address
+ )
+
+ const weights = await api.query.SubtensorModule.Weights.getValue(netuid, neuron_uid)
+
+ if (weights === undefined) {
+ throw new Error("weights not available onchain")
+ }
+ for (const weight of weights) {
+ assert.equal(weight[0], neuron_uid)
+ assert.ok(weight[1] !== undefined)
+ }
+ })
+});
\ No newline at end of file
diff --git a/evm-tests/test/neuron.precompile.serve.axon-prometheus.test.ts b/evm-tests/test/neuron.precompile.serve.axon-prometheus.test.ts
new file mode 100644
index 0000000000..aee84f130c
--- /dev/null
+++ b/evm-tests/test/neuron.precompile.serve.axon-prometheus.test.ts
@@ -0,0 +1,162 @@
+import * as assert from "assert";
+import { getAliceSigner, getClient, getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { SUB_LOCAL_URL, } from "../src/config";
+import { devnet } from "@polkadot-api/descriptors"
+import { PolkadotSigner, TypedApi } from "polkadot-api";
+import { convertPublicKeyToSs58, convertH160ToSS58 } from "../src/address-utils"
+import { ethers } from "ethers"
+import { INEURON_ADDRESS, INeuronABI } from "../src/contracts/neuron"
+import { generateRandomEthersWallet } from "../src/utils"
+import { forceSetBalanceToEthAddress, forceSetBalanceToSs58Address, addNewSubnetwork, burnedRegister } from "../src/subtensor"
+
+describe("Test neuron precompile Serve Axon Prometheus", () => {
+ // init eth part
+ const wallet1 = generateRandomEthersWallet();
+ const wallet2 = generateRandomEthersWallet();
+ const wallet3 = generateRandomEthersWallet();
+
+ // init substrate part
+ const hotkey = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+
+ let api: TypedApi
+
+ // sudo account alice as signer
+ let alice: PolkadotSigner;
+ before(async () => {
+ // init variables got from await and async
+ const subClient = await getClient(SUB_LOCAL_URL)
+ api = await getDevnetApi()
+ alice = await getAliceSigner();
+
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(alice.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ await forceSetBalanceToEthAddress(api, wallet1.address)
+ await forceSetBalanceToEthAddress(api, wallet2.address)
+ await forceSetBalanceToEthAddress(api, wallet3.address)
+ let netuid = await addNewSubnetwork(api, hotkey, coldkey)
+
+ console.log("test the case on subnet ", netuid)
+
+ await burnedRegister(api, netuid, convertH160ToSS58(wallet1.address), coldkey)
+ await burnedRegister(api, netuid, convertH160ToSS58(wallet2.address), coldkey)
+ await burnedRegister(api, netuid, convertH160ToSS58(wallet3.address), coldkey)
+ })
+
+ it("Serve Axon", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ const version = 0;
+ const ip = 1;
+ const port = 2;
+ const ipType = 4;
+ const protocol = 0;
+ const placeholder1 = 8;
+ const placeholder2 = 9;
+
+ const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet1);
+
+ const tx = await contract.serveAxon(
+ netuid,
+ version,
+ ip,
+ port,
+ ipType,
+ protocol,
+ placeholder1,
+ placeholder2
+ );
+ await tx.wait();
+
+ const axon = await api.query.SubtensorModule.Axons.getValue(
+ netuid,
+ convertH160ToSS58(wallet1.address)
+ )
+ assert.notEqual(axon?.block, undefined)
+ assert.equal(axon?.version, version)
+ assert.equal(axon?.ip, ip)
+ assert.equal(axon?.port, port)
+ assert.equal(axon?.ip_type, ipType)
+ assert.equal(axon?.protocol, protocol)
+ assert.equal(axon?.placeholder1, placeholder1)
+ assert.equal(axon?.placeholder2, placeholder2)
+ });
+
+ it("Serve Axon TLS", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ const version = 0;
+ const ip = 1;
+ const port = 2;
+ const ipType = 4;
+ const protocol = 0;
+ const placeholder1 = 8;
+ const placeholder2 = 9;
+ // certificate length is 65
+ const certificate = new Uint8Array([
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ ]);
+
+ const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet2);
+
+ const tx = await contract.serveAxonTls(
+ netuid,
+ version,
+ ip,
+ port,
+ ipType,
+ protocol,
+ placeholder1,
+ placeholder2,
+ certificate
+ );
+ await tx.wait();
+
+ const axon = await api.query.SubtensorModule.Axons.getValue(
+ netuid,
+ convertH160ToSS58(wallet2.address))
+
+ assert.notEqual(axon?.block, undefined)
+ assert.equal(axon?.version, version)
+ assert.equal(axon?.ip, ip)
+ assert.equal(axon?.port, port)
+ assert.equal(axon?.ip_type, ipType)
+ assert.equal(axon?.protocol, protocol)
+ assert.equal(axon?.placeholder1, placeholder1)
+ assert.equal(axon?.placeholder2, placeholder2)
+ });
+
+ it("Serve Prometheus", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ const version = 0;
+ const ip = 1;
+ const port = 2;
+ const ipType = 4;
+
+ const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet3);
+
+ const tx = await contract.servePrometheus(
+ netuid,
+ version,
+ ip,
+ port,
+ ipType
+ );
+ await tx.wait();
+
+ const prometheus = (
+ await api.query.SubtensorModule.Prometheus.getValue(
+ netuid,
+ convertH160ToSS58(wallet3.address)
+ )
+ )
+
+ assert.notEqual(prometheus?.block, undefined)
+ assert.equal(prometheus?.version, version)
+ assert.equal(prometheus?.ip, ip)
+ assert.equal(prometheus?.port, port)
+ assert.equal(prometheus?.ip_type, ipType)
+ });
+});
\ No newline at end of file
diff --git a/evm-tests/test/neuron.precompile.set-weights.test.ts b/evm-tests/test/neuron.precompile.set-weights.test.ts
new file mode 100644
index 0000000000..393c2b97b8
--- /dev/null
+++ b/evm-tests/test/neuron.precompile.set-weights.test.ts
@@ -0,0 +1,65 @@
+import * as assert from "assert";
+
+import { getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { devnet } from "@polkadot-api/descriptors"
+import { TypedApi } from "polkadot-api";
+import { convertH160ToSS58, convertPublicKeyToSs58, } from "../src/address-utils"
+import { ethers } from "ethers"
+import { INEURON_ADDRESS, INeuronABI } from "../src/contracts/neuron"
+import { generateRandomEthersWallet } from "../src/utils"
+import {
+ forceSetBalanceToSs58Address, forceSetBalanceToEthAddress, addNewSubnetwork, burnedRegister, setCommitRevealWeightsEnabled,
+ setWeightsSetRateLimit
+} from "../src/subtensor"
+
+describe("Test neuron precompile contract, set weights function", () => {
+ // init eth part
+ const wallet = generateRandomEthersWallet();
+
+ // init substrate part
+ const hotkey = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+
+ let api: TypedApi
+
+ before(async () => {
+ api = await getDevnetApi()
+
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
+
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ await forceSetBalanceToEthAddress(api, wallet.address)
+
+ const netuid = await addNewSubnetwork(api, hotkey, coldkey)
+ console.log("test on subnet ", netuid)
+
+ await burnedRegister(api, netuid, convertH160ToSS58(wallet.address), coldkey)
+ const uid = await api.query.SubtensorModule.Uids.getValue(netuid, convertH160ToSS58(wallet.address))
+ assert.notEqual(uid, undefined)
+ // disable reveal and enable direct set weights
+ await setCommitRevealWeightsEnabled(api, netuid, false)
+ await setWeightsSetRateLimit(api, netuid, BigInt(0))
+ })
+
+ it("Set weights is ok", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ const uid = await api.query.SubtensorModule.Uids.getValue(netuid, convertH160ToSS58(wallet.address))
+
+ const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet);
+ const dests = [1];
+ const weights = [2];
+ const version_key = 0;
+
+ const tx = await contract.setWeights(netuid, dests, weights, version_key);
+
+ await tx.wait();
+ const weightsOnChain = await api.query.SubtensorModule.Weights.getValue(netuid, uid)
+
+ weightsOnChain.forEach((weight, _) => {
+ const uidInWeight = weight[0];
+ const value = weight[1];
+ assert.equal(uidInWeight, uid)
+ assert.ok(value > 0)
+ });
+ })
+});
\ No newline at end of file
diff --git a/evm-tests/test/staking.precompile.add-remove.test.ts b/evm-tests/test/staking.precompile.add-remove.test.ts
new file mode 100644
index 0000000000..5387e62428
--- /dev/null
+++ b/evm-tests/test/staking.precompile.add-remove.test.ts
@@ -0,0 +1,326 @@
+import * as assert from "assert";
+import { getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { devnet } from "@polkadot-api/descriptors"
+import { PolkadotSigner, TypedApi } from "polkadot-api";
+import { convertPublicKeyToSs58, convertH160ToSS58 } from "../src/address-utils"
+import { raoToEth, tao } from "../src/balance-math"
+import { ethers } from "ethers"
+import { generateRandomEthersWallet, getPublicClient } from "../src/utils"
+import { convertH160ToPublicKey } from "../src/address-utils"
+import {
+ forceSetBalanceToEthAddress, forceSetBalanceToSs58Address, addNewSubnetwork, burnedRegister,
+ sendProxyCall,
+} from "../src/subtensor"
+import { ETH_LOCAL_URL } from "../src/config";
+import { ISTAKING_ADDRESS, ISTAKING_V2_ADDRESS, IStakingABI, IStakingV2ABI } from "../src/contracts/staking"
+import { PublicClient } from "viem";
+
+describe("Test neuron precompile reveal weights", () => {
+ // init eth part
+ const wallet1 = generateRandomEthersWallet();
+ const wallet2 = generateRandomEthersWallet();
+ let publicClient: PublicClient;
+ // init substrate part
+ const hotkey = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+ const proxy = getRandomSubstrateKeypair();
+
+ let api: TypedApi
+
+ // sudo account alice as signer
+ let alice: PolkadotSigner;
+ before(async () => {
+ publicClient = await getPublicClient(ETH_LOCAL_URL)
+ // init variables got from await and async
+ api = await getDevnetApi()
+
+ // await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(alice.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(proxy.publicKey))
+ await forceSetBalanceToEthAddress(api, wallet1.address)
+ await forceSetBalanceToEthAddress(api, wallet2.address)
+ let netuid = await addNewSubnetwork(api, hotkey, coldkey)
+
+ console.log("test the case on subnet ", netuid)
+
+ await burnedRegister(api, netuid, convertH160ToSS58(wallet1.address), coldkey)
+ await burnedRegister(api, netuid, convertH160ToSS58(wallet2.address), coldkey)
+ })
+
+ it("Can add stake", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ // ETH unit
+ let stakeBalance = raoToEth(tao(20))
+ const stakeBefore = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet1.address), netuid)
+ const contract = new ethers.Contract(ISTAKING_ADDRESS, IStakingABI, wallet1);
+ const tx = await contract.addStake(hotkey.publicKey, netuid, { value: stakeBalance.toString() })
+ await tx.wait()
+
+ const stakeFromContract = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)
+ );
+
+ assert.ok(stakeFromContract > stakeBefore)
+ const stakeAfter = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet1.address), netuid)
+ assert.ok(stakeAfter > stakeBefore)
+ })
+
+ it("Can add stake V2", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ // the unit in V2 is RAO, not ETH
+ let stakeBalance = tao(20)
+ const stakeBefore = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet2.address), netuid)
+ const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet2);
+ const tx = await contract.addStake(hotkey.publicKey, stakeBalance.toString(), netuid)
+ await tx.wait()
+
+ const stakeFromContract = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet2.address), netuid)
+ );
+
+ assert.ok(stakeFromContract > stakeBefore)
+ const stakeAfter = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet2.address), netuid)
+ assert.ok(stakeAfter > stakeBefore)
+ })
+
+ it("Can not add stake if subnet doesn't exist", async () => {
+ // wrong netuid
+ let netuid = 12345;
+ let stakeBalance = raoToEth(tao(20))
+ const stakeBefore = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet1.address), netuid)
+ const contract = new ethers.Contract(ISTAKING_ADDRESS, IStakingABI, wallet1);
+ try {
+ const tx = await contract.addStake(hotkey.publicKey, netuid, { value: stakeBalance.toString() })
+ await tx.wait()
+ assert.fail("Transaction should have failed");
+ } catch (error) {
+ // Transaction failed as expected
+ }
+
+ const stakeFromContract = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)
+ );
+ assert.equal(stakeFromContract, stakeBefore)
+ const stakeAfter = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet1.address), netuid)
+ assert.equal(stakeAfter, stakeBefore)
+ });
+
+ it("Can not add stake V2 if subnet doesn't exist", async () => {
+ // wrong netuid
+ let netuid = 12345;
+ // the unit in V2 is RAO, not ETH
+ let stakeBalance = tao(20)
+ const stakeBefore = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet2.address), netuid)
+ const contract = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet2);
+
+ try {
+ const tx = await contract.addStake(hotkey.publicKey, stakeBalance.toString(), netuid);
+ await tx.wait();
+ assert.fail("Transaction should have failed");
+ } catch (error) {
+ // Transaction failed as expected
+ }
+
+ const stakeFromContract = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet2.address), netuid)
+ );
+ assert.equal(stakeFromContract, stakeBefore)
+ const stakeAfter = await api.query.SubtensorModule.Alpha.getValue(convertPublicKeyToSs58(hotkey.publicKey), convertH160ToSS58(wallet2.address), netuid)
+ assert.equal(stakeAfter, stakeBefore)
+ })
+
+ it("Can get stake via contract read method", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+
+ // TODO need check how to pass bytes32 as parameter of readContract
+ // const value = await publicClient.readContract({
+ // address: ISTAKING_ADDRESS,
+ // abi: IStakingABI,
+ // functionName: "getStake",
+ // args: [hotkey.publicKey, // Convert to bytes32 format
+ // convertH160ToPublicKey(wallet1.address),
+ // netuid]
+ // })
+ // if (value === undefined || value === null) {
+ // throw new Error("value of getStake from contract is undefined")
+ // }
+ // const intValue = BigInt(value.toString())
+
+ const contractV1 = new ethers.Contract(ISTAKING_ADDRESS, IStakingABI, wallet1);
+ const stakeFromContractV1 = BigInt(
+ await contractV1.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)
+ );
+
+ const contractV2 = new ethers.Contract(ISTAKING_V2_ADDRESS, IStakingV2ABI, wallet1);
+ // unit from contract V2 is RAO, not ETH
+ const stakeFromContractV2 = Number(
+ await contractV2.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)
+ );
+
+ assert.equal(stakeFromContractV1, tao(stakeFromContractV2))
+
+ })
+
+ it("Can remove stake", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ const contract = new ethers.Contract(
+ ISTAKING_ADDRESS,
+ IStakingABI,
+ wallet1
+ );
+
+ const stakeBeforeRemove = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)
+ );
+
+ let stakeBalance = raoToEth(tao(10))
+ const tx = await contract.removeStake(hotkey.publicKey, stakeBalance, netuid)
+ await tx.wait()
+
+ const stakeAfterRemove = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet1.address), netuid)
+ );
+ assert.ok(stakeAfterRemove < stakeBeforeRemove)
+
+ })
+
+ it("Can remove stake V2", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ const contract = new ethers.Contract(
+ ISTAKING_V2_ADDRESS,
+ IStakingV2ABI,
+ wallet2
+ );
+
+ const stakeBeforeRemove = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet2.address), netuid)
+ );
+
+ let stakeBalance = tao(10)
+ const tx = await contract.removeStake(hotkey.publicKey, stakeBalance, netuid)
+ await tx.wait()
+
+ const stakeAfterRemove = BigInt(
+ await contract.getStake(hotkey.publicKey, convertH160ToPublicKey(wallet2.address), netuid)
+ );
+
+ assert.ok(stakeAfterRemove < stakeBeforeRemove)
+ })
+
+ it("Can add/remove proxy", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ // add/remove are done in a single test case, because we can't use the same private/public key
+ // between substrate and EVM, but to test the remove part, we must predefine the proxy first.
+ // it makes `remove` being dependent on `add`, because we should use `addProxy` from contract
+ // to prepare the proxy for `removeProxy` testing - the proxy is specified for the
+ // caller/origin.
+
+ // first, check we don't have proxies
+ const ss58Address = convertH160ToSS58(wallet1.address);
+ // the result include two items array, first one is delegate info, second one is balance
+ const initProxies = await api.query.Proxy.Proxies.getValue(ss58Address);
+ assert.equal(initProxies[0].length, 0);
+
+ // intialize the contract
+ const contract = new ethers.Contract(
+ ISTAKING_ADDRESS,
+ IStakingABI,
+ wallet1
+ );
+
+ // test "add"
+ let tx = await contract.addProxy(proxy.publicKey);
+ await tx.wait();
+
+ const proxiesAfterAdd = await api.query.Proxy.Proxies.getValue(ss58Address);
+
+ assert.equal(proxiesAfterAdd[0][0].delegate, convertPublicKeyToSs58(proxy.publicKey))
+
+ let stakeBefore = await api.query.SubtensorModule.Alpha.getValue(
+ convertPublicKeyToSs58(hotkey.publicKey),
+ ss58Address,
+ netuid
+ )
+
+ const call = api.tx.SubtensorModule.add_stake({
+ hotkey: convertPublicKeyToSs58(hotkey.publicKey),
+ netuid: netuid,
+ amount_staked: tao(1)
+ })
+ await sendProxyCall(api, call.decodedCall, ss58Address, proxy)
+
+ let stakeAfter = await api.query.SubtensorModule.Alpha.getValue(
+ convertPublicKeyToSs58(hotkey.publicKey),
+ ss58Address,
+ netuid
+ )
+
+ assert.ok(stakeAfter > stakeBefore)
+ // test "remove"
+ tx = await contract.removeProxy(proxy.publicKey);
+ await tx.wait();
+
+ const proxiesAfterRemove = await api.query.Proxy.Proxies.getValue(ss58Address);
+ assert.equal(proxiesAfterRemove[0].length, 0)
+ });
+
+ it("Can add/remove proxy V2", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+ // add/remove are done in a single test case, because we can't use the same private/public key
+ // between substrate and EVM, but to test the remove part, we must predefine the proxy first.
+ // it makes `remove` being dependent on `add`, because we should use `addProxy` from contract
+ // to prepare the proxy for `removeProxy` testing - the proxy is specified for the
+ // caller/origin.
+
+ // first, check we don't have proxies
+ const ss58Address = convertH160ToSS58(wallet1.address);
+ // the result include two items array, first one is delegate info, second one is balance
+ const initProxies = await api.query.Proxy.Proxies.getValue(ss58Address);
+ assert.equal(initProxies[0].length, 0);
+
+ // intialize the contract
+ // const signer = new ethers.Wallet(fundedEthWallet.privateKey, provider);
+ const contract = new ethers.Contract(
+ ISTAKING_V2_ADDRESS,
+ IStakingV2ABI,
+ wallet1
+ );
+
+ // test "add"
+ let tx = await contract.addProxy(proxy.publicKey);
+ await tx.wait();
+
+ const proxiesAfterAdd = await api.query.Proxy.Proxies.getValue(ss58Address);
+
+ assert.equal(proxiesAfterAdd[0][0].delegate, convertPublicKeyToSs58(proxy.publicKey))
+
+ let stakeBefore = await api.query.SubtensorModule.Alpha.getValue(
+ convertPublicKeyToSs58(hotkey.publicKey),
+ ss58Address,
+ netuid
+ )
+
+ const call = api.tx.SubtensorModule.add_stake({
+ hotkey: convertPublicKeyToSs58(hotkey.publicKey),
+ netuid: netuid,
+ amount_staked: tao(1)
+ })
+
+ await sendProxyCall(api, call.decodedCall, ss58Address, proxy)
+
+ let stakeAfter = await api.query.SubtensorModule.Alpha.getValue(
+ convertPublicKeyToSs58(hotkey.publicKey),
+ ss58Address,
+ netuid
+ )
+
+ assert.ok(stakeAfter > stakeBefore)
+ // test "remove"
+ tx = await contract.removeProxy(proxy.publicKey);
+ await tx.wait();
+
+ const proxiesAfterRemove = await api.query.Proxy.Proxies.getValue(ss58Address);
+ assert.equal(proxiesAfterRemove[0].length, 0)
+ });
+});
diff --git a/evm-tests/test/staking.precompile.reward.test.ts b/evm-tests/test/staking.precompile.reward.test.ts
new file mode 100644
index 0000000000..3600a6d08d
--- /dev/null
+++ b/evm-tests/test/staking.precompile.reward.test.ts
@@ -0,0 +1,105 @@
+import * as assert from "assert";
+import { getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { devnet } from "@polkadot-api/descriptors"
+import { TypedApi } from "polkadot-api";
+import { convertPublicKeyToSs58 } from "../src/address-utils"
+import { tao } from "../src/balance-math"
+import {
+ forceSetBalanceToSs58Address, addNewSubnetwork, burnedRegister,
+ setTxRateLimit, setTempo, setWeightsSetRateLimit, setSubnetOwnerCut, setMaxAllowedUids,
+ setMinDelegateTake, becomeDelegate, setActivityCutoff, addStake, setWeight, rootRegister
+} from "../src/subtensor"
+
+describe("Test neuron precompile reveal weights", () => {
+ const hotkey = getRandomSubstrateKeypair();
+ const coldkey = getRandomSubstrateKeypair();
+
+ const validator = getRandomSubstrateKeypair();
+ const miner = getRandomSubstrateKeypair();
+ const nominator = getRandomSubstrateKeypair();
+
+ let api: TypedApi
+
+ before(async () => {
+ const root_netuid = 0;
+ const root_tempo = 1; // neet root epoch to happen before subnet tempo
+ const subnet_tempo = 1;
+ api = await getDevnetApi()
+
+ // await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(alice.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(coldkey.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(validator.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(miner.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(nominator.publicKey))
+ // await forceSetBalanceToEthAddress(api, wallet1.address)
+ // await forceSetBalanceToEthAddress(api, wallet2.address)
+ let netuid = await addNewSubnetwork(api, hotkey, coldkey)
+
+ console.log("test the case on subnet ", netuid)
+
+ await setTxRateLimit(api, BigInt(0))
+ await setTempo(api, root_netuid, root_tempo)
+ await setTempo(api, netuid, subnet_tempo)
+ await setWeightsSetRateLimit(api, netuid, BigInt(0))
+
+ await burnedRegister(api, netuid, convertPublicKeyToSs58(validator.publicKey), coldkey)
+ await burnedRegister(api, netuid, convertPublicKeyToSs58(miner.publicKey), coldkey)
+ await burnedRegister(api, netuid, convertPublicKeyToSs58(nominator.publicKey), coldkey)
+ await setSubnetOwnerCut(api, 0)
+ await setActivityCutoff(api, netuid, 65535)
+ await setMaxAllowedUids(api, netuid, 65535)
+ await setMinDelegateTake(api, 0)
+ await becomeDelegate(api, convertPublicKeyToSs58(validator.publicKey), coldkey)
+ await becomeDelegate(api, convertPublicKeyToSs58(miner.publicKey), coldkey)
+ })
+
+ it("Staker receives rewards", async () => {
+ let netuid = (await api.query.SubtensorModule.TotalNetworks.getValue()) - 1
+
+ await addStake(api, netuid, convertPublicKeyToSs58(miner.publicKey), tao(1), coldkey)
+ await addStake(api, netuid, convertPublicKeyToSs58(nominator.publicKey), tao(1), coldkey)
+
+ await addStake(api, netuid, convertPublicKeyToSs58(validator.publicKey), tao(100), coldkey)
+
+ const miner_alpha_before_emission = await api.query.SubtensorModule.Alpha.getValue(
+ convertPublicKeyToSs58(miner.publicKey),
+ convertPublicKeyToSs58(coldkey.publicKey),
+ netuid
+ )
+
+ await setWeight(api, netuid, [0, 1], [0xffff, 0xffff], BigInt(0), validator)
+ await rootRegister(api, convertPublicKeyToSs58(validator.publicKey), coldkey)
+
+ let index = 0;
+ while (index < 60) {
+ const pending = await api.query.SubtensorModule.PendingEmission.getValue(netuid);
+ if (pending > 0) {
+ console.log("pending amount is ", pending);
+ break;
+ }
+
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+ console.log("wait for the pendingEmission update");
+ index += 1;
+ }
+
+ index = 0;
+ while (index < 60) {
+ let miner_current_alpha = await api.query.SubtensorModule.Alpha.getValue(
+ convertPublicKeyToSs58(miner.publicKey),
+ convertPublicKeyToSs58(coldkey.publicKey),
+ netuid
+ )
+
+ if (miner_current_alpha > miner_alpha_before_emission) {
+ console.log("miner got reward");
+ break;
+ }
+
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+ console.log(" waiting for emission");
+ index += 1;
+ }
+ })
+})
diff --git a/evm-tests/test/subnet.precompile.hyperparameter.test.ts b/evm-tests/test/subnet.precompile.hyperparameter.test.ts
new file mode 100644
index 0000000000..1805b85ce9
--- /dev/null
+++ b/evm-tests/test/subnet.precompile.hyperparameter.test.ts
@@ -0,0 +1,442 @@
+import * as assert from "assert";
+
+import { getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate"
+import { devnet } from "@polkadot-api/descriptors"
+import { TypedApi } from "polkadot-api";
+import { convertPublicKeyToSs58 } from "../src/address-utils"
+import { generateRandomEthersWallet } from "../src/utils";
+import { ISubnetABI, ISUBNET_ADDRESS } from "../src/contracts/subnet"
+import { ethers } from "ethers"
+import { forceSetBalanceToEthAddress, forceSetBalanceToSs58Address } from "../src/subtensor"
+
+describe("Test the Subnet precompile contract", () => {
+ // init eth part
+ const wallet = generateRandomEthersWallet();
+ // init substrate part
+
+ const hotkey1 = getRandomSubstrateKeypair();
+ const hotkey2 = getRandomSubstrateKeypair();
+ let api: TypedApi
+
+ before(async () => {
+ // init variables got from await and async
+ api = await getDevnetApi()
+
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey1.publicKey))
+ await forceSetBalanceToSs58Address(api, convertPublicKeyToSs58(hotkey2.publicKey))
+ await forceSetBalanceToEthAddress(api, wallet.address)
+ })
+
+ it("Can register network without identity info", async () => {
+ const totalNetwork = await api.query.SubtensorModule.TotalNetworks.getValue()
+
+ const contract = new ethers.Contract(ISUBNET_ADDRESS, ISubnetABI, wallet);
+ const tx = await contract.registerNetwork(hotkey1.publicKey);
+ await tx.wait();
+
+ const totalNetworkAfterAdd = await api.query.SubtensorModule.TotalNetworks.getValue()
+ assert.ok(totalNetwork + 1 === totalNetworkAfterAdd)
+ });
+
+ it("Can register network with identity info", async () => {
+ const totalNetwork = await api.query.SubtensorModule.TotalNetworks.getValue()
+
+ const contract = new ethers.Contract(ISUBNET_ADDRESS, ISubnetABI, wallet);
+ const tx = await contract.registerNetwork(hotkey2.publicKey,
+ "name",
+ "repo",
+ "contact",
+ "subnetUrl",
+ "discord",
+ "description",
+ "additional"
+ );
+ await tx.wait();
+
+ const totalNetworkAfterAdd = await api.query.SubtensorModule.TotalNetworks.getValue()
+ assert.ok(totalNetwork + 1 === totalNetworkAfterAdd)
+ });
+
+ it("Can set subnet parameter", async () => {
+
+ const totalNetwork = await api.query.SubtensorModule.TotalNetworks.getValue()
+ const contract = new ethers.Contract(ISUBNET_ADDRESS, ISubnetABI, wallet);
+ const netuid = totalNetwork - 1;
+
+ // servingRateLimit hyperparameter
+ {
+ const newValue = 100;
+ const tx = await contract.setServingRateLimit(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.ServingRateLimit.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getServingRateLimit(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // minDifficulty hyperparameter
+ //
+ // disabled: only by sudo
+ //
+ // newValue = 101;
+ // tx = await contract.setMinDifficulty(netuid, newValue);
+ // await tx.wait();
+
+ // await usingApi(async (api) => {
+ // onchainValue = Number(
+ // await api.query.subtensorModule.minDifficulty(netuid)
+ // );
+ // });
+
+ // valueFromContract = Number(await contract.getMinDifficulty(netuid));
+
+ // expect(valueFromContract).to.eq(newValue);
+ // expect(valueFromContract).to.eq(onchainValue);
+
+ // maxDifficulty hyperparameter
+
+ {
+ const newValue = 102;
+ const tx = await contract.setMaxDifficulty(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.MaxDifficulty.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getMaxDifficulty(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // weightsVersionKey hyperparameter
+ {
+ const newValue = 103;
+ const tx = await contract.setWeightsVersionKey(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.WeightsVersionKey.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getWeightsVersionKey(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+ // weightsSetRateLimit hyperparameter
+ {
+ const newValue = 104;
+ const tx = await contract.setWeightsSetRateLimit(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.WeightsSetRateLimit.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getWeightsSetRateLimit(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // adjustmentAlpha hyperparameter
+ {
+ const newValue = 105;
+ const tx = await contract.setAdjustmentAlpha(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.AdjustmentAlpha.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getAdjustmentAlpha(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // maxWeightLimit hyperparameter
+ {
+ const newValue = 106;
+ const tx = await contract.setMaxWeightLimit(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.MaxWeightsLimit.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getMaxWeightLimit(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+ // immunityPeriod hyperparameter
+ {
+ const newValue = 107;
+ const tx = await contract.setImmunityPeriod(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.ImmunityPeriod.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getImmunityPeriod(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // minAllowedWeights hyperparameter
+ {
+ const newValue = 108;
+ const tx = await contract.setMinAllowedWeights(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.MinAllowedWeights.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getMinAllowedWeights(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // kappa hyperparameter
+ {
+ const newValue = 109;
+ const tx = await contract.setKappa(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.Kappa.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getKappa(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // rho hyperparameter
+ {
+ const newValue = 110;
+ const tx = await contract.setRho(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.Rho.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getRho(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // activityCutoff hyperparameter
+ {
+ const newValue = 111;
+ const tx = await contract.setActivityCutoff(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.ActivityCutoff.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getActivityCutoff(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // networkRegistrationAllowed hyperparameter
+ {
+ const newValue = true;
+ const tx = await contract.setNetworkRegistrationAllowed(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.NetworkRegistrationAllowed.getValue(netuid)
+
+
+ let valueFromContract = Boolean(
+ await contract.getNetworkRegistrationAllowed(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // networkPowRegistrationAllowed hyperparameter
+ {
+ const newValue = true;
+ const tx = await contract.setNetworkPowRegistrationAllowed(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.NetworkPowRegistrationAllowed.getValue(netuid)
+
+
+ let valueFromContract = Boolean(
+ await contract.getNetworkPowRegistrationAllowed(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // minBurn hyperparameter. only sudo can set it now
+ // newValue = 112;
+
+ // tx = await contract.setMinBurn(netuid, newValue);
+ // await tx.wait();
+
+ // await usingApi(async (api) => {
+ // onchainValue = Number(
+ // await api.query.subtensorModule.minBurn(netuid)
+ // );
+ // });
+
+ // valueFromContract = Number(await contract.getMinBurn(netuid));
+
+ // expect(valueFromContract).to.eq(newValue);
+ // expect(valueFromContract).to.eq(onchainValue);
+
+ // maxBurn hyperparameter
+ {
+ const newValue = 113;
+ const tx = await contract.setMaxBurn(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.MaxBurn.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getMaxBurn(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+
+ // difficulty hyperparameter (disabled: sudo only)
+ // newValue = 114;
+
+ // tx = await contract.setDifficulty(netuid, newValue);
+ // await tx.wait();
+
+ // await usingApi(async (api) => {
+ // onchainValue = Number(
+ // await api.query.subtensorModule.difficulty(netuid)
+ // );
+ // });
+
+ // valueFromContract = Number(await contract.getDifficulty(netuid));
+
+ // expect(valueFromContract).to.eq(newValue);
+ // expect(valueFromContract).to.eq(onchainValue);
+
+ // bondsMovingAverage hyperparameter
+ {
+ const newValue = 115;
+ const tx = await contract.setBondsMovingAverage(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.BondsMovingAverage.getValue(netuid)
+
+
+ let valueFromContract = Number(
+ await contract.getBondsMovingAverage(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+
+ // commitRevealWeightsEnabled hyperparameter
+ {
+ const newValue = true;
+ const tx = await contract.setCommitRevealWeightsEnabled(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.CommitRevealWeightsEnabled.getValue(netuid)
+
+
+ let valueFromContract = Boolean(
+ await contract.getCommitRevealWeightsEnabled(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // liquidAlphaEnabled hyperparameter
+ {
+ const newValue = true;
+ const tx = await contract.setLiquidAlphaEnabled(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.LiquidAlphaOn.getValue(netuid)
+
+
+ let valueFromContract = Boolean(
+ await contract.getLiquidAlphaEnabled(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+
+ // alphaValues hyperparameter
+ {
+ const newValue = [118, 52429];
+ const tx = await contract.setAlphaValues(netuid, newValue[0], newValue[1]);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.AlphaValues.getValue(netuid)
+
+ let value = await contract.getAlphaValues(netuid)
+ let valueFromContract = [Number(value[0]), Number(value[1])]
+
+ assert.equal(valueFromContract[0], newValue[0])
+ assert.equal(valueFromContract[1], newValue[1])
+ assert.equal(valueFromContract[0], onchainValue[0]);
+ assert.equal(valueFromContract[1], onchainValue[1]);
+ }
+
+ // commitRevealWeightsInterval hyperparameter
+ {
+ const newValue = 119;
+ const tx = await contract.setCommitRevealWeightsInterval(netuid, newValue);
+ await tx.wait();
+
+ let onchainValue = await api.query.SubtensorModule.RevealPeriodEpochs.getValue(netuid)
+
+ let valueFromContract = Number(
+ await contract.getCommitRevealWeightsInterval(netuid)
+ );
+
+ assert.equal(valueFromContract, newValue)
+ assert.equal(valueFromContract, onchainValue);
+ }
+ })
+});
\ No newline at end of file
diff --git a/evm-tests/tsconfig.json b/evm-tests/tsconfig.json
new file mode 100644
index 0000000000..c9c555d96f
--- /dev/null
+++ b/evm-tests/tsconfig.json
@@ -0,0 +1,111 @@
+{
+ "compilerOptions": {
+ /* Visit https://aka.ms/tsconfig to read more about this file */
+
+ /* Projects */
+ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
+ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
+ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
+ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
+ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
+ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
+
+ /* Language and Environment */
+ "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
+ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
+ // "jsx": "preserve", /* Specify what JSX code is generated. */
+ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
+ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
+ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
+ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
+ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
+ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
+ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
+ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
+ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
+
+ /* Modules */
+ "module": "commonjs", /* Specify what module code is generated. */
+ // "rootDir": "./", /* Specify the root folder within your source files. */
+ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
+ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
+ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
+ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
+ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
+ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
+ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
+ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
+ // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */
+ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
+ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
+ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
+ // "noUncheckedSideEffectImports": true, /* Check side effect imports. */
+ // "resolveJsonModule": true, /* Enable importing .json files. */
+ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
+ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
+
+ /* JavaScript Support */
+ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
+ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
+ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
+
+ /* Emit */
+ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
+ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
+ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
+ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
+ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
+ // "noEmit": true, /* Disable emitting files from a compilation. */
+ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
+ // "outDir": "./", /* Specify an output folder for all emitted files. */
+ // "removeComments": true, /* Disable emitting comments. */
+ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
+ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
+ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
+ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
+ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
+ // "newLine": "crlf", /* Set the newline character for emitting files. */
+ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
+ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
+ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
+ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
+ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
+
+ /* Interop Constraints */
+ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
+ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
+ // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
+ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
+ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
+ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
+ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
+
+ /* Type Checking */
+ "strict": true, /* Enable all strict type-checking options. */
+ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
+ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
+ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
+ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
+ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
+ // "strictBuiltinIteratorReturn": true, /* Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'. */
+ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
+ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
+ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
+ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
+ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
+ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
+ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
+ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
+ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
+ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
+ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
+ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
+ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
+
+ /* Completeness */
+ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
+ }
+}
diff --git a/node/Cargo.toml b/node/Cargo.toml
index f97425ba9a..6cea8f6950 100644
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -66,7 +66,7 @@ pallet-transaction-payment = { workspace = true }
pallet-commitments = { path = "../pallets/commitments" }
pallet-drand = { workspace = true }
sp-crypto-ec-utils = { workspace = true }
-sp-keystore = { workspace = true, default-features = false }
+sp-keystore = { workspace = true, default-features = false }
# These dependencies are used for the subtensor's RPCs
@@ -105,9 +105,10 @@ thiserror = { workspace = true }
num-traits = { version = "0.2", features = ["std"] }
# Local Dependencies
-node-subtensor-runtime = { path = "../runtime" }
-subtensor-custom-rpc = { path = "../pallets/subtensor/rpc" }
-subtensor-custom-rpc-runtime-api = { path = "../pallets/subtensor/runtime-api" }
+node-subtensor-runtime = { workspace = true, features = ["std"] }
+subtensor-runtime-common = { workspace = true, features = ["std"] }
+subtensor-custom-rpc = { workspace = true, features = ["std"] }
+subtensor-custom-rpc-runtime-api = { workspace = true, features = ["std"] }
[build-dependencies]
substrate-build-script-utils = { workspace = true }
@@ -133,7 +134,7 @@ runtime-benchmarks = [
"sc-service/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"pallet-commitments/runtime-benchmarks",
- "pallet-drand/runtime-benchmarks"
+ "pallet-drand/runtime-benchmarks",
]
pow-faucet = []
@@ -145,7 +146,7 @@ try-runtime = [
"pallet-transaction-payment/try-runtime",
"sp-runtime/try-runtime",
"pallet-commitments/try-runtime",
- "pallet-drand/try-runtime"
+ "pallet-drand/try-runtime",
]
metadata-hash = ["node-subtensor-runtime/metadata-hash"]
diff --git a/node/src/benchmarking.rs b/node/src/benchmarking.rs
index cee1cb4ac8..40031ac1aa 100644
--- a/node/src/benchmarking.rs
+++ b/node/src/benchmarking.rs
@@ -7,13 +7,14 @@ use crate::client::FullClient;
use node_subtensor_runtime as runtime;
use node_subtensor_runtime::check_nonce;
use node_subtensor_runtime::pallet_subtensor;
-use runtime::{AccountId, Balance, BalancesCall, SystemCall};
+use runtime::{BalancesCall, SystemCall};
use sc_cli::Result;
use sc_client_api::BlockBackend;
use sp_core::{Encode, Pair};
use sp_inherents::{InherentData, InherentDataProvider};
use sp_keyring::Sr25519Keyring;
use sp_runtime::{OpaqueExtrinsic, SaturatedConversion};
+use subtensor_runtime_common::{AccountId, Balance, Signature};
use std::{sync::Arc, time::Duration};
@@ -161,7 +162,7 @@ pub fn create_benchmark_extrinsic(
runtime::UncheckedExtrinsic::new_signed(
call.clone(),
sp_runtime::AccountId32::from(sender.public()).into(),
- runtime::Signature::Sr25519(signature),
+ Signature::Sr25519(signature),
extra.clone(),
)
}
diff --git a/node/src/chain_spec/mod.rs b/node/src/chain_spec/mod.rs
index 25942658d5..e8efbb1647 100644
--- a/node/src/chain_spec/mod.rs
+++ b/node/src/chain_spec/mod.rs
@@ -6,7 +6,7 @@ pub mod finney;
pub mod localnet;
pub mod testnet;
-use node_subtensor_runtime::{AccountId, Block, Signature, WASM_BINARY};
+use node_subtensor_runtime::{Block, WASM_BINARY};
use sc_chain_spec_derive::ChainSpecExtension;
use sc_service::ChainType;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -18,6 +18,7 @@ use sp_runtime::traits::{IdentifyAccount, Verify};
use std::collections::HashSet;
use std::env;
use std::str::FromStr;
+use subtensor_runtime_common::{AccountId, Signature};
// The URL for the telemetry server.
// const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
diff --git a/node/src/rpc.rs b/node/src/rpc.rs
index 39a63c602e..0d4cd355de 100644
--- a/node/src/rpc.rs
+++ b/node/src/rpc.rs
@@ -13,7 +13,6 @@ pub use fc_rpc::EthBlockDataCacheTask;
pub use fc_rpc_core::types::{FeeHistoryCache, FeeHistoryCacheLimit, FilterPool};
use fc_storage::StorageOverride;
use jsonrpsee::RpcModule;
-use node_subtensor_runtime::Hash;
use node_subtensor_runtime::opaque::Block;
use sc_consensus_manual_seal::EngineCommand;
use sc_network::service::traits::NetworkService;
@@ -24,6 +23,7 @@ use sc_transaction_pool_api::TransactionPool;
use sp_core::H256;
use sp_inherents::CreateInherentDataProviders;
use sp_runtime::traits::Block as BlockT;
+use subtensor_runtime_common::Hash;
use crate::{
client::{FullBackend, FullClient},
diff --git a/node/src/service.rs b/node/src/service.rs
index a0b7cb1c6a..4ce041b0a4 100644
--- a/node/src/service.rs
+++ b/node/src/service.rs
@@ -796,7 +796,7 @@ fn run_manual_seal_authorship(
) -> Result<(), sp_inherents::Error> {
TIMESTAMP.with(|x| {
let mut x_ref = x.borrow_mut();
- *x_ref = x_ref.saturating_add(node_subtensor_runtime::SLOT_DURATION);
+ *x_ref = x_ref.saturating_add(subtensor_runtime_common::time::SLOT_DURATION);
inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, &*x.borrow())
})
}
diff --git a/pallets/admin-utils/src/benchmarking.rs b/pallets/admin-utils/src/benchmarking.rs
index af9b68051f..c5794e0279 100644
--- a/pallets/admin-utils/src/benchmarking.rs
+++ b/pallets/admin-utils/src/benchmarking.rs
@@ -272,13 +272,5 @@ mod benchmarks {
_(RawOrigin::Root, 1u16/*netuid*/, true/*enabled*/)/*set_commit_reveal_weights_enabled*/;
}
- #[benchmark]
- fn sudo_set_network_max_stake() {
- pallet_subtensor::Pallet::::init_new_network(1u16 /*netuid*/, 1u16 /*tempo*/);
-
- #[extrinsic_call]
- _(RawOrigin::Root, 1u16/*netuid*/, 1_000_000_000_000_000u64/*max_stake*/)/*sudo_set_network_max_stake*/;
- }
-
//impl_benchmark_test_suite!(AdminUtils, crate::mock::new_test_ext(), crate::mock::Test);
}
diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs
index 7bc9e986e0..0ca6fee2c8 100644
--- a/pallets/admin-utils/src/lib.rs
+++ b/pallets/admin-utils/src/lib.rs
@@ -25,9 +25,13 @@ pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_support::traits::tokens::Balance;
- use frame_support::{dispatch::DispatchResult, pallet_prelude::StorageMap};
+ use frame_support::{
+ dispatch::{DispatchResult, RawOrigin},
+ pallet_prelude::StorageMap,
+ };
use frame_system::pallet_prelude::*;
use pallet_evm_chain_id::{self, ChainId};
+ use pallet_subtensor::utils::rate_limiting::TransactionType;
use sp_runtime::BoundedVec;
use substrate_fixed::types::I96F32;
@@ -249,12 +253,35 @@ pub mod pallet {
netuid: u16,
weights_version_key: u64,
) -> DispatchResult {
- pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?;
+ pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin.clone(), netuid)?;
ensure!(
pallet_subtensor::Pallet::::if_subnet_exist(netuid),
Error::::SubnetDoesNotExist
);
+
+ if let Ok(RawOrigin::Signed(who)) = origin.into() {
+ // SN Owner
+ // Ensure the origin passes the rate limit.
+ ensure!(
+ pallet_subtensor::Pallet::::passes_rate_limit_on_subnet(
+ &TransactionType::SetWeightsVersionKey,
+ &who,
+ netuid,
+ ),
+ pallet_subtensor::Error::::TxRateLimitExceeded
+ );
+
+ // Set last transaction block
+ let current_block = pallet_subtensor::Pallet::::get_current_block_as_u64();
+ pallet_subtensor::Pallet::::set_last_transaction_block_on_subnet(
+ &who,
+ netuid,
+ &TransactionType::SetWeightsVersionKey,
+ current_block,
+ );
+ }
+
pallet_subtensor::Pallet::::set_weights_version_key(netuid, weights_version_key);
log::debug!(
"WeightsVersionKeySet( netuid: {:?} weights_version_key: {:?} ) ",
@@ -910,12 +937,8 @@ pub mod pallet {
DispatchClass::Operational,
Pays::No
))]
- pub fn sudo_set_subnet_limit(origin: OriginFor, max_subnets: u16) -> DispatchResult {
+ pub fn sudo_set_subnet_limit(origin: OriginFor, _max_subnets: u16) -> DispatchResult {
ensure_root(origin)?;
- pallet_subtensor::Pallet::::set_max_subnets(max_subnets);
-
- log::debug!("SubnetLimit( max_subnets: {:?} ) ", max_subnets);
-
Ok(())
}
@@ -1155,22 +1178,11 @@ pub mod pallet {
#[pallet::weight((0, DispatchClass::Operational, Pays::No))]
pub fn sudo_set_network_max_stake(
origin: OriginFor,
- netuid: u16,
- max_stake: u64,
+ _netuid: u16,
+ _max_stake: u64,
) -> DispatchResult {
// Ensure the call is made by the root account
ensure_root(origin)?;
-
- // Set the new maximum stake for the specified network
- pallet_subtensor::Pallet::::set_network_max_stake(netuid, max_stake);
-
- // Log the change
- log::trace!(
- "NetworkMaxStakeSet( netuid: {:?}, max_stake: {:?} )",
- netuid,
- max_stake
- );
-
Ok(())
}
@@ -1399,6 +1411,65 @@ pub mod pallet {
log::debug!("SubnetMovingAlphaSet( alpha: {:?} )", alpha);
Ok(())
}
+
+ /// Change the SubnetOwnerHotkey for a given subnet.
+ ///
+ /// # Arguments
+ /// * `origin` - The origin of the call, which must be the subnet owner.
+ /// * `netuid` - The unique identifier for the subnet.
+ /// * `hotkey` - The new hotkey for the subnet owner.
+ ///
+ /// # Errors
+ /// * `BadOrigin` - If the caller is not the subnet owner or root account.
+ ///
+ /// # Weight
+ /// Weight is handled by the `#[pallet::weight]` attribute.
+ #[pallet::call_index(64)]
+ #[pallet::weight((0, DispatchClass::Operational, Pays::No))]
+ pub fn sudo_set_subnet_owner_hotkey(
+ origin: OriginFor,
+ netuid: u16,
+ hotkey: T::AccountId,
+ ) -> DispatchResult {
+ pallet_subtensor::Pallet::::ensure_subnet_owner(origin.clone(), netuid)?;
+ pallet_subtensor::Pallet::::set_subnet_owner_hotkey(netuid, &hotkey);
+
+ log::debug!(
+ "SubnetOwnerHotkeySet( netuid: {:?}, hotkey: {:?} )",
+ netuid,
+ hotkey
+ );
+ Ok(())
+ }
+
+ ///
+ ///
+ /// # Arguments
+ /// * `origin` - The origin of the call, which must be the root account.
+ /// * `ema_alpha_period` - Number of blocks for EMA price to halve
+ ///
+ /// # Errors
+ /// * `BadOrigin` - If the caller is not the root account.
+ ///
+ /// # Weight
+ /// Weight is handled by the `#[pallet::weight]` attribute.
+ #[pallet::call_index(65)]
+ #[pallet::weight((0, DispatchClass::Operational, Pays::No))]
+ pub fn sudo_set_ema_price_halving_period(
+ origin: OriginFor,
+ netuid: u16,
+ ema_halving: u64,
+ ) -> DispatchResult {
+ ensure_root(origin)?;
+ pallet_subtensor::EMAPriceHalvingBlocks::::set(netuid, ema_halving);
+
+ log::debug!(
+ "EMAPriceHalvingBlocks( netuid: {:?}, ema_halving: {:?} )",
+ netuid,
+ ema_halving
+ );
+ Ok(())
+ }
}
}
diff --git a/pallets/admin-utils/src/tests/mock.rs b/pallets/admin-utils/src/tests/mock.rs
index 40e29e54dd..fc0d016198 100644
--- a/pallets/admin-utils/src/tests/mock.rs
+++ b/pallets/admin-utils/src/tests/mock.rs
@@ -123,17 +123,18 @@ parameter_types! {
pub const InitialNetworkMinLockCost: u64 = 100_000_000_000;
pub const InitialSubnetOwnerCut: u16 = 0; // 0%. 100% of rewards go to validators + miners.
pub const InitialNetworkLockReductionInterval: u64 = 2; // 2 blocks.
- pub const InitialSubnetLimit: u16 = 10; // Max 10 subnets.
+ // pub const InitialSubnetLimit: u16 = 10; // (DEPRECATED)
pub const InitialNetworkRateLimit: u64 = 0;
pub const InitialKeySwapCost: u64 = 1_000_000_000;
pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default
pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default
pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn
// pub const InitialHotkeyEmissionTempo: u64 = 1; // (DEPRECATED)
- pub const InitialNetworkMaxStake: u64 = u64::MAX; // Maximum possible value for u64, this make the make stake infinity
+ // pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED)
pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight.
+ pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks
}
impl pallet_subtensor::Config for Test {
@@ -188,18 +189,16 @@ impl pallet_subtensor::Config for Test {
type InitialNetworkMinLockCost = InitialNetworkMinLockCost;
type InitialSubnetOwnerCut = InitialSubnetOwnerCut;
type InitialNetworkLockReductionInterval = InitialNetworkLockReductionInterval;
- type InitialSubnetLimit = InitialSubnetLimit;
type InitialNetworkRateLimit = InitialNetworkRateLimit;
type KeySwapCost = InitialKeySwapCost;
type AlphaHigh = InitialAlphaHigh;
type AlphaLow = InitialAlphaLow;
type LiquidAlphaOn = InitialLiquidAlphaOn;
- // type InitialHotkeyEmissionTempo = InitialHotkeyEmissionTempo; // (DEPRECATED)
- type InitialNetworkMaxStake = InitialNetworkMaxStake;
type Preimages = ();
type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration;
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
+ type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
}
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs
index 6c879635e3..ed7ddcbcb2 100644
--- a/pallets/admin-utils/src/tests/mod.rs
+++ b/pallets/admin-utils/src/tests/mod.rs
@@ -5,7 +5,7 @@ use frame_support::{
traits::Hooks,
};
use frame_system::Config;
-use pallet_subtensor::Error as SubtensorError;
+use pallet_subtensor::{Error as SubtensorError, SubnetOwner, Tempo, WeightsVersionKeyRateLimit};
// use pallet_subtensor::{migrations, Event};
use pallet_subtensor::Event;
use sp_consensus_grandpa::AuthorityId as GrandpaId;
@@ -162,6 +162,107 @@ fn test_sudo_set_weights_version_key() {
});
}
+#[test]
+fn test_sudo_set_weights_version_key_rate_limit() {
+ new_test_ext().execute_with(|| {
+ let netuid: u16 = 1;
+ let to_be_set: u64 = 10;
+
+ let sn_owner = U256::from(1);
+ add_network(netuid, 10);
+ // Set the Subnet Owner
+ SubnetOwner::::insert(netuid, sn_owner);
+
+ let rate_limit = WeightsVersionKeyRateLimit::::get();
+ let tempo: u16 = Tempo::::get(netuid);
+
+ let rate_limit_period = rate_limit * (tempo as u64);
+
+ assert_ok!(AdminUtils::sudo_set_weights_version_key(
+ <::RuntimeOrigin>::signed(sn_owner),
+ netuid,
+ to_be_set
+ ));
+ assert_eq!(SubtensorModule::get_weights_version_key(netuid), to_be_set);
+
+ // Try to set again with
+ // Assert rate limit not passed
+ assert!(!SubtensorModule::passes_rate_limit_on_subnet(
+ &pallet_subtensor::utils::rate_limiting::TransactionType::SetWeightsVersionKey,
+ &sn_owner,
+ netuid
+ ));
+
+ // Try transaction
+ assert_noop!(
+ AdminUtils::sudo_set_weights_version_key(
+ <::RuntimeOrigin>::signed(sn_owner),
+ netuid,
+ to_be_set + 1
+ ),
+ pallet_subtensor::Error::::TxRateLimitExceeded
+ );
+
+ // Wait for rate limit to pass
+ run_to_block(rate_limit_period + 2);
+ assert!(SubtensorModule::passes_rate_limit_on_subnet(
+ &pallet_subtensor::utils::rate_limiting::TransactionType::SetWeightsVersionKey,
+ &sn_owner,
+ netuid
+ ));
+
+ // Try transaction
+ assert_ok!(AdminUtils::sudo_set_weights_version_key(
+ <::RuntimeOrigin>::signed(sn_owner),
+ netuid,
+ to_be_set + 1
+ ));
+ assert_eq!(
+ SubtensorModule::get_weights_version_key(netuid),
+ to_be_set + 1
+ );
+ });
+}
+
+#[test]
+fn test_sudo_set_weights_version_key_rate_limit_root() {
+ // root should not be effected by rate limit
+ new_test_ext().execute_with(|| {
+ let netuid: u16 = 1;
+ let to_be_set: u64 = 10;
+
+ let sn_owner = U256::from(1);
+ add_network(netuid, 10);
+ // Set the Subnet Owner
+ SubnetOwner::::insert(netuid, sn_owner);
+
+ let rate_limit = WeightsVersionKeyRateLimit::::get();
+ let tempo: u16 = Tempo::::get(netuid);
+
+ let rate_limit_period = rate_limit * (tempo as u64);
+ // Verify the rate limit is more than 0 blocks
+ assert!(rate_limit_period > 0);
+
+ assert_ok!(AdminUtils::sudo_set_weights_version_key(
+ <::RuntimeOrigin>::root(),
+ netuid,
+ to_be_set
+ ));
+ assert_eq!(SubtensorModule::get_weights_version_key(netuid), to_be_set);
+
+ // Try transaction
+ assert_ok!(AdminUtils::sudo_set_weights_version_key(
+ <::RuntimeOrigin>::signed(sn_owner),
+ netuid,
+ to_be_set + 1
+ ));
+ assert_eq!(
+ SubtensorModule::get_weights_version_key(netuid),
+ to_be_set + 1
+ );
+ });
+}
+
#[test]
fn test_sudo_set_weights_set_rate_limit() {
new_test_ext().execute_with(|| {
@@ -850,30 +951,6 @@ fn test_sudo_set_rao_recycled() {
});
}
-#[test]
-fn test_sudo_set_subnet_limit() {
- new_test_ext().execute_with(|| {
- let netuid: u16 = 1;
- let to_be_set: u16 = 10;
- add_network(netuid, 10);
-
- let init_value: u16 = SubtensorModule::get_max_subnets();
- assert_eq!(
- AdminUtils::sudo_set_subnet_limit(
- <::RuntimeOrigin>::signed(U256::from(1)),
- to_be_set
- ),
- Err(DispatchError::BadOrigin)
- );
- assert_eq!(SubtensorModule::get_max_subnets(), init_value);
- assert_ok!(AdminUtils::sudo_set_subnet_limit(
- <::RuntimeOrigin>::root(),
- to_be_set
- ));
- assert_eq!(SubtensorModule::get_max_subnets(), to_be_set);
- });
-}
-
#[test]
fn test_sudo_set_network_lock_reduction_interval() {
new_test_ext().execute_with(|| {
@@ -1466,3 +1543,171 @@ fn test_sudo_root_sets_subnet_moving_alpha() {
assert_eq!(pallet_subtensor::SubnetMovingAlpha::::get(), alpha);
});
}
+
+#[test]
+fn test_sets_a_lower_value_clears_small_nominations() {
+ new_test_ext().execute_with(|| {
+ let hotkey: U256 = U256::from(3);
+ let owner_coldkey: U256 = U256::from(1);
+ let staker_coldkey: U256 = U256::from(2);
+
+ let initial_nominator_min_required_stake = 10u64;
+ let nominator_min_required_stake_0 = 5u64;
+ let nominator_min_required_stake_1 = 20u64;
+
+ assert!(nominator_min_required_stake_0 < nominator_min_required_stake_1);
+ assert!(nominator_min_required_stake_0 < initial_nominator_min_required_stake);
+
+ let to_stake = initial_nominator_min_required_stake + 1;
+
+ assert!(to_stake > initial_nominator_min_required_stake);
+ assert!(to_stake > nominator_min_required_stake_0); // Should stay when set
+ assert!(to_stake < nominator_min_required_stake_1); // Should be removed when set
+
+ // Create network
+ let netuid = 2;
+ add_network(netuid, 10);
+
+ // Register a neuron
+ register_ok_neuron(netuid, hotkey, owner_coldkey, 0);
+
+ assert_ok!(AdminUtils::sudo_set_nominator_min_required_stake(
+ RuntimeOrigin::root(),
+ initial_nominator_min_required_stake
+ ));
+ assert_eq!(
+ SubtensorModule::get_nominator_min_required_stake(),
+ initial_nominator_min_required_stake
+ );
+
+ // Stake to the hotkey as staker_coldkey
+ SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
+ &hotkey,
+ &staker_coldkey,
+ netuid,
+ to_stake,
+ );
+
+ assert_ok!(AdminUtils::sudo_set_nominator_min_required_stake(
+ RuntimeOrigin::root(),
+ nominator_min_required_stake_0
+ ));
+ assert_eq!(
+ SubtensorModule::get_nominator_min_required_stake(),
+ nominator_min_required_stake_0
+ );
+
+ // Check this nomination is not cleared
+ assert!(
+ SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
+ &hotkey,
+ &staker_coldkey,
+ netuid
+ ) > 0
+ );
+
+ assert_ok!(AdminUtils::sudo_set_nominator_min_required_stake(
+ RuntimeOrigin::root(),
+ nominator_min_required_stake_1
+ ));
+ assert_eq!(
+ SubtensorModule::get_nominator_min_required_stake(),
+ nominator_min_required_stake_1
+ );
+
+ // Check this nomination is cleared
+ assert_eq!(
+ SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
+ &hotkey,
+ &staker_coldkey,
+ netuid
+ ),
+ 0
+ );
+ });
+}
+
+#[test]
+fn test_sudo_set_subnet_owner_hotkey() {
+ new_test_ext().execute_with(|| {
+ let netuid: u16 = 1;
+
+ let coldkey: U256 = U256::from(1);
+ let hotkey: U256 = U256::from(2);
+ let new_hotkey: U256 = U256::from(3);
+
+ let coldkey_origin = <::RuntimeOrigin>::signed(coldkey);
+ let root = RuntimeOrigin::root();
+ let random_account = RuntimeOrigin::signed(U256::from(123456));
+
+ pallet_subtensor::SubnetOwner::::insert(netuid, coldkey);
+ pallet_subtensor::SubnetOwnerHotkey::::insert(netuid, hotkey);
+ assert_eq!(
+ pallet_subtensor::SubnetOwnerHotkey::::get(netuid),
+ hotkey
+ );
+
+ assert_ok!(AdminUtils::sudo_set_subnet_owner_hotkey(
+ coldkey_origin,
+ netuid,
+ new_hotkey
+ ));
+
+ assert_eq!(
+ pallet_subtensor::SubnetOwnerHotkey::::get(netuid),
+ new_hotkey
+ );
+
+ assert_noop!(
+ AdminUtils::sudo_set_subnet_owner_hotkey(random_account, netuid, new_hotkey),
+ DispatchError::BadOrigin
+ );
+
+ assert_noop!(
+ AdminUtils::sudo_set_subnet_owner_hotkey(root, netuid, new_hotkey),
+ DispatchError::BadOrigin
+ );
+ });
+}
+
+// cargo test --package pallet-admin-utils --lib -- tests::test_sudo_set_ema_halving --exact --show-output
+#[test]
+fn test_sudo_set_ema_halving() {
+ new_test_ext().execute_with(|| {
+ let netuid: u16 = 1;
+ let to_be_set: u64 = 10;
+ add_network(netuid, 10);
+
+ let value_before: u64 = pallet_subtensor::EMAPriceHalvingBlocks::::get(netuid);
+ assert_eq!(
+ AdminUtils::sudo_set_ema_price_halving_period(
+ <::RuntimeOrigin>::signed(U256::from(1)),
+ netuid,
+ to_be_set
+ ),
+ Err(DispatchError::BadOrigin)
+ );
+ let value_after_0: u64 = pallet_subtensor::EMAPriceHalvingBlocks::::get(netuid);
+ assert_eq!(value_after_0, value_before);
+
+ let owner = U256::from(10);
+ pallet_subtensor::SubnetOwner::::insert(netuid, owner);
+ assert_eq!(
+ AdminUtils::sudo_set_ema_price_halving_period(
+ <::RuntimeOrigin>::signed(owner),
+ netuid,
+ to_be_set
+ ),
+ Err(DispatchError::BadOrigin)
+ );
+ let value_after_1: u64 = pallet_subtensor::EMAPriceHalvingBlocks::::get(netuid);
+ assert_eq!(value_after_1, value_before);
+ assert_ok!(AdminUtils::sudo_set_ema_price_halving_period(
+ <::RuntimeOrigin>::root(),
+ netuid,
+ to_be_set
+ ));
+ let value_after_2: u64 = pallet_subtensor::EMAPriceHalvingBlocks::::get(netuid);
+ assert_eq!(value_after_2, to_be_set);
+ });
+}
diff --git a/pallets/proxy/Cargo.toml b/pallets/proxy/Cargo.toml
new file mode 100644
index 0000000000..f3a97dfedf
--- /dev/null
+++ b/pallets/proxy/Cargo.toml
@@ -0,0 +1,57 @@
+[package]
+name = "pallet-proxy"
+version = "38.0.0"
+authors = ["Bittensor Nucleus Team"]
+edition = "2021"
+license = "Apache-2.0"
+homepage = "https://bittensor.com"
+description = "FRAME proxying pallet"
+readme = "README.md"
+
+[lints]
+workspace = true
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies]
+codec = { features = ["max-encoded-len"], workspace = true }
+scale-info = { features = ["derive"], workspace = true }
+frame-benchmarking = { optional = true, workspace = true }
+frame-support.workspace = true
+frame-system.workspace = true
+sp-io.workspace = true
+sp-runtime.workspace = true
+subtensor-macros.workspace = true
+
+[dev-dependencies]
+pallet-balances = { default-features = true, workspace = true }
+pallet-utility = { default-features = true, workspace = true }
+sp-core = { default-features = true, workspace = true }
+
+[features]
+default = ["std"]
+std = [
+ "codec/std",
+ "frame-benchmarking?/std",
+ "frame-support/std",
+ "frame-system/std",
+ "scale-info/std",
+ "sp-io/std",
+ "sp-runtime/std",
+]
+runtime-benchmarks = [
+ "frame-benchmarking/runtime-benchmarks",
+ "frame-support/runtime-benchmarks",
+ "frame-system/runtime-benchmarks",
+ "sp-runtime/runtime-benchmarks",
+ "pallet-balances/runtime-benchmarks",
+ "pallet-utility/runtime-benchmarks"
+]
+try-runtime = [
+ "frame-support/try-runtime",
+ "frame-system/try-runtime",
+ "sp-runtime/try-runtime",
+ "pallet-balances/try-runtime",
+ "pallet-utility/try-runtime"
+]
diff --git a/pallets/proxy/README.md b/pallets/proxy/README.md
new file mode 100644
index 0000000000..290c49c050
--- /dev/null
+++ b/pallets/proxy/README.md
@@ -0,0 +1,26 @@
+# Proxy Module
+A module allowing accounts to give permission to other accounts to dispatch types of calls from
+their signed origin.
+
+The accounts to which permission is delegated may be required to announce the action that they
+wish to execute some duration prior to execution happens. In this case, the target account may
+reject the announcement and in doing so, veto the execution.
+
+- [`Config`](https://docs.rs/pallet-proxy/latest/pallet_proxy/pallet/trait.Config.html)
+- [`Call`](https://docs.rs/pallet-proxy/latest/pallet_proxy/pallet/enum.Call.html)
+
+## Overview
+
+## Interface
+
+### Dispatchable Functions
+
+[`Call`]: ./enum.Call.html
+[`Config`]: ./trait.Config.html
+
+License: Apache-2.0
+
+
+## Release
+
+Polkadot SDK stable2409
diff --git a/pallets/proxy/src/benchmarking.rs b/pallets/proxy/src/benchmarking.rs
new file mode 100644
index 0000000000..f519c0f0c3
--- /dev/null
+++ b/pallets/proxy/src/benchmarking.rs
@@ -0,0 +1,261 @@
+// This file is part of Substrate.
+//
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Benchmarks for Proxy Pallet
+
+#![cfg(feature = "runtime-benchmarks")]
+
+use super::*;
+use crate::Pallet as Proxy;
+use alloc::{boxed::Box, vec};
+use frame_benchmarking::v1::{account, benchmarks, whitelisted_caller};
+use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
+use sp_runtime::traits::{Bounded, CheckedDiv};
+
+const SEED: u32 = 0;
+
+fn assert_last_event(generic_event: ::RuntimeEvent) {
+ frame_system::Pallet::::assert_last_event(generic_event.into());
+}
+
+fn half_max_balance() -> BalanceOf {
+ BalanceOf::::max_value()
+ .checked_div(&BalanceOf::::from(2_u32))
+ .unwrap_or_else(BalanceOf::::max_value)
+}
+
+fn add_proxies(n: u32, maybe_who: Option) -> Result<(), &'static str> {
+ let caller = maybe_who.unwrap_or_else(whitelisted_caller);
+ T::Currency::make_free_balance_be(&caller, half_max_balance::());
+ for i in 0..n {
+ let real = T::Lookup::unlookup(account("target", i, SEED));
+
+ Proxy::::add_proxy(
+ RawOrigin::Signed(caller.clone()).into(),
+ real,
+ T::ProxyType::default(),
+ BlockNumberFor::::zero(),
+ )?;
+ }
+ Ok(())
+}
+
+fn add_announcements(
+ n: u32,
+ maybe_who: Option,
+ maybe_real: Option,
+) -> Result<(), &'static str> {
+ let caller = maybe_who.unwrap_or_else(|| account("caller", 0, SEED));
+ let caller_lookup = T::Lookup::unlookup(caller.clone());
+ T::Currency::make_free_balance_be(&caller, half_max_balance::());
+ let real = if let Some(real) = maybe_real {
+ real
+ } else {
+ let real = account("real", 0, SEED);
+ T::Currency::make_free_balance_be(&real, half_max_balance::());
+ Proxy::::add_proxy(
+ RawOrigin::Signed(real.clone()).into(),
+ caller_lookup,
+ T::ProxyType::default(),
+ BlockNumberFor::::zero(),
+ )?;
+ real
+ };
+ let real_lookup = T::Lookup::unlookup(real);
+ for _ in 0..n {
+ Proxy::::announce(
+ RawOrigin::Signed(caller.clone()).into(),
+ real_lookup.clone(),
+ T::CallHasher::hash_of(&("add_announcement", n)),
+ )?;
+ }
+ Ok(())
+}
+
+benchmarks! {
+ proxy {
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = account("target", p.saturating_sub(1), SEED);
+ T::Currency::make_free_balance_be(&caller, half_max_balance::());
+ let real: T::AccountId = whitelisted_caller();
+ let real_lookup = T::Lookup::unlookup(real);
+ let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into();
+ }: _(RawOrigin::Signed(caller), real_lookup, Some(T::ProxyType::default()), Box::new(call))
+ verify {
+ assert_last_event::(Event::ProxyExecuted { result: Ok(()) }.into())
+ }
+
+ proxy_announced {
+ let a in 0 .. T::MaxPending::get().saturating_sub(1);
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = account("pure", 0, SEED);
+ let delegate: T::AccountId = account("target", p.saturating_sub(1), SEED);
+ let delegate_lookup = T::Lookup::unlookup(delegate.clone());
+ T::Currency::make_free_balance_be(&delegate, half_max_balance::());
+ let real: T::AccountId = whitelisted_caller();
+ let real_lookup = T::Lookup::unlookup(real);
+ let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into();
+ Proxy::::announce(
+ RawOrigin::Signed(delegate.clone()).into(),
+ real_lookup.clone(),
+ T::CallHasher::hash_of(&call),
+ )?;
+ add_announcements::(a, Some(delegate.clone()), None)?;
+ }: _(RawOrigin::Signed(caller), delegate_lookup, real_lookup, Some(T::ProxyType::default()), Box::new(call))
+ verify {
+ assert_last_event::(Event::ProxyExecuted { result: Ok(()) }.into())
+ }
+
+ remove_announcement {
+ let a in 0 .. T::MaxPending::get().saturating_sub(1);
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = account("target", p.saturating_sub(1), SEED);
+ T::Currency::make_free_balance_be(&caller, half_max_balance::());
+ let real: T::AccountId = whitelisted_caller();
+ let real_lookup = T::Lookup::unlookup(real);
+ let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into();
+ Proxy::::announce(
+ RawOrigin::Signed(caller.clone()).into(),
+ real_lookup.clone(),
+ T::CallHasher::hash_of(&call),
+ )?;
+ add_announcements::(a, Some(caller.clone()), None)?;
+ }: _(RawOrigin::Signed(caller.clone()), real_lookup, T::CallHasher::hash_of(&call))
+ verify {
+ let (announcements, _) = Announcements::::get(&caller);
+ assert_eq!(announcements.len() as u32, a);
+ }
+
+ reject_announcement {
+ let a in 0 .. T::MaxPending::get().saturating_sub(1);
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = account("target", p.saturating_sub(1), SEED);
+ let caller_lookup = T::Lookup::unlookup(caller.clone());
+ T::Currency::make_free_balance_be(&caller, half_max_balance::());
+ let real: T::AccountId = whitelisted_caller();
+ let real_lookup = T::Lookup::unlookup(real.clone());
+ let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into();
+ Proxy::::announce(
+ RawOrigin::Signed(caller.clone()).into(),
+ real_lookup,
+ T::CallHasher::hash_of(&call),
+ )?;
+ add_announcements::(a, Some(caller.clone()), None)?;
+ }: _(RawOrigin::Signed(real), caller_lookup, T::CallHasher::hash_of(&call))
+ verify {
+ let (announcements, _) = Announcements::::get(&caller);
+ assert_eq!(announcements.len() as u32, a);
+ }
+
+ announce {
+ let a in 0 .. T::MaxPending::get().saturating_sub(1);
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = account("target", p.saturating_sub(1), SEED);
+ T::Currency::make_free_balance_be(&caller, half_max_balance::());
+ let real: T::AccountId = whitelisted_caller();
+ let real_lookup = T::Lookup::unlookup(real.clone());
+ add_announcements::(a, Some(caller.clone()), None)?;
+ let call: ::RuntimeCall = frame_system::Call::::remark { remark: vec![] }.into();
+ let call_hash = T::CallHasher::hash_of(&call);
+ }: _(RawOrigin::Signed(caller.clone()), real_lookup, call_hash)
+ verify {
+ assert_last_event::(Event::Announced { real, proxy: caller, call_hash }.into());
+ }
+
+ add_proxy {
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = whitelisted_caller();
+ let real = T::Lookup::unlookup(account("target", T::MaxProxies::get(), SEED));
+ }: _(
+ RawOrigin::Signed(caller.clone()),
+ real,
+ T::ProxyType::default(),
+ BlockNumberFor::::zero()
+ )
+ verify {
+ let (proxies, _) = Proxies::::get(caller);
+ assert_eq!(proxies.len() as u32, p.saturating_add(1));
+ }
+
+ remove_proxy {
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = whitelisted_caller();
+ let delegate = T::Lookup::unlookup(account("target", 0, SEED));
+ }: _(
+ RawOrigin::Signed(caller.clone()),
+ delegate,
+ T::ProxyType::default(),
+ BlockNumberFor::::zero()
+ )
+ verify {
+ let (proxies, _) = Proxies::::get(caller);
+ assert_eq!(proxies.len() as u32, p.saturating_sub(1));
+ }
+
+ remove_proxies {
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = whitelisted_caller();
+ }: _(RawOrigin::Signed(caller.clone()))
+ verify {
+ let (proxies, _) = Proxies::::get(caller);
+ assert_eq!(proxies.len() as u32, 0);
+ }
+
+ create_pure {
+ let p in 1 .. (T::MaxProxies::get().saturating_sub(1)) => add_proxies::(p, None)?;
+ let caller: T::AccountId = whitelisted_caller();
+ }: _(
+ RawOrigin::Signed(caller.clone()),
+ T::ProxyType::default(),
+ BlockNumberFor::::zero(),
+ 0
+ )
+ verify {
+ let pure_account = Pallet::::pure_account(&caller, &T::ProxyType::default(), 0, None);
+ assert_last_event::(Event::PureCreated {
+ pure: pure_account,
+ who: caller,
+ proxy_type: T::ProxyType::default(),
+ disambiguation_index: 0,
+ }.into());
+ }
+
+ kill_pure {
+ let p in 0 .. (T::MaxProxies::get().saturating_sub(2));
+
+ let caller: T::AccountId = whitelisted_caller();
+ let caller_lookup = T::Lookup::unlookup(caller.clone());
+ T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value());
+ Pallet::::create_pure(
+ RawOrigin::Signed(whitelisted_caller()).into(),
+ T::ProxyType::default(),
+ BlockNumberFor::::zero(),
+ 0
+ )?;
+ let height = system::Pallet::::block_number();
+ let ext_index = system::Pallet::::extrinsic_index().unwrap_or(0);
+ let pure_account = Pallet::::pure_account(&caller, &T::ProxyType::default(), 0, None);
+
+ add_proxies::(p, Some(pure_account.clone()))?;
+ ensure!(Proxies::::contains_key(&pure_account), "pure proxy not created");
+ }: _(RawOrigin::Signed(pure_account.clone()), caller_lookup, T::ProxyType::default(), 0, height, ext_index)
+ verify {
+ assert!(!Proxies::::contains_key(&pure_account));
+ }
+
+ impl_benchmark_test_suite!(Proxy, crate::tests::new_test_ext(), crate::tests::Test);
+}
diff --git a/pallets/proxy/src/lib.rs b/pallets/proxy/src/lib.rs
new file mode 100644
index 0000000000..3f45951190
--- /dev/null
+++ b/pallets/proxy/src/lib.rs
@@ -0,0 +1,891 @@
+// This file is part of Substrate.
+//
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! # Proxy Pallet
+//! A pallet allowing accounts to give permission to other accounts to dispatch types of calls from
+//! their signed origin.
+//!
+//! The accounts to which permission is delegated may be required to announce the action that they
+//! wish to execute some duration prior to execution happens. In this case, the target account may
+//! reject the announcement and in doing so, veto the execution.
+//!
+//! - [`Config`]
+//! - [`Call`]
+
+// Ensure we're `no_std` when compiling for Wasm.
+#![cfg_attr(not(feature = "std"), no_std)]
+
+mod benchmarking;
+mod tests;
+pub mod weights;
+
+extern crate alloc;
+
+use alloc::{boxed::Box, vec};
+use codec::{Decode, Encode, MaxEncodedLen};
+use frame_support::pallet_prelude::{Pays, Weight};
+use frame_support::{
+ dispatch::GetDispatchInfo,
+ ensure,
+ traits::{Currency, Get, InstanceFilter, IsSubType, IsType, OriginTrait, ReservableCurrency},
+ BoundedVec,
+};
+use frame_system::{self as system, ensure_signed, pallet_prelude::BlockNumberFor};
+pub use pallet::*;
+use scale_info::{prelude::cmp::Ordering, TypeInfo};
+use sp_io::hashing::blake2_256;
+use sp_runtime::{
+ traits::{Dispatchable, Hash, Saturating, StaticLookup, TrailingZeroInput, Zero},
+ DispatchError, DispatchResult, RuntimeDebug,
+};
+use subtensor_macros::freeze_struct;
+pub use weights::WeightInfo;
+
+type CallHashOf = <::CallHasher as Hash>::Output;
+
+type BalanceOf =
+ <::Currency as Currency<::AccountId>>::Balance;
+
+type AccountIdLookupOf = <::Lookup as StaticLookup>::Source;
+
+/// The parameters under which a particular account has a proxy relationship with some other
+/// account.
+#[derive(
+ Encode,
+ Decode,
+ Clone,
+ Copy,
+ Eq,
+ PartialEq,
+ Ord,
+ PartialOrd,
+ RuntimeDebug,
+ MaxEncodedLen,
+ TypeInfo,
+)]
+#[freeze_struct("a37bb67fe5520678")]
+pub struct ProxyDefinition {
+ /// The account which may act on behalf of another.
+ pub delegate: AccountId,
+ /// A value defining the subset of calls that it is allowed to make.
+ pub proxy_type: ProxyType,
+ /// The number of blocks that an announcement must be in place for before the corresponding
+ /// call may be dispatched. If zero, then no announcement is needed.
+ pub delay: BlockNumber,
+}
+
+/// Details surrounding a specific instance of an announcement to make a call.
+#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
+#[freeze_struct("4c1b5c8c3bc489ad")]
+pub struct Announcement {
+ /// The account which made the announcement.
+ real: AccountId,
+ /// The hash of the call to be made.
+ call_hash: Hash,
+ /// The height at which the announcement was made.
+ height: BlockNumber,
+}
+
+#[frame_support::pallet]
+pub mod pallet {
+ use super::{DispatchResult, *};
+ use frame_support::pallet_prelude::*;
+ use frame_system::pallet_prelude::*;
+
+ #[pallet::pallet]
+ pub struct Pallet(_);
+
+ /// Configuration trait.
+ #[pallet::config]
+ pub trait Config: frame_system::Config {
+ /// The overarching event type.
+ type RuntimeEvent: From> + IsType<::RuntimeEvent>;
+
+ /// The overarching call type.
+ type RuntimeCall: Parameter
+ + Dispatchable
+ + GetDispatchInfo
+ + From>
+ + IsSubType>
+ + IsType<::RuntimeCall>;
+
+ /// The currency mechanism.
+ type Currency: ReservableCurrency;
+
+ /// A kind of proxy; specified with the proxy and passed in to the `IsProxyable` filter.
+ /// The instance filter determines whether a given call may be proxied under this type.
+ ///
+ /// IMPORTANT: `Default` must be provided and MUST BE the the *most permissive* value.
+ type ProxyType: Parameter
+ + Member
+ + Ord
+ + PartialOrd
+ + InstanceFilter<::RuntimeCall>
+ + Default
+ + MaxEncodedLen;
+
+ /// The base amount of currency needed to reserve for creating a proxy.
+ ///
+ /// This is held for an additional storage item whose value size is
+ /// `sizeof(Balance)` bytes and whose key size is `sizeof(AccountId)` bytes.
+ #[pallet::constant]
+ type ProxyDepositBase: Get>;
+
+ /// The amount of currency needed per proxy added.
+ ///
+ /// This is held for adding 32 bytes plus an instance of `ProxyType` more into a
+ /// pre-existing storage value. Thus, when configuring `ProxyDepositFactor` one should take
+ /// into account `32 + proxy_type.encode().len()` bytes of data.
+ #[pallet::constant]
+ type ProxyDepositFactor: Get>;
+
+ /// The maximum amount of proxies allowed for a single account.
+ #[pallet::constant]
+ type MaxProxies: Get;
+
+ /// Weight information for extrinsics in this pallet.
+ type WeightInfo: WeightInfo;
+
+ /// The maximum amount of time-delayed announcements that are allowed to be pending.
+ #[pallet::constant]
+ type MaxPending: Get;
+
+ /// The type of hash used for hashing the call.
+ type CallHasher: Hash;
+
+ /// The base amount of currency needed to reserve for creating an announcement.
+ ///
+ /// This is held when a new storage item holding a `Balance` is created (typically 16
+ /// bytes).
+ #[pallet::constant]
+ type AnnouncementDepositBase: Get>;
+
+ /// The amount of currency needed per announcement made.
+ ///
+ /// This is held for adding an `AccountId`, `Hash` and `BlockNumber` (typically 68 bytes)
+ /// into a pre-existing storage value.
+ #[pallet::constant]
+ type AnnouncementDepositFactor: Get>;
+ }
+
+ #[pallet::call]
+ impl Pallet {
+ /// Dispatch the given `call` from an account that the sender is authorised for through
+ /// `add_proxy`.
+ ///
+ /// The dispatch origin for this call must be _Signed_.
+ ///
+ /// Parameters:
+ /// - `real`: The account that the proxy will make a call on behalf of.
+ /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call.
+ /// - `call`: The call to be made by the `real` account.
+ #[pallet::call_index(0)]
+ #[pallet::weight({
+ let di = call.get_dispatch_info();
+ let inner_call_weight = match di.pays_fee {
+ Pays::Yes => di.weight,
+ Pays::No => Weight::zero(),
+ };
+ let base_weight = T::WeightInfo::proxy(T::MaxProxies::get())
+ .saturating_add(T::DbWeight::get().reads_writes(1, 1));
+ (base_weight.saturating_add(inner_call_weight), di.class)
+ })]
+ pub fn proxy(
+ origin: OriginFor,
+ real: AccountIdLookupOf,
+ force_proxy_type: Option,
+ call: Box<::RuntimeCall>,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ let real = T::Lookup::lookup(real)?;
+ let def = Self::find_proxy(&real, &who, force_proxy_type)?;
+ ensure!(def.delay.is_zero(), Error::::Unannounced);
+
+ Self::do_proxy(def, real, *call);
+
+ Ok(())
+ }
+
+ /// Register a proxy account for the sender that is able to make calls on its behalf.
+ ///
+ /// The dispatch origin for this call must be _Signed_.
+ ///
+ /// Parameters:
+ /// - `proxy`: The account that the `caller` would like to make a proxy.
+ /// - `proxy_type`: The permissions allowed for this proxy account.
+ /// - `delay`: The announcement period required of the initial proxy. Will generally be
+ /// zero.
+ #[pallet::call_index(1)]
+ #[pallet::weight(T::WeightInfo::add_proxy(T::MaxProxies::get()))]
+ pub fn add_proxy(
+ origin: OriginFor,
+ delegate: AccountIdLookupOf,
+ proxy_type: T::ProxyType,
+ delay: BlockNumberFor,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ let delegate = T::Lookup::lookup(delegate)?;
+ Self::add_proxy_delegate(&who, delegate, proxy_type, delay)
+ }
+
+ /// Unregister a proxy account for the sender.
+ ///
+ /// The dispatch origin for this call must be _Signed_.
+ ///
+ /// Parameters:
+ /// - `proxy`: The account that the `caller` would like to remove as a proxy.
+ /// - `proxy_type`: The permissions currently enabled for the removed proxy account.
+ #[pallet::call_index(2)]
+ #[pallet::weight(T::WeightInfo::remove_proxy(T::MaxProxies::get()))]
+ pub fn remove_proxy(
+ origin: OriginFor,
+ delegate: AccountIdLookupOf,
+ proxy_type: T::ProxyType,
+ delay: BlockNumberFor,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ let delegate = T::Lookup::lookup(delegate)?;
+ Self::remove_proxy_delegate(&who, delegate, proxy_type, delay)
+ }
+
+ /// Unregister all proxy accounts for the sender.
+ ///
+ /// The dispatch origin for this call must be _Signed_.
+ ///
+ /// WARNING: This may be called on accounts created by `pure`, however if done, then
+ /// the unreserved fees will be inaccessible. **All access to this account will be lost.**
+ #[pallet::call_index(3)]
+ #[pallet::weight(T::WeightInfo::remove_proxies(T::MaxProxies::get()))]
+ pub fn remove_proxies(origin: OriginFor) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ Self::remove_all_proxy_delegates(&who);
+ Ok(())
+ }
+
+ /// Spawn a fresh new account that is guaranteed to be otherwise inaccessible, and
+ /// initialize it with a proxy of `proxy_type` for `origin` sender.
+ ///
+ /// Requires a `Signed` origin.
+ ///
+ /// - `proxy_type`: The type of the proxy that the sender will be registered as over the
+ /// new account. This will almost always be the most permissive `ProxyType` possible to
+ /// allow for maximum flexibility.
+ /// - `index`: A disambiguation index, in case this is called multiple times in the same
+ /// transaction (e.g. with `utility::batch`). Unless you're using `batch` you probably just
+ /// want to use `0`.
+ /// - `delay`: The announcement period required of the initial proxy. Will generally be
+ /// zero.
+ ///
+ /// Fails with `Duplicate` if this has already been called in this transaction, from the
+ /// same sender, with the same parameters.
+ ///
+ /// Fails if there are insufficient funds to pay for deposit.
+ #[pallet::call_index(4)]
+ #[pallet::weight(T::WeightInfo::create_pure(T::MaxProxies::get()))]
+ pub fn create_pure(
+ origin: OriginFor,
+ proxy_type: T::ProxyType,
+ delay: BlockNumberFor,
+ index: u16,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+
+ let pure = Self::pure_account(&who, &proxy_type, index, None);
+ ensure!(!Proxies::::contains_key(&pure), Error::::Duplicate);
+
+ let proxy_def = ProxyDefinition {
+ delegate: who.clone(),
+ proxy_type: proxy_type.clone(),
+ delay,
+ };
+ let bounded_proxies: BoundedVec<_, T::MaxProxies> = vec![proxy_def]
+ .try_into()
+ .map_err(|_| Error::::TooMany)?;
+
+ let deposit = T::ProxyDepositBase::get().saturating_add(T::ProxyDepositFactor::get());
+ T::Currency::reserve(&who, deposit)?;
+
+ Proxies::::insert(&pure, (bounded_proxies, deposit));
+ Self::deposit_event(Event::PureCreated {
+ pure,
+ who,
+ proxy_type,
+ disambiguation_index: index,
+ });
+
+ Ok(())
+ }
+
+ /// Removes a previously spawned pure proxy.
+ ///
+ /// WARNING: **All access to this account will be lost.** Any funds held in it will be
+ /// inaccessible.
+ ///
+ /// Requires a `Signed` origin, and the sender account must have been created by a call to
+ /// `pure` with corresponding parameters.
+ ///
+ /// - `spawner`: The account that originally called `pure` to create this account.
+ /// - `index`: The disambiguation index originally passed to `pure`. Probably `0`.
+ /// - `proxy_type`: The proxy type originally passed to `pure`.
+ /// - `height`: The height of the chain when the call to `pure` was processed.
+ /// - `ext_index`: The extrinsic index in which the call to `pure` was processed.
+ ///
+ /// Fails with `NoPermission` in case the caller is not a previously created pure
+ /// account whose `pure` call has corresponding parameters.
+ #[pallet::call_index(5)]
+ #[pallet::weight(T::WeightInfo::kill_pure(T::MaxProxies::get()))]
+ pub fn kill_pure(
+ origin: OriginFor,
+ spawner: AccountIdLookupOf,
+ proxy_type: T::ProxyType,
+ index: u16,
+ #[pallet::compact] height: BlockNumberFor,
+ #[pallet::compact] ext_index: u32,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ let spawner = T::Lookup::lookup(spawner)?;
+
+ let when = (height, ext_index);
+ let proxy = Self::pure_account(&spawner, &proxy_type, index, Some(when));
+ ensure!(proxy == who, Error::::NoPermission);
+
+ let (_, deposit) = Proxies::::take(&who);
+ T::Currency::unreserve(&spawner, deposit);
+
+ Ok(())
+ }
+
+ /// Publish the hash of a proxy-call that will be made in the future.
+ ///
+ /// This must be called some number of blocks before the corresponding `proxy` is attempted
+ /// if the delay associated with the proxy relationship is greater than zero.
+ ///
+ /// No more than `MaxPending` announcements may be made at any one time.
+ ///
+ /// This will take a deposit of `AnnouncementDepositFactor` as well as
+ /// `AnnouncementDepositBase` if there are no other pending announcements.
+ ///
+ /// The dispatch origin for this call must be _Signed_ and a proxy of `real`.
+ ///
+ /// Parameters:
+ /// - `real`: The account that the proxy will make a call on behalf of.
+ /// - `call_hash`: The hash of the call to be made by the `real` account.
+ #[pallet::call_index(6)]
+ #[pallet::weight(T::WeightInfo::announce(T::MaxPending::get(), T::MaxProxies::get()))]
+ pub fn announce(
+ origin: OriginFor,
+ real: AccountIdLookupOf,
+ call_hash: CallHashOf,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ let real = T::Lookup::lookup(real)?;
+ Proxies::::get(&real)
+ .0
+ .into_iter()
+ .find(|x| x.delegate == who)
+ .ok_or(Error::::NotProxy)?;
+
+ let announcement = Announcement {
+ real: real.clone(),
+ call_hash,
+ height: system::Pallet::::block_number(),
+ };
+
+ Announcements::::try_mutate(&who, |(ref mut pending, ref mut deposit)| {
+ pending
+ .try_push(announcement)
+ .map_err(|_| Error::::TooMany)?;
+ Self::rejig_deposit(
+ &who,
+ *deposit,
+ T::AnnouncementDepositBase::get(),
+ T::AnnouncementDepositFactor::get(),
+ pending.len(),
+ )
+ .map(|d| {
+ d.expect("Just pushed; pending.len() > 0; rejig_deposit returns Some; qed")
+ })
+ .map(|d| *deposit = d)
+ })?;
+ Self::deposit_event(Event::Announced {
+ real,
+ proxy: who,
+ call_hash,
+ });
+
+ Ok(())
+ }
+
+ /// Remove a given announcement.
+ ///
+ /// May be called by a proxy account to remove a call they previously announced and return
+ /// the deposit.
+ ///
+ /// The dispatch origin for this call must be _Signed_.
+ ///
+ /// Parameters:
+ /// - `real`: The account that the proxy will make a call on behalf of.
+ /// - `call_hash`: The hash of the call to be made by the `real` account.
+ #[pallet::call_index(7)]
+ #[pallet::weight(T::WeightInfo::remove_announcement(
+ T::MaxPending::get(),
+ T::MaxProxies::get()
+ ))]
+ pub fn remove_announcement(
+ origin: OriginFor,
+ real: AccountIdLookupOf,
+ call_hash: CallHashOf,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ let real = T::Lookup::lookup(real)?;
+ Self::edit_announcements(&who, |ann| ann.real != real || ann.call_hash != call_hash)?;
+
+ Ok(())
+ }
+
+ /// Remove the given announcement of a delegate.
+ ///
+ /// May be called by a target (proxied) account to remove a call that one of their delegates
+ /// (`delegate`) has announced they want to execute. The deposit is returned.
+ ///
+ /// The dispatch origin for this call must be _Signed_.
+ ///
+ /// Parameters:
+ /// - `delegate`: The account that previously announced the call.
+ /// - `call_hash`: The hash of the call to be made.
+ #[pallet::call_index(8)]
+ #[pallet::weight(T::WeightInfo::reject_announcement(
+ T::MaxPending::get(),
+ T::MaxProxies::get()
+ ))]
+ pub fn reject_announcement(
+ origin: OriginFor,
+ delegate: AccountIdLookupOf,
+ call_hash: CallHashOf,
+ ) -> DispatchResult {
+ let who = ensure_signed(origin)?;
+ let delegate = T::Lookup::lookup(delegate)?;
+ Self::edit_announcements(&delegate, |ann| {
+ ann.real != who || ann.call_hash != call_hash
+ })?;
+
+ Ok(())
+ }
+
+ /// Dispatch the given `call` from an account that the sender is authorized for through
+ /// `add_proxy`.
+ ///
+ /// Removes any corresponding announcement(s).
+ ///
+ /// The dispatch origin for this call must be _Signed_.
+ ///
+ /// Parameters:
+ /// - `real`: The account that the proxy will make a call on behalf of.
+ /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call.
+ /// - `call`: The call to be made by the `real` account.
+ #[pallet::call_index(9)]
+ #[pallet::weight({
+ let di = call.get_dispatch_info();
+ (T::WeightInfo::proxy_announced(T::MaxPending::get(), T::MaxProxies::get())
+ // AccountData for inner call origin accountdata.
+ .saturating_add(T::DbWeight::get().reads_writes(1, 1))
+ .saturating_add(di.weight),
+ di.class)
+ })]
+ pub fn proxy_announced(
+ origin: OriginFor,
+ delegate: AccountIdLookupOf,
+ real: AccountIdLookupOf,
+ force_proxy_type: Option,
+ call: Box<::RuntimeCall>,
+ ) -> DispatchResult {
+ ensure_signed(origin)?;
+ let delegate = T::Lookup::lookup(delegate)?;
+ let real = T::Lookup::lookup(real)?;
+ let def = Self::find_proxy(&real, &delegate, force_proxy_type)?;
+
+ let call_hash = T::CallHasher::hash_of(&call);
+ let now = system::Pallet::::block_number();
+ Self::edit_announcements(&delegate, |ann| {
+ ann.real != real
+ || ann.call_hash != call_hash
+ || now.saturating_sub(ann.height) < def.delay
+ })
+ .map_err(|_| Error::::Unannounced)?;
+
+ Self::do_proxy(def, real, *call);
+
+ Ok(())
+ }
+ }
+
+ #[pallet::event]
+ #[pallet::generate_deposit(pub(super) fn deposit_event)]
+ pub enum Event {
+ /// A proxy was executed correctly, with the given.
+ ProxyExecuted { result: DispatchResult },
+ /// A pure account has been created by new proxy with given
+ /// disambiguation index and proxy type.
+ PureCreated {
+ pure: T::AccountId,
+ who: T::AccountId,
+ proxy_type: T::ProxyType,
+ disambiguation_index: u16,
+ },
+ /// An announcement was placed to make a call in the future.
+ Announced {
+ real: T::AccountId,
+ proxy: T::AccountId,
+ call_hash: CallHashOf,
+ },
+ /// A proxy was added.
+ ProxyAdded {
+ delegator: T::AccountId,
+ delegatee: T::AccountId,
+ proxy_type: T::ProxyType,
+ delay: BlockNumberFor,
+ },
+ /// A proxy was removed.
+ ProxyRemoved {
+ delegator: T::AccountId,
+ delegatee: T::AccountId,
+ proxy_type: T::ProxyType,
+ delay: BlockNumberFor,
+ },
+ }
+
+ #[pallet::error]
+ pub enum Error {
+ /// There are too many proxies registered or too many announcements pending.
+ TooMany,
+ /// Proxy registration not found.
+ NotFound,
+ /// Sender is not a proxy of the account to be proxied.
+ NotProxy,
+ /// A call which is incompatible with the proxy type's filter was attempted.
+ Unproxyable,
+ /// Account is already a proxy.
+ Duplicate,
+ /// Call may not be made by proxy because it may escalate its privileges.
+ NoPermission,
+ /// Announcement, if made at all, was made too recently.
+ Unannounced,
+ /// Cannot add self as proxy.
+ NoSelfProxy,
+ }
+
+ /// The set of account proxies. Maps the account which has delegated to the accounts
+ /// which are being delegated to, together with the amount held on deposit.
+ #[pallet::storage]
+ pub type Proxies = StorageMap<
+ _,
+ Twox64Concat,
+ T::AccountId,
+ (
+ BoundedVec<
+ ProxyDefinition>,
+ T::MaxProxies,
+ >,
+ BalanceOf,
+ ),
+ ValueQuery,
+ >;
+
+ /// The announcements made by the proxy (key).
+ #[pallet::storage]
+ pub type Announcements = StorageMap<
+ _,
+ Twox64Concat,
+ T::AccountId,
+ (
+ BoundedVec, BlockNumberFor>, T::MaxPending>,
+ BalanceOf,
+ ),
+ ValueQuery,
+ >;
+}
+
+impl