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..06933b9232 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", @@ -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", ] @@ -6616,7 +6823,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 +6894,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 +6955,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 +6976,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 +7005,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 +7065,7 @@ dependencies = [ "libc", "log", "polkavm-assembler", - "polkavm-common", + "polkavm-common 0.9.0", "polkavm-linux-raw", ] @@ -6880,25 +7087,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" +checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c" +dependencies = [ + "polkavm-common 0.9.0", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "polkavm-derive-impl" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f2116a92e6e96220a398930f4c8a6cda1264206f3e2034fc9982bfd93f261f7" dependencies = [ - "polkavm-common", + "polkavm-common 0.18.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -6907,8 +7141,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 +7165,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 +7178,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 +7216,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 +7266,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 +7289,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 +7299,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 +7325,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 +7340,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 +7365,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 +7410,7 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7165,14 +7421,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 +7449,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 +7463,7 @@ dependencies = [ "lazy_static", "memchr", "parking_lot 0.12.3", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7230,7 +7486,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7264,7 +7520,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 +7541,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 +7575,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7342,24 +7598,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 +7644,7 @@ dependencies = [ "asynchronous-codec", "bytes", "quick-protobuf", - "thiserror", + "thiserror 1.0.69", "unsigned-varint 0.7.2", ] @@ -7404,7 +7660,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 +7679,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 +7696,7 @@ dependencies = [ "rustc-hash 1.1.0", "rustls 0.20.9", "slab", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tracing", "webpki", @@ -7458,7 +7714,7 @@ dependencies = [ "rustc-hash 1.1.0", "rustls 0.21.12", "slab", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tracing", ] @@ -7484,16 +7740,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 +7787,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 +7811,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 +7867,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 +7880,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 +7902,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -7676,13 +7932,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 +7953,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 +8011,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "ed9b823fa29b721a59671b41d6b06e66b29e0628e207e8b1c3ceeda701ec928d" 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 +8083,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 +8123,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 +8148,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 +8176,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 +8205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.8", + "ring 0.17.12", "rustls-webpki", "sct", ] @@ -7979,15 +8237,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.12", "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 +8260,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 +8284,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 +8308,7 @@ dependencies = [ "log", "sp-core", "sp-wasm-interface 21.0.1", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8125,7 +8383,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -8165,7 +8423,7 @@ dependencies = [ "sp-panic-handler", "sp-runtime", "sp-version", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -8243,7 +8501,7 @@ dependencies = [ "sp-runtime", "sp-state-machine", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8272,7 +8530,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8308,7 +8566,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8365,7 +8623,7 @@ dependencies = [ "sp-keystore", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8385,7 +8643,7 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8420,7 +8678,7 @@ dependencies = [ "sp-runtime", "sp-timestamp", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8478,7 +8736,7 @@ dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", "sp-wasm-interface 21.0.1", - "thiserror", + "thiserror 1.0.69", "wasm-instrument", ] @@ -8539,7 +8797,7 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-keystore", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8568,7 +8826,7 @@ dependencies = [ "sp-keystore", "sp-mixnet", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8613,7 +8871,7 @@ dependencies = [ "sp-core", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "unsigned-varint 0.7.2", @@ -8677,7 +8935,7 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8712,7 +8970,7 @@ dependencies = [ "sp-core", "sp-runtime", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -8747,9 +9005,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 +9021,7 @@ dependencies = [ "fnv", "futures", "futures-timer", - "hyper 0.14.30", + "hyper 0.14.32", "hyper-rustls", "log", "num_cpus", @@ -8845,7 +9103,7 @@ dependencies = [ "sp-rpc", "sp-runtime", "sp-version", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8857,9 +9115,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 +9157,7 @@ dependencies = [ "sp-rpc", "sp-runtime", "sp-version", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -8962,7 +9220,7 @@ dependencies = [ "static_init", "substrate-prometheus-endpoint", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "tracing-futures", @@ -8984,7 +9242,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 +9274,7 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "wasm-timer", ] @@ -9043,10 +9301,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 +9315,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -9084,7 +9342,7 @@ dependencies = [ "sp-tracing 17.0.1", "sp-transaction-pool", "substrate-prometheus-endpoint", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9100,7 +9358,7 @@ dependencies = [ "sp-blockchain", "sp-core", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9134,7 +9392,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 +9401,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 +9415,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 +9433,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 +9488,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.12", "untrusted 0.9.0", ] @@ -9246,7 +9504,7 @@ dependencies = [ "log", "rand", "slab", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9297,7 +9555,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 +9564,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 +9592,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 +9613,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 +9650,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 +9717,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -9583,9 +9841,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 +9858,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 +9911,7 @@ dependencies = [ "chacha20poly1305", "curve25519-dalek", "rand_core", - "ring 0.17.8", + "ring 0.17.12", "rustc_version 0.4.1", "sha2 0.10.8", "subtle 2.6.1", @@ -9671,9 +9929,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 +9939,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 +9972,7 @@ dependencies = [ "sp-state-machine", "sp-trie", "sp-version", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9728,7 +9986,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -9791,7 +10049,7 @@ dependencies = [ "sp-database", "sp-runtime", "sp-state-machine", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -9807,7 +10065,7 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-state-machine", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9887,7 +10145,7 @@ dependencies = [ "futures", "hash-db", "hash256-std-hasher", - "impl-serde", + "impl-serde 0.4.0", "itertools 0.11.0", "k256", "libsecp256k1", @@ -9897,7 +10155,7 @@ dependencies = [ "parity-scale-codec", "parking_lot 0.12.3", "paste", - "primitive-types", + "primitive-types 0.12.2", "rand", "scale-info", "schnorrkel", @@ -9912,7 +10170,7 @@ dependencies = [ "sp-storage 21.0.0", "ss58-registry", "substrate-bip39", - "thiserror", + "thiserror 1.0.69", "tracing", "w3f-bls", "zeroize", @@ -9921,7 +10179,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 +10250,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 +10269,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 +10324,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "sp-runtime", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -10080,7 +10338,7 @@ dependencies = [ "libsecp256k1", "log", "parity-scale-codec", - "polkavm-derive", + "polkavm-derive 0.9.1", "rustversion", "secp256k1", "sp-core", @@ -10121,7 +10379,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 +10463,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 +10487,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 +10501,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 +10521,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -10308,7 +10566,7 @@ dependencies = [ "sp-externalities 0.29.0", "sp-panic-handler", "sp-trie", - "thiserror", + "thiserror 1.0.69", "tracing", "trie-db", ] @@ -10333,7 +10591,7 @@ dependencies = [ "sp-externalities 0.29.0", "sp-runtime", "sp-runtime-interface 28.0.0", - "thiserror", + "thiserror 1.0.69", "x25519-dalek", ] @@ -10345,14 +10603,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 +10622,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 +10638,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 +10660,7 @@ dependencies = [ "parity-scale-codec", "tracing", "tracing-core", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.19", ] [[package]] @@ -10445,7 +10703,7 @@ dependencies = [ "schnellru", "sp-core", "sp-externalities 0.29.0", - "thiserror", + "thiserror 1.0.69", "tracing", "trie-db", "trie-root", @@ -10456,7 +10714,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 +10723,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 +10734,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 +10808,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 +10821,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 +10854,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 +10883,7 @@ dependencies = [ "sha2 0.10.8", "sqlx-core", "sqlx-sqlite", - "syn 2.0.90", + "syn 2.0.96", "tempfile", "tokio", "url", @@ -10649,9 +10891,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 +10914,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 +10975,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 +11002,7 @@ dependencies = [ "sctp-proto", "serde", "sha-1", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -10808,7 +11050,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -10865,11 +11107,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 +11154,7 @@ dependencies = [ "quote", "rayon", "subtensor-linting", - "syn 2.0.90", + "syn 2.0.96", "walkdir", ] @@ -10950,7 +11192,7 @@ dependencies = [ "proc-macro2", "procedural-fork", "quote", - "syn 2.0.90", + "syn 2.0.96", ] [[package]] @@ -10960,7 +11202,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", + "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 +11246,7 @@ version = "0.1.0" dependencies = [ "anyhow", "clap", - "semver 1.0.23", + "semver 1.0.25", "toml_edit", ] @@ -10998,9 +11275,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 +11304,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 +11342,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 +11365,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 +11456,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 +11477,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 +11494,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 +11549,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 +11560,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 +11588,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 +11615,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 +11663,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 +11691,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 +11715,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 +11727,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 +11778,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 +11836,7 @@ dependencies = [ "rand", "smallvec", "socket2 0.4.10", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -11553,7 +11861,7 @@ dependencies = [ "once_cell", "rand", "smallvec", - "thiserror", + "thiserror 1.0.69", "tinyvec", "tokio", "tracing", @@ -11575,7 +11883,7 @@ dependencies = [ "rand", "resolv-conf", "smallvec", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "trust-dns-proto 0.23.2", @@ -11608,7 +11916,7 @@ dependencies = [ "rand", "rustls 0.21.12", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", ] @@ -11658,17 +11966,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 +12006,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 +12063,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 +12078,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 +12098,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 +12140,7 @@ dependencies = [ "rand_core", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -11837,49 +12169,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 +12229,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 +12269,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 +12396,7 @@ dependencies = [ "log", "object 0.30.4", "target-lexicon", - "thiserror", + "thiserror 1.0.69", "wasmparser", "wasmtime-cranelift-shared", "wasmtime-environ", @@ -12086,7 +12431,7 @@ dependencies = [ "object 0.30.4", "serde", "target-lexicon", - "thiserror", + "thiserror 1.0.69", "wasmparser", "wasmtime-types", ] @@ -12169,15 +12514,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 +12534,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.12", "untrusted 0.9.0", ] @@ -12208,14 +12553,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 +12605,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 +12872,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 +12889,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 +12944,7 @@ dependencies = [ "nom", "oid-registry 0.6.1", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -12585,7 +12961,7 @@ dependencies = [ "nom", "oid-registry 0.7.1", "rusticata-macros", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -12597,14 +12973,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 +13015,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 +13057,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 +13098,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..781fe6dfe9 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"] } @@ -181,7 +191,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 +211,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 +257,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/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..70e4cdd753 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,36 @@ 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(()) + } } } diff --git a/pallets/admin-utils/src/tests/mock.rs b/pallets/admin-utils/src/tests/mock.rs index 40e29e54dd..0c443255c4 100644 --- a/pallets/admin-utils/src/tests/mock.rs +++ b/pallets/admin-utils/src/tests/mock.rs @@ -123,14 +123,14 @@ 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. @@ -188,14 +188,11 @@ 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; diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 6c879635e3..259961e656 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,129 @@ 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 + ); + }); +} diff --git a/pallets/subtensor/src/coinbase/root.rs b/pallets/subtensor/src/coinbase/root.rs index d36602bbbb..b2633fa381 100644 --- a/pallets/subtensor/src/coinbase/root.rs +++ b/pallets/subtensor/src/coinbase/root.rs @@ -70,31 +70,6 @@ impl Pallet { false } - /// Sets the emission values for each netuid - /// - pub fn set_emission_values(netuids: &[u16], emission: Vec) -> Result<(), &'static str> { - log::debug!( - "set_emission_values: netuids: {:?} emission:{:?}", - netuids, - emission - ); - - // Be careful this function can fail. - if Self::contains_invalid_root_uids(netuids) { - log::error!("set_emission_values: contains_invalid_root_uids"); - return Err("Invalid netuids"); - } - if netuids.len() != emission.len() { - log::error!("set_emission_values: netuids.len() != emission.len()"); - return Err("netuids and emission must have the same length"); - } - for (netuid_i, emission_i) in netuids.iter().zip(emission) { - log::debug!("set netuid:{:?} emission:{:?}", netuid_i, emission_i); - EmissionValues::::insert(*netuid_i, emission_i); - } - Ok(()) - } - /// Retrieves weight matrix associated with the root network. /// Weights represent the preferences for each subnetwork. /// @@ -577,7 +552,6 @@ impl Pallet { MaxAllowedUids::::remove(netuid); ImmunityPeriod::::remove(netuid); ActivityCutoff::::remove(netuid); - EmissionValues::::remove(netuid); MaxWeightsLimit::::remove(netuid); MinAllowedWeights::::remove(netuid); RegistrationsThisInterval::::remove(netuid); @@ -647,55 +621,6 @@ impl Pallet { lock_cost } - /// This function is used to determine which subnet to prune when the total number of networks has reached the limit. - /// It iterates over all the networks and finds the oldest subnet with the minimum emission value that is not in the immunity period. - /// - /// # Returns: - /// * 'u16': - /// - The uid of the network to be pruned. - /// - pub fn get_subnet_to_prune() -> u16 { - let mut netuids: Vec = vec![]; - let current_block = Self::get_current_block_as_u64(); - - // Even if we don't have a root subnet, this still works - for netuid in NetworksAdded::::iter_keys_from(NetworksAdded::::hashed_key_for(0)) { - if current_block.saturating_sub(Self::get_network_registered_block(netuid)) - < Self::get_network_immunity_period() - { - continue; - } - - // This iterator seems to return them in order anyways, so no need to sort by key - netuids.push(netuid); - } - - // Now we sort by emission, and then by subnet creation time. - netuids.sort_by(|a, b| { - use sp_std::cmp::Ordering; - - match Self::get_emission_value(*b).cmp(&Self::get_emission_value(*a)) { - Ordering::Equal => { - if Self::get_network_registered_block(*b) - < Self::get_network_registered_block(*a) - { - Ordering::Less - } else { - Ordering::Equal - } - } - v => v, - } - }); - - log::debug!("Netuids Order: {:?}", netuids); - - match netuids.last() { - Some(netuid) => *netuid, - None => 0, - } - } - pub fn get_network_registered_block(netuid: u16) -> u64 { NetworkRegisteredAt::::get(netuid) } diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index 50c691819f..7836423868 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -266,8 +266,6 @@ impl Pallet { pending_swapped, owner_cut ); - // Setup. - let zero: I96F32 = asfloat!(0.0); // Run the epoch. let hotkey_emission: Vec<(T::AccountId, u64, u64)> = @@ -297,6 +295,25 @@ impl Pallet { log::debug!("incentives: {:?}", incentives); log::debug!("dividends: {:?}", dividends); + Self::distribute_dividends_and_incentives( + netuid, + pending_tao, + owner_cut, + incentives, + dividends, + ); + } + + pub fn distribute_dividends_and_incentives( + netuid: u16, + pending_tao: u64, + owner_cut: u64, + incentives: BTreeMap, + dividends: BTreeMap, + ) { + // Setup. + let zero: I96F32 = asfloat!(0.0); + // Accumulate root divs and alpha_divs. For each hotkey we compute their // local and root dividend proportion based on their alpha_stake/root_stake let mut total_root_divs: I96F32 = asfloat!(0); @@ -375,8 +392,19 @@ impl Pallet { // Distribute mining incentives. for (hotkey, incentive) in incentives { - // Increase stake for miner. log::debug!("incentives: hotkey: {:?}", incentive); + + if let Ok(owner_hotkey) = SubnetOwnerHotkey::::try_get(netuid) { + if hotkey == owner_hotkey { + log::debug!( + "incentives: hotkey: {:?} is SN owner hotkey, skipping {:?}", + hotkey, + incentive + ); + continue; // Skip/burn miner-emission for SN owner hotkey. + } + } + // Increase stake for miner. Self::increase_stake_for_hotkey_and_coldkey_on_subnet( &hotkey.clone(), &Owner::::get(hotkey.clone()), @@ -497,6 +525,7 @@ impl Pallet { // Calculate the hotkey's share of the validator emission based on its childkey take let validating_emission: I96F32 = I96F32::saturating_from_num(dividends); + let mut remaining_emission: I96F32 = validating_emission; let childkey_take_proportion: I96F32 = I96F32::saturating_from_num(Self::get_childkey_take(hotkey, netuid)) .safe_div(I96F32::saturating_from_num(u16::MAX)); @@ -507,23 +536,12 @@ impl Pallet { ); // NOTE: Only the validation emission should be split amongst parents. - // Reserve childkey take - let child_emission_take: I96F32 = childkey_take_proportion - .saturating_mul(I96F32::saturating_from_num(validating_emission)); - let remaining_emission: I96F32 = validating_emission.saturating_sub(child_emission_take); - log::debug!( - "Child emission take: {:?} for hotkey {:?}", - child_emission_take, - hotkey - ); - log::debug!( - "Remaining emission: {:?} for hotkey {:?}", - remaining_emission, - hotkey - ); + // Grab the owner of the childkey. + let childkey_owner = Self::get_owning_coldkey_for_hotkey(hotkey); // Initialize variables to track emission distribution let mut to_parents: u64 = 0; + let mut total_child_emission_take: I96F32 = I96F32::saturating_from_num(0); // Initialize variables to calculate total stakes from parents let mut total_contribution: I96F32 = I96F32::saturating_from_num(0); @@ -580,33 +598,66 @@ impl Pallet { // Distribute emission to parents based on their contributions. // Deduct childkey take from parent contribution. for (parent, contribution) in parent_contributions { - // Sum up the total emission for this parent + let parent_owner = Self::get_owning_coldkey_for_hotkey(&parent); + + // Get the stake contribution of this parent key of the total stake. let emission_factor: I96F32 = contribution .checked_div(total_contribution) .unwrap_or(I96F32::saturating_from_num(0)); - let parent_emission: u64 = - (remaining_emission.saturating_mul(emission_factor)).saturating_to_num::(); + + // Get the parent's portion of the validating emission based on their contribution. + let mut parent_emission: I96F32 = validating_emission.saturating_mul(emission_factor); + // Remove this emission from the remaining emission. + remaining_emission = remaining_emission.saturating_sub(parent_emission); + + // Get the childkey take for this parent. + let child_emission_take: I96F32 = if parent_owner == childkey_owner { + // The parent is from the same coldkey, so we don't remove any childkey take. + I96F32::saturating_from_num(0) + } else { + childkey_take_proportion + .saturating_mul(I96F32::saturating_from_num(parent_emission)) + }; + + // Remove the childkey take from the parent's emission. + parent_emission = parent_emission.saturating_sub(child_emission_take); + + // Add the childkey take to the total childkey take tracker. + total_child_emission_take = + total_child_emission_take.saturating_add(child_emission_take); + + log::debug!( + "Child emission take: {:?} for hotkey {:?}", + child_emission_take, + hotkey + ); + log::debug!( + "Parent emission: {:?} for hotkey {:?}", + parent_emission, + hotkey + ); + log::debug!("remaining emission: {:?}", remaining_emission); // Add the parent's emission to the distribution list - dividend_tuples.push((parent.clone(), parent_emission)); + dividend_tuples.push((parent.clone(), parent_emission.saturating_to_num::())); // Keep track of total emission distributed to parents - to_parents = to_parents.saturating_add(parent_emission); + to_parents = to_parents.saturating_add(parent_emission.saturating_to_num::()); log::debug!( - "Parent contribution for parent {:?} with contribution: {:?}, of total: {:?} of emission: {:?} gets: {:?}", + "Parent contribution for parent {:?} with contribution: {:?}, of total: {:?} ({:?}), of emission: {:?} gets: {:?}", parent, contribution, total_contribution, - remaining_emission, - parent_emission + emission_factor, + validating_emission, + parent_emission, ); } // Calculate the final emission for the hotkey itself. // This includes the take left from the parents and the self contribution. let child_emission = remaining_emission - .saturating_add(child_emission_take) - .saturating_to_num::() - .saturating_sub(to_parents); + .saturating_add(total_child_emission_take) + .saturating_to_num::(); // Add the hotkey's own emission to the distribution list dividend_tuples.push((hotkey.clone(), child_emission)); diff --git a/pallets/subtensor/src/epoch/math.rs b/pallets/subtensor/src/epoch/math.rs index 9818b06a48..436dba84a0 100644 --- a/pallets/subtensor/src/epoch/math.rs +++ b/pallets/subtensor/src/epoch/math.rs @@ -569,6 +569,33 @@ pub fn inplace_mask_diag(matrix: &mut [Vec]) { }); } +// Mask out the diagonal of the input matrix in-place, except for the diagonal entry at except_index. +#[allow(dead_code)] +pub fn inplace_mask_diag_except_index(matrix: &mut [Vec], except_index: u16) { + let Some(first_row) = matrix.first() else { + return; + }; + if first_row.is_empty() { + return; + } + assert_eq!(matrix.len(), first_row.len()); + + let diag_at_index = matrix + .get(except_index as usize) + .and_then(|row| row.get(except_index as usize)) + .cloned(); + + inplace_mask_diag(matrix); + + matrix.get_mut(except_index as usize).map(|row| { + row.get_mut(except_index as usize).map(|value| { + if let Some(diag_at_index) = diag_at_index { + *value = diag_at_index; + } + }) + }); +} + // Return a new sparse matrix that replaces masked rows with an empty vector placeholder. #[allow(dead_code)] pub fn mask_rows_sparse( @@ -604,6 +631,29 @@ pub fn mask_diag_sparse(sparse_matrix: &[Vec<(u16, I32F32)>]) -> Vec], + except_index: u16, +) -> Vec> { + sparse_matrix + .iter() + .enumerate() + .map(|(i, sparse_row)| { + sparse_row + .iter() + .filter(|(j, _)| { + // Is not a diagonal OR is the diagonal at except_index + i != (*j as usize) || (i == except_index as usize && *j == except_index) + }) + .copied() + .collect() + }) + .collect() +} + // Remove cells from sparse matrix where the mask function of two vectors is true. #[allow(dead_code, clippy::indexing_slicing)] pub fn vec_mask_sparse_matrix( diff --git a/pallets/subtensor/src/epoch/run_epoch.rs b/pallets/subtensor/src/epoch/run_epoch.rs index a53c8d562f..27dd17fa0b 100644 --- a/pallets/subtensor/src/epoch/run_epoch.rs +++ b/pallets/subtensor/src/epoch/run_epoch.rs @@ -111,6 +111,9 @@ impl Pallet { // == Weights == // ============= + // Get owner uid. + let owner_uid: Option = Self::get_owner_uid(netuid); + // Access network weights row unnormalized. let mut weights: Vec> = Self::get_weights(netuid); log::trace!("W:\n{:?}\n", &weights); @@ -119,7 +122,13 @@ impl Pallet { inplace_mask_rows(&validator_forbids, &mut weights); log::trace!("W (permit): {:?}", &weights); - // Remove self-weight by masking diagonal. + // Remove self-weight by masking diagonal; keep owner_uid self-weight. + if let Some(owner_uid) = owner_uid { + inplace_mask_diag_except_index(&mut weights, owner_uid); + } else { + inplace_mask_diag(&mut weights); + } + inplace_mask_diag(&mut weights); log::trace!("W (permit+diag):\n{:?}\n", &weights); @@ -454,6 +463,8 @@ impl Pallet { // == Weights == // ============= + let owner_uid: Option = Self::get_owner_uid(netuid); + // Access network weights row unnormalized. let mut weights: Vec> = Self::get_weights_sparse(netuid); log::trace!("Weights: {:?}", &weights); @@ -462,8 +473,12 @@ impl Pallet { weights = mask_rows_sparse(&validator_forbids, &weights); log::trace!("Weights (permit): {:?}", &weights); - // Remove self-weight by masking diagonal. - weights = mask_diag_sparse(&weights); + // Remove self-weight by masking diagonal; keep owner_uid self-weight. + if let Some(owner_uid) = owner_uid { + weights = mask_diag_sparse_except_index(&weights, owner_uid); + } else { + weights = mask_diag_sparse(&weights); + } log::trace!("Weights (permit+diag): {:?}", &weights); // Remove weights referring to deregistered neurons. diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 0ef0029f9f..f3fccbfcef 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -501,11 +501,6 @@ pub mod pallet { T::InitialSubnetOwnerCut::get() } #[pallet::type_value] - /// Default value for subnet limit. - pub fn DefaultSubnetLimit() -> u16 { - T::InitialSubnetLimit::get() - } - #[pallet::type_value] /// Default value for network rate limit. pub fn DefaultNetworkRateLimit() -> u64 { if cfg!(feature = "pow-faucet") { @@ -514,9 +509,10 @@ pub mod pallet { T::InitialNetworkRateLimit::get() } #[pallet::type_value] - /// Default value for emission values. - pub fn DefaultEmissionValues() -> u64 { - 0 + /// Default value for weights version key rate limit. + /// In units of tempos. + pub fn DefaultWeightsVersionKeyRateLimit() -> u64 { + 5 // 5 tempos } #[pallet::type_value] /// Default value for pending emission. @@ -728,11 +724,6 @@ pub mod pallet { pub fn DefaultAlphaValues() -> (u16, u16) { (45875, 58982) } - #[pallet::type_value] - /// Default value for network max stake. - pub fn DefaultNetworkMaxStake() -> u64 { - T::InitialNetworkMaxStake::get() - } #[pallet::type_value] /// Default value for coldkey swap schedule duration @@ -743,7 +734,11 @@ pub mod pallet { #[pallet::type_value] /// Default value for applying pending items (e.g. childkeys). pub fn DefaultPendingCooldown() -> u64 { - 1 + if cfg!(feature = "fast-blocks") { + return 15; + } + + 7_200 } #[pallet::type_value] @@ -1055,9 +1050,6 @@ pub mod pallet { pub type MaxRegistrationsPerBlock = StorageMap<_, Identity, u16, u16, ValueQuery, DefaultMaxRegistrationsPerBlock>; #[pallet::storage] - /// --- ITEM( maximum_number_of_networks ) - pub type SubnetLimit = StorageValue<_, u16, ValueQuery, DefaultSubnetLimit>; - #[pallet::storage] /// --- ITEM( total_number_of_existing_networks ) pub type TotalNetworks = StorageValue<_, u16, ValueQuery>; #[pallet::storage] @@ -1091,6 +1083,10 @@ pub mod pallet { pub type NetworkRateLimit = StorageValue<_, u64, ValueQuery, DefaultNetworkRateLimit>; #[pallet::storage] // --- ITEM( nominator_min_required_stake ) pub type NominatorMinRequiredStake = StorageValue<_, u64, ValueQuery, DefaultZeroU64>; + #[pallet::storage] + /// ITEM( weights_version_key_rate_limit ) --- Rate limit in tempos. + pub type WeightsVersionKeyRateLimit = + StorageValue<_, u64, ValueQuery, DefaultWeightsVersionKeyRateLimit>; /// ============================ /// ==== Subnet Locks ===== @@ -1152,10 +1148,6 @@ pub mod pallet { pub type NetworkRegisteredAt = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultNetworkRegisteredAt>; #[pallet::storage] - /// --- MAP ( netuid ) --> emission_values - pub type EmissionValues = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultEmissionValues>; - #[pallet::storage] /// --- MAP ( netuid ) --> pending_emission pub type PendingEmission = StorageMap<_, Identity, u16, u64, ValueQuery, DefaultPendingEmission>; @@ -1324,10 +1316,6 @@ pub mod pallet { /// MAP ( netuid ) --> (alpha_low, alpha_high) pub type AlphaValues = StorageMap<_, Identity, u16, (u16, u16), ValueQuery, DefaultAlphaValues>; - /// MAP ( netuid ) --> max stake allowed on a subnet. - #[pallet::storage] - pub type NetworkMaxStake = - StorageMap<_, Identity, u16, u64, ValueQuery, DefaultNetworkMaxStake>; /// ======================================= /// ==== Subnetwork Consensus Storage ==== @@ -2229,9 +2217,13 @@ where self, who: &Self::AccountId, call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, + info: &DispatchInfoOf, + len: usize, ) -> Result { + // We need to perform same checks as Self::validate so that + // the validation is performed during Executive::apply_extrinsic as well. + // this prevents inclusion of invalid tx in a block by malicious block author. + self.validate(who, call, info, len)?; match call.is_sub_type() { Some(Call::add_stake { .. }) => { let transaction_fee = 100000; diff --git a/pallets/subtensor/src/macros/config.rs b/pallets/subtensor/src/macros/config.rs index 72a4c5f0d3..60140a8ab2 100644 --- a/pallets/subtensor/src/macros/config.rs +++ b/pallets/subtensor/src/macros/config.rs @@ -180,9 +180,6 @@ mod config { /// Initial lock reduction interval. #[pallet::constant] type InitialNetworkLockReductionInterval: Get; - /// Initial max allowed subnets - #[pallet::constant] - type InitialSubnetLimit: Get; /// Initial network creation rate limit #[pallet::constant] type InitialNetworkRateLimit: Get; @@ -198,9 +195,6 @@ mod config { /// A flag to indicate if Liquid Alpha is enabled. #[pallet::constant] type LiquidAlphaOn: Get; - /// Initial network max stake. - #[pallet::constant] - type InitialNetworkMaxStake: Get; // /// Initial hotkey emission tempo. // #[pallet::constant] // type InitialHotkeyEmissionTempo: Get; diff --git a/pallets/subtensor/src/macros/events.rs b/pallets/subtensor/src/macros/events.rs index 40890b018a..834aa901fa 100644 --- a/pallets/subtensor/src/macros/events.rs +++ b/pallets/subtensor/src/macros/events.rs @@ -65,8 +65,6 @@ mod events { AxonServed(u16, T::AccountId), /// the prometheus server information is added to the network. PrometheusServed(u16, T::AccountId), - /// emission ratios for all networks is set. - EmissionValuesSet(), /// a hotkey has become a delegate. DelegateAdded(T::AccountId, T::AccountId, u16), /// the default take is set. @@ -124,7 +122,7 @@ mod events { /// the network minimum locking cost is set. NetworkMinLockCostSet(u64), /// the maximum number of subnets is set - SubnetLimitSet(u16), + // SubnetLimitSet(u16), /// the lock cost reduction is set NetworkLockCostReductionIntervalSet(u64), /// the take for a delegate is decreased. @@ -193,8 +191,8 @@ mod events { SetChildren(T::AccountId, u16, Vec<(u64, T::AccountId)>), // /// The hotkey emission tempo has been set // HotkeyEmissionTempoSet(u64), - /// The network maximum stake has been set - NetworkMaxStakeSet(u16, u64), + // /// The network maximum stake has been set + // NetworkMaxStakeSet(u16, u64), /// The identity of a coldkey has been set ChainIdentitySet(T::AccountId), /// The identity of a subnet has been set @@ -271,5 +269,11 @@ mod events { /// Parameters: /// (netuid, bool) TransferToggle(u16, bool), + + /// The owner hotkey for a subnet has been set. + /// + /// Parameters: + /// (netuid, new_hotkey) + SubnetOwnerHotkeySet(u16, T::AccountId), } } diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 812b840f50..df9dffabca 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -79,7 +79,9 @@ mod hooks { // Set the min difficulty across all subnets to a new minimum .saturating_add(migrations::migrate_set_min_difficulty::migrate_set_min_difficulty::()) // Remove Stake map entries - .saturating_add(migrations::migrate_remove_stake_map::migrate_remove_stake_map::()); + .saturating_add(migrations::migrate_remove_stake_map::migrate_remove_stake_map::()) + // Remove unused maps entries + .saturating_add(migrations::migrate_remove_unused_maps_and_values::migrate_remove_unused_maps_and_values::()); weight } diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs index c917c7cab1..d12a58ed37 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_21.rs @@ -103,7 +103,6 @@ pub fn migrate_delete_subnet_21() -> Weight { MaxAllowedUids::::remove(netuid); ImmunityPeriod::::remove(netuid); ActivityCutoff::::remove(netuid); - EmissionValues::::remove(netuid); MaxWeightsLimit::::remove(netuid); MinAllowedWeights::::remove(netuid); RegistrationsThisInterval::::remove(netuid); diff --git a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs index 2176963574..0e85c56554 100644 --- a/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs +++ b/pallets/subtensor/src/migrations/migrate_delete_subnet_3.rs @@ -106,7 +106,6 @@ pub fn migrate_delete_subnet_3() -> Weight { MaxAllowedUids::::remove(netuid); ImmunityPeriod::::remove(netuid); ActivityCutoff::::remove(netuid); - EmissionValues::::remove(netuid); MaxWeightsLimit::::remove(netuid); MinAllowedWeights::::remove(netuid); RegistrationsThisInterval::::remove(netuid); diff --git a/pallets/subtensor/src/migrations/migrate_rao.rs b/pallets/subtensor/src/migrations/migrate_rao.rs index 3b2de079e5..623faa1661 100644 --- a/pallets/subtensor/src/migrations/migrate_rao.rs +++ b/pallets/subtensor/src/migrations/migrate_rao.rs @@ -3,7 +3,6 @@ use alloc::string::String; use frame_support::IterableStorageMap; use frame_support::{traits::Get, weights::Weight}; use sp_runtime::format; -use substrate_fixed::types::I96F32; use super::*; @@ -89,12 +88,12 @@ pub fn migrate_rao() -> Weight { let remaining_lock = lock.saturating_sub(pool_initial_tao); // Refund the owner for the remaining lock. - SubnetMovingPrice::::insert( - netuid, - I96F32::from_num(EmissionValues::::get(netuid)) - .checked_div(I96F32::from_num(1_000_000_000)) - .unwrap_or(I96F32::from_num(0.0)), - ); + // SubnetMovingPrice::::insert( + // netuid, + // I96F32::from_num(EmissionValues::::get(netuid)) + // .checked_div(I96F32::from_num(1_000_000_000)) + // .unwrap_or(I96F32::from_num(0.0)), + // ); Pallet::::add_balance_to_coldkey_account(&owner, remaining_lock); SubnetLocked::::insert(netuid, 0); // Clear lock amount. SubnetTAO::::insert(netuid, pool_initial_tao); diff --git a/pallets/subtensor/src/migrations/migrate_remove_unused_maps_and_values.rs b/pallets/subtensor/src/migrations/migrate_remove_unused_maps_and_values.rs new file mode 100644 index 0000000000..e61ff66f04 --- /dev/null +++ b/pallets/subtensor/src/migrations/migrate_remove_unused_maps_and_values.rs @@ -0,0 +1,71 @@ +use super::*; +use crate::HasMigrationRun; +use frame_support::{traits::Get, weights::Weight}; +use scale_info::prelude::string::String; +use sp_io::{ + KillStorageResult, + hashing::twox_128, + storage::{clear, clear_prefix}, +}; + +fn remove_prefix(old_map: &str, weight: &mut Weight) { + let mut prefix = Vec::new(); + prefix.extend_from_slice(&twox_128("SubtensorModule".as_bytes())); + prefix.extend_from_slice(&twox_128(old_map.as_bytes())); + + let removal_results = clear_prefix(&prefix, Some(u32::MAX)); + + let removed_entries_count = match removal_results { + KillStorageResult::AllRemoved(removed) => removed as u64, + KillStorageResult::SomeRemaining(removed) => { + log::info!("Failed To Remove Some Items During migration"); + removed as u64 + } + }; + + log::info!( + "Removed {:?} entries from {:?} map.", + removed_entries_count, + old_map + ); + + *weight = (*weight).saturating_add(T::DbWeight::get().writes(removed_entries_count)); +} + +pub fn migrate_remove_unused_maps_and_values() -> Weight { + let migration_name = b"migrate_remove_unused_maps_and_values".to_vec(); + let mut weight = T::DbWeight::get().reads(1); + + if HasMigrationRun::::get(&migration_name) { + log::info!( + "Migration '{:?}' has already run. Skipping.", + migration_name + ); + return weight; + } + + log::info!( + "Running migration '{}'", + String::from_utf8_lossy(&migration_name) + ); + + // Remove EmissionValues entries + remove_prefix::("EmissionValues", &mut weight); + + // Remove NetworkMaxStake + remove_prefix::("NetworkMaxStake", &mut weight); + + // Remove SubnetLimit + clear(b"SubtensorModule::SubnetLimit"); + + // Mark Migration as Completed + HasMigrationRun::::insert(&migration_name, true); + weight = weight.saturating_add(T::DbWeight::get().writes(1)); + + log::info!( + "Migration '{:?}' completed successfully.", + String::from_utf8_lossy(&migration_name) + ); + + weight +} diff --git a/pallets/subtensor/src/migrations/mod.rs b/pallets/subtensor/src/migrations/mod.rs index b8754c07bf..6af6ad2a56 100644 --- a/pallets/subtensor/src/migrations/mod.rs +++ b/pallets/subtensor/src/migrations/mod.rs @@ -10,6 +10,7 @@ pub mod migrate_init_total_issuance; pub mod migrate_populate_owned_hotkeys; pub mod migrate_rao; pub mod migrate_remove_stake_map; +pub mod migrate_remove_unused_maps_and_values; pub mod migrate_set_min_burn; pub mod migrate_set_min_difficulty; pub mod migrate_stake_threshold; diff --git a/pallets/subtensor/src/rpc_info/dynamic_info.rs b/pallets/subtensor/src/rpc_info/dynamic_info.rs index e197e1b57c..b363931d9c 100644 --- a/pallets/subtensor/src/rpc_info/dynamic_info.rs +++ b/pallets/subtensor/src/rpc_info/dynamic_info.rs @@ -54,7 +54,7 @@ impl Pallet { tempo: Tempo::::get(netuid).into(), last_step: last_step.into(), blocks_since_last_step: blocks_since_last_step.into(), - emission: EmissionValues::::get(netuid).into(), + emission: 0.into(), alpha_in: SubnetAlphaIn::::get(netuid).into(), alpha_out: SubnetAlphaOut::::get(netuid).into(), tao_in: SubnetTAO::::get(netuid).into(), diff --git a/pallets/subtensor/src/rpc_info/metagraph.rs b/pallets/subtensor/src/rpc_info/metagraph.rs index 5404f0bff8..3d5ee7537b 100644 --- a/pallets/subtensor/src/rpc_info/metagraph.rs +++ b/pallets/subtensor/src/rpc_info/metagraph.rs @@ -173,10 +173,10 @@ impl Pallet { blocks_since_last_step: blocks_since_last_step.into(), // blocks since last epoch. // Subnet emission terms - subnet_emission: EmissionValues::::get(netuid).into(), // subnet emission via stao - alpha_in: SubnetAlphaIn::::get(netuid).into(), // amount of alpha in reserve - alpha_out: SubnetAlphaOut::::get(netuid).into(), // amount of alpha outstanding - tao_in: SubnetTAO::::get(netuid).into(), // amount of tao injected per block + subnet_emission: 0.into(), // DEPRECATED + alpha_in: SubnetAlphaIn::::get(netuid).into(), // amount of alpha in reserve + alpha_out: SubnetAlphaOut::::get(netuid).into(), // amount of alpha outstanding + tao_in: SubnetTAO::::get(netuid).into(), // amount of tao injected per block alpha_out_emission: SubnetAlphaOutEmission::::get(netuid).into(), // amount injected in alpha reserves per block alpha_in_emission: SubnetAlphaInEmission::::get(netuid).into(), // amount injected outstanding per block tao_in_emission: SubnetTaoInEmission::::get(netuid).into(), // amount of tao injected per block diff --git a/pallets/subtensor/src/rpc_info/subnet_info.rs b/pallets/subtensor/src/rpc_info/subnet_info.rs index 46644e7467..6e9e722295 100644 --- a/pallets/subtensor/src/rpc_info/subnet_info.rs +++ b/pallets/subtensor/src/rpc_info/subnet_info.rs @@ -102,7 +102,6 @@ impl Pallet { let blocks_since_last_step = Self::get_blocks_since_last_step(netuid); let tempo = Self::get_tempo(netuid); let network_modality = >::get(netuid); - let emission_values = Self::get_emission_value(netuid); let burn: Compact = Self::get_burn_as_u64(netuid).into(); // DEPRECATED let network_connect: Vec<[u16; 2]> = Vec::<[u16; 2]>::new(); @@ -126,7 +125,7 @@ impl Pallet { tempo: tempo.into(), network_modality: network_modality.into(), network_connect, - emission_values: emission_values.into(), + emission_values: 0.into(), burn, owner: Self::get_subnet_owner(netuid), }) @@ -172,7 +171,6 @@ impl Pallet { let blocks_since_last_step = Self::get_blocks_since_last_step(netuid); let tempo = Self::get_tempo(netuid); let network_modality = >::get(netuid); - let emission_value = Self::get_emission_value(netuid); let burn: Compact = Self::get_burn_as_u64(netuid).into(); let identity: Option = SubnetIdentitiesV2::::get(netuid); @@ -198,7 +196,7 @@ impl Pallet { tempo: tempo.into(), network_modality: network_modality.into(), network_connect, - emission_value: emission_value.into(), + emission_value: 0.into(), burn, owner: Self::get_subnet_owner(netuid), identity, diff --git a/pallets/subtensor/src/staking/add_stake.rs b/pallets/subtensor/src/staking/add_stake.rs index ed607eec54..e599262cef 100644 --- a/pallets/subtensor/src/staking/add_stake.rs +++ b/pallets/subtensor/src/staking/add_stake.rs @@ -1,5 +1,5 @@ use super::*; -use sp_core::Get; +use substrate_fixed::types::I96F32; impl Pallet { /// ---- The implementation for the extrinsic add_stake: Adds stake to a hotkey account. @@ -58,13 +58,19 @@ impl Pallet { )?; // 3. Ensure the remove operation from the coldkey is a success. - let tao_staked: u64 = - Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?; + let tao_staked: I96F32 = + Self::remove_balance_from_coldkey_account(&coldkey, stake_to_be_added)?.into(); // 4. Swap the stake into alpha on the subnet and increase counters. // Emit the staking event. let fee = DefaultStakingFee::::get(); - Self::stake_into_subnet(&hotkey, &coldkey, netuid, tao_staked, fee); + Self::stake_into_subnet( + &hotkey, + &coldkey, + netuid, + tao_staked.saturating_to_num::(), + fee, + ); // Ok and return. Ok(()) @@ -148,12 +154,19 @@ impl Pallet { } // 5. Ensure the remove operation from the coldkey is a success. - let tao_staked: u64 = Self::remove_balance_from_coldkey_account(&coldkey, possible_stake)?; + let tao_staked: I96F32 = + Self::remove_balance_from_coldkey_account(&coldkey, possible_stake)?.into(); // 6. Swap the stake into alpha on the subnet and increase counters. // Emit the staking event. let fee = DefaultStakingFee::::get(); - Self::stake_into_subnet(&hotkey, &coldkey, netuid, tao_staked, fee); + Self::stake_into_subnet( + &hotkey, + &coldkey, + netuid, + tao_staked.saturating_to_num::(), + fee, + ); // Ok and return. Ok(()) diff --git a/pallets/subtensor/src/staking/move_stake.rs b/pallets/subtensor/src/staking/move_stake.rs index 9620664b5c..cfe3b8cde1 100644 --- a/pallets/subtensor/src/staking/move_stake.rs +++ b/pallets/subtensor/src/staking/move_stake.rs @@ -1,7 +1,7 @@ use super::*; use safe_math::*; use sp_core::Get; -use substrate_fixed::types::U64F64; +use substrate_fixed::types::{I96F32, U64F64}; impl Pallet { /// Moves stake from one hotkey to another across subnets. @@ -330,13 +330,26 @@ impl Pallet { check_transfer_toggle, )?; + // Calculate the amount that should be moved in this operation + let move_amount = if alpha_amount < max_amount { + alpha_amount + } else { + max_amount + }; + // Unstake from the origin subnet, returning TAO (or a 1:1 equivalent). - let fee = DefaultStakingFee::::get().safe_div(2); + let fee = Self::calculate_staking_fee( + origin_netuid, + origin_hotkey, + I96F32::saturating_from_num(alpha_amount), + ) + .safe_div(2); + let tao_unstaked = Self::unstake_from_subnet( origin_hotkey, origin_coldkey, origin_netuid, - alpha_amount, + move_amount, fee, ); diff --git a/pallets/subtensor/src/staking/remove_stake.rs b/pallets/subtensor/src/staking/remove_stake.rs index c1db7012c3..235d075e6f 100644 --- a/pallets/subtensor/src/staking/remove_stake.rs +++ b/pallets/subtensor/src/staking/remove_stake.rs @@ -1,5 +1,5 @@ use super::*; -use sp_core::Get; +use substrate_fixed::types::I96F32; impl Pallet { /// ---- The implementation for the extrinsic remove_stake: Removes stake from a hotkey account and adds it onto a coldkey. @@ -58,7 +58,11 @@ impl Pallet { )?; // 3. Swap the alpba to tao and update counters for this subnet. - let fee = DefaultStakingFee::::get(); + let fee = Self::calculate_staking_fee( + netuid, + &hotkey, + I96F32::saturating_from_num(alpha_unstaked), + ); let tao_unstaked: u64 = Self::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_unstaked, fee); @@ -109,8 +113,6 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, ) -> dispatch::DispatchResult { - let fee = DefaultStakingFee::::get(); - // 1. We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information. let coldkey = ensure_signed(origin)?; log::info!("do_unstake_all( origin:{:?} hotkey:{:?} )", coldkey, hotkey); @@ -126,20 +128,26 @@ impl Pallet { log::debug!("All subnet netuids: {:?}", netuids); // 4. Iterate through all subnets and remove stake. - for netuid in netuids.iter() { + for netuid in netuids.into_iter() { // Ensure that the hotkey has enough stake to withdraw. let alpha_unstaked = - Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, *netuid); + Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); + let fee = Self::calculate_staking_fee( + netuid, + &hotkey, + I96F32::saturating_from_num(alpha_unstaked), + ); + if alpha_unstaked > 0 { // Swap the alpha to tao and update counters for this subnet. let tao_unstaked: u64 = - Self::unstake_from_subnet(&hotkey, &coldkey, *netuid, alpha_unstaked, fee); + Self::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_unstaked, fee); // Add the balance to the coldkey. If the above fails we will not credit this coldkey. Self::add_balance_to_coldkey_account(&coldkey, tao_unstaked); // If the stake is below the minimum, we clear the nomination from storage. - Self::clear_small_nomination_if_required(&hotkey, &coldkey, *netuid); + Self::clear_small_nomination_if_required(&hotkey, &coldkey, netuid); } } @@ -177,8 +185,6 @@ impl Pallet { origin: T::RuntimeOrigin, hotkey: T::AccountId, ) -> dispatch::DispatchResult { - let fee = DefaultStakingFee::::get(); - // 1. We check the transaction is signed by the caller and retrieve the T::AccountId coldkey information. let coldkey = ensure_signed(origin)?; log::info!("do_unstake_all( origin:{:?} hotkey:{:?} )", coldkey, hotkey); @@ -195,22 +201,28 @@ impl Pallet { // 4. Iterate through all subnets and remove stake. let mut total_tao_unstaked: u64 = 0; - for netuid in netuids.iter() { + for netuid in netuids.into_iter() { // If not Root network. - if *netuid != Self::get_root_netuid() { + if netuid != Self::get_root_netuid() { // Ensure that the hotkey has enough stake to withdraw. let alpha_unstaked = - Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, *netuid); + Self::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); + let fee = Self::calculate_staking_fee( + netuid, + &hotkey, + I96F32::saturating_from_num(alpha_unstaked), + ); + if alpha_unstaked > 0 { // Swap the alpha to tao and update counters for this subnet. - let tao_unstaked: u64 = - Self::unstake_from_subnet(&hotkey, &coldkey, *netuid, alpha_unstaked, fee); + let tao_unstaked = + Self::unstake_from_subnet(&hotkey, &coldkey, netuid, alpha_unstaked, fee); // Increment total total_tao_unstaked = total_tao_unstaked.saturating_add(tao_unstaked); // If the stake is below the minimum, we clear the nomination from storage. - Self::clear_small_nomination_if_required(&hotkey, &coldkey, *netuid); + Self::clear_small_nomination_if_required(&hotkey, &coldkey, netuid); } } } @@ -302,8 +314,12 @@ impl Pallet { )?; // 4. Swap the alpha to tao and update counters for this subnet. - let fee = DefaultStakingFee::::get(); - let tao_unstaked: u64 = + let fee = Self::calculate_staking_fee( + netuid, + &hotkey, + I96F32::saturating_from_num(alpha_unstaked), + ); + let tao_unstaked = Self::unstake_from_subnet(&hotkey, &coldkey, netuid, possible_alpha, fee); // 5. We add the balance to the coldkey. If the above fails we will not credit this coldkey. diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 0a3659b6ac..be9a3744f2 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -57,7 +57,14 @@ impl Pallet { } } pub fn update_moving_price(netuid: u16) { - let alpha: I96F32 = SubnetMovingAlpha::::get(); + let blocks_since_registration = I96F32::saturating_from_num( + Self::get_current_block_as_u64().saturating_sub(NetworkRegisteredAt::::get(netuid)), + ); + // 7200 * 14 = 100_800 is the halving time + let alpha: I96F32 = + SubnetMovingAlpha::::get().saturating_mul(blocks_since_registration.safe_div( + blocks_since_registration.saturating_add(I96F32::saturating_from_num(100_800)), + )); let minus_alpha: I96F32 = I96F32::saturating_from_num(1.0).saturating_sub(alpha); let current_price: I96F32 = alpha .saturating_mul(Self::get_alpha_price(netuid).min(I96F32::saturating_from_num(1.0))); @@ -546,8 +553,12 @@ impl Pallet { amount: u64, ) -> u64 { let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid); + // We expect to add a positive amount here. let actual_alpha = alpha_share_pool.update_value_for_one(coldkey, amount as i64); - actual_alpha.unsigned_abs() + + // We should return a positive amount, or 0 if the operation failed. + // e.g. the stake was removed due to precision issues. + actual_alpha.max(0).unsigned_abs() } pub fn try_increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -576,6 +587,8 @@ impl Pallet { amount: u64, ) -> u64 { let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid); + + // We expect a negative value here let mut actual_alpha = 0; if let Ok(value) = alpha_share_pool.try_get_value(coldkey) { if value >= amount { @@ -583,7 +596,11 @@ impl Pallet { alpha_share_pool.update_value_for_one(coldkey, (amount as i64).neg()); } } - actual_alpha.unsigned_abs() + + // Get the negation of the removed alpha, and clamp at 0. + // This ensures we return a positive value, but only if + // `actual_alpha` was negative (i.e. a decrease in stake). + actual_alpha.neg().max(0).unsigned_abs() } /// Calculates Some(Alpha) returned from pool by staking operation @@ -789,7 +806,7 @@ impl Pallet { /// Stakes TAO into a subnet for a given hotkey and coldkey pair. /// /// We update the pools associated with a subnet as well as update hotkey alpha shares. - pub fn stake_into_subnet( + pub(crate) fn stake_into_subnet( hotkey: &T::AccountId, coldkey: &T::AccountId, netuid: u16, @@ -1049,6 +1066,28 @@ impl Pallet { Ok(()) } + + pub(crate) fn calculate_staking_fee( + netuid: u16, + hotkey: &T::AccountId, + alpha_estimate: I96F32, + ) -> u64 { + if (netuid == Self::get_root_netuid()) || (SubnetMechanism::::get(netuid)) == 0 { + DefaultStakingFee::::get() + } else { + let fee = alpha_estimate + .saturating_mul( + I96F32::saturating_from_num(AlphaDividendsPerSubnet::::get(netuid, &hotkey)) + .safe_div(I96F32::saturating_from_num(TotalHotkeyAlpha::::get( + &hotkey, netuid, + ))), + ) + .saturating_mul(Self::get_alpha_price(netuid)) // fee needs to be in TAO + .saturating_to_num::(); + + fee.max(DefaultStakingFee::::get()) + } + } } /////////////////////////////////////////// diff --git a/pallets/subtensor/src/subnets/subnet.rs b/pallets/subtensor/src/subnets/subnet.rs index 505905af98..87704c558a 100644 --- a/pallets/subtensor/src/subnets/subnet.rs +++ b/pallets/subtensor/src/subnets/subnet.rs @@ -25,37 +25,6 @@ impl Pallet { TotalNetworks::::get() } - /// Fetches the max number of subnet - /// - /// This function retrieves the max number of subnet. - /// - /// # Returns: - /// * 'u16': The max number of subnet - /// - pub fn get_max_subnets() -> u16 { - SubnetLimit::::get() - } - - /// Sets the max number of subnet - /// - /// This function sets the max number of subnet. - /// - pub fn set_max_subnets(limit: u16) { - SubnetLimit::::put(limit); - Self::deposit_event(Event::SubnetLimitSet(limit)); - } - - /// Returns the emission value for the given subnet. - /// - /// This function retrieves the emission value for the given subnet. - /// - /// # Returns: - /// * 'u64': The emission value for the given subnet. - /// - pub fn get_subnet_emission_value(netuid: u16) -> u64 { - EmissionValues::::get(netuid) - } - /// Returns true if the subnetwork exists. /// /// This function checks if a subnetwork with the given UID exists. @@ -321,9 +290,6 @@ impl Pallet { if !ActivityCutoff::::contains_key(netuid) { ActivityCutoff::::insert(netuid, ActivityCutoff::::get(netuid)); } - if !EmissionValues::::contains_key(netuid) { - EmissionValues::::insert(netuid, EmissionValues::::get(netuid)); - } if !MaxWeightsLimit::::contains_key(netuid) { MaxWeightsLimit::::insert(netuid, MaxWeightsLimit::::get(netuid)); } diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index 74070faaca..fa336c687b 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -158,56 +158,63 @@ impl Pallet { OwnedHotkeys::::insert(coldkey, hotkeys); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - // 3. Swap total hotkey alpha for all subnets. + // 3. Swap total hotkey alpha for all subnets it exists on. // TotalHotkeyAlpha( hotkey, netuid ) -> alpha -- the total alpha that the hotkey has on a specific subnet. - let all_netuids: Vec = Self::get_all_subnet_netuids(); - for netuid in all_netuids { - let old_total_hotkey_alpha = TotalHotkeyAlpha::::get(old_hotkey, netuid); - let new_total_hotkey_alpha = TotalHotkeyAlpha::::get(new_hotkey, netuid); - TotalHotkeyAlpha::::remove(old_hotkey, netuid); - TotalHotkeyAlpha::::insert( - new_hotkey, - netuid, - old_total_hotkey_alpha.saturating_add(new_total_hotkey_alpha), - ); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } - - // 4. Swap total hotkey shares on all subnets + TotalHotkeyAlpha::::iter_prefix(old_hotkey) + .drain() + .for_each(|(netuid, old_alpha)| { + let new_total_hotkey_alpha = TotalHotkeyAlpha::::get(new_hotkey, netuid); + TotalHotkeyAlpha::::insert( + new_hotkey, + netuid, + old_alpha.saturating_add(new_total_hotkey_alpha), + ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + }); + + // 4. Swap total hotkey shares on all subnets it exists on. // TotalHotkeyShares( hotkey, netuid ) -> alpha -- the total alpha that the hotkey has on a specific subnet. - let all_netuids: Vec = Self::get_all_subnet_netuids(); - for netuid in all_netuids { - let old_total_hotkey_shares = TotalHotkeyShares::::get(old_hotkey, netuid); - let new_total_hotkey_shares = TotalHotkeyShares::::get(new_hotkey, netuid); - TotalHotkeyShares::::remove(old_hotkey, netuid); - TotalHotkeyShares::::insert( - new_hotkey, - netuid, - old_total_hotkey_shares.saturating_add(new_total_hotkey_shares), - ); - weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); - } + TotalHotkeyShares::::iter_prefix(old_hotkey) + .drain() + .for_each(|(netuid, old_shares)| { + let new_total_hotkey_shares = TotalHotkeyShares::::get(new_hotkey, netuid); + TotalHotkeyShares::::insert( + new_hotkey, + netuid, + old_shares.saturating_add(new_total_hotkey_shares), + ); + weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2)); + }); // 5. Swap LastTxBlock // LastTxBlock( hotkey ) --> u64 -- the last transaction block for the hotkey. + let last_tx_block: u64 = LastTxBlock::::get(old_hotkey); LastTxBlock::::remove(old_hotkey); - LastTxBlock::::insert(new_hotkey, Self::get_current_block_as_u64()); - weight.saturating_accrue(T::DbWeight::get().reads_writes(0, 2)); + LastTxBlock::::insert(new_hotkey, last_tx_block); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); // 6. Swap LastTxBlockDelegateTake // LastTxBlockDelegateTake( hotkey ) --> u64 -- the last transaction block for the hotkey delegate take. + let last_tx_block_delegate_take: u64 = LastTxBlockDelegateTake::::get(old_hotkey); LastTxBlockDelegateTake::::remove(old_hotkey); - LastTxBlockDelegateTake::::insert(new_hotkey, Self::get_current_block_as_u64()); + LastTxBlockDelegateTake::::insert(new_hotkey, last_tx_block_delegate_take); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + + // 7. Swap LastTxBlockChildKeyTake + // LastTxBlockChildKeyTake( hotkey ) --> u64 -- the last transaction block for the hotkey child key take. + let last_tx_block_child_key_take: u64 = LastTxBlockChildKeyTake::::get(old_hotkey); + LastTxBlockChildKeyTake::::remove(old_hotkey); + LastTxBlockChildKeyTake::::insert(new_hotkey, last_tx_block_child_key_take); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); - // 7. Swap Senate members. + // 8. Swap Senate members. // Senate( hotkey ) --> ? if T::SenateMembers::is_member(old_hotkey) { T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?; weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); } - // 8. Swap delegates. + // 9. Swap delegates. // Delegates( hotkey ) -> take value -- the hotkey delegate take value. if Delegates::::contains_key(old_hotkey) { let old_delegate_take = Delegates::::get(old_hotkey); diff --git a/pallets/subtensor/src/tests/children.rs b/pallets/subtensor/src/tests/children.rs index b16836e8f8..21ddd453f5 100644 --- a/pallets/subtensor/src/tests/children.rs +++ b/pallets/subtensor/src/tests/children.rs @@ -1421,128 +1421,6 @@ fn test_do_revoke_children_multiple_complex_scenario() { }); } -// 35: Test getting network max stake -// This test verifies the functionality of getting the network max stake: -// - Checks the default max stake value -// - Sets a new max stake value -// - Verifies that the new value is retrieved correctly -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::children::test_get_network_max_stake --exact --show-output --nocapture -#[test] -fn test_get_network_max_stake() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let default_max_stake = SubtensorModule::get_network_max_stake(netuid); - - // Check that the default value is set correctly - assert_eq!(default_max_stake, u64::MAX); - - // Set a new max stake value - let new_max_stake: u64 = 1_000_000; - SubtensorModule::set_network_max_stake(netuid, new_max_stake); - - // Check that the new value is retrieved correctly - assert_eq!( - SubtensorModule::get_network_max_stake(netuid), - new_max_stake - ); - }); -} - -// 36: Test setting network max stake -// This test verifies the functionality of setting the network max stake: -// - Checks the initial max stake value -// - Sets a new max stake value -// - Verifies that the new value is set correctly -// - Checks that the appropriate event is emitted -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::children::test_set_network_max_stake --exact --show-output --nocapture -#[test] -fn test_set_network_max_stake() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - let initial_max_stake = SubtensorModule::get_network_max_stake(netuid); - - // Set a new max stake value - let new_max_stake: u64 = 500_000; - SubtensorModule::set_network_max_stake(netuid, new_max_stake); - - // Check that the new value is set correctly - assert_eq!( - SubtensorModule::get_network_max_stake(netuid), - new_max_stake - ); - assert_ne!( - SubtensorModule::get_network_max_stake(netuid), - initial_max_stake - ); - - // Check that the event is emitted - System::assert_last_event(Event::NetworkMaxStakeSet(netuid, new_max_stake).into()); - }); -} - -// 37: Test setting network max stake for multiple networks -// This test verifies the functionality of setting different max stake values for multiple networks: -// - Sets different max stake values for two networks -// - Verifies that the values are set correctly for each network -// - Checks that the values are different between networks -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::children::test_set_network_max_stake_multiple_networks --exact --show-output --nocapture -#[test] -fn test_set_network_max_stake_multiple_networks() { - new_test_ext(1).execute_with(|| { - let netuid1: u16 = 1; - let netuid2: u16 = 2; - - // Set different max stake values for two networks - let max_stake1: u64 = 1_000_000; - let max_stake2: u64 = 2_000_000; - SubtensorModule::set_network_max_stake(netuid1, max_stake1); - SubtensorModule::set_network_max_stake(netuid2, max_stake2); - - // Check that the values are set correctly for each network - assert_eq!(SubtensorModule::get_network_max_stake(netuid1), max_stake1); - assert_eq!(SubtensorModule::get_network_max_stake(netuid2), max_stake2); - assert_ne!( - SubtensorModule::get_network_max_stake(netuid1), - SubtensorModule::get_network_max_stake(netuid2) - ); - }); -} - -// 38: Test updating network max stake -// This test verifies the functionality of updating an existing network max stake value: -// - Sets an initial max stake value -// - Updates the max stake value -// - Verifies that the value is updated correctly -// - Checks that the appropriate event is emitted for the update -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::children::test_set_network_max_stake_update --exact --show-output --nocapture -#[test] -fn test_set_network_max_stake_update() { - new_test_ext(1).execute_with(|| { - let netuid: u16 = 1; - - // Set an initial max stake value - let initial_max_stake: u64 = 1_000_000; - SubtensorModule::set_network_max_stake(netuid, initial_max_stake); - - // Update the max stake value - let updated_max_stake: u64 = 1_500_000; - SubtensorModule::set_network_max_stake(netuid, updated_max_stake); - - // Check that the value is updated correctly - assert_eq!( - SubtensorModule::get_network_max_stake(netuid), - updated_max_stake - ); - assert_ne!( - SubtensorModule::get_network_max_stake(netuid), - initial_max_stake - ); - - // Check that the event is emitted for the update - System::assert_last_event(Event::NetworkMaxStakeSet(netuid, updated_max_stake).into()); - }); -} - // 39: Test children stake values // This test verifies the correct distribution of stake among parent and child neurons: // - Sets up a network with a parent neuron and multiple child neurons @@ -2003,9 +1881,8 @@ fn test_get_stake_for_hotkey_on_subnet_edge_cases() { register_ok_neuron(netuid, child1, coldkey, 0); register_ok_neuron(netuid, child2, coldkey, 0); - // Set network max stake - let network_max_stake: u64 = 500_000_000_000_000; // 500_000 TAO - SubtensorModule::set_network_max_stake(netuid, network_max_stake); + // Set above old value of network max stake + let network_max_stake: u64 = 600_000_000_000_000; // Increase stake to the network max SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -3906,3 +3783,210 @@ fn test_do_set_child_as_sn_owner_not_enough_stake() { ); }); } + +// Test dividend distribution for children with same coldkey Owner +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::children::test_dividend_distribution_with_children_same_coldkey_owner --exact --show-output +#[test] +fn test_dividend_distribution_with_children_same_coldkey_owner() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + // Set SN owner cut to 0 + SubtensorModule::set_subnet_owner_cut(0_u16); + + // Define hotkeys and coldkeys + let hotkey_a: U256 = U256::from(1); + let hotkey_b: U256 = U256::from(2); + let coldkey_a: U256 = U256::from(100); // Only one coldkey + + // Register neurons with decreasing stakes + register_ok_neuron(netuid, hotkey_a, coldkey_a, 0); + register_ok_neuron(netuid, hotkey_b, coldkey_a, 0); + + // Add initial stakes + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); + SubtensorModule::add_balance_to_coldkey_account(&coldkey_a, 1_000); + + // Swap to alpha + let total_tao: I96F32 = I96F32::from_num(300_000 + 100_000); + let total_alpha: I96F32 = I96F32::from_num(SubtensorModule::swap_tao_for_alpha( + netuid, + total_tao.saturating_to_num::(), + )); + + // Set the stakes directly + // This avoids needing to swap tao to alpha, impacting the initial stake distribution. + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_a, + &coldkey_a, + netuid, + (total_alpha * I96F32::from_num(300_000) / total_tao).saturating_to_num::(), + ); + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_b, + &coldkey_a, + netuid, + (total_alpha * I96F32::from_num(100_000) / total_tao).saturating_to_num::(), + ); + + // Get old stakes + let stake_a: u64 = SubtensorModule::get_total_stake_for_hotkey(&hotkey_a); + let stake_b: u64 = SubtensorModule::get_total_stake_for_hotkey(&hotkey_b); + + // Assert initial stake is correct + let rel_stake_a = I96F32::from_num(stake_a) / total_tao; + let rel_stake_b = I96F32::from_num(stake_b) / total_tao; + + log::info!("rel_stake_a: {:?}", rel_stake_a); // 0.75 -> 3/4 + log::info!("rel_stake_b: {:?}", rel_stake_b); // 0.25 -> 1/4 + assert_eq!(rel_stake_a, I96F32::from_num(300_000) / total_tao); + assert_eq!(rel_stake_b, I96F32::from_num(100_000) / total_tao); + + // Set parent-child relationships + // A -> B (50% of A's stake) + mock_set_children(&coldkey_a, &hotkey_a, netuid, &[(u64::MAX / 2, hotkey_b)]); + + // Set CHK take rate to 1/9 + let chk_take: I96F32 = I96F32::from_num(1_f64 / 9_f64); + let chk_take_u16: u16 = (chk_take * I96F32::from_num(u16::MAX)).saturating_to_num::(); + ChildkeyTake::::insert(hotkey_b, netuid, chk_take_u16); + + // Set the weight of root TAO to be 0%, so only alpha is effective. + SubtensorModule::set_tao_weight(0); + + let hardcoded_emission: I96F32 = I96F32::from_num(1_000_000); // 1 million (adjust as needed) + + let hotkey_emission: Vec<(U256, u64, u64)> = + SubtensorModule::epoch(netuid, hardcoded_emission.saturating_to_num::()); + log::info!("hotkey_emission: {:?}", hotkey_emission); + let total_emission: I96F32 = hotkey_emission + .iter() + .map(|(_, _, emission)| I96F32::from_num(*emission)) + .sum(); + + // Verify emissions match expected from CHK arrangements + let em_eps: I96F32 = I96F32::from_num(1e-4); // 4 decimal places + // A's pending emission: + assert!( + ((I96F32::from_num(hotkey_emission[0].2) / total_emission) - + I96F32::from_num(3_f64 / 4_f64 * 1_f64 / 2_f64)).abs() // 3/4 * 1/2 = 3/8; 50% -> B + <= em_eps, + "A should have pending emission of 3/8 of total emission" + ); + // B's pending emission: + assert!( + ((I96F32::from_num(hotkey_emission[1].2) / total_emission) - + (I96F32::from_num(1_f64 / 4_f64 + 3_f64 / 4_f64 * 1_f64 / 2_f64))).abs() // 1/4 + 3/4 * 1/2 = 5/8; 50% from A + <= em_eps, + "B should have pending emission of 5/8 of total emission: {:?}", + I96F32::from_num(hotkey_emission[1].2) / total_emission + ); + + // Get the distribution of dividends including the Parent/Child relationship. + let dividends_a = SubtensorModule::get_dividends_distribution( + &hotkey_a, + netuid, + hardcoded_emission.saturating_to_num::(), + ); + let dividends_b = SubtensorModule::get_dividends_distribution( + &hotkey_b, + netuid, + hardcoded_emission.saturating_to_num::(), + ); + log::info!("dividends_a: {:?}", dividends_a); + log::info!("dividends_b: {:?}", dividends_b); + + // We expect A should have no impact from B, as they have the same owner. + assert_eq!(dividends_a.len(), 1); + assert_eq!(dividends_a[0].0, hotkey_a); + assert_eq!( + dividends_a[0].1, + hardcoded_emission.saturating_to_num::() + ); + assert_abs_diff_eq!( + dividends_a + .iter() + .map(|(_, emission)| *emission) + .sum::(), + hardcoded_emission.saturating_to_num::(), + epsilon = (hardcoded_emission / 1000).saturating_to_num::() + ); + + // Expect only 2 dividends. Parent key A and child key B. + assert_eq!(dividends_b.len(), 2); // A and B + assert_eq!(dividends_b[0].0, hotkey_a); + assert_eq!(dividends_b[1].0, hotkey_b); + + // We expect B's coldkey to have no increase in dividends from A, as they have the same owner. + // And therefore, B should get no CHK_TAKE. + + // A should also have no decrease because there is no CHK_TAKE. + let total_stake_b = rel_stake_b + rel_stake_a * 1 / 2; + let expected_b_b: u64 = + (rel_stake_b / total_stake_b * hardcoded_emission).saturating_to_num::(); + + assert_abs_diff_eq!( + dividends_b[1].1, + expected_b_b, + epsilon = (hardcoded_emission / 1000).saturating_to_num::(), + ); + + let expected_b_a: u64 = + ((rel_stake_a * 1 / 2) / total_stake_b * hardcoded_emission).saturating_to_num::(); + assert_eq!(dividends_b[0].0, hotkey_a); + assert_abs_diff_eq!( + dividends_b[0].1, + expected_b_a, + epsilon = (hardcoded_emission / 1000).saturating_to_num::() + ); + assert_abs_diff_eq!( + dividends_b + .iter() + .map(|(_, emission)| *emission) + .sum::(), + hardcoded_emission.saturating_to_num::(), + epsilon = (hardcoded_emission / 1000).saturating_to_num::() + ); + }); +} + +#[test] +fn test_pending_cooldown_one_day() { + let curr_block = 1; + + let expected_cooldown = if cfg!(feature = "fast-blocks") { + 15 + } else { + 7_200 + }; + + new_test_ext(curr_block).execute_with(|| { + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let child1 = U256::from(3); + let child2 = U256::from(4); + let netuid: u16 = 1; + let proportion1: u64 = 1000; + let proportion2: u64 = 2000; + + // Add network and register hotkey + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Set multiple children + mock_schedule_children( + &coldkey, + &hotkey, + netuid, + &[(proportion1, child1), (proportion2, child2)], + ); + + // Verify pending map + let pending_children = PendingChildKeys::::get(netuid, hotkey); + assert_eq!( + pending_children.0, + vec![(proportion1, child1), (proportion2, child2)] + ); + assert_eq!(pending_children.1, curr_block + expected_cooldown); + }); +} diff --git a/pallets/subtensor/src/tests/coinbase.rs b/pallets/subtensor/src/tests/coinbase.rs index 94cb786e48..4ab5d349fd 100644 --- a/pallets/subtensor/src/tests/coinbase.rs +++ b/pallets/subtensor/src/tests/coinbase.rs @@ -2,6 +2,7 @@ use super::mock::*; use crate::*; +use alloc::collections::BTreeMap; use approx::assert_abs_diff_eq; use frame_support::assert_ok; use sp_core::U256; @@ -190,11 +191,16 @@ fn test_coinbase_moving_prices() { SubnetAlphaIn::::insert(netuid, 1_000_000); SubnetMechanism::::insert(netuid, 1); SubnetMovingPrice::::insert(netuid, I96F32::from_num(1)); + NetworkRegisteredAt::::insert(netuid, 1); + // Updating the moving price keeps it the same. assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), I96F32::from_num(1) ); + // Skip some blocks so that EMA price is not slowed down + System::set_block_number(7_200_000); + SubtensorModule::update_moving_price(netuid); assert_eq!( SubtensorModule::get_moving_alpha_price(netuid), @@ -206,29 +212,78 @@ fn test_coinbase_moving_prices() { SubnetMovingAlpha::::set(I96F32::from_num(1.0)); // Run moving 1 times. SubtensorModule::update_moving_price(netuid); - // Assert price is == 100% of the real price. - assert_eq!( - SubtensorModule::get_moving_alpha_price(netuid), - I96F32::from_num(1.0) - ); + // Assert price is ~ 100% of the real price. + assert!(I96F32::from_num(1.0) - SubtensorModule::get_moving_alpha_price(netuid) < 0.05); // Set price to zero. SubnetMovingPrice::::insert(netuid, I96F32::from_num(0)); SubnetMovingAlpha::::set(I96F32::from_num(0.1)); - // Run moving 6 times. - SubtensorModule::update_moving_price(netuid); - SubtensorModule::update_moving_price(netuid); - SubtensorModule::update_moving_price(netuid); - SubtensorModule::update_moving_price(netuid); - SubtensorModule::update_moving_price(netuid); - SubtensorModule::update_moving_price(netuid); + + // EMA price 14 days after registration + System::set_block_number(7_200 * 14); + + // Run moving 14 times. + for _ in 0..14 { + SubtensorModule::update_moving_price(netuid); + } + // Assert price is > 50% of the real price. - assert_eq!( - SubtensorModule::get_moving_alpha_price(netuid), - I96F32::from_num(0.468559) + assert!( + (I96F32::from_num(0.512325) - SubtensorModule::get_moving_alpha_price(netuid)).abs() + < 0.001 ); }); } +// Test moving price updates slow down at the beginning. +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_update_moving_price_initial --exact --show-output --nocapture +#[test] +fn test_update_moving_price_initial() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + // Set current price to 1.0 + SubnetTAO::::insert(netuid, 1_000_000); + SubnetAlphaIn::::insert(netuid, 1_000_000); + SubnetMechanism::::insert(netuid, 1); + SubnetMovingAlpha::::set(I96F32::from_num(0.5)); + SubnetMovingPrice::::insert(netuid, I96F32::from_num(0)); + + // Registered recently + System::set_block_number(510); + NetworkRegisteredAt::::insert(netuid, 500); + + SubtensorModule::update_moving_price(netuid); + + let new_price = SubnetMovingPrice::::get(netuid); + assert!(new_price.to_num::() < 0.001); + }); +} + +// Test moving price updates slow down at the beginning. +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_update_moving_price_after_time --exact --show-output --nocapture +#[test] +fn test_update_moving_price_after_time() { + new_test_ext(1).execute_with(|| { + let netuid: u16 = 1; + add_network(netuid, 1, 0); + // Set current price to 1.0 + SubnetTAO::::insert(netuid, 1_000_000); + SubnetAlphaIn::::insert(netuid, 1_000_000); + SubnetMechanism::::insert(netuid, 1); + SubnetMovingAlpha::::set(I96F32::from_num(0.5)); + SubnetMovingPrice::::insert(netuid, I96F32::from_num(0)); + + // Registered long time ago + System::set_block_number(72_000_500); + NetworkRegisteredAt::::insert(netuid, 500); + + SubtensorModule::update_moving_price(netuid); + + let new_price = SubnetMovingPrice::::get(netuid); + assert!((new_price.to_num::() - 0.5).abs() < 0.001); + }); +} + // Test basic alpha issuance in coinbase mechanism. // This test verifies that: // - Alpha issuance is initialized to 0 for new subnets @@ -934,32 +989,33 @@ fn test_get_root_children_drain() { // Set TAO weight to 1. SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1. // Create keys. - let cold = U256::from(0); - let alice = U256::from(1); - let bob = U256::from(2); + let cold_alice = U256::from(0); + let cold_bob = U256::from(1); + let alice = U256::from(2); + let bob = U256::from(3); // Register Alice and Bob to the root network and alpha subnet. - register_ok_neuron(alpha, alice, cold, 0); - register_ok_neuron(alpha, bob, cold, 0); + register_ok_neuron(alpha, alice, cold_alice, 0); + register_ok_neuron(alpha, bob, cold_bob, 0); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_alice).clone(), alice, )); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_bob).clone(), bob, )); // Add stake for Alice and Bob on root. let alice_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, root, alice_root_stake, ); let bob_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, root, alice_root_stake, ); @@ -967,14 +1023,14 @@ fn test_get_root_children_drain() { let alice_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, alpha, alice_alpha_stake, ); let bob_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, alpha, bob_alpha_stake, ); @@ -1056,32 +1112,33 @@ fn test_get_root_children_drain_half_proportion() { // Set TAO weight to 1. SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1. // Create keys. - let cold = U256::from(0); - let alice = U256::from(1); - let bob = U256::from(2); + let cold_alice = U256::from(0); + let cold_bob = U256::from(1); + let alice = U256::from(2); + let bob = U256::from(3); // Register Alice and Bob to the root network and alpha subnet. - register_ok_neuron(alpha, alice, cold, 0); - register_ok_neuron(alpha, bob, cold, 0); + register_ok_neuron(alpha, alice, cold_alice, 0); + register_ok_neuron(alpha, bob, cold_bob, 0); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_alice).clone(), alice, )); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_bob).clone(), bob, )); // Add stake for Alice and Bob on root. let alice_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, root, alice_root_stake, ); let bob_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, root, alice_root_stake, ); @@ -1089,14 +1146,14 @@ fn test_get_root_children_drain_half_proportion() { let alice_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, alpha, alice_alpha_stake, ); let bob_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, alpha, bob_alpha_stake, ); @@ -1138,32 +1195,33 @@ fn test_get_root_children_drain_with_take() { // Set TAO weight to 1. SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1. // Create keys. - let cold = U256::from(0); - let alice = U256::from(1); - let bob = U256::from(2); + let cold_alice = U256::from(0); + let cold_bob = U256::from(1); + let alice = U256::from(2); + let bob = U256::from(3); // Register Alice and Bob to the root network and alpha subnet. - register_ok_neuron(alpha, alice, cold, 0); - register_ok_neuron(alpha, bob, cold, 0); + register_ok_neuron(alpha, alice, cold_alice, 0); + register_ok_neuron(alpha, bob, cold_bob, 0); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_alice).clone(), alice, )); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_bob).clone(), bob, )); // Add stake for Alice and Bob on root. let alice_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, root, alice_root_stake, ); let bob_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, root, alice_root_stake, ); @@ -1171,14 +1229,14 @@ fn test_get_root_children_drain_with_take() { let alice_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, alpha, alice_alpha_stake, ); let bob_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, alpha, bob_alpha_stake, ); @@ -1215,32 +1273,33 @@ fn test_get_root_children_drain_with_half_take() { // Set TAO weight to 1. SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1. // Create keys. - let cold = U256::from(0); - let alice = U256::from(1); - let bob = U256::from(2); + let cold_alice = U256::from(0); + let cold_bob = U256::from(1); + let alice = U256::from(2); + let bob = U256::from(3); // Register Alice and Bob to the root network and alpha subnet. - register_ok_neuron(alpha, alice, cold, 0); - register_ok_neuron(alpha, bob, cold, 0); + register_ok_neuron(alpha, alice, cold_alice, 0); + register_ok_neuron(alpha, bob, cold_bob, 0); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_alice).clone(), alice, )); assert_ok!(SubtensorModule::root_register( - RuntimeOrigin::signed(cold).clone(), + RuntimeOrigin::signed(cold_bob).clone(), bob, )); // Add stake for Alice and Bob on root. let alice_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, root, alice_root_stake, ); let bob_root_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, root, alice_root_stake, ); @@ -1248,14 +1307,14 @@ fn test_get_root_children_drain_with_half_take() { let alice_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &alice, - &cold, + &cold_alice, alpha, alice_alpha_stake, ); let bob_alpha_stake: u64 = 1_000_000_000; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( &bob, - &cold, + &cold_bob, alpha, bob_alpha_stake, ); @@ -1381,3 +1440,51 @@ fn test_get_root_children_drain_with_half_take() { // ); // }); // } + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_incentive_to_subnet_owner_is_burned --exact --show-output --nocapture +#[test] +fn test_incentive_to_subnet_owner_is_burned() { + new_test_ext(1).execute_with(|| { + let subnet_owner_ck = U256::from(0); + let subnet_owner_hk = U256::from(1); + + let other_ck = U256::from(2); + let other_hk = U256::from(3); + + let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck); + + let pending_tao: u64 = 1_000_000_000; + let owner_cut: u64 = 0; + let mut incentives: BTreeMap = BTreeMap::new(); + let mut dividends: BTreeMap = BTreeMap::new(); + + // Give incentive to other_hk + incentives.insert(other_hk, 10_000_000); + + // Give incentives to subnet_owner_hk + incentives.insert(subnet_owner_hk, 10_000_000); + + // Verify stake before + let subnet_owner_stake_before = + SubtensorModule::get_stake_for_hotkey_on_subnet(&subnet_owner_hk, netuid); + assert_eq!(subnet_owner_stake_before, 0); + let other_stake_before = SubtensorModule::get_stake_for_hotkey_on_subnet(&other_hk, netuid); + assert_eq!(other_stake_before, 0); + + // Distribute dividends and incentives + SubtensorModule::distribute_dividends_and_incentives( + netuid, + pending_tao, + owner_cut, + incentives, + dividends, + ); + + // Verify stake after + let subnet_owner_stake_after = + SubtensorModule::get_stake_for_hotkey_on_subnet(&subnet_owner_hk, netuid); + assert_eq!(subnet_owner_stake_after, 0); + let other_stake_after = SubtensorModule::get_stake_for_hotkey_on_subnet(&other_hk, netuid); + assert!(other_stake_after > 0); + }); +} diff --git a/pallets/subtensor/src/tests/epoch.rs b/pallets/subtensor/src/tests/epoch.rs index 4c24769c27..38b104ac2b 100644 --- a/pallets/subtensor/src/tests/epoch.rs +++ b/pallets/subtensor/src/tests/epoch.rs @@ -582,11 +582,6 @@ fn test_1_graph() { )); // SubtensorModule::set_weights_for_testing( netuid, i as u16, vec![ ( 0, u16::MAX )]); // doesn't set update status // SubtensorModule::set_bonds_for_testing( netuid, uid, vec![ ( 0, u16::MAX )]); // rather, bonds are calculated in epoch - SubtensorModule::set_emission_values(&[netuid], vec![1_000_000_000]).unwrap(); - assert_eq!( - SubtensorModule::get_subnet_emission_value(netuid), - 1_000_000_000 - ); SubtensorModule::epoch(netuid, 1_000_000_000); assert_eq!( SubtensorModule::get_total_stake_for_hotkey(&hotkey), @@ -597,10 +592,6 @@ fn test_1_graph() { assert_eq!(SubtensorModule::get_consensus_for_uid(netuid, uid), 0); assert_eq!(SubtensorModule::get_incentive_for_uid(netuid, uid), 0); assert_eq!(SubtensorModule::get_dividends_for_uid(netuid, uid), 0); - assert_eq!( - SubtensorModule::get_emission_for_uid(netuid, uid), - 1_000_000_000 - ); }); } @@ -2285,19 +2276,19 @@ fn test_compute_alpha_values() { // exp_val = exp(0.0 - 1.0 * 0.1) = exp(-0.1) // alpha[0] = 1 / (1 + exp(-0.1)) ~ 0.9048374180359595 let exp_val_0 = I32F32::from_num(0.9048374180359595); - let expected_alpha_0 = I32F32::from_num(1.0) / I32F32::from_num(1.0).saturating_add(exp_val_0); + let expected_alpha_0 = I32F32::from_num(1.0) / (I32F32::from_num(1.0) + exp_val_0); // For consensus[1] = 0.5: // exp_val = exp(0.0 - 1.0 * 0.5) = exp(-0.5) // alpha[1] = 1 / (1 + exp(-0.5)) ~ 0.6065306597126334 let exp_val_1 = I32F32::from_num(0.6065306597126334); - let expected_alpha_1 = I32F32::from_num(1.0) / I32F32::from_num(1.0).saturating_add(exp_val_1); + let expected_alpha_1 = I32F32::from_num(1.0) / (I32F32::from_num(1.0) + exp_val_1); // For consensus[2] = 0.9: // exp_val = exp(0.0 - 1.0 * 0.9) = exp(-0.9) // alpha[2] = 1 / (1 + exp(-0.9)) ~ 0.4065696597405991 let exp_val_2 = I32F32::from_num(0.4065696597405991); - let expected_alpha_2 = I32F32::from_num(1.0) / I32F32::from_num(1.0).saturating_add(exp_val_2); + let expected_alpha_2 = I32F32::from_num(1.0) / (I32F32::from_num(1.0) + exp_val_2); // Define an epsilon for approximate equality checks. let epsilon = I32F32::from_num(1e-6); @@ -2329,13 +2320,13 @@ fn test_compute_alpha_values_256_miners() { for (i, &c) in consensus.iter().enumerate() { // Use saturating subtraction and multiplication - let exponent = b.saturating_sub(a.saturating_mul(c)); + let exponent = b - (a * c); // Use safe_exp instead of exp let exp_val = safe_exp(exponent); // Use saturating addition and division - let expected_alpha = I32F32::from_num(1.0) / I32F32::from_num(1.0).saturating_add(exp_val); + let expected_alpha = I32F32::from_num(1.0) / (I32F32::from_num(1.0) + exp_val); // Assert that the computed alpha values match the expected values within the epsilon. assert_approx_eq(alpha[i], expected_alpha, epsilon); @@ -2782,6 +2773,61 @@ fn test_blocks_since_last_step() { }); } +#[test] +fn test_can_set_self_weight_as_subnet_owner() { + new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey: U256 = U256::from(1); + let subnet_owner_hotkey: U256 = U256::from(1 + 456); + + let other_hotkey: U256 = U256::from(2); + + let stake = 5_000_000_000_000; // 5k TAO + let to_emit: u64 = 1_000_000_000; // 1 TAO + + // Create subnet + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + // Register the other hotkey + register_ok_neuron(netuid, other_hotkey, subnet_owner_coldkey, 0); + + // Add stake to owner hotkey. + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &subnet_owner_hotkey, + &subnet_owner_coldkey, + netuid, + stake, + ); + + // Give vpermits to owner hotkey ONLY + ValidatorPermit::::insert(netuid, vec![true, false]); + + // Set weight of 50% to each hotkey. + // This includes a self-weight + let fifty_percent: u16 = u16::MAX / 2; + Weights::::insert(netuid, 0, vec![(0, fifty_percent), (1, fifty_percent)]); + + step_block(1); + // Set updated so weights are valid + LastUpdate::::insert(netuid, vec![2, 0]); + + // Run epoch + let hotkey_emission: Vec<(U256, u64, u64)> = SubtensorModule::epoch(netuid, to_emit); + + // hotkey_emission is [(hotkey, incentive, dividend)] + assert_eq!(hotkey_emission.len(), 2); + assert_eq!(hotkey_emission[0].0, subnet_owner_hotkey); + assert_eq!(hotkey_emission[1].0, other_hotkey); + + log::debug!("hotkey_emission: {:?}", hotkey_emission); + // Both should have received incentive emission + assert!(hotkey_emission[0].1 > 0); + assert!(hotkey_emission[1].1 > 0); + + // Their incentive should be equal + assert_eq!(hotkey_emission[0].1, hotkey_emission[1].1); + }); +} + // Map the retention graph for consensus guarantees with an single epoch on a graph with 512 nodes, // of which the first 64 are validators, the graph is split into a major and minor set, each setting // specific weight on itself and the complement on the other. diff --git a/pallets/subtensor/src/tests/math.rs b/pallets/subtensor/src/tests/math.rs index 19bab75b4e..036e2015ab 100644 --- a/pallets/subtensor/src/tests/math.rs +++ b/pallets/subtensor/src/tests/math.rs @@ -58,7 +58,13 @@ fn assert_sparse_mat_compare( ) { assert!(ma.len() == mb.len()); for row in 0..ma.len() { - assert!(ma[row].len() == mb[row].len()); + assert!( + ma[row].len() == mb[row].len(), + "row: {}, ma: {:?}, mb: {:?}", + row, + ma[row], + mb[row] + ); for j in 0..ma[row].len() { assert!(ma[row][j].0 == mb[row][j].0); // u16 assert_float_compare(ma[row][j].1, mb[row][j].1, epsilon) // I32F32 @@ -1034,6 +1040,27 @@ fn test_math_inplace_mask_diag() { ); } +#[test] +fn test_math_inplace_mask_diag_except_index() { + let vector: Vec = vec![1., 2., 3., 4., 5., 6., 7., 8., 9.]; + let rows = 3; + + for i in 0..rows { + let mut target: Vec = vec![0., 2., 3., 4., 0., 6., 7., 8., 0.]; + let row = i * rows; + let col = i; + target[row + col] = vector[row + col]; + + let mut mat = vec_to_mat_fixed(&vector, rows, false); + inplace_mask_diag_except_index(&mut mat, i as u16); + assert_mat_compare( + &mat, + &vec_to_mat_fixed(&target, rows, false), + I32F32::from_num(0), + ); + } +} + #[test] fn test_math_mask_rows_sparse() { let input: Vec = vec![1., 2., 3., 4., 5., 6., 7., 8., 9.]; @@ -1105,6 +1132,58 @@ fn test_math_mask_diag_sparse() { ); } +#[test] +fn test_math_mask_diag_sparse_except_index() { + let rows = 3; + + let vector: Vec = vec![1., 2., 3., 4., 5., 6., 7., 8., 9.]; + let mat = vec_to_sparse_mat_fixed(&vector, rows, false); + + for i in 0..rows { + let mut target: Vec = vec![0., 2., 3., 4., 0., 6., 7., 8., 0.]; + let row = i * rows; + let col = i; + target[row + col] = vector[row + col]; + + let result = mask_diag_sparse_except_index(&mat, i as u16); + let target_as_mat = vec_to_sparse_mat_fixed(&target, rows, false); + + assert_sparse_mat_compare(&result, &target_as_mat, I32F32::from_num(0)); + } + + let vector: Vec = vec![1., 0., 0., 0., 5., 0., 0., 0., 9.]; + let mat = vec_to_sparse_mat_fixed(&vector, rows, false); + + for i in 0..rows { + let mut target: Vec = vec![0., 0., 0., 0., 0., 0., 0., 0., 0.]; + let row = i * rows; + let col = i; + target[row + col] = vector[row + col]; + + let result = mask_diag_sparse_except_index(&mat, i as u16); + let target_as_mat = vec_to_sparse_mat_fixed(&target, rows, false); + assert_eq!(result.len(), target_as_mat.len()); + + assert_sparse_mat_compare(&result, &target_as_mat, I32F32::from_num(0)); + } + + for i in 0..rows { + let vector: Vec = vec![0., 0., 0., 0., 0., 0., 0., 0., 0.]; + let mat = vec_to_sparse_mat_fixed(&vector, rows, false); + + let mut target: Vec = vec![0., 0., 0., 0., 0., 0., 0., 0., 0.]; + let row = i * rows; + let col = i; + target[row + col] = vector[row + col]; + + let result = mask_diag_sparse_except_index(&mat, i as u16); + let target_as_mat = vec_to_sparse_mat_fixed(&target, rows, false); + assert_eq!(result.len(), target_as_mat.len()); + + assert_sparse_mat_compare(&result, &target_as_mat, I32F32::from_num(0)); + } +} + #[test] fn test_math_vec_mask_sparse_matrix() { let vector: Vec = vec![1., 2., 3., 4., 5., 6., 7., 8., 9.]; diff --git a/pallets/subtensor/src/tests/mock.rs b/pallets/subtensor/src/tests/mock.rs index aae6aa60ef..79da754815 100644 --- a/pallets/subtensor/src/tests/mock.rs +++ b/pallets/subtensor/src/tests/mock.rs @@ -175,13 +175,12 @@ 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 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 InitialNetworkMaxStake: u64 = u64::MAX; // Maximum possible value for u64 + // pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED) pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days pub const InitialTaoWeight: u64 = 0; // 100% global weight. @@ -398,13 +397,11 @@ impl crate::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 InitialNetworkMaxStake = InitialNetworkMaxStake; type Preimages = Preimage; type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration; diff --git a/pallets/subtensor/src/tests/registration.rs b/pallets/subtensor/src/tests/registration.rs index 988f1de662..50d409561d 100644 --- a/pallets/subtensor/src/tests/registration.rs +++ b/pallets/subtensor/src/tests/registration.rs @@ -1571,11 +1571,6 @@ fn test_full_pass_through() { assert_eq!(SubtensorModule::get_tempo(netuid1), tempo1); assert_eq!(SubtensorModule::get_tempo(netuid2), tempo2); - // Check their emission value. - assert_eq!(SubtensorModule::get_emission_value(netuid0), 0); - assert_eq!(SubtensorModule::get_emission_value(netuid1), 0); - assert_eq!(SubtensorModule::get_emission_value(netuid2), 0); - // Set their max allowed uids. SubtensorModule::set_max_allowed_uids(netuid0, 2); SubtensorModule::set_max_allowed_uids(netuid1, 2); diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 5d9db9f4e8..38c440fe71 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -2219,11 +2219,71 @@ fn test_remove_stake_fee_goes_to_subnet_tao() { }); } +// cargo test --package pallet-subtensor --lib -- tests::staking::test_remove_stake_fee_realistic_values --exact --show-output --nocapture #[test] -fn test_stake_below_min_validate() { - // Testing the signed extension validate function - // correctly filters the `add_stake` transaction. +fn test_remove_stake_fee_realistic_values() { + new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let hotkey = U256::from(2); + let coldkey = U256::from(3); + let alpha_to_unstake = 111_180_000_000; + let alpha_divs = 2_816_190; + + let netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + SubtensorModule::create_account_if_non_existent(&coldkey, &hotkey); + + // Mock a realistic scenario: + // Subnet 1 has 3896 TAO and 128_011 Alpha in reserves, which + // makes its price ~0.03. + // A hotkey has 111 Alpha stake and is unstaking all Alpha. + // Alpha dividends of this hotkey are ~0.0028 + // This makes fee be equal ~0.0028 Alpha ~= 84000 rao + let tao_reserve: U96F32 = U96F32::from_num(3_896_056_559_708_u64); + let alpha_in: U96F32 = U96F32::from_num(128_011_331_299_964_u64); + SubnetTAO::::insert(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + AlphaDividendsPerSubnet::::insert(netuid, hotkey, alpha_divs); + let current_price = SubtensorModule::get_alpha_price(netuid).to_num::(); + + // Add stake first time to init TotalHotkeyAlpha + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, + &coldkey, + netuid, + alpha_to_unstake, + ); + + // Estimate fees + let expected_fee: f64 = current_price * alpha_divs as f64; + + // Remove stake to measure fee + let balance_before = SubtensorModule::get_coldkey_balance(&coldkey); + let expected_tao_no_fee = + SubtensorModule::sim_swap_alpha_for_tao(netuid, alpha_to_unstake).unwrap(); + + assert_ok!(SubtensorModule::remove_stake( + RuntimeOrigin::signed(coldkey), + hotkey, + netuid, + alpha_to_unstake + )); + + // Calculate expected fee + let balance_after = SubtensorModule::get_coldkey_balance(&coldkey); + let actual_fee = expected_tao_no_fee as f64 - (balance_after - balance_before) as f64; + log::info!("Actual fee: {:?}", actual_fee); + + assert_abs_diff_eq!( + actual_fee as u64, + expected_fee as u64, + epsilon = expected_fee as u64 / 1000 + ); + }); +} +#[test] +fn test_stake_below_min_validate() { new_test_ext(0).execute_with(|| { let subnet_owner_coldkey = U256::from(1001); let subnet_owner_hotkey = U256::from(1002); @@ -3885,3 +3945,65 @@ fn test_remove_99_9989_per_cent_stake_leaves_a_little() { assert_abs_diff_eq!(new_alpha, (alpha as f64 * 0.01) as u64, epsilon = 10); }); } + +#[test] +fn test_move_stake_limit_partial() { + new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let stake_amount = 150_000_000_000; + let move_amount = 150_000_000_000; + + // add network + let origin_netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let destination_netuid: u16 = + add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + register_ok_neuron(origin_netuid, hotkey, coldkey, 192213123); + register_ok_neuron(destination_netuid, hotkey, coldkey, 192213123); + + // Give the neuron some stake to remove + SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, + &coldkey, + origin_netuid, + stake_amount, + ); + + // Forse-set alpha in and tao reserve to make price equal 1.5 on both origin and destination, + // but there's much more liquidity on destination, so its price wouldn't go up when restaked + let tao_reserve: U96F32 = U96F32::from_num(150_000_000_000_u64); + let alpha_in: U96F32 = U96F32::from_num(100_000_000_000_u64); + SubnetTAO::::insert(origin_netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(origin_netuid, alpha_in.to_num::()); + SubnetTAO::::insert(destination_netuid, (tao_reserve * 100_000).to_num::()); + SubnetAlphaIn::::insert(destination_netuid, (alpha_in * 100_000).to_num::()); + let current_price: U96F32 = + U96F32::from_num(SubtensorModule::get_alpha_price(origin_netuid)); + assert_eq!(current_price, U96F32::from_num(1.5)); + + // The relative price between origin and destination subnets is 1. + // Setup limit relative price so that it doesn't drop by more than 1% from current price + let limit_price = 990_000_000; + + // Move stake with slippage safety - executes partially + assert_ok!(SubtensorModule::swap_stake_limit( + RuntimeOrigin::signed(coldkey), + hotkey, + origin_netuid, + destination_netuid, + move_amount, + limit_price, + true, + )); + + let new_alpha = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, + &coldkey, + origin_netuid, + ); + + assert_abs_diff_eq!(new_alpha, 149_000_000_000, epsilon = 100_000_000,); + }); +} diff --git a/pallets/subtensor/src/tests/swap_coldkey.rs b/pallets/subtensor/src/tests/swap_coldkey.rs index 8f7b024e4c..ad1fd68526 100644 --- a/pallets/subtensor/src/tests/swap_coldkey.rs +++ b/pallets/subtensor/src/tests/swap_coldkey.rs @@ -14,6 +14,7 @@ use frame_support::traits::schedule::DispatchTime; use frame_support::traits::schedule::v3::Named as ScheduleNamed; use sp_core::{Get, H256, U256}; use sp_runtime::DispatchError; +use substrate_fixed::types::I96F32; // // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_coldkey -- test_swap_total_hotkey_coldkey_stakes_this_interval --exact --nocapture // #[test] @@ -537,7 +538,9 @@ fn test_swap_concurrent_modifications() { let netuid: u16 = 1; let initial_stake = 1_000_000_000_000; let additional_stake = 500_000_000_000; - let fee = DefaultStakingFee::::get(); + let initial_stake_alpha = + I96F32::from(initial_stake).saturating_mul(SubtensorModule::get_alpha_price(netuid)); + let fee = SubtensorModule::calculate_staking_fee(netuid, &hotkey, initial_stake_alpha); // Setup initial state add_network(netuid, 1, 1); @@ -588,7 +591,6 @@ fn test_swap_concurrent_modifications() { &mut weight )); - let eps = 500; // RAO assert_abs_diff_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, @@ -596,7 +598,7 @@ fn test_swap_concurrent_modifications() { netuid ), stake_before_swap + additional_stake - fee, - epsilon = eps + epsilon = (stake_before_swap + additional_stake - fee) / 1000 ); assert!(!Alpha::::contains_key((hotkey, old_coldkey, netuid))); }); diff --git a/pallets/subtensor/src/tests/swap_hotkey.rs b/pallets/subtensor/src/tests/swap_hotkey.rs index dab1675074..63413b0667 100644 --- a/pallets/subtensor/src/tests/swap_hotkey.rs +++ b/pallets/subtensor/src/tests/swap_hotkey.rs @@ -116,56 +116,6 @@ fn test_swap_total_hotkey_stake() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_last_tx_block --exact --nocapture -#[test] -fn test_swap_last_tx_block() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let mut weight = Weight::zero(); - - LastTxBlock::::insert(old_hotkey, 1000); - assert_ok!(SubtensorModule::perform_hotkey_swap( - &old_hotkey, - &new_hotkey, - &coldkey, - &mut weight - )); - - assert!(!LastTxBlock::::contains_key(old_hotkey)); - assert_eq!( - LastTxBlock::::get(new_hotkey), - SubtensorModule::get_current_block_as_u64() - ); - }); -} - -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_last_tx_block_delegate_take --exact --nocapture -#[test] -fn test_swap_last_tx_block_delegate_take() { - new_test_ext(1).execute_with(|| { - let old_hotkey = U256::from(1); - let new_hotkey = U256::from(2); - let coldkey = U256::from(3); - let mut weight = Weight::zero(); - - crate::LastTxBlockDelegateTake::::insert(old_hotkey, 1000); - assert_ok!(SubtensorModule::perform_hotkey_swap( - &old_hotkey, - &new_hotkey, - &coldkey, - &mut weight - )); - - assert!(!LastTxBlockDelegateTake::::contains_key(old_hotkey)); - assert_eq!( - LastTxBlockDelegateTake::::get(new_hotkey), - SubtensorModule::get_current_block_as_u64() - ); - }); -} - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_senate_members --exact --nocapture #[test] fn test_swap_senate_members() { @@ -1387,3 +1337,39 @@ fn test_swap_hotkey_is_sn_owner_hotkey() { assert_eq!(SubnetOwnerHotkey::::get(netuid), new_hotkey); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_swap_rate_limits --exact --nocapture +#[test] +fn test_swap_hotkey_swap_rate_limits() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let mut weight = Weight::zero(); + + let last_tx_block = 123; + let delegate_take_block = 4567; + let child_key_take_block = 8910; + + // Set the last tx block for the old hotkey + LastTxBlock::::insert(old_hotkey, last_tx_block); + // Set the last delegate take block for the old hotkey + LastTxBlockDelegateTake::::insert(old_hotkey, delegate_take_block); + // Set last childkey take block for the old hotkey + LastTxBlockChildKeyTake::::insert(old_hotkey, child_key_take_block); + + // Perform the swap + SubtensorModule::perform_hotkey_swap(&old_hotkey, &new_hotkey, &coldkey, &mut weight); + + // Check for new hotkey + assert_eq!(LastTxBlock::::get(new_hotkey), last_tx_block); + assert_eq!( + LastTxBlockDelegateTake::::get(new_hotkey), + delegate_take_block + ); + assert_eq!( + LastTxBlockChildKeyTake::::get(new_hotkey), + child_key_take_block + ); + }); +} diff --git a/pallets/subtensor/src/utils/misc.rs b/pallets/subtensor/src/utils/misc.rs index bd093a76b5..19d07248d2 100644 --- a/pallets/subtensor/src/utils/misc.rs +++ b/pallets/subtensor/src/utils/misc.rs @@ -1,7 +1,7 @@ use super::*; use crate::{ Error, - system::{ensure_root, ensure_signed_or_root, pallet_prelude::BlockNumberFor}, + system::{ensure_root, ensure_signed, ensure_signed_or_root, pallet_prelude::BlockNumberFor}, }; use safe_math::*; use sp_core::Get; @@ -23,6 +23,15 @@ impl Pallet { } } + pub fn ensure_subnet_owner(o: T::RuntimeOrigin, netuid: u16) -> Result<(), DispatchError> { + let coldkey = ensure_signed(o); + match coldkey { + Ok(who) if SubnetOwner::::get(netuid) == who => Ok(()), + Ok(_) => Err(DispatchError::BadOrigin), + Err(x) => Err(x.into()), + } + } + // ======================== // ==== Global Setters ==== // ======================== @@ -204,9 +213,6 @@ impl Pallet { pub fn get_tempo(netuid: u16) -> u16 { Tempo::::get(netuid) } - pub fn get_emission_value(netuid: u16) -> u64 { - EmissionValues::::get(netuid) - } pub fn get_pending_emission(netuid: u16) -> u64 { PendingEmission::::get(netuid) } @@ -682,38 +688,6 @@ impl Pallet { LiquidAlphaOn::::get(netuid) } - /// Retrieves the maximum stake allowed for a given network. - /// - /// # Arguments - /// - /// * `netuid` - The unique identifier of the network. - /// - /// # Returns - /// - /// * `u64` - The maximum stake allowed for the specified network. - pub fn get_network_max_stake(netuid: u16) -> u64 { - NetworkMaxStake::::get(netuid) - } - - /// Sets the maximum stake allowed for a given network. - /// - /// # Arguments - /// - /// * `netuid` - The unique identifier of the network. - /// * `max_stake` - The new maximum stake value to set. - /// - /// # Effects - /// - /// * Updates the NetworkMaxStake storage. - /// * Emits a NetworkMaxStakeSet event. - pub fn set_network_max_stake(netuid: u16, max_stake: u64) { - // Update the NetworkMaxStake storage with the new max_stake value - NetworkMaxStake::::insert(netuid, max_stake); - - // Emit an event to notify listeners about the change - Self::deposit_event(Event::NetworkMaxStakeSet(netuid, max_stake)); - } - /// Set the duration for coldkey swap /// /// # Arguments @@ -743,4 +717,28 @@ impl Pallet { DissolveNetworkScheduleDuration::::set(duration); Self::deposit_event(Event::DissolveNetworkScheduleDurationSet(duration)); } + + /// Set the owner hotkey for a subnet. + /// + /// # Arguments + /// + /// * `netuid` - The unique identifier for the subnet. + /// * `hotkey` - The new hotkey for the subnet owner. + /// + /// # Effects + /// + /// * Update the SubnetOwnerHotkey storage. + /// * Emits a SubnetOwnerHotkeySet event. + pub fn set_subnet_owner_hotkey(netuid: u16, hotkey: &T::AccountId) { + SubnetOwnerHotkey::::insert(netuid, hotkey.clone()); + Self::deposit_event(Event::SubnetOwnerHotkeySet(netuid, hotkey.clone())); + } + + // Get the uid of the Owner Hotkey for a subnet. + pub fn get_owner_uid(netuid: u16) -> Option { + match SubnetOwnerHotkey::::try_get(netuid) { + Ok(owner_hotkey) => Uids::::get(netuid, &owner_hotkey), + Err(_) => None, + } + } } diff --git a/pallets/subtensor/src/utils/rate_limiting.rs b/pallets/subtensor/src/utils/rate_limiting.rs index 8b30f9665b..c37a78d2e4 100644 --- a/pallets/subtensor/src/utils/rate_limiting.rs +++ b/pallets/subtensor/src/utils/rate_limiting.rs @@ -7,6 +7,7 @@ pub enum TransactionType { SetChildkeyTake, Unknown, RegisterNetwork, + SetWeightsVersionKey, } /// Implement conversion from TransactionType to u16 @@ -17,6 +18,7 @@ impl From for u16 { TransactionType::SetChildkeyTake => 1, TransactionType::Unknown => 2, TransactionType::RegisterNetwork => 3, + TransactionType::SetWeightsVersionKey => 4, } } } @@ -28,6 +30,7 @@ impl From for TransactionType { 0 => TransactionType::SetChildren, 1 => TransactionType::SetChildkeyTake, 3 => TransactionType::RegisterNetwork, + 4 => TransactionType::SetWeightsVersionKey, _ => TransactionType::Unknown, } } @@ -41,14 +44,18 @@ impl Pallet { match tx_type { TransactionType::SetChildren => 150, // 30 minutes TransactionType::SetChildkeyTake => TxChildkeyTakeRateLimit::::get(), - TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) TransactionType::RegisterNetwork => NetworkRateLimit::::get(), + + TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) + _ => 0, } } - pub fn get_rate_limit_on_subnet(tx_type: &TransactionType, _netuid: u16) -> u64 { + pub fn get_rate_limit_on_subnet(tx_type: &TransactionType, netuid: u16) -> u64 { #[allow(clippy::match_single_binding)] match tx_type { + TransactionType::SetWeightsVersionKey => (Tempo::::get(netuid) as u64) + .saturating_mul(WeightsVersionKeyRateLimit::::get()), _ => Self::get_rate_limit(tx_type), } } diff --git a/precompiles/Cargo.toml b/precompiles/Cargo.toml new file mode 100644 index 0000000000..ec46e6aee2 --- /dev/null +++ b/precompiles/Cargo.toml @@ -0,0 +1,58 @@ +[package] +name = "subtensor-precompiles" +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] +ed25519-dalek = { workspace = true } +fp-evm = { workspace = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +log = { workspace = true } +pallet-balances = { workspace = true } +pallet-evm = { workspace = true } +pallet-evm-precompile-modexp = { workspace = true } +pallet-evm-precompile-sha3fips = { workspace = true } +pallet-evm-precompile-simple = { workspace = true } +pallet-proxy = { workspace = true } +precompile-utils = { workspace = true } +sp-core = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } +subtensor-runtime-common = { workspace = true } + +pallet-subtensor = { workspace = true } +pallet-admin-utils = { workspace = true } + +[lints] +workspace = true + +[features] +default = ["std"] +std = [ + "ed25519-dalek/std", + "fp-evm/std", + "frame-support/std", + "frame-system/std", + "log/std", + "pallet-admin-utils/std", + "pallet-balances/std", + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-sha3fips/std", + "pallet-evm-precompile-simple/std", + "pallet-evm/std", + "pallet-proxy/std", + "pallet-subtensor/std", + "precompile-utils/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", + "subtensor-runtime-common/std", +] diff --git a/precompiles/src/balance_transfer.rs b/precompiles/src/balance_transfer.rs new file mode 100644 index 0000000000..b132125f22 --- /dev/null +++ b/precompiles/src/balance_transfer.rs @@ -0,0 +1,60 @@ +use core::marker::PhantomData; + +use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_system::RawOrigin; +use pallet_evm::PrecompileHandle; +use precompile_utils::EvmResult; +use sp_core::{H256, U256}; +use sp_runtime::traits::{Dispatchable, StaticLookup, UniqueSaturatedInto}; + +use crate::{PrecompileExt, PrecompileHandleExt}; + +pub(crate) struct BalanceTransferPrecompile(PhantomData); + +impl PrecompileExt for BalanceTransferPrecompile +where + R: frame_system::Config + pallet_balances::Config + pallet_evm::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: + GetDispatchInfo + Dispatchable, + ::RuntimeCall: From> + + GetDispatchInfo + + Dispatchable, + <::Lookup as StaticLookup>::Source: From, + ::Balance: TryFrom, +{ + const INDEX: u64 = 2048; +} + +#[precompile_utils::precompile] +impl BalanceTransferPrecompile +where + R: frame_system::Config + pallet_balances::Config + pallet_evm::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: + GetDispatchInfo + Dispatchable, + ::RuntimeCall: From> + + GetDispatchInfo + + Dispatchable, + <::Lookup as StaticLookup>::Source: From, + ::Balance: TryFrom, +{ + #[precompile::public("transfer(bytes32)")] + #[precompile::payable] + fn transfer(handle: &mut impl PrecompileHandle, address: H256) -> EvmResult<()> { + let amount_sub = handle.try_convert_apparent_value::()?; + + if amount_sub.is_zero() { + return Ok(()); + } + + let dest = R::AccountId::from(address.0).into(); + + let call = pallet_balances::Call::::transfer_allow_death { + dest, + value: amount_sub.unique_saturated_into(), + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(Self::account_id())) + } +} diff --git a/runtime/src/precompiles/ed25519.rs b/precompiles/src/ed25519.rs similarity index 61% rename from runtime/src/precompiles/ed25519.rs rename to precompiles/src/ed25519.rs index 601247f4e8..ae23a70e78 100644 --- a/runtime/src/precompiles/ed25519.rs +++ b/precompiles/src/ed25519.rs @@ -1,20 +1,26 @@ extern crate alloc; use alloc::vec::Vec; +use core::marker::PhantomData; use ed25519_dalek::{Signature, Verifier, VerifyingKey}; use fp_evm::{ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure}; -use crate::precompiles::{PrecompileExt, parse_slice}; +use crate::PrecompileExt; -pub struct Ed25519Verify; +pub(crate) struct Ed25519Verify(PhantomData); -impl PrecompileExt for Ed25519Verify { +impl PrecompileExt for Ed25519Verify +where + A: From<[u8; 32]>, +{ const INDEX: u64 = 1026; - const ADDRESS_SS58: [u8; 32] = [0; 32]; } -impl LinearCostPrecompile for Ed25519Verify { +impl LinearCostPrecompile for Ed25519Verify +where + A: From<[u8; 32]>, +{ const BASE: u64 = 15; const WORD: u64 = 3; @@ -46,3 +52,21 @@ impl LinearCostPrecompile for Ed25519Verify { Ok((ExitSucceed::Returned, buf.to_vec())) } } + +/// Takes a slice from bytes with PrecompileFailure as Error +fn parse_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], PrecompileFailure> { + let maybe_slice = data.get(from..to); + if let Some(slice) = maybe_slice { + Ok(slice) + } else { + log::error!( + "fail to get slice from data, {:?}, from {}, to {}", + &data, + from, + to + ); + Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }) + } +} diff --git a/precompiles/src/extensions.rs b/precompiles/src/extensions.rs new file mode 100644 index 0000000000..373bf0a60d --- /dev/null +++ b/precompiles/src/extensions.rs @@ -0,0 +1,180 @@ +extern crate alloc; + +use alloc::format; + +use frame_support::dispatch::{GetDispatchInfo, Pays, PostDispatchInfo}; +use frame_system::RawOrigin; +use pallet_admin_utils::{PrecompileEnable, PrecompileEnum}; +use pallet_evm::{ + AddressMapping, BalanceConverter, ExitError, GasWeightMapping, Precompile, PrecompileFailure, + PrecompileHandle, PrecompileResult, +}; +use precompile_utils::EvmResult; +use sp_core::{H160, U256, blake2_256}; +use sp_runtime::traits::Dispatchable; +use sp_std::vec::Vec; + +pub(crate) trait PrecompileHandleExt: PrecompileHandle { + fn caller_account_id(&self) -> R::AccountId + where + R: frame_system::Config + pallet_evm::Config, + ::AddressMapping: AddressMapping, + { + ::AddressMapping::into_account_id(self.context().caller) + } + + fn try_convert_apparent_value(&self) -> EvmResult + where + R: pallet_evm::Config, + { + let amount = self.context().apparent_value; + ::BalanceConverter::into_substrate_balance(amount).ok_or( + PrecompileFailure::Error { + exit_status: ExitError::Other( + "error converting balance from ETH to subtensor".into(), + ), + }, + ) + } + + /// Dispatches a runtime call, but also checks and records the gas costs. + fn try_dispatch_runtime_call( + &mut self, + call: Call, + origin: RawOrigin, + ) -> EvmResult<()> + where + R: frame_system::Config + pallet_evm::Config, + R::RuntimeCall: From, + R::RuntimeCall: GetDispatchInfo + Dispatchable, + R::RuntimeOrigin: From>, + { + let call = R::RuntimeCall::from(call); + let info = GetDispatchInfo::get_dispatch_info(&call); + + let target_gas = self.gas_limit(); + if let Some(gas) = target_gas { + let valid_weight = + ::GasWeightMapping::gas_to_weight(gas, false).ref_time(); + if info.weight.ref_time() > valid_weight { + return Err(PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + }); + } + } + + self.record_external_cost( + Some(info.weight.ref_time()), + Some(info.weight.proof_size()), + None, + )?; + + match call.dispatch(R::RuntimeOrigin::from(origin)) { + Ok(post_info) => { + if post_info.pays_fee(&info) == Pays::Yes { + let actual_weight = post_info.actual_weight.unwrap_or(info.weight); + let cost = + ::GasWeightMapping::weight_to_gas(actual_weight); + self.record_cost(cost)?; + + self.refund_external_cost( + Some( + info.weight + .ref_time() + .saturating_sub(actual_weight.ref_time()), + ), + Some( + info.weight + .proof_size() + .saturating_sub(actual_weight.proof_size()), + ), + ); + } + + log::info!("Dispatch succeeded. Post info: {:?}", post_info); + + Ok(()) + } + Err(e) => { + log::error!("Dispatch failed. Error: {:?}", e); + log::warn!("Returning error PrecompileFailure::Error"); + Err(PrecompileFailure::Error { + exit_status: ExitError::Other( + format!("dispatch execution failed: {}", <&'static str>::from(e)).into(), + ), + }) + } + } + } +} + +impl PrecompileHandleExt for T where T: PrecompileHandle {} + +pub(crate) trait PrecompileExt>: Precompile { + const INDEX: u64; + + // ss58 public key i.e., the contract sends funds it received to the destination address from + // the method parameter. + fn account_id() -> AccountId { + let hash = H160::from_low_u64_be(Self::INDEX); + let prefix = b"evm:"; + + // Concatenate prefix and ethereum address + let mut combined = Vec::new(); + combined.extend_from_slice(prefix); + combined.extend_from_slice(hash.as_bytes()); + + let hash = blake2_256(&combined); + + hash.into() + } + + fn try_execute( + handle: &mut impl PrecompileHandle, + precompile_enum: PrecompileEnum, + ) -> Option + where + R: frame_system::Config + pallet_admin_utils::Config, + { + if PrecompileEnable::::get(&precompile_enum) { + Some(Self::execute(handle)) + } else { + Some(Err(PrecompileFailure::Error { + exit_status: ExitError::Other( + format!("Precompile {:?} is disabled", precompile_enum).into(), + ), + })) + } + } +} + +// allowing unreachable for the whole module fixes clippy reports about precompile macro +// implementation for `TestPrecompile`, that couldn't be fixed granularly +#[allow(unreachable_code)] +#[cfg(test)] +mod test { + use super::*; + + use sp_core::crypto::AccountId32; + + #[test] + fn ss58_address_from_index_works() { + assert_eq!( + TestPrecompile::account_id(), + AccountId32::from([ + 0x3a, 0x86, 0x18, 0xfb, 0xbb, 0x1b, 0xbc, 0x47, 0x86, 0x64, 0xff, 0x53, 0x46, 0x18, + 0x0c, 0x35, 0xd0, 0x9f, 0xac, 0x26, 0xf2, 0x02, 0x70, 0x85, 0xb3, 0x1c, 0x56, 0xc1, + 0x06, 0x3c, 0x1c, 0xd3, + ]) + ); + } + + struct TestPrecompile; + + impl PrecompileExt for TestPrecompile { + const INDEX: u64 = 2051; + } + + #[precompile_utils::precompile] + impl TestPrecompile {} +} diff --git a/precompiles/src/lib.rs b/precompiles/src/lib.rs new file mode 100644 index 0000000000..42f250d563 --- /dev/null +++ b/precompiles/src/lib.rs @@ -0,0 +1,175 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +use core::marker::PhantomData; + +use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use pallet_evm::{ + AddressMapping, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, + PrecompileSet, +}; +use pallet_evm_precompile_modexp::Modexp; +use pallet_evm_precompile_sha3fips::Sha3FIPS256; +use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; +use sp_core::{H160, U256, crypto::ByteArray}; +use sp_runtime::traits::Dispatchable; +use sp_runtime::traits::StaticLookup; +use subtensor_runtime_common::ProxyType; + +use pallet_admin_utils::PrecompileEnum; + +use crate::balance_transfer::*; +use crate::ed25519::*; +use crate::extensions::*; +use crate::metagraph::*; +use crate::neuron::*; +use crate::staking::*; +use crate::subnet::*; + +mod balance_transfer; +mod ed25519; +mod extensions; +mod metagraph; +mod neuron; +mod staking; +mod subnet; + +pub struct Precompiles(PhantomData); + +impl Default for Precompiles +where + R: frame_system::Config + + pallet_evm::Config + + pallet_balances::Config + + pallet_admin_utils::Config + + pallet_subtensor::Config + + pallet_proxy::Config, + R::AccountId: From<[u8; 32]> + ByteArray, + ::RuntimeCall: From> + + From> + + From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, + ::Balance: TryFrom, + <::Lookup as StaticLookup>::Source: From, +{ + fn default() -> Self { + Self::new() + } +} + +impl Precompiles +where + R: frame_system::Config + + pallet_evm::Config + + pallet_balances::Config + + pallet_admin_utils::Config + + pallet_subtensor::Config + + pallet_proxy::Config, + R::AccountId: From<[u8; 32]> + ByteArray, + ::RuntimeCall: From> + + From> + + From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, + ::Balance: TryFrom, + <::Lookup as StaticLookup>::Source: From, +{ + pub fn new() -> Self { + Self(Default::default()) + } + + pub fn used_addresses() -> [H160; 14] { + [ + hash(1), + hash(2), + hash(3), + hash(4), + hash(5), + hash(1024), + hash(1025), + hash(Ed25519Verify::::INDEX), + hash(BalanceTransferPrecompile::::INDEX), + hash(StakingPrecompile::::INDEX), + hash(SubnetPrecompile::::INDEX), + hash(MetagraphPrecompile::::INDEX), + hash(NeuronPrecompile::::INDEX), + hash(StakingPrecompileV2::::INDEX), + ] + } +} +impl PrecompileSet for Precompiles +where + R: frame_system::Config + + pallet_evm::Config + + pallet_balances::Config + + pallet_admin_utils::Config + + pallet_subtensor::Config + + pallet_proxy::Config, + R::AccountId: From<[u8; 32]> + ByteArray, + ::RuntimeCall: From> + + From> + + From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, + ::Balance: TryFrom, + <::Lookup as StaticLookup>::Source: From, +{ + fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { + match handle.code_address() { + // Ethereum precompiles : + a if a == hash(1) => Some(ECRecover::execute(handle)), + a if a == hash(2) => Some(Sha256::execute(handle)), + a if a == hash(3) => Some(Ripemd160::execute(handle)), + a if a == hash(4) => Some(Identity::execute(handle)), + a if a == hash(5) => Some(Modexp::execute(handle)), + // Non-Frontier specific nor Ethereum precompiles : + a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), + a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), + a if a == hash(Ed25519Verify::::INDEX) => { + Some(Ed25519Verify::::execute(handle)) + } + // Subtensor specific precompiles : + a if a == hash(BalanceTransferPrecompile::::INDEX) => { + BalanceTransferPrecompile::::try_execute::( + handle, + PrecompileEnum::BalanceTransfer, + ) + } + a if a == hash(StakingPrecompile::::INDEX) => { + StakingPrecompile::::try_execute::(handle, PrecompileEnum::Staking) + } + a if a == hash(StakingPrecompileV2::::INDEX) => { + StakingPrecompileV2::::try_execute::(handle, PrecompileEnum::Staking) + } + a if a == hash(SubnetPrecompile::::INDEX) => { + SubnetPrecompile::::try_execute::(handle, PrecompileEnum::Subnet) + } + a if a == hash(MetagraphPrecompile::::INDEX) => { + MetagraphPrecompile::::try_execute::(handle, PrecompileEnum::Metagraph) + } + a if a == hash(NeuronPrecompile::::INDEX) => { + NeuronPrecompile::::try_execute::(handle, PrecompileEnum::Neuron) + } + _ => None, + } + } + + fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { + IsPrecompileResult::Answer { + is_precompile: Self::used_addresses().contains(&address), + extra_cost: 0, + } + } +} + +fn hash(a: u64) -> H160 { + H160::from_low_u64_be(a) +} diff --git a/runtime/src/precompiles/metagraph.rs b/precompiles/src/metagraph.rs similarity index 67% rename from runtime/src/precompiles/metagraph.rs rename to precompiles/src/metagraph.rs index e7a9243503..758ce8f8eb 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/precompiles/src/metagraph.rs @@ -1,52 +1,58 @@ -extern crate alloc; use alloc::string::String; +use core::marker::PhantomData; use fp_evm::{ExitError, PrecompileFailure, PrecompileHandle}; use pallet_subtensor::AxonInfo as SubtensorModuleAxonInfo; use precompile_utils::{EvmResult, solidity::Codec}; use sp_core::{ByteArray, H256}; -use crate::Runtime; -use crate::precompiles::PrecompileExt; +use crate::PrecompileExt; -pub struct MetagraphPrecompile; +pub struct MetagraphPrecompile(PhantomData); -impl PrecompileExt for MetagraphPrecompile { +impl PrecompileExt for MetagraphPrecompile +where + R: frame_system::Config + pallet_subtensor::Config, + R::AccountId: From<[u8; 32]> + ByteArray, +{ const INDEX: u64 = 2050; - const ADDRESS_SS58: [u8; 32] = [0; 32]; } #[precompile_utils::precompile] -impl MetagraphPrecompile { +impl MetagraphPrecompile +where + R: frame_system::Config + pallet_subtensor::Config, + R::AccountId: ByteArray, +{ #[precompile::public("getUidCount(uint16)")] #[precompile::view] fn get_uid_count(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::SubnetworkN::::get(netuid)) + Ok(pallet_subtensor::SubnetworkN::::get(netuid)) } #[precompile::public("getStake(uint16,uint16)")] #[precompile::view] fn get_stake(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - })?; + exit_status: ExitError::InvalidRange, + })?; - Ok(pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey)) + Ok(pallet_subtensor::Pallet::::get_total_stake_for_hotkey( + &hotkey, + )) } #[precompile::public("getRank(uint16,uint16)")] #[precompile::view] fn get_rank(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_rank_for_uid( - netuid, uid, - )) + Ok(pallet_subtensor::Pallet::::get_rank_for_uid(netuid, uid)) } #[precompile::public("getTrust(uint16,uint16)")] #[precompile::view] fn get_trust(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_trust_for_uid( + Ok(pallet_subtensor::Pallet::::get_trust_for_uid( netuid, uid, )) } @@ -54,7 +60,7 @@ impl MetagraphPrecompile { #[precompile::public("getConsensus(uint16,uint16)")] #[precompile::view] fn get_consensus(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_consensus_for_uid( + Ok(pallet_subtensor::Pallet::::get_consensus_for_uid( netuid, uid, )) } @@ -62,7 +68,7 @@ impl MetagraphPrecompile { #[precompile::public("getIncentive(uint16,uint16)")] #[precompile::view] fn get_incentive(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_incentive_for_uid( + Ok(pallet_subtensor::Pallet::::get_incentive_for_uid( netuid, uid, )) } @@ -70,7 +76,7 @@ impl MetagraphPrecompile { #[precompile::public("getDividends(uint16,uint16)")] #[precompile::view] fn get_dividends(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_dividends_for_uid( + Ok(pallet_subtensor::Pallet::::get_dividends_for_uid( netuid, uid, )) } @@ -78,7 +84,7 @@ impl MetagraphPrecompile { #[precompile::public("getEmission(uint16,uint16)")] #[precompile::view] fn get_emission(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_emission_for_uid( + Ok(pallet_subtensor::Pallet::::get_emission_for_uid( netuid, uid, )) } @@ -86,7 +92,9 @@ impl MetagraphPrecompile { #[precompile::public("getVtrust(uint16,uint16)")] #[precompile::view] fn get_vtrust(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_validator_trust_for_uid(netuid, uid)) + Ok(pallet_subtensor::Pallet::::get_validator_trust_for_uid( + netuid, uid, + )) } #[precompile::public("getValidatorStatus(uint16,uint16)")] @@ -96,19 +104,23 @@ impl MetagraphPrecompile { netuid: u16, uid: u16, ) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_validator_permit_for_uid(netuid, uid)) + Ok(pallet_subtensor::Pallet::::get_validator_permit_for_uid( + netuid, uid, + )) } #[precompile::public("getLastUpdate(uint16,uint16)")] #[precompile::view] fn get_last_update(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_last_update_for_uid(netuid, uid)) + Ok(pallet_subtensor::Pallet::::get_last_update_for_uid( + netuid, uid, + )) } #[precompile::public("getIsActive(uint16,uint16)")] #[precompile::view] fn get_is_active(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - Ok(pallet_subtensor::Pallet::::get_active_for_uid( + Ok(pallet_subtensor::Pallet::::get_active_for_uid( netuid, uid, )) } @@ -116,18 +128,18 @@ impl MetagraphPrecompile { #[precompile::public("getAxon(uint16,uint16)")] #[precompile::view] fn get_axon(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::Other("hotkey not found".into()), - })?; + exit_status: ExitError::Other("hotkey not found".into()), + })?; - Ok(pallet_subtensor::Pallet::::get_axon_info(netuid, &hotkey).into()) + Ok(pallet_subtensor::Pallet::::get_axon_info(netuid, &hotkey).into()) } #[precompile::public("getHotkey(uint16,uint16)")] #[precompile::view] fn get_hotkey(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map(|acc| H256::from_slice(acc.as_slice())) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::InvalidRange, @@ -137,11 +149,11 @@ impl MetagraphPrecompile { #[precompile::public("getColdkey(uint16,uint16)")] #[precompile::view] fn get_coldkey(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { - let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - })?; - let coldkey = pallet_subtensor::Owner::::get(&hotkey); + exit_status: ExitError::InvalidRange, + })?; + let coldkey = pallet_subtensor::Owner::::get(&hotkey); Ok(H256::from_slice(coldkey.as_slice())) } diff --git a/runtime/src/precompiles/neuron.rs b/precompiles/src/neuron.rs similarity index 56% rename from runtime/src/precompiles/neuron.rs rename to precompiles/src/neuron.rs index 65306f87cc..cedb3a56db 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/precompiles/src/neuron.rs @@ -1,25 +1,39 @@ +use core::marker::PhantomData; + +use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; use frame_system::RawOrigin; -use pallet_evm::PrecompileHandle; +use pallet_evm::{AddressMapping, PrecompileHandle}; use precompile_utils::{EvmResult, prelude::UnboundedBytes}; use sp_core::H256; +use sp_runtime::traits::Dispatchable; use sp_std::vec::Vec; -use crate::Runtime; -use crate::precompiles::{PrecompileExt, PrecompileHandleExt, parse_pubkey}; +use crate::{PrecompileExt, PrecompileHandleExt}; -pub struct NeuronPrecompile; +pub struct NeuronPrecompile(PhantomData); -impl PrecompileExt for NeuronPrecompile { +impl PrecompileExt for NeuronPrecompile +where + R: frame_system::Config + pallet_evm::Config + pallet_subtensor::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, +{ const INDEX: u64 = 2052; - const ADDRESS_SS58: [u8; 32] = [ - 0xbc, 0x46, 0x35, 0x79, 0xbc, 0x99, 0xf9, 0xee, 0x7c, 0x59, 0xed, 0xee, 0x20, 0x61, 0xa3, - 0x09, 0xd2, 0x1e, 0x68, 0xd5, 0x39, 0xb6, 0x40, 0xec, 0x66, 0x46, 0x90, 0x30, 0xab, 0x74, - 0xc1, 0xdb, - ]; } #[precompile_utils::precompile] -impl NeuronPrecompile { +impl NeuronPrecompile +where + R: frame_system::Config + pallet_evm::Config + pallet_subtensor::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, +{ #[precompile::public("setWeights(uint16,uint16[],uint16[],uint64)")] #[precompile::payable] pub fn set_weights( @@ -29,14 +43,17 @@ impl NeuronPrecompile { weights: Vec, version_key: u64, ) -> EvmResult<()> { - let call = pallet_subtensor::Call::::set_weights { + let call = pallet_subtensor::Call::::set_weights { netuid, dests, weights, version_key, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("commitWeights(uint16,bytes32)")] @@ -46,12 +63,15 @@ impl NeuronPrecompile { netuid: u16, commit_hash: H256, ) -> EvmResult<()> { - let call = pallet_subtensor::Call::::commit_weights { + let call = pallet_subtensor::Call::::commit_weights { netuid, commit_hash, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("revealWeights(uint16,uint16[],uint16[],uint16[],uint64)")] @@ -64,7 +84,7 @@ impl NeuronPrecompile { salt: Vec, version_key: u64, ) -> EvmResult<()> { - let call = pallet_subtensor::Call::::reveal_weights { + let call = pallet_subtensor::Call::::reveal_weights { netuid, uids, values, @@ -72,7 +92,10 @@ impl NeuronPrecompile { version_key, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("burnedRegister(uint16,bytes32)")] @@ -82,11 +105,11 @@ impl NeuronPrecompile { netuid: u16, hotkey: H256, ) -> EvmResult<()> { - let coldkey = handle.caller_account_id(); - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; - let call = pallet_subtensor::Call::::burned_register { netuid, hotkey }; + let coldkey = handle.caller_account_id::(); + let hotkey = R::AccountId::from(hotkey.0); + let call = pallet_subtensor::Call::::burned_register { netuid, hotkey }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(coldkey)) + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(coldkey)) } #[precompile::public("serveAxon(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8)")] @@ -103,7 +126,7 @@ impl NeuronPrecompile { placeholder1: u8, placeholder2: u8, ) -> EvmResult<()> { - let call = pallet_subtensor::Call::::serve_axon { + let call = pallet_subtensor::Call::::serve_axon { netuid, version, ip, @@ -114,7 +137,10 @@ impl NeuronPrecompile { placeholder2, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public( @@ -134,7 +160,7 @@ impl NeuronPrecompile { placeholder2: u8, certificate: UnboundedBytes, ) -> EvmResult<()> { - let call = pallet_subtensor::Call::::serve_axon_tls { + let call = pallet_subtensor::Call::::serve_axon_tls { netuid, version, ip, @@ -146,7 +172,10 @@ impl NeuronPrecompile { certificate: certificate.into(), }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("servePrometheus(uint16,uint32,uint128,uint16,uint8)")] @@ -160,7 +189,7 @@ impl NeuronPrecompile { port: u16, ip_type: u8, ) -> EvmResult<()> { - let call = pallet_subtensor::Call::::serve_prometheus { + let call = pallet_subtensor::Call::::serve_prometheus { netuid, version, ip, @@ -168,6 +197,9 @@ impl NeuronPrecompile { ip_type, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } } diff --git a/runtime/src/precompiles/solidity/balanceTransfer.abi b/precompiles/src/solidity/balanceTransfer.abi similarity index 100% rename from runtime/src/precompiles/solidity/balanceTransfer.abi rename to precompiles/src/solidity/balanceTransfer.abi diff --git a/runtime/src/precompiles/solidity/balanceTransfer.sol b/precompiles/src/solidity/balanceTransfer.sol similarity index 100% rename from runtime/src/precompiles/solidity/balanceTransfer.sol rename to precompiles/src/solidity/balanceTransfer.sol diff --git a/runtime/src/precompiles/solidity/ed25519Verify.abi b/precompiles/src/solidity/ed25519Verify.abi similarity index 100% rename from runtime/src/precompiles/solidity/ed25519Verify.abi rename to precompiles/src/solidity/ed25519Verify.abi diff --git a/runtime/src/precompiles/solidity/ed25519Verify.sol b/precompiles/src/solidity/ed25519Verify.sol similarity index 100% rename from runtime/src/precompiles/solidity/ed25519Verify.sol rename to precompiles/src/solidity/ed25519Verify.sol diff --git a/runtime/src/precompiles/solidity/metagraph.abi b/precompiles/src/solidity/metagraph.abi similarity index 100% rename from runtime/src/precompiles/solidity/metagraph.abi rename to precompiles/src/solidity/metagraph.abi diff --git a/runtime/src/precompiles/solidity/metagraph.sol b/precompiles/src/solidity/metagraph.sol similarity index 100% rename from runtime/src/precompiles/solidity/metagraph.sol rename to precompiles/src/solidity/metagraph.sol diff --git a/runtime/src/precompiles/solidity/neuron.abi b/precompiles/src/solidity/neuron.abi similarity index 100% rename from runtime/src/precompiles/solidity/neuron.abi rename to precompiles/src/solidity/neuron.abi diff --git a/runtime/src/precompiles/solidity/neuron.sol b/precompiles/src/solidity/neuron.sol similarity index 100% rename from runtime/src/precompiles/solidity/neuron.sol rename to precompiles/src/solidity/neuron.sol diff --git a/runtime/src/precompiles/solidity/staking.abi b/precompiles/src/solidity/staking.abi similarity index 72% rename from runtime/src/precompiles/solidity/staking.abi rename to precompiles/src/solidity/staking.abi index 3c4a018c90..f06dfb651b 100644 --- a/runtime/src/precompiles/solidity/staking.abi +++ b/precompiles/src/solidity/staking.abi @@ -94,5 +94,43 @@ "outputs": [], "stateMutability": "nonpayable", "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" } ] \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/staking.sol b/precompiles/src/solidity/staking.sol similarity index 71% rename from runtime/src/precompiles/solidity/staking.sol rename to precompiles/src/solidity/staking.sol index 19d51d0470..4666183700 100644 --- a/runtime/src/precompiles/solidity/staking.sol +++ b/precompiles/src/solidity/staking.sol @@ -46,12 +46,36 @@ interface IStaking { uint256 netuid ) external; - /** - * @dev Delegates staking to a proxy account. - * - * @param delegate The public key (32 bytes) of the delegate. - */ - function addProxy(bytes32 delegate) external; + /** + * @dev Returns the amount of RAO staked by the coldkey. + * + * This function allows external accounts and contracts to query the amount of RAO staked by the coldkey + * which effectively calls `get_total_coldkey_stake` on the subtensor pallet with + * specified coldkey as a parameter. + * + * @param coldkey The coldkey public key (32 bytes). + * @return The amount of RAO staked by the coldkey. + */ + function getTotalColdkeyStake(bytes32 coldkey) external view returns (uint256); + + /** + * @dev Returns the total amount of stake under a hotkey (delegative or otherwise) + * + * This function allows external accounts and contracts to query the total amount of RAO staked under a hotkey + * which effectively calls `get_total_hotkey_stake` on the subtensor pallet with + * specified hotkey as a parameter. + * + * @param hotkey The hotkey public key (32 bytes). + * @return The total amount of RAO staked under the hotkey. + */ + function getTotalHotkeyStake(bytes32 hotkey) external view returns (uint256); + + /** + * @dev Delegates staking to a proxy account. + * + * @param delegate The public key (32 bytes) of the delegate. + */ + function addProxy(bytes32 delegate) external; /** * @dev Removes staking proxy account. diff --git a/precompiles/src/solidity/stakingV2.abi b/precompiles/src/solidity/stakingV2.abi new file mode 100644 index 0000000000..21dd2761e4 --- /dev/null +++ b/precompiles/src/solidity/stakingV2.abi @@ -0,0 +1,141 @@ +[ + { + "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" + } +] diff --git a/precompiles/src/solidity/stakingV2.sol b/precompiles/src/solidity/stakingV2.sol new file mode 100644 index 0000000000..67ac0cb129 --- /dev/null +++ b/precompiles/src/solidity/stakingV2.sol @@ -0,0 +1,103 @@ +pragma solidity ^0.8.0; + +address constant ISTAKING_ADDRESS = 0x0000000000000000000000000000000000000805; + +interface IStaking { + /** + * @dev Adds a subtensor stake `amount` associated with the `hotkey`. + * + * This function allows external accounts and contracts to stake TAO into the subtensor pallet, + * which effectively calls `add_stake` on the subtensor pallet with specified hotkey as a parameter + * and coldkey being the hashed address mapping of H160 sender address to Substrate ss58 address as + * implemented in Frontier HashedAddressMapping: + * https://github.com/polkadot-evm/frontier/blob/2e219e17a526125da003e64ef22ec037917083fa/frame/evm/src/lib.rs#L739 + * + * @param hotkey The hotkey public key (32 bytes). + * @param amount The amount to stake in rao. + * @param netuid The subnet to stake to (uint256). + * + * Requirements: + * - `hotkey` must be a valid hotkey registered on the network, ensuring that the stake is + * correctly attributed. + */ + function addStake(bytes32 hotkey, uint256 amount, uint256 netuid) external payable; + + /** + * @dev Removes a subtensor stake `amount` from the specified `hotkey`. + * + * This function allows external accounts and contracts to unstake TAO from the subtensor pallet, + * which effectively calls `remove_stake` on the subtensor pallet with specified hotkey as a parameter + * and coldkey being the hashed address mapping of H160 sender address to Substrate ss58 address as + * implemented in Frontier HashedAddressMapping: + * https://github.com/polkadot-evm/frontier/blob/2e219e17a526125da003e64ef22ec037917083fa/frame/evm/src/lib.rs#L739 + * + * @param hotkey The hotkey public key (32 bytes). + * @param amount The amount to unstake in alpha. + * @param netuid The subnet to stake to (uint256). + * + * Requirements: + * - `hotkey` must be a valid hotkey registered on the network, ensuring that the stake is + * correctly attributed. + * - The existing stake amount must be not lower than specified amount + */ + function removeStake( + bytes32 hotkey, + uint256 amount, + uint256 netuid + ) external; + + /** + * @dev Returns the amount of RAO staked by the coldkey. + * + * This function allows external accounts and contracts to query the amount of RAO staked by the coldkey + * which effectively calls `get_total_coldkey_stake` on the subtensor pallet with + * specified coldkey as a parameter. + * + * @param coldkey The coldkey public key (32 bytes). + * @return The amount of RAO staked by the coldkey. + */ + function getTotalColdkeyStake(bytes32 coldkey) external view returns (uint256); + + /** + * @dev Returns the total amount of stake under a hotkey (delegative or otherwise) + * + * This function allows external accounts and contracts to query the total amount of RAO staked under a hotkey + * which effectively calls `get_total_hotkey_stake` on the subtensor pallet with + * specified hotkey as a parameter. + * + * @param hotkey The hotkey public key (32 bytes). + * @return The total amount of RAO staked under the hotkey. + */ + function getTotalHotkeyStake(bytes32 hotkey) external view returns (uint256); + + /** + * @dev Returns the stake amount associated with the specified `hotkey` and `coldkey`. + * + * This function retrieves the current stake amount linked to a specific hotkey and coldkey pair. + * It is a view function, meaning it does not modify the state of the contract and is free to call. + * + * @param hotkey The hotkey public key (32 bytes). + * @param coldkey The coldkey public key (32 bytes). + * @param netuid The subnet the stake is on (uint256). + * @return The current stake amount in uint256 format. + */ + function getStake( + bytes32 hotkey, + bytes32 coldkey, + uint256 netuid + ) external view returns (uint256); + + /** + * @dev Delegates staking to a proxy account. + * + * @param delegate The public key (32 bytes) of the delegate. + */ + function addProxy(bytes32 delegate) external; + + /** + * @dev Removes staking proxy account. + * + * @param delegate The public key (32 bytes) of the delegate. + */ + function removeProxy(bytes32 delegate) external; +} diff --git a/runtime/src/precompiles/solidity/subnet.abi b/precompiles/src/solidity/subnet.abi similarity index 100% rename from runtime/src/precompiles/solidity/subnet.abi rename to precompiles/src/solidity/subnet.abi diff --git a/runtime/src/precompiles/solidity/subnet.sol b/precompiles/src/solidity/subnet.sol similarity index 100% rename from runtime/src/precompiles/solidity/subnet.sol rename to precompiles/src/solidity/subnet.sol diff --git a/precompiles/src/staking.rs b/precompiles/src/staking.rs new file mode 100644 index 0000000000..9022f45a36 --- /dev/null +++ b/precompiles/src/staking.rs @@ -0,0 +1,397 @@ +// The goal of staking precompile is to allow interaction between EVM users and smart contracts and +// subtensor staking functionality, namely add_stake, and remove_stake extrinsicsk, as well as the +// staking state. +// +// Additional requirement is to preserve compatibility with Ethereum indexers, which requires +// no balance transfers from EVM accounts without a corresponding transaction that can be +// parsed by an indexer. +// +// Implementation of add_stake: +// - User transfers balance that will be staked to the precompile address with a payable +// method addStake. This method also takes hotkey public key (bytes32) of the hotkey +// that the stake should be assigned to. +// - Precompile transfers the balance back to the signing address, and then invokes +// do_add_stake from subtensor pallet with signing origin that mmatches to HashedAddressMapping +// of the message sender, which will effectively withdraw and stake balance from the message +// sender. +// - Precompile checks the result of do_add_stake and, in case of a failure, reverts the transaction, +// and leaves the balance on the message sender account. +// +// Implementation of remove_stake: +// - User involkes removeStake method and specifies hotkey public key (bytes32) of the hotkey +// to remove stake from, and the amount to unstake. +// - Precompile calls do_remove_stake method of the subtensor pallet with the signing origin of message +// sender, which effectively unstakes the specified amount and credits it to the message sender +// - Precompile checks the result of do_remove_stake and, in case of a failure, reverts the transaction. +// + +use core::marker::PhantomData; + +use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_system::RawOrigin; +use pallet_evm::{ + AddressMapping, BalanceConverter, ExitError, PrecompileFailure, PrecompileHandle, +}; +use precompile_utils::EvmResult; +use sp_core::{H256, U256}; +use sp_runtime::traits::{Dispatchable, StaticLookup, UniqueSaturatedInto}; +use subtensor_runtime_common::ProxyType; + +use crate::{PrecompileExt, PrecompileHandleExt}; + +// Old StakingPrecompile had ETH-precision in values, which was not alligned with Substrate API. So +// it's kinda deprecated, but exists for backward compatibility. Eventually, we should remove it +// to stop supporting both precompiles. +// +// All the future extensions should happen in StakingPrecompileV2. +pub(crate) struct StakingPrecompileV2(PhantomData); + +impl PrecompileExt for StakingPrecompileV2 +where + R: frame_system::Config + + pallet_evm::Config + + pallet_subtensor::Config + + pallet_proxy::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, + <::Lookup as StaticLookup>::Source: From, +{ + const INDEX: u64 = 2053; +} + +#[precompile_utils::precompile] +impl StakingPrecompileV2 +where + R: frame_system::Config + + pallet_evm::Config + + pallet_subtensor::Config + + pallet_proxy::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, + <::Lookup as StaticLookup>::Source: From, +{ + #[precompile::public("addStake(bytes32,uint256,uint256)")] + #[precompile::payable] + fn add_stake( + handle: &mut impl PrecompileHandle, + address: H256, + amount_rao: U256, + netuid: U256, + ) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let amount_staked = amount_rao.unique_saturated_into(); + let hotkey = R::AccountId::from(address.0); + let netuid = try_u16_from_u256(netuid)?; + let call = pallet_subtensor::Call::::add_stake { + hotkey, + netuid, + amount_staked, + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } + + #[precompile::public("removeStake(bytes32,uint256,uint256)")] + fn remove_stake( + handle: &mut impl PrecompileHandle, + address: H256, + amount_alpha: U256, + netuid: U256, + ) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let hotkey = R::AccountId::from(address.0); + let netuid = try_u16_from_u256(netuid)?; + let amount_unstaked = amount_alpha.unique_saturated_into(); + let call = pallet_subtensor::Call::::remove_stake { + hotkey, + netuid, + amount_unstaked, + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } + + #[precompile::public("getTotalColdkeyStake(bytes32)")] + fn get_total_coldkey_stake( + _handle: &mut impl PrecompileHandle, + coldkey: H256, + ) -> EvmResult { + let coldkey = R::AccountId::from(coldkey.0); + let stake = pallet_subtensor::Pallet::::get_total_stake_for_coldkey(&coldkey); + + Ok(stake.into()) + } + + #[precompile::public("getTotalHotkeyStake(bytes32)")] + fn get_total_hotkey_stake( + _handle: &mut impl PrecompileHandle, + hotkey: H256, + ) -> EvmResult { + let hotkey = R::AccountId::from(hotkey.0); + let stake = pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey); + + Ok(stake.into()) + } + + #[precompile::public("getStake(bytes32,bytes32,uint256)")] + #[precompile::view] + fn get_stake( + _: &mut impl PrecompileHandle, + hotkey: H256, + coldkey: H256, + netuid: U256, + ) -> EvmResult { + let hotkey = R::AccountId::from(hotkey.0); + let coldkey = R::AccountId::from(coldkey.0); + let netuid = try_u16_from_u256(netuid)?; + let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, &coldkey, netuid, + ); + + Ok(stake.into()) + } + + #[precompile::public("addProxy(bytes32)")] + fn add_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let delegate = R::AccountId::from(delegate.0); + let delegate = ::Lookup::unlookup(delegate); + let call = pallet_proxy::Call::::add_proxy { + delegate, + proxy_type: ProxyType::Staking, + delay: 0u32.into(), + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } + + #[precompile::public("removeProxy(bytes32)")] + fn remove_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let delegate = R::AccountId::from(delegate.0); + let delegate = ::Lookup::unlookup(delegate); + let call = pallet_proxy::Call::::remove_proxy { + delegate, + proxy_type: ProxyType::Staking, + delay: 0u32.into(), + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } +} + +// Deprecated, exists for backward compatibility. +pub(crate) struct StakingPrecompile(PhantomData); + +impl PrecompileExt for StakingPrecompile +where + R: frame_system::Config + + pallet_evm::Config + + pallet_subtensor::Config + + pallet_proxy::Config + + pallet_balances::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, + ::Balance: TryFrom, + <::Lookup as StaticLookup>::Source: From, +{ + const INDEX: u64 = 2049; +} + +#[precompile_utils::precompile] +impl StakingPrecompile +where + R: frame_system::Config + + pallet_evm::Config + + pallet_subtensor::Config + + pallet_proxy::Config + + pallet_balances::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, + ::Balance: TryFrom, + <::Lookup as StaticLookup>::Source: From, +{ + #[precompile::public("addStake(bytes32,uint256)")] + #[precompile::payable] + fn add_stake(handle: &mut impl PrecompileHandle, address: H256, netuid: U256) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let amount = handle.context().apparent_value; + + if !amount.is_zero() { + Self::transfer_back_to_caller(&account_id, amount)?; + } + + let amount_sub = handle.try_convert_apparent_value::()?; + let hotkey = R::AccountId::from(address.0); + let netuid = try_u16_from_u256(netuid)?; + let call = pallet_subtensor::Call::::add_stake { + hotkey, + netuid, + amount_staked: amount_sub.unique_saturated_into(), + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } + + #[precompile::public("removeStake(bytes32,uint256,uint256)")] + fn remove_stake( + handle: &mut impl PrecompileHandle, + address: H256, + amount: U256, + netuid: U256, + ) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let hotkey = R::AccountId::from(address.0); + let netuid = try_u16_from_u256(netuid)?; + let amount_unstaked = + ::BalanceConverter::into_substrate_balance(amount) + .ok_or(ExitError::OutOfFund)?; + let amount_unstaked = amount_unstaked.unique_saturated_into(); + let call = pallet_subtensor::Call::::remove_stake { + hotkey, + netuid, + amount_unstaked, + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } + + #[precompile::public("getTotalColdkeyStake(bytes32)")] + fn get_total_coldkey_stake( + _handle: &mut impl PrecompileHandle, + coldkey: H256, + ) -> EvmResult { + let coldkey = R::AccountId::from(coldkey.0); + + // get total stake of coldkey + let total_stake = pallet_subtensor::Pallet::::get_total_stake_for_coldkey(&coldkey); + // Convert to EVM decimals + let stake_u256 = U256::from(total_stake); + let stake_eth = ::BalanceConverter::into_evm_balance(stake_u256) + .ok_or(ExitError::InvalidRange)?; + + Ok(stake_eth) + } + + #[precompile::public("getTotalHotkeyStake(bytes32)")] + fn get_total_hotkey_stake( + _handle: &mut impl PrecompileHandle, + hotkey: H256, + ) -> EvmResult { + let hotkey = R::AccountId::from(hotkey.0); + + // get total stake of hotkey + let total_stake = pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey); + // Convert to EVM decimals + let stake_u256 = U256::from(total_stake); + let stake_eth = ::BalanceConverter::into_evm_balance(stake_u256) + .ok_or(ExitError::InvalidRange)?; + + Ok(stake_eth) + } + + #[precompile::public("getStake(bytes32,bytes32,uint256)")] + #[precompile::view] + fn get_stake( + _: &mut impl PrecompileHandle, + hotkey: H256, + coldkey: H256, + netuid: U256, + ) -> EvmResult { + let hotkey = R::AccountId::from(hotkey.0); + let coldkey = R::AccountId::from(coldkey.0); + let netuid = try_u16_from_u256(netuid)?; + let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, &coldkey, netuid, + ); + let stake = U256::from(stake); + let stake = ::BalanceConverter::into_evm_balance(stake) + .ok_or(ExitError::InvalidRange)?; + + Ok(stake) + } + + #[precompile::public("addProxy(bytes32)")] + fn add_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let delegate = R::AccountId::from(delegate.0); + let delegate = ::Lookup::unlookup(delegate); + let call = pallet_proxy::Call::::add_proxy { + delegate, + proxy_type: ProxyType::Staking, + delay: 0u32.into(), + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } + + #[precompile::public("removeProxy(bytes32)")] + fn remove_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { + let account_id = handle.caller_account_id::(); + let delegate = R::AccountId::from(delegate.0); + let delegate = ::Lookup::unlookup(delegate); + let call = pallet_proxy::Call::::remove_proxy { + delegate, + proxy_type: ProxyType::Staking, + delay: 0u32.into(), + }; + + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(account_id)) + } + + fn transfer_back_to_caller( + account_id: &::AccountId, + amount: U256, + ) -> Result<(), PrecompileFailure> { + let amount_sub = + ::BalanceConverter::into_substrate_balance(amount) + .ok_or(ExitError::OutOfFund)?; + + // Create a transfer call from the smart contract to the caller + let transfer_call = ::RuntimeCall::from( + pallet_balances::Call::::transfer_allow_death { + dest: account_id.clone().into(), + value: amount_sub.unique_saturated_into(), + }, + ); + + // Execute the transfer + let transfer_result = transfer_call.dispatch(RawOrigin::Signed(Self::account_id()).into()); + + if let Err(dispatch_error) = transfer_result { + log::error!( + "Transfer back to caller failed. Error: {:?}", + dispatch_error + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::Other("Transfer back to caller failed".into()), + }); + } + + Ok(()) + } +} + +fn try_u16_from_u256(value: U256) -> Result { + value.try_into().map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::Other("the value is outside of u16 bounds".into()), + }) +} diff --git a/runtime/src/precompiles/subnet.rs b/precompiles/src/subnet.rs similarity index 59% rename from runtime/src/precompiles/subnet.rs rename to precompiles/src/subnet.rs index db46b3033b..cffe82ab78 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/precompiles/src/subnet.rs @@ -1,35 +1,60 @@ +use core::marker::PhantomData; + +use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; use frame_support::traits::ConstU32; use frame_system::RawOrigin; -use pallet_evm::PrecompileHandle; +use pallet_evm::{AddressMapping, PrecompileHandle}; use precompile_utils::{EvmResult, prelude::BoundedString}; use sp_core::H256; - -use crate::Runtime; -use crate::precompiles::{PrecompileExt, PrecompileHandleExt, parse_pubkey}; - -pub struct SubnetPrecompile; - -impl PrecompileExt for SubnetPrecompile { +use sp_runtime::traits::Dispatchable; + +use crate::{PrecompileExt, PrecompileHandleExt}; + +pub struct SubnetPrecompile(PhantomData); + +impl PrecompileExt for SubnetPrecompile +where + R: frame_system::Config + + pallet_evm::Config + + pallet_subtensor::Config + + pallet_admin_utils::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, +{ const INDEX: u64 = 2051; - const ADDRESS_SS58: [u8; 32] = [ - 0x3a, 0x86, 0x18, 0xfb, 0xbb, 0x1b, 0xbc, 0x47, 0x86, 0x64, 0xff, 0x53, 0x46, 0x18, 0x0c, - 0x35, 0xd0, 0x9f, 0xac, 0x26, 0xf2, 0x02, 0x70, 0x85, 0xb3, 0x1c, 0x56, 0xc1, 0x06, 0x3c, - 0x1c, 0xd3, - ]; } #[precompile_utils::precompile] -impl SubnetPrecompile { +impl SubnetPrecompile +where + R: frame_system::Config + + pallet_evm::Config + + pallet_subtensor::Config + + pallet_admin_utils::Config, + R::AccountId: From<[u8; 32]>, + ::RuntimeCall: From> + + From> + + GetDispatchInfo + + Dispatchable, + ::AddressMapping: AddressMapping, +{ #[precompile::public("registerNetwork(bytes32)")] #[precompile::payable] fn register_network(handle: &mut impl PrecompileHandle, hotkey: H256) -> EvmResult<()> { - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; - let call = pallet_subtensor::Call::::register_network_with_identity { + let hotkey = R::AccountId::from(hotkey.0); + let call = pallet_subtensor::Call::::register_network_with_identity { hotkey, identity: None, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public( @@ -48,7 +73,7 @@ impl SubnetPrecompile { description: BoundedString>, additional: BoundedString>, ) -> EvmResult<()> { - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); let identity = pallet_subtensor::SubnetIdentityOfV2 { subnet_name: subnet_name.into(), github_repo: github_repo.into(), @@ -59,18 +84,21 @@ impl SubnetPrecompile { additional: additional.into(), }; - let call = pallet_subtensor::Call::::register_network_with_identity { + let call = pallet_subtensor::Call::::register_network_with_identity { hotkey, identity: Some(identity), }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getServingRateLimit(uint16)")] #[precompile::view] fn get_serving_rate_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::ServingRateLimit::::get(netuid)) + Ok(pallet_subtensor::ServingRateLimit::::get(netuid)) } #[precompile::public("setServingRateLimit(uint16,uint64)")] @@ -80,18 +108,21 @@ impl SubnetPrecompile { netuid: u16, serving_rate_limit: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_serving_rate_limit { + let call = pallet_admin_utils::Call::::sudo_set_serving_rate_limit { netuid, serving_rate_limit, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getMinDifficulty(uint16)")] #[precompile::view] fn get_min_difficulty(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::MinDifficulty::::get(netuid)) + Ok(pallet_subtensor::MinDifficulty::::get(netuid)) } #[precompile::public("setMinDifficulty(uint16,uint64)")] @@ -101,18 +132,21 @@ impl SubnetPrecompile { netuid: u16, min_difficulty: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_min_difficulty { + let call = pallet_admin_utils::Call::::sudo_set_min_difficulty { netuid, min_difficulty, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getMaxDifficulty(uint16)")] #[precompile::view] fn get_max_difficulty(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::MaxDifficulty::::get(netuid)) + Ok(pallet_subtensor::MaxDifficulty::::get(netuid)) } #[precompile::public("setMaxDifficulty(uint16,uint64)")] @@ -122,18 +156,21 @@ impl SubnetPrecompile { netuid: u16, max_difficulty: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_max_difficulty { + let call = pallet_admin_utils::Call::::sudo_set_max_difficulty { netuid, max_difficulty, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getWeightsVersionKey(uint16)")] #[precompile::view] fn get_weights_version_key(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::WeightsVersionKey::::get(netuid)) + Ok(pallet_subtensor::WeightsVersionKey::::get(netuid)) } #[precompile::public("setWeightsVersionKey(uint16,uint64)")] @@ -143,20 +180,21 @@ impl SubnetPrecompile { netuid: u16, weights_version_key: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_weights_version_key { + let call = pallet_admin_utils::Call::::sudo_set_weights_version_key { netuid, weights_version_key, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getWeightsSetRateLimit(uint16)")] #[precompile::view] fn get_weights_set_rate_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::WeightsSetRateLimit::::get( - netuid, - )) + Ok(pallet_subtensor::WeightsSetRateLimit::::get(netuid)) } #[precompile::public("setWeightsSetRateLimit(uint16,uint64)")] @@ -166,18 +204,21 @@ impl SubnetPrecompile { netuid: u16, weights_set_rate_limit: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_weights_set_rate_limit { + let call = pallet_admin_utils::Call::::sudo_set_weights_set_rate_limit { netuid, weights_set_rate_limit, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getAdjustmentAlpha(uint16)")] #[precompile::view] fn get_adjustment_alpha(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::AdjustmentAlpha::::get(netuid)) + Ok(pallet_subtensor::AdjustmentAlpha::::get(netuid)) } #[precompile::public("setAdjustmentAlpha(uint16,uint64)")] @@ -187,18 +228,21 @@ impl SubnetPrecompile { netuid: u16, adjustment_alpha: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_adjustment_alpha { + let call = pallet_admin_utils::Call::::sudo_set_adjustment_alpha { netuid, adjustment_alpha, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getMaxWeightLimit(uint16)")] #[precompile::view] fn get_max_weight_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::MaxWeightsLimit::::get(netuid)) + Ok(pallet_subtensor::MaxWeightsLimit::::get(netuid)) } #[precompile::public("setMaxWeightLimit(uint16,uint16)")] @@ -208,18 +252,21 @@ impl SubnetPrecompile { netuid: u16, max_weight_limit: u16, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_max_weight_limit { + let call = pallet_admin_utils::Call::::sudo_set_max_weight_limit { netuid, max_weight_limit, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getImmunityPeriod(uint16)")] #[precompile::view] fn get_immunity_period(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::ImmunityPeriod::::get(netuid)) + Ok(pallet_subtensor::ImmunityPeriod::::get(netuid)) } #[precompile::public("setImmunityPeriod(uint16,uint16)")] @@ -229,18 +276,21 @@ impl SubnetPrecompile { netuid: u16, immunity_period: u16, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_immunity_period { + let call = pallet_admin_utils::Call::::sudo_set_immunity_period { netuid, immunity_period, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getMinAllowedWeights(uint16)")] #[precompile::view] fn get_min_allowed_weights(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::MinAllowedWeights::::get(netuid)) + Ok(pallet_subtensor::MinAllowedWeights::::get(netuid)) } #[precompile::public("setMinAllowedWeights(uint16,uint16)")] @@ -250,46 +300,55 @@ impl SubnetPrecompile { netuid: u16, min_allowed_weights: u16, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_min_allowed_weights { + let call = pallet_admin_utils::Call::::sudo_set_min_allowed_weights { netuid, min_allowed_weights, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getKappa(uint16)")] #[precompile::view] fn get_kappa(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::Kappa::::get(netuid)) + Ok(pallet_subtensor::Kappa::::get(netuid)) } #[precompile::public("setKappa(uint16,uint16)")] #[precompile::payable] fn set_kappa(handle: &mut impl PrecompileHandle, netuid: u16, kappa: u16) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_kappa { netuid, kappa }; + let call = pallet_admin_utils::Call::::sudo_set_kappa { netuid, kappa }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getRho(uint16)")] #[precompile::view] fn get_rho(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::Rho::::get(netuid)) + Ok(pallet_subtensor::Rho::::get(netuid)) } #[precompile::public("setRho(uint16,uint16)")] #[precompile::payable] fn set_rho(handle: &mut impl PrecompileHandle, netuid: u16, rho: u16) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_rho { netuid, rho }; + let call = pallet_admin_utils::Call::::sudo_set_rho { netuid, rho }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getActivityCutoff(uint16)")] #[precompile::view] fn get_activity_cutoff(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::ActivityCutoff::::get(netuid)) + Ok(pallet_subtensor::ActivityCutoff::::get(netuid)) } #[precompile::public("setActivityCutoff(uint16,uint16)")] @@ -299,12 +358,15 @@ impl SubnetPrecompile { netuid: u16, activity_cutoff: u16, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_activity_cutoff { + let call = pallet_admin_utils::Call::::sudo_set_activity_cutoff { netuid, activity_cutoff, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getNetworkRegistrationAllowed(uint16)")] @@ -313,7 +375,9 @@ impl SubnetPrecompile { _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { - Ok(pallet_subtensor::NetworkRegistrationAllowed::::get(netuid)) + Ok(pallet_subtensor::NetworkRegistrationAllowed::::get( + netuid, + )) } #[precompile::public("setNetworkRegistrationAllowed(uint16,bool)")] @@ -323,12 +387,15 @@ impl SubnetPrecompile { netuid: u16, registration_allowed: bool, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_network_registration_allowed { + let call = pallet_admin_utils::Call::::sudo_set_network_registration_allowed { netuid, registration_allowed, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getNetworkPowRegistrationAllowed(uint16)")] @@ -337,7 +404,9 @@ impl SubnetPrecompile { _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { - Ok(pallet_subtensor::NetworkPowRegistrationAllowed::::get(netuid)) + Ok(pallet_subtensor::NetworkPowRegistrationAllowed::::get( + netuid, + )) } #[precompile::public("setNetworkPowRegistrationAllowed(uint16,bool)")] @@ -347,18 +416,21 @@ impl SubnetPrecompile { netuid: u16, registration_allowed: bool, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_network_pow_registration_allowed { + let call = pallet_admin_utils::Call::::sudo_set_network_pow_registration_allowed { netuid, registration_allowed, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getMinBurn(uint16)")] #[precompile::view] fn get_min_burn(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::MinBurn::::get(netuid)) + Ok(pallet_subtensor::MinBurn::::get(netuid)) } #[precompile::public("setMinBurn(uint16,uint64)")] @@ -368,15 +440,18 @@ impl SubnetPrecompile { netuid: u16, min_burn: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_min_burn { netuid, min_burn }; + let call = pallet_admin_utils::Call::::sudo_set_min_burn { netuid, min_burn }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getMaxBurn(uint16)")] #[precompile::view] fn get_max_burn(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::MaxBurn::::get(netuid)) + Ok(pallet_subtensor::MaxBurn::::get(netuid)) } #[precompile::public("setMaxBurn(uint16,uint64)")] @@ -386,15 +461,18 @@ impl SubnetPrecompile { netuid: u16, max_burn: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_max_burn { netuid, max_burn }; + let call = pallet_admin_utils::Call::::sudo_set_max_burn { netuid, max_burn }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getDifficulty(uint16)")] #[precompile::view] fn get_difficulty(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::Difficulty::::get(netuid)) + Ok(pallet_subtensor::Difficulty::::get(netuid)) } #[precompile::public("setDifficulty(uint16,uint64)")] @@ -404,15 +482,18 @@ impl SubnetPrecompile { netuid: u16, difficulty: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_difficulty { netuid, difficulty }; + let call = pallet_admin_utils::Call::::sudo_set_difficulty { netuid, difficulty }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getBondsMovingAverage(uint16)")] #[precompile::view] fn get_bonds_moving_average(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::BondsMovingAverage::::get(netuid)) + Ok(pallet_subtensor::BondsMovingAverage::::get(netuid)) } #[precompile::public("setBondsMovingAverage(uint16,uint64)")] @@ -422,12 +503,15 @@ impl SubnetPrecompile { netuid: u16, bonds_moving_average: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_bonds_moving_average { + let call = pallet_admin_utils::Call::::sudo_set_bonds_moving_average { netuid, bonds_moving_average, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getCommitRevealWeightsEnabled(uint16)")] @@ -436,7 +520,9 @@ impl SubnetPrecompile { _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { - Ok(pallet_subtensor::CommitRevealWeightsEnabled::::get(netuid)) + Ok(pallet_subtensor::CommitRevealWeightsEnabled::::get( + netuid, + )) } #[precompile::public("setCommitRevealWeightsEnabled(uint16,bool)")] @@ -446,18 +532,21 @@ impl SubnetPrecompile { netuid: u16, enabled: bool, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_enabled { + let call = pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_enabled { netuid, enabled, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getLiquidAlphaEnabled(uint16)")] #[precompile::view] fn get_liquid_alpha_enabled(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { - Ok(pallet_subtensor::LiquidAlphaOn::::get(netuid)) + Ok(pallet_subtensor::LiquidAlphaOn::::get(netuid)) } #[precompile::public("setLiquidAlphaEnabled(uint16,bool)")] @@ -467,16 +556,18 @@ impl SubnetPrecompile { netuid: u16, enabled: bool, ) -> EvmResult<()> { - let call = - pallet_admin_utils::Call::::sudo_set_liquid_alpha_enabled { netuid, enabled }; + let call = pallet_admin_utils::Call::::sudo_set_liquid_alpha_enabled { netuid, enabled }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getAlphaValues(uint16)")] #[precompile::view] fn get_alpha_values(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<(u16, u16)> { - Ok(pallet_subtensor::AlphaValues::::get(netuid)) + Ok(pallet_subtensor::AlphaValues::::get(netuid)) } #[precompile::public("setAlphaValues(uint16,uint16,uint16)")] @@ -487,13 +578,16 @@ impl SubnetPrecompile { alpha_low: u16, alpha_high: u16, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_alpha_values { + let call = pallet_admin_utils::Call::::sudo_set_alpha_values { netuid, alpha_low, alpha_high, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } #[precompile::public("getCommitRevealWeightsInterval(uint16)")] @@ -502,7 +596,7 @@ impl SubnetPrecompile { _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { - Ok(pallet_subtensor::RevealPeriodEpochs::::get(netuid)) + Ok(pallet_subtensor::RevealPeriodEpochs::::get(netuid)) } #[precompile::public("setCommitRevealWeightsInterval(uint16,uint64)")] @@ -512,11 +606,14 @@ impl SubnetPrecompile { netuid: u16, interval: u64, ) -> EvmResult<()> { - let call = pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_interval { + let call = pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_interval { netuid, interval, }; - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + handle.try_dispatch_runtime_call::( + call, + RawOrigin::Signed(handle.caller_account_id::()), + ) } } diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index e28b7ba1b2..67add266a4 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -20,11 +20,8 @@ name = "spec_version" path = "src/spec_version.rs" [dependencies] -ed25519-dalek = { workspace = true, default-features = false, features = [ - "alloc", -] } subtensor-macros.workspace = true -subtensor-custom-rpc-runtime-api = { path = "../pallets/subtensor/runtime-api", default-features = false } +subtensor-custom-rpc-runtime-api = { workspace = true } smallvec = { workspace = true } log = { workspace = true } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ @@ -34,7 +31,7 @@ scale-info = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["alloc"] } pallet-aura = { workspace = true } pallet-balances = { workspace = true } -pallet-subtensor = { default-features = false, path = "../pallets/subtensor" } +pallet-subtensor = { workspace = true } frame-support = { workspace = true } pallet-grandpa = { workspace = true } pallet-insecure-randomness-collective-flip = { workspace = true } @@ -58,14 +55,16 @@ sp-session = { workspace = true } sp-std = { workspace = true } sp-transaction-pool = { workspace = true } sp-version = { workspace = true } +subtensor-runtime-common = { workspace = true } +subtensor-precompiles = { workspace = true } # Temporary sudo pallet-sudo = { workspace = true } -pallet-admin-utils = { default-features = false, path = "../pallets/admin-utils" } +pallet-admin-utils = { workspace = true } # Used for sudo decentralization -pallet-collective = { default-features = false, path = "../pallets/collective" } +pallet-collective = { workspace = true } pallet-membership = { workspace = true } # Multisig @@ -91,10 +90,10 @@ frame-benchmarking = { workspace = true, optional = true } frame-system-benchmarking = { workspace = true, optional = true } # Identity registry pallet for registering project info -pallet-registry = { default-features = false, path = "../pallets/registry" } +pallet-registry = { workspace = true } # Metadata commitment pallet -pallet-commitments = { default-features = false, path = "../pallets/commitments" } +pallet-commitments = { workspace = true } # Frontier fp-evm = { workspace = true } @@ -134,13 +133,15 @@ substrate-wasm-builder = { workspace = true, optional = true } [features] default = ["std"] pow-faucet = ["pallet-subtensor/pow-faucet"] -fast-blocks = ["pallet-subtensor/fast-blocks"] +fast-blocks = [ + "pallet-subtensor/fast-blocks", + "subtensor-runtime-common/fast-blocks", +] std = [ "frame-try-runtime?/std", "frame-system-benchmarking?/std", "frame-benchmarking/std", "codec/std", - "ed25519-dalek/std", "scale-info/std", "frame-executive/std", "frame-metadata-hash-extension/std", @@ -188,6 +189,8 @@ std = [ "log/std", "sp-storage/std", "sp-genesis-builder/std", + "subtensor-precompiles/std", + "subtensor-runtime-common/std", # Frontier "fp-evm/std", "fp-rpc/std", diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a8774795b9..909207e142 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -11,7 +11,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod check_nonce; mod migrations; -use codec::{Compact, Decode, Encode, MaxEncodedLen}; +use codec::{Compact, Decode, Encode}; use frame_support::traits::Imbalance; use frame_support::{ dispatch::DispatchResultWithPostInfo, @@ -39,7 +39,6 @@ use pallet_subtensor::rpc_info::{ stake_info::StakeInfo, subnet_info::{SubnetHyperparams, SubnetInfo, SubnetInfov2}, }; -use scale_info::TypeInfo; use smallvec::smallvec; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -49,11 +48,11 @@ use sp_core::{ }; use sp_runtime::generic::Era; use sp_runtime::{ - AccountId32, ApplyExtrinsicResult, ConsensusEngineId, MultiSignature, create_runtime_str, - generic, impl_opaque_keys, + AccountId32, ApplyExtrinsicResult, ConsensusEngineId, create_runtime_str, generic, + impl_opaque_keys, traits::{ - AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, - IdentifyAccount, NumberFor, One, PostDispatchInfoOf, UniqueSaturatedInto, Verify, + AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, NumberFor, + One, PostDispatchInfoOf, UniqueSaturatedInto, Verify, }, transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, }; @@ -62,6 +61,8 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; +use subtensor_precompiles::Precompiles; +use subtensor_runtime_common::{time::*, *}; // A few exports that help ease life for downstream crates. pub use frame_support::{ @@ -88,9 +89,6 @@ pub use sp_runtime::{Perbill, Permill}; use core::marker::PhantomData; -mod precompiles; -use precompiles::FrontierPrecompiles; - // Frontier use fp_rpc::TransactionStatus; use pallet_ethereum::{Call::transact, PostLogContent, Transaction as EthereumTransaction}; @@ -159,30 +157,9 @@ impl frame_system::offchain::CreateSignedTransaction pub use pallet_scheduler; pub use pallet_subtensor; -// 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; - -// Balance of an account. -pub type Balance = u64; - -// 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; - // Member type for membership type MemberCount = u32; -pub type Nonce = u32; - // Method used to calculate the fee of an extrinsic pub const fn deposit(items: u32, bytes: u32) -> Balance { pub const ITEMS_FEE: Balance = 2_000 * 10_000; @@ -228,35 +205,13 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 244, + spec_version: 246, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, state_version: 1, }; -/// 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; - pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts(4u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX); @@ -694,33 +649,6 @@ parameter_types! { pub const AnnouncementDepositFactor: Balance = deposit(0, 68); } -#[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, -} -// Transfers below SMALL_TRANSFER_LIMIT are considered small transfers -pub const SMALL_TRANSFER_LIMIT: Balance = 500_000_000; // 0.5 TAO -impl Default for ProxyType { - fn default() -> Self { - Self::Any - } -} // allow all Calls; required to be most permissive impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { @@ -1078,14 +1006,14 @@ parameter_types! { pub const SubtensorInitialMinAllowedUids: u16 = 128; pub const SubtensorInitialMinLockCost: u64 = 1_000_000_000_000; // 1000 TAO pub const SubtensorInitialSubnetOwnerCut: u16 = 11_796; // 18 percent - pub const SubtensorInitialSubnetLimit: u16 = 12; + // pub const SubtensorInitialSubnetLimit: u16 = 12; // (DEPRECATED) pub const SubtensorInitialNetworkLockReductionInterval: u64 = 14 * 7200; pub const SubtensorInitialNetworkRateLimit: u64 = 7200; pub const SubtensorInitialKeySwapCost: u64 = 100_000_000; // 0.1 TAO 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 SubtensorInitialNetworkMaxStake: u64 = u64::MAX; // Maximum possible value for u64, this make the make stake infinity + // pub const SubtensorInitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED) pub const InitialColdkeySwapScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days pub const InitialDissolveNetworkScheduleDuration: BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days pub const SubtensorInitialTaoWeight: u64 = 971_718_665_099_567_868; // 0.05267697438728329% tao weight. @@ -1143,13 +1071,11 @@ impl pallet_subtensor::Config for Runtime { type InitialNetworkMinLockCost = SubtensorInitialMinLockCost; type InitialNetworkLockReductionInterval = SubtensorInitialNetworkLockReductionInterval; type InitialSubnetOwnerCut = SubtensorInitialSubnetOwnerCut; - type InitialSubnetLimit = SubtensorInitialSubnetLimit; type InitialNetworkRateLimit = SubtensorInitialNetworkRateLimit; type KeySwapCost = SubtensorInitialKeySwapCost; type AlphaHigh = InitialAlphaHigh; type AlphaLow = InitialAlphaLow; type LiquidAlphaOn = InitialLiquidAlphaOn; - type InitialNetworkMaxStake = SubtensorInitialNetworkMaxStake; type InitialTaoWeight = SubtensorInitialTaoWeight; type Preimages = Preimage; type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration; @@ -1232,7 +1158,7 @@ fn weight_per_gas() -> Weight { parameter_types! { pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); pub const GasLimitPovSizeRatio: u64 = 0; - pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); + pub PrecompilesValue: Precompiles = Precompiles::<_>::new(); pub WeightPerGas: Weight = weight_per_gas(); pub SuicideQuickClearLimit: u32 = 0; } @@ -1304,7 +1230,7 @@ impl pallet_evm::Config for Runtime { type AddressMapping = pallet_evm::HashedAddressMapping; type Currency = Balances; type RuntimeEvent = RuntimeEvent; - type PrecompilesType = FrontierPrecompiles; + type PrecompilesType = Precompiles; type PrecompilesValue = PrecompilesValue; type ChainId = ConfigurableChainId; type BlockGasLimit = BlockGasLimit; diff --git a/runtime/src/precompiles/balance_transfer.rs b/runtime/src/precompiles/balance_transfer.rs deleted file mode 100644 index c1b68d4f74..0000000000 --- a/runtime/src/precompiles/balance_transfer.rs +++ /dev/null @@ -1,40 +0,0 @@ -use pallet_evm::PrecompileHandle; -use precompile_utils::EvmResult; -use sp_core::H256; -use sp_runtime::traits::UniqueSaturatedInto; - -use crate::Runtime; -use crate::precompiles::{PrecompileExt, PrecompileHandleExt, contract_to_origin, parse_pubkey}; - -pub struct BalanceTransferPrecompile; - -impl PrecompileExt for BalanceTransferPrecompile { - const INDEX: u64 = 2048; - const ADDRESS_SS58: [u8; 32] = [ - 0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd, - 0xfc, 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93, - 0x70, 0x5d, - ]; -} - -#[precompile_utils::precompile] -impl BalanceTransferPrecompile { - #[precompile::public("transfer(bytes32)")] - #[precompile::payable] - fn transfer(handle: &mut impl PrecompileHandle, address: H256) -> EvmResult<()> { - let amount_sub = handle.try_convert_apparent_value()?; - - if amount_sub.is_zero() { - return Ok(()); - } - - let dest = parse_pubkey(address.as_bytes())?.0.into(); - - let call = pallet_balances::Call::::transfer_allow_death { - dest, - value: amount_sub.unique_saturated_into(), - }; - - handle.try_dispatch_runtime_call(call, contract_to_origin(&Self::ADDRESS_SS58)?) - } -} diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs deleted file mode 100644 index bba70eb027..0000000000 --- a/runtime/src/precompiles/mod.rs +++ /dev/null @@ -1,292 +0,0 @@ -extern crate alloc; - -use alloc::format; -use core::marker::PhantomData; - -use frame_support::dispatch::{GetDispatchInfo, Pays}; -use frame_system::RawOrigin; -use pallet_evm::{ - AddressMapping, BalanceConverter, ExitError, GasWeightMapping, HashedAddressMapping, - IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult, - PrecompileSet, -}; -use pallet_evm_precompile_modexp::Modexp; -use pallet_evm_precompile_sha3fips::Sha3FIPS256; -use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; -use precompile_utils::EvmResult; -use sp_core::{H160, U256}; -use sp_runtime::traits::BlakeTwo256; -use sp_runtime::{AccountId32, traits::Dispatchable}; - -use pallet_admin_utils::{PrecompileEnable, PrecompileEnum}; -use sp_std::vec; - -use crate::{Runtime, RuntimeCall}; - -// Include custom precompiles -mod balance_transfer; -mod ed25519; -mod metagraph; -mod neuron; -mod staking; -mod subnet; - -use balance_transfer::*; -use ed25519::*; -use metagraph::*; -use neuron::*; -use staking::*; -use subnet::*; - -pub struct FrontierPrecompiles(PhantomData); -impl Default for FrontierPrecompiles -where - R: pallet_evm::Config, -{ - fn default() -> Self { - Self::new() - } -} - -impl FrontierPrecompiles -where - R: pallet_evm::Config, -{ - pub fn new() -> Self { - Self(Default::default()) - } - pub fn used_addresses() -> [H160; 13] { - [ - hash(1), - hash(2), - hash(3), - hash(4), - hash(5), - hash(1024), - hash(1025), - hash(Ed25519Verify::INDEX), - hash(BalanceTransferPrecompile::INDEX), - hash(StakingPrecompile::INDEX), - hash(SubnetPrecompile::INDEX), - hash(MetagraphPrecompile::INDEX), - hash(NeuronPrecompile::INDEX), - ] - } -} -impl PrecompileSet for FrontierPrecompiles -where - R: pallet_evm::Config, -{ - fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { - match handle.code_address() { - // Ethereum precompiles : - a if a == hash(1) => Some(ECRecover::execute(handle)), - a if a == hash(2) => Some(Sha256::execute(handle)), - a if a == hash(3) => Some(Ripemd160::execute(handle)), - a if a == hash(4) => Some(Identity::execute(handle)), - a if a == hash(5) => Some(Modexp::execute(handle)), - // Non-Frontier specific nor Ethereum precompiles : - a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), - a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), - a if a == hash(Ed25519Verify::INDEX) => Some(Ed25519Verify::execute(handle)), - // Subtensor specific precompiles : - a if a == hash(BalanceTransferPrecompile::INDEX) => { - if PrecompileEnable::::get(PrecompileEnum::BalanceTransfer) { - Some(BalanceTransferPrecompile::execute(handle)) - } else { - Some(Err(PrecompileFailure::Error { - exit_status: ExitError::Other( - "Precompile Balance Transfer is disabled".into(), - ), - })) - } - } - a if a == hash(StakingPrecompile::INDEX) => { - if PrecompileEnable::::get(PrecompileEnum::Staking) { - Some(StakingPrecompile::execute(handle)) - } else { - Some(Err(PrecompileFailure::Error { - exit_status: ExitError::Other( - "Precompile Balance Transfer is disabled".into(), - ), - })) - } - } - - a if a == hash(SubnetPrecompile::INDEX) => { - if PrecompileEnable::::get(PrecompileEnum::Subnet) { - Some(SubnetPrecompile::execute(handle)) - } else { - Some(Err(PrecompileFailure::Error { - exit_status: ExitError::Other("Precompile Subnet is disabled".into()), - })) - } - } - a if a == hash(MetagraphPrecompile::INDEX) => { - if PrecompileEnable::::get(PrecompileEnum::Metagraph) { - Some(MetagraphPrecompile::execute(handle)) - } else { - Some(Err(PrecompileFailure::Error { - exit_status: ExitError::Other("Precompile Metagrah is disabled".into()), - })) - } - } - a if a == hash(NeuronPrecompile::INDEX) => { - if PrecompileEnable::::get(PrecompileEnum::Neuron) { - Some(NeuronPrecompile::execute(handle)) - } else { - Some(Err(PrecompileFailure::Error { - exit_status: ExitError::Other("Precompile Neuron is disabled".into()), - })) - } - } - - _ => None, - } - } - - fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: Self::used_addresses().contains(&address), - extra_cost: 0, - } - } -} - -fn hash(a: u64) -> H160 { - H160::from_low_u64_be(a) -} - -/// Takes a slice from bytes with PrecompileFailure as Error -fn parse_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], PrecompileFailure> { - let maybe_slice = data.get(from..to); - if let Some(slice) = maybe_slice { - Ok(slice) - } else { - log::error!( - "fail to get slice from data, {:?}, from {}, to {}", - &data, - from, - to - ); - Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }) - } -} - -fn parse_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), PrecompileFailure> { - let mut pubkey = [0u8; 32]; - pubkey.copy_from_slice(parse_slice(data, 0, 32)?); - - Ok(( - pubkey.into(), - data.get(32..) - .map_or_else(vec::Vec::new, |slice| slice.to_vec()), - )) -} - -fn try_u16_from_u256(value: U256) -> Result { - value.try_into().map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::Other("the value is outside of u16 bounds".into()), - }) -} - -fn contract_to_origin(contract: &[u8; 32]) -> Result, PrecompileFailure> { - let (account_id, _) = parse_pubkey(contract)?; - Ok(RawOrigin::Signed(account_id)) -} - -trait PrecompileHandleExt: PrecompileHandle { - fn caller_account_id(&self) -> AccountId32 { - as AddressMapping>::into_account_id( - self.context().caller, - ) - } - - fn try_convert_apparent_value(&self) -> EvmResult { - let amount = self.context().apparent_value; - ::BalanceConverter::into_substrate_balance(amount).ok_or( - PrecompileFailure::Error { - exit_status: ExitError::Other( - "error converting balance from ETH to subtensor".into(), - ), - }, - ) - } - - /// Dispatches a runtime call, but also checks and records the gas costs. - fn try_dispatch_runtime_call( - &mut self, - call: impl Into, - origin: RawOrigin, - ) -> EvmResult<()> { - let call = Into::::into(call); - let info = call.get_dispatch_info(); - - let target_gas = self.gas_limit(); - if let Some(gas) = target_gas { - let valid_weight = - ::GasWeightMapping::gas_to_weight(gas, false) - .ref_time(); - if info.weight.ref_time() > valid_weight { - return Err(PrecompileFailure::Error { - exit_status: ExitError::OutOfGas, - }); - } - } - - self.record_external_cost( - Some(info.weight.ref_time()), - Some(info.weight.proof_size()), - None, - )?; - - match call.dispatch(origin.into()) { - Ok(post_info) => { - if post_info.pays_fee(&info) == Pays::Yes { - let actual_weight = post_info.actual_weight.unwrap_or(info.weight); - let cost = ::GasWeightMapping::weight_to_gas( - actual_weight, - ); - self.record_cost(cost)?; - - self.refund_external_cost( - Some( - info.weight - .ref_time() - .saturating_sub(actual_weight.ref_time()), - ), - Some( - info.weight - .proof_size() - .saturating_sub(actual_weight.proof_size()), - ), - ); - } - - log::info!("Dispatch succeeded. Post info: {:?}", post_info); - - Ok(()) - } - Err(e) => { - log::error!("Dispatch failed. Error: {:?}", e); - log::warn!("Returning error PrecompileFailure::Error"); - Err(PrecompileFailure::Error { - exit_status: ExitError::Other( - format!("dispatch execution failed: {}", <&'static str>::from(e)).into(), - ), - }) - } - } - } -} - -impl PrecompileHandleExt for T where T: PrecompileHandle {} - -trait PrecompileExt: Precompile { - const INDEX: u64; - // ss58 public key i.e., the contract sends funds it received to the destination address from - // the method parameter. - const ADDRESS_SS58: [u8; 32]; -} diff --git a/runtime/src/precompiles/staking.rs b/runtime/src/precompiles/staking.rs deleted file mode 100644 index 848fe8e750..0000000000 --- a/runtime/src/precompiles/staking.rs +++ /dev/null @@ -1,171 +0,0 @@ -// The goal of staking precompile is to allow interaction between EVM users and smart contracts and -// subtensor staking functionality, namely add_stake, and remove_stake extrinsicsk, as well as the -// staking state. -// -// Additional requirement is to preserve compatibility with Ethereum indexers, which requires -// no balance transfers from EVM accounts without a corresponding transaction that can be -// parsed by an indexer. -// -// Implementation of add_stake: -// - User transfers balance that will be staked to the precompile address with a payable -// method addStake. This method also takes hotkey public key (bytes32) of the hotkey -// that the stake should be assigned to. -// - Precompile transfers the balance back to the signing address, and then invokes -// do_add_stake from subtensor pallet with signing origin that mmatches to HashedAddressMapping -// of the message sender, which will effectively withdraw and stake balance from the message -// sender. -// - Precompile checks the result of do_add_stake and, in case of a failure, reverts the transaction, -// and leaves the balance on the message sender account. -// -// Implementation of remove_stake: -// - User involkes removeStake method and specifies hotkey public key (bytes32) of the hotkey -// to remove stake from, and the amount to unstake. -// - Precompile calls do_remove_stake method of the subtensor pallet with the signing origin of message -// sender, which effectively unstakes the specified amount and credits it to the message sender -// - Precompile checks the result of do_remove_stake and, in case of a failure, reverts the transaction. -// - -use frame_system::RawOrigin; -use pallet_evm::{BalanceConverter, ExitError, PrecompileFailure, PrecompileHandle}; -use precompile_utils::EvmResult; -use sp_core::{H256, U256}; -use sp_runtime::AccountId32; -use sp_runtime::traits::{Dispatchable, StaticLookup, UniqueSaturatedInto}; - -use crate::precompiles::{PrecompileExt, PrecompileHandleExt, parse_pubkey, try_u16_from_u256}; -use crate::{ProxyType, Runtime, RuntimeCall}; - -pub struct StakingPrecompile; - -impl PrecompileExt for StakingPrecompile { - const INDEX: u64 = 2049; - const ADDRESS_SS58: [u8; 32] = [ - 0x26, 0xf4, 0x10, 0x1e, 0x52, 0xb7, 0x57, 0x34, 0x33, 0x24, 0x5b, 0xc3, 0x0a, 0xe1, 0x8b, - 0x63, 0x99, 0x53, 0xd8, 0x41, 0x79, 0x33, 0x03, 0x61, 0x4d, 0xfa, 0xcf, 0xf0, 0x37, 0xf7, - 0x12, 0x94, - ]; -} - -#[precompile_utils::precompile] -impl StakingPrecompile { - #[precompile::public("addStake(bytes32,uint256)")] - #[precompile::payable] - fn add_stake(handle: &mut impl PrecompileHandle, address: H256, netuid: U256) -> EvmResult<()> { - let account_id = handle.caller_account_id(); - let amount = handle.context().apparent_value; - - if !amount.is_zero() { - Self::transfer_back_to_caller(&account_id, amount)?; - } - - let amount_sub = handle.try_convert_apparent_value()?; - let (hotkey, _) = parse_pubkey(address.as_bytes())?; - let netuid = try_u16_from_u256(netuid)?; - let call = pallet_subtensor::Call::::add_stake { - hotkey, - netuid, - amount_staked: amount_sub.unique_saturated_into(), - }; - - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) - } - - #[precompile::public("removeStake(bytes32,uint256,uint256)")] - fn remove_stake( - handle: &mut impl PrecompileHandle, - address: H256, - amount: U256, - netuid: U256, - ) -> EvmResult<()> { - let account_id = handle.caller_account_id(); - let (hotkey, _) = parse_pubkey(address.as_bytes())?; - let netuid = try_u16_from_u256(netuid)?; - let amount_unstaked = amount.unique_saturated_into(); - let call = pallet_subtensor::Call::::remove_stake { - hotkey, - netuid, - amount_unstaked, - }; - - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) - } - - #[precompile::public("addProxy(bytes32)")] - fn add_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { - let account_id = handle.caller_account_id(); - let (delegate, _) = parse_pubkey(delegate.as_bytes())?; - let delegate = ::Lookup::unlookup(delegate); - let call = pallet_proxy::Call::::add_proxy { - delegate, - proxy_type: ProxyType::Staking, - delay: 0, - }; - - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) - } - - #[precompile::public("removeProxy(bytes32)")] - fn remove_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { - let account_id = handle.caller_account_id(); - let (delegate, _) = parse_pubkey(delegate.as_bytes())?; - let delegate = ::Lookup::unlookup(delegate); - let call = pallet_proxy::Call::::remove_proxy { - delegate, - proxy_type: ProxyType::Staking, - delay: 0, - }; - - handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) - } - - #[precompile::public("getStake(bytes32,bytes32,uint256)")] - #[precompile::view] - fn get_stake( - _: &mut impl PrecompileHandle, - hotkey: H256, - coldkey: H256, - netuid: U256, - ) -> EvmResult { - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; - let (coldkey, _) = parse_pubkey(coldkey.as_bytes())?; - let netuid = try_u16_from_u256(netuid)?; - let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, &coldkey, netuid, - ); - - Ok(stake.into()) - } - - fn transfer_back_to_caller( - account_id: &AccountId32, - amount: U256, - ) -> Result<(), PrecompileFailure> { - let smart_contract_account_id: AccountId32 = Self::ADDRESS_SS58.into(); - let amount_sub = - ::BalanceConverter::into_substrate_balance(amount) - .ok_or(ExitError::OutOfFund)?; - - // Create a transfer call from the smart contract to the caller - let transfer_call = - RuntimeCall::Balances(pallet_balances::Call::::transfer_allow_death { - dest: account_id.clone().into(), - value: amount_sub.unique_saturated_into(), - }); - - // Execute the transfer - let transfer_result = - transfer_call.dispatch(RawOrigin::Signed(smart_contract_account_id).into()); - - if let Err(dispatch_error) = transfer_result { - log::error!( - "Transfer back to caller failed. Error: {:?}", - dispatch_error - ); - return Err(PrecompileFailure::Error { - exit_status: ExitError::Other("Transfer back to caller failed".into()), - }); - } - - Ok(()) - } -} diff --git a/runtime/tests/pallet_proxy.rs b/runtime/tests/pallet_proxy.rs index 7d0dec9679..563c274bb9 100644 --- a/runtime/tests/pallet_proxy.rs +++ b/runtime/tests/pallet_proxy.rs @@ -3,9 +3,10 @@ use codec::Encode; use frame_support::{BoundedVec, assert_ok, traits::InstanceFilter}; use node_subtensor_runtime::{ - AccountId, BalancesCall, BuildStorage, Proxy, ProxyType, Runtime, RuntimeCall, RuntimeEvent, - RuntimeGenesisConfig, RuntimeOrigin, SubtensorModule, System, SystemCall, + BalancesCall, BuildStorage, Proxy, Runtime, RuntimeCall, RuntimeEvent, RuntimeGenesisConfig, + RuntimeOrigin, SubtensorModule, System, SystemCall, }; +use subtensor_runtime_common::{AccountId, ProxyType}; const ACCOUNT: [u8; 32] = [1_u8; 32]; const DELEGATE: [u8; 32] = [2_u8; 32]; diff --git a/support/linting/src/forbid_saturating_math.rs b/support/linting/src/forbid_saturating_math.rs new file mode 100644 index 0000000000..9ad5385b36 --- /dev/null +++ b/support/linting/src/forbid_saturating_math.rs @@ -0,0 +1,113 @@ +use super::*; +use syn::{Expr, ExprCall, ExprMethodCall, ExprPath, File, Path, spanned::Spanned, visit::Visit}; + +pub struct ForbidSaturatingMath; + +impl Lint for ForbidSaturatingMath { + fn lint(source: &File) -> Result { + let mut visitor = SaturatingMathBanVisitor::default(); + visitor.visit_file(source); + + if visitor.errors.is_empty() { + Ok(()) + } else { + Err(visitor.errors) + } + } +} + +#[derive(Default)] +struct SaturatingMathBanVisitor { + errors: Vec, +} + +impl<'ast> Visit<'ast> for SaturatingMathBanVisitor { + fn visit_expr_method_call(&mut self, node: &'ast ExprMethodCall) { + let ExprMethodCall { method, .. } = node; + + if method.to_string().starts_with("saturating_") { + let msg = "Safe math is banned to encourage tests to panic"; + self.errors.push(syn::Error::new(method.span(), msg)); + } + } + + fn visit_expr_call(&mut self, node: &'ast ExprCall) { + let ExprCall { func, .. } = node; + + if is_saturating_math_call(func) { + let msg = "Safe math is banned to encourage tests to panic"; + self.errors.push(syn::Error::new(node.func.span(), msg)); + } + } +} + +fn is_saturating_math_call(func: &Expr) -> bool { + let Expr::Path(ExprPath { + path: Path { segments: path, .. }, + .. + }) = func + else { + return false; + }; + + path.last() + .is_some_and(|seg| seg.ident.to_string().starts_with("saturating_")) +} + +#[cfg(test)] +mod tests { + use super::*; + use quote::quote; + + fn lint(input: proc_macro2::TokenStream) -> Result { + let mut visitor = SaturatingMathBanVisitor::default(); + let expr: syn::Expr = syn::parse2(input).expect("should be a valid expression"); + + match &expr { + syn::Expr::MethodCall(call) => visitor.visit_expr_method_call(call), + syn::Expr::Call(call) => visitor.visit_expr_call(call), + _ => panic!("should be a valid method call or function call"), + } + + if visitor.errors.is_empty() { + Ok(()) + } else { + Err(visitor.errors) + } + } + + #[test] + fn test_saturating_forbidden() { + let input = quote! { stake.saturating_add(alpha) }; + assert!(lint(input).is_err()); + let input = quote! { alpha_price.saturating_mul(float_alpha_block_emission) }; + assert!(lint(input).is_err()); + let input = quote! { alpha_out_i.saturating_sub(root_alpha) }; + assert!(lint(input).is_err()); + } + + #[test] + fn test_saturating_ufcs_forbidden() { + let input = quote! { SaturatingAdd::saturating_add(stake, alpha) }; + assert!(lint(input).is_err()); + let input = quote! { core::num::SaturatingAdd::saturating_add(stake, alpha) }; + assert!(lint(input).is_err()); + let input = + quote! { SaturatingMul::saturating_mul(alpha_price, float_alpha_block_emission) }; + assert!(lint(input).is_err()); + let input = quote! { core::num::SaturatingMul::saturating_mul(alpha_price, float_alpha_block_emission) }; + assert!(lint(input).is_err()); + let input = quote! { SaturatingSub::saturating_sub(alpha_out_i, root_alpha) }; + assert!(lint(input).is_err()); + let input = quote! { core::num::SaturatingSub::saturating_sub(alpha_out_i, root_alpha) }; + assert!(lint(input).is_err()); + } + + #[test] + fn test_saturating_to_from_num_forbidden() { + let input = quote! { I96F32::saturating_from_num(u64::MAX) }; + assert!(lint(input).is_err()); + let input = quote! { remaining_emission.saturating_to_num::() }; + assert!(lint(input).is_err()); + } +} diff --git a/support/linting/src/lib.rs b/support/linting/src/lib.rs index a65466e6a5..864d4a5572 100644 --- a/support/linting/src/lib.rs +++ b/support/linting/src/lib.rs @@ -3,10 +3,12 @@ pub use lint::*; mod forbid_as_primitive; mod forbid_keys_remove; +mod forbid_saturating_math; mod pallet_index; mod require_freeze_struct; pub use forbid_as_primitive::ForbidAsPrimitiveConversion; pub use forbid_keys_remove::ForbidKeysRemoveCall; +pub use forbid_saturating_math::ForbidSaturatingMath; pub use pallet_index::RequireExplicitPalletIndex; pub use require_freeze_struct::RequireFreezeStruct;